diff options
author | Ryan <ry@tinyclouds.org> | 2009-06-08 18:34:06 +0200 |
---|---|---|
committer | Ryan <ry@tinyclouds.org> | 2009-06-08 18:34:06 +0200 |
commit | 696f02455792b368249bf9b013dde637b5ec31fd (patch) | |
tree | 95b2dbd6c2537df9df52f6627aac36fcf05f6a7a /deps/v8/src/jump-target.cc | |
parent | f6a7fe26574defaa807a13248102ebe0f23270af (diff) | |
download | node-new-696f02455792b368249bf9b013dde637b5ec31fd.tar.gz |
Upgrade to v8 1.2.7
Diffstat (limited to 'deps/v8/src/jump-target.cc')
-rw-r--r-- | deps/v8/src/jump-target.cc | 494 |
1 files changed, 184 insertions, 310 deletions
diff --git a/deps/v8/src/jump-target.cc b/deps/v8/src/jump-target.cc index 6e41270ee0..a8eda6bd98 100644 --- a/deps/v8/src/jump-target.cc +++ b/deps/v8/src/jump-target.cc @@ -28,115 +28,23 @@ #include "v8.h" #include "codegen-inl.h" +#include "jump-target-inl.h" #include "register-allocator-inl.h" -namespace v8 { namespace internal { +namespace v8 { +namespace internal { // ------------------------------------------------------------------------- // JumpTarget implementation. -JumpTarget::JumpTarget(CodeGenerator* cgen, Directionality direction) - : cgen_(cgen), - direction_(direction), - reaching_frames_(0), - merge_labels_(0), - entry_frame_(NULL), - is_bound_(false), - is_linked_(false) { - ASSERT(cgen != NULL); - masm_ = cgen->masm(); -} - - -JumpTarget::JumpTarget() - : cgen_(NULL), - masm_(NULL), - direction_(FORWARD_ONLY), - reaching_frames_(0), - merge_labels_(0), - entry_frame_(NULL), - is_bound_(false), - is_linked_(false) { -} - - -void JumpTarget::Initialize(CodeGenerator* cgen, Directionality direction) { - ASSERT(cgen != NULL); - ASSERT(cgen_ == NULL); - cgen_ = cgen; - masm_ = cgen->masm(); - direction_ = direction; -} +bool JumpTarget::compiling_deferred_code_ = false; void JumpTarget::Unuse() { - // We should not deallocate jump targets that have unresolved jumps - // to them. In the event of a compile-time stack overflow or an - // uninitialized jump target, we don't care. - ASSERT(!is_linked() || cgen_ == NULL || cgen_->HasStackOverflow()); - for (int i = 0; i < reaching_frames_.length(); i++) { - delete reaching_frames_[i]; - } - delete entry_frame_; - Reset(); -} - - -void JumpTarget::Reset() { reaching_frames_.Clear(); merge_labels_.Clear(); entry_frame_ = NULL; entry_label_.Unuse(); - is_bound_ = false; - is_linked_ = false; -} - - -FrameElement* JumpTarget::Combine(FrameElement* left, FrameElement* right) { - // Given a pair of non-null frame element pointers, return one of - // them as an entry frame candidate or null if they are - // incompatible. - - // If either is invalid, the result is. - if (!left->is_valid()) return left; - if (!right->is_valid()) return right; - - // If they have the same value, the result is the same. If either - // is unsynced, the result is. - - if (left->is_memory() && right->is_memory()) return left; - - if (left->is_register() && right->is_register() && - left->reg().is(right->reg())) { - if (!left->is_synced()) { - return left; - } else { - return right; - } - } - - if (left->is_constant() && - right->is_constant() && - left->handle().is_identical_to(right->handle())) { - if (!left->is_synced()) { - return left; - } else { - return right; - } - } - - if (left->is_copy() && - right->is_copy() && - left->index() == right->index()) { - if (!left->is_synced()) { - return left; - } else { - return right; - } - } - - // Otherwise they are incompatible and we will reallocate them. - return NULL; } @@ -145,13 +53,29 @@ void JumpTarget::ComputeEntryFrame(int mergable_elements) { // the directionality of the block. Compute: an entry frame for the // block. + Counters::compute_entry_frame.Increment(); +#ifdef DEBUG + if (compiling_deferred_code_) { + ASSERT(reaching_frames_.length() > 1); + VirtualFrame* frame = reaching_frames_[0]; + bool all_identical = true; + for (int i = 1; i < reaching_frames_.length(); i++) { + if (!frame->Equals(reaching_frames_[i])) { + all_identical = false; + break; + } + } + ASSERT(!all_identical || all_identical); + } +#endif + // Choose an initial frame. VirtualFrame* initial_frame = reaching_frames_[0]; // A list of pointers to frame elements in the entry frame. NULL // indicates that the element has not yet been determined. - int length = initial_frame->elements_.length(); - List<FrameElement*> elements(length); + int length = initial_frame->element_count(); + ZoneList<FrameElement*> elements(length); // Convert the number of mergable elements (counted from the top // down) to a frame high-water mark (counted from the bottom up). @@ -165,63 +89,59 @@ void JumpTarget::ComputeEntryFrame(int mergable_elements) { // frame. for (int i = 0; i < length; i++) { FrameElement element = initial_frame->elements_[i]; - // We do not allow copies or constants in bidirectional frames. - if (direction_ == BIDIRECTIONAL && i > high_water_mark && - (element.is_constant() || element.is_copy())) { - elements.Add(NULL); - } else { - elements.Add(&initial_frame->elements_[i]); + // We do not allow copies or constants in bidirectional frames. All + // elements above the water mark on bidirectional frames have + // unknown static types. + if (direction_ == BIDIRECTIONAL && i > high_water_mark) { + if (element.is_constant() || element.is_copy()) { + elements.Add(NULL); + continue; + } + // It's safe to change the static type on the initial frame + // element, see comment in JumpTarget::Combine. + initial_frame->elements_[i].set_static_type(StaticType::unknown()); } + elements.Add(&initial_frame->elements_[i]); } // Compute elements based on the other reaching frames. if (reaching_frames_.length() > 1) { for (int i = 0; i < length; i++) { + FrameElement* element = elements[i]; for (int j = 1; j < reaching_frames_.length(); j++) { - FrameElement* element = elements[i]; - // Element computation is monotonic: new information will not // change our decision about undetermined or invalid elements. if (element == NULL || !element->is_valid()) break; - elements[i] = Combine(element, &reaching_frames_[j]->elements_[i]); + element = element->Combine(&reaching_frames_[j]->elements_[i]); } + elements[i] = element; } } // Build the new frame. A freshly allocated frame has memory elements // for the parameters and some platform-dependent elements (e.g., // return address). Replace those first. - entry_frame_ = new VirtualFrame(cgen_); + entry_frame_ = new VirtualFrame(); int index = 0; - for (; index < entry_frame_->elements_.length(); index++) { + for (; index < entry_frame_->element_count(); index++) { + FrameElement* target = elements[index]; // If the element is determined, set it now. Count registers. Mark // elements as copied exactly when they have a copy. Undetermined // elements are initially recorded as if in memory. - if (elements[index] != NULL) { - entry_frame_->elements_[index] = *elements[index]; - entry_frame_->elements_[index].clear_copied(); - if (elements[index]->is_register()) { - entry_frame_->register_locations_[elements[index]->reg().code()] = - index; - } else if (elements[index]->is_copy()) { - entry_frame_->elements_[elements[index]->index()].set_copied(); - } + if (target != NULL) { + entry_frame_->elements_[index] = *target; + InitializeEntryElement(index, target); } } // Then fill in the rest of the frame with new elements. for (; index < length; index++) { - if (elements[index] == NULL) { + FrameElement* target = elements[index]; + if (target == NULL) { entry_frame_->elements_.Add(FrameElement::MemoryElement()); } else { - entry_frame_->elements_.Add(*elements[index]); - entry_frame_->elements_[index].clear_copied(); - if (elements[index]->is_register()) { - entry_frame_->register_locations_[elements[index]->reg().code()] = - index; - } else if (elements[index]->is_copy()) { - entry_frame_->elements_[elements[index]->index()].set_copied(); - } + entry_frame_->elements_.Add(*target); + InitializeEntryElement(index, target); } } @@ -229,82 +149,74 @@ void JumpTarget::ComputeEntryFrame(int mergable_elements) { // memory, from the top down. for (int i = length - 1; i >= 0; i--) { if (elements[i] == NULL) { - // If the value is synced on all frames, put it in memory. This - // costs nothing at the merge code but will incur a - // memory-to-register move when the value is needed later. + // Loop over all the reaching frames to check whether the element + // is synced on all frames, to count the registers it occupies, + // and to compute a merged static type. bool is_synced = true; - for (int j = 0; is_synced && j < reaching_frames_.length(); j++) { - is_synced = reaching_frames_[j]->elements_[i].is_synced(); - } - - // There is nothing to be done if the elements are all synced. - // It is already recorded as a memory element. - if (is_synced) continue; - - // Choose an available register. Prefer ones that the element - // is already occupying on some reaching frame. RegisterFile candidate_registers; - int max_count = kMinInt; - int best_reg_code = no_reg.code_; + int best_count = kMinInt; + int best_reg_num = RegisterAllocator::kInvalidRegister; + + StaticType type; // Initially invalid. + if (direction_ != BIDIRECTIONAL || i < high_water_mark) { + type = reaching_frames_[0]->elements_[i].static_type(); + } for (int j = 0; j < reaching_frames_.length(); j++) { FrameElement element = reaching_frames_[j]->elements_[i]; - if (element.is_register() && - !entry_frame_->is_used(element.reg())) { - candidate_registers.Use(element.reg()); - if (candidate_registers.count(element.reg()) > max_count) { - max_count = candidate_registers.count(element.reg()); - best_reg_code = element.reg().code(); + is_synced = is_synced && element.is_synced(); + if (element.is_register() && !entry_frame_->is_used(element.reg())) { + // Count the register occurrence and remember it if better + // than the previous best. + int num = RegisterAllocator::ToNumber(element.reg()); + candidate_registers.Use(num); + if (candidate_registers.count(num) > best_count) { + best_count = candidate_registers.count(num); + best_reg_num = num; } } + type = type.merge(element.static_type()); } - // If there was no preferred choice consider any free register. - if (best_reg_code == no_reg.code_) { - for (int j = 0; j < kNumRegisters; j++) { - if (!entry_frame_->is_used(j) && !RegisterAllocator::IsReserved(j)) { - best_reg_code = j; + + // If the value is synced on all frames, put it in memory. This + // costs nothing at the merge code but will incur a + // memory-to-register move when the value is needed later. + if (is_synced) { + // Already recorded as a memory element. + entry_frame_->elements_[i].set_static_type(type); + continue; + } + + // Try to put it in a register. If there was no best choice + // consider any free register. + if (best_reg_num == RegisterAllocator::kInvalidRegister) { + for (int j = 0; j < RegisterAllocator::kNumRegisters; j++) { + if (!entry_frame_->is_used(j)) { + best_reg_num = j; break; } } } - if (best_reg_code != no_reg.code_) { + if (best_reg_num == RegisterAllocator::kInvalidRegister) { + // If there was no register found, the element is already + // recorded as in memory. + entry_frame_->elements_[i].set_static_type(type); + } else { // If there was a register choice, use it. Preserve the copied - // flag on the element. + // flag on the element. Set the static type as computed. bool is_copied = entry_frame_->elements_[i].is_copied(); - Register reg = { best_reg_code }; + Register reg = RegisterAllocator::ToRegister(best_reg_num); entry_frame_->elements_[i] = FrameElement::RegisterElement(reg, FrameElement::NOT_SYNCED); if (is_copied) entry_frame_->elements_[i].set_copied(); - entry_frame_->register_locations_[best_reg_code] = i; + entry_frame_->elements_[i].set_static_type(type); + entry_frame_->set_register_location(reg, i); } - // If there was no register found, the element is already - // recorded as in memory. } } - // Set the static type of frame elements. - for (int i = 0; i < length; i++) { - FrameElement* current = &entry_frame_->elements_[i]; - if (direction_ == BIDIRECTIONAL && i >= high_water_mark) { - current->set_static_type(StaticType::unknown()); - } else { - StaticType merged_type = reaching_frames_[0]->elements_[i].static_type(); - for (int j = 1, n = reaching_frames_.length(); - !merged_type.is_unknown() && j < n; - j++) { - merged_type = - merged_type.merge(reaching_frames_[j]->elements_[i].static_type()); - } - current->set_static_type(merged_type); - } - } - - // Fill in the other fields of the entry frame. - entry_frame_->local_count_ = initial_frame->local_count_; - entry_frame_->frame_pointer_ = initial_frame->frame_pointer_; - // The stack pointer is at the highest synced element or the base of // the expression stack. int stack_pointer = length - 1; @@ -322,31 +234,28 @@ void JumpTarget::Jump() { void JumpTarget::Jump(Result* arg) { - ASSERT(cgen_ != NULL); - ASSERT(cgen_->has_valid_frame()); + ASSERT(cgen()->has_valid_frame()); - cgen_->frame()->Push(arg); + cgen()->frame()->Push(arg); DoJump(); } void JumpTarget::Jump(Result* arg0, Result* arg1) { - ASSERT(cgen_ != NULL); - ASSERT(cgen_->has_valid_frame()); + ASSERT(cgen()->has_valid_frame()); - cgen_->frame()->Push(arg0); - cgen_->frame()->Push(arg1); + cgen()->frame()->Push(arg0); + cgen()->frame()->Push(arg1); DoJump(); } void JumpTarget::Jump(Result* arg0, Result* arg1, Result* arg2) { - ASSERT(cgen_ != NULL); - ASSERT(cgen_->has_valid_frame()); + ASSERT(cgen()->has_valid_frame()); - cgen_->frame()->Push(arg0); - cgen_->frame()->Push(arg1); - cgen_->frame()->Push(arg2); + cgen()->frame()->Push(arg0); + cgen()->frame()->Push(arg1); + cgen()->frame()->Push(arg2); DoJump(); } @@ -372,35 +281,33 @@ void JumpTarget::Branch(Condition cc, Hint hint) { #endif void JumpTarget::Branch(Condition cc, Result* arg, Hint hint) { - ASSERT(cgen_ != NULL); - ASSERT(cgen_->has_valid_frame()); + ASSERT(cgen()->has_valid_frame()); // We want to check that non-frame registers at the call site stay in // the same registers on the fall-through branch. DECLARE_ARGCHECK_VARS(arg); - cgen_->frame()->Push(arg); + cgen()->frame()->Push(arg); DoBranch(cc, hint); - *arg = cgen_->frame()->Pop(); + *arg = cgen()->frame()->Pop(); ASSERT_ARGCHECK(arg); } void JumpTarget::Branch(Condition cc, Result* arg0, Result* arg1, Hint hint) { - ASSERT(cgen_ != NULL); - ASSERT(cgen_->frame() != NULL); + ASSERT(cgen()->frame() != NULL); // We want to check that non-frame registers at the call site stay in // the same registers on the fall-through branch. DECLARE_ARGCHECK_VARS(arg0); DECLARE_ARGCHECK_VARS(arg1); - cgen_->frame()->Push(arg0); - cgen_->frame()->Push(arg1); + cgen()->frame()->Push(arg0); + cgen()->frame()->Push(arg1); DoBranch(cc, hint); - *arg1 = cgen_->frame()->Pop(); - *arg0 = cgen_->frame()->Pop(); + *arg1 = cgen()->frame()->Pop(); + *arg0 = cgen()->frame()->Pop(); ASSERT_ARGCHECK(arg0); ASSERT_ARGCHECK(arg1); @@ -412,8 +319,7 @@ void JumpTarget::Branch(Condition cc, Result* arg1, Result* arg2, Hint hint) { - ASSERT(cgen_ != NULL); - ASSERT(cgen_->frame() != NULL); + ASSERT(cgen()->frame() != NULL); // We want to check that non-frame registers at the call site stay in // the same registers on the fall-through branch. @@ -421,13 +327,13 @@ void JumpTarget::Branch(Condition cc, DECLARE_ARGCHECK_VARS(arg1); DECLARE_ARGCHECK_VARS(arg2); - cgen_->frame()->Push(arg0); - cgen_->frame()->Push(arg1); - cgen_->frame()->Push(arg2); + cgen()->frame()->Push(arg0); + cgen()->frame()->Push(arg1); + cgen()->frame()->Push(arg2); DoBranch(cc, hint); - *arg2 = cgen_->frame()->Pop(); - *arg1 = cgen_->frame()->Pop(); - *arg0 = cgen_->frame()->Pop(); + *arg2 = cgen()->frame()->Pop(); + *arg1 = cgen()->frame()->Pop(); + *arg0 = cgen()->frame()->Pop(); ASSERT_ARGCHECK(arg0); ASSERT_ARGCHECK(arg1); @@ -441,8 +347,7 @@ void JumpTarget::Branch(Condition cc, Result* arg2, Result* arg3, Hint hint) { - ASSERT(cgen_ != NULL); - ASSERT(cgen_->frame() != NULL); + ASSERT(cgen()->frame() != NULL); // We want to check that non-frame registers at the call site stay in // the same registers on the fall-through branch. @@ -451,15 +356,15 @@ void JumpTarget::Branch(Condition cc, DECLARE_ARGCHECK_VARS(arg2); DECLARE_ARGCHECK_VARS(arg3); - cgen_->frame()->Push(arg0); - cgen_->frame()->Push(arg1); - cgen_->frame()->Push(arg2); - cgen_->frame()->Push(arg3); + cgen()->frame()->Push(arg0); + cgen()->frame()->Push(arg1); + cgen()->frame()->Push(arg2); + cgen()->frame()->Push(arg3); DoBranch(cc, hint); - *arg3 = cgen_->frame()->Pop(); - *arg2 = cgen_->frame()->Pop(); - *arg1 = cgen_->frame()->Pop(); - *arg0 = cgen_->frame()->Pop(); + *arg3 = cgen()->frame()->Pop(); + *arg2 = cgen()->frame()->Pop(); + *arg1 = cgen()->frame()->Pop(); + *arg0 = cgen()->frame()->Pop(); ASSERT_ARGCHECK(arg0); ASSERT_ARGCHECK(arg1); @@ -469,15 +374,14 @@ void JumpTarget::Branch(Condition cc, void BreakTarget::Branch(Condition cc, Result* arg, Hint hint) { - ASSERT(cgen_ != NULL); - ASSERT(cgen_->has_valid_frame()); + ASSERT(cgen()->has_valid_frame()); - int count = cgen_->frame()->height() - expected_height_; + int count = cgen()->frame()->height() - expected_height_; if (count > 0) { // We negate and branch here rather than using DoBranch's negate // and branch. This gives us a hook to remove statement state // from the frame. - JumpTarget fall_through(cgen_); + JumpTarget fall_through; // Branch to fall through will not negate, because it is a // forward-only target. fall_through.Branch(NegateCondition(cc), NegateHint(hint)); @@ -485,9 +389,9 @@ void BreakTarget::Branch(Condition cc, Result* arg, Hint hint) { fall_through.Bind(); } else { DECLARE_ARGCHECK_VARS(arg); - cgen_->frame()->Push(arg); + cgen()->frame()->Push(arg); DoBranch(cc, hint); - *arg = cgen_->frame()->Pop(); + *arg = cgen()->frame()->Pop(); ASSERT_ARGCHECK(arg); } } @@ -502,26 +406,22 @@ void JumpTarget::Bind(int mergable_elements) { void JumpTarget::Bind(Result* arg, int mergable_elements) { - ASSERT(cgen_ != NULL); - - if (cgen_->has_valid_frame()) { - cgen_->frame()->Push(arg); + if (cgen()->has_valid_frame()) { + cgen()->frame()->Push(arg); } DoBind(mergable_elements); - *arg = cgen_->frame()->Pop(); + *arg = cgen()->frame()->Pop(); } void JumpTarget::Bind(Result* arg0, Result* arg1, int mergable_elements) { - ASSERT(cgen_ != NULL); - - if (cgen_->has_valid_frame()) { - cgen_->frame()->Push(arg0); - cgen_->frame()->Push(arg1); + if (cgen()->has_valid_frame()) { + cgen()->frame()->Push(arg0); + cgen()->frame()->Push(arg1); } DoBind(mergable_elements); - *arg1 = cgen_->frame()->Pop(); - *arg0 = cgen_->frame()->Pop(); + *arg1 = cgen()->frame()->Pop(); + *arg0 = cgen()->frame()->Pop(); } @@ -529,17 +429,15 @@ void JumpTarget::Bind(Result* arg0, Result* arg1, Result* arg2, int mergable_elements) { - ASSERT(cgen_ != NULL); - - if (cgen_->has_valid_frame()) { - cgen_->frame()->Push(arg0); - cgen_->frame()->Push(arg1); - cgen_->frame()->Push(arg2); + if (cgen()->has_valid_frame()) { + cgen()->frame()->Push(arg0); + cgen()->frame()->Push(arg1); + cgen()->frame()->Push(arg2); } DoBind(mergable_elements); - *arg2 = cgen_->frame()->Pop(); - *arg1 = cgen_->frame()->Pop(); - *arg0 = cgen_->frame()->Pop(); + *arg2 = cgen()->frame()->Pop(); + *arg1 = cgen()->frame()->Pop(); + *arg0 = cgen()->frame()->Pop(); } @@ -548,24 +446,23 @@ void JumpTarget::Bind(Result* arg0, Result* arg2, Result* arg3, int mergable_elements) { - ASSERT(cgen_ != NULL); - - if (cgen_->has_valid_frame()) { - cgen_->frame()->Push(arg0); - cgen_->frame()->Push(arg1); - cgen_->frame()->Push(arg2); - cgen_->frame()->Push(arg3); + if (cgen()->has_valid_frame()) { + cgen()->frame()->Push(arg0); + cgen()->frame()->Push(arg1); + cgen()->frame()->Push(arg2); + cgen()->frame()->Push(arg3); } DoBind(mergable_elements); - *arg3 = cgen_->frame()->Pop(); - *arg2 = cgen_->frame()->Pop(); - *arg1 = cgen_->frame()->Pop(); - *arg0 = cgen_->frame()->Pop(); + *arg3 = cgen()->frame()->Pop(); + *arg2 = cgen()->frame()->Pop(); + *arg1 = cgen()->frame()->Pop(); + *arg0 = cgen()->frame()->Pop(); } void JumpTarget::AddReachingFrame(VirtualFrame* frame) { ASSERT(reaching_frames_.length() == merge_labels_.length()); + ASSERT(entry_frame_ == NULL); Label fresh; merge_labels_.Add(fresh); reaching_frames_.Add(frame); @@ -575,64 +472,54 @@ void JumpTarget::AddReachingFrame(VirtualFrame* frame) { // ------------------------------------------------------------------------- // BreakTarget implementation. -void BreakTarget::Initialize(CodeGenerator* cgen, Directionality direction) { - JumpTarget::Initialize(cgen, direction); - ASSERT(cgen_->has_valid_frame()); - expected_height_ = cgen_->frame()->height(); +void BreakTarget::set_direction(Directionality direction) { + JumpTarget::set_direction(direction); + ASSERT(cgen()->has_valid_frame()); + expected_height_ = cgen()->frame()->height(); } void BreakTarget::CopyTo(BreakTarget* destination) { ASSERT(destination != NULL); - destination->cgen_ = cgen_; - destination->masm_ = masm_; destination->direction_ = direction_; - destination->reaching_frames_.Clear(); - destination->merge_labels_.Clear(); - ASSERT(reaching_frames_.length() == merge_labels_.length()); - for (int i = 0; i < reaching_frames_.length(); i++) { - destination->reaching_frames_.Add(reaching_frames_[i]); - destination->merge_labels_.Add(merge_labels_[i]); - } + destination->reaching_frames_.Rewind(0); + destination->reaching_frames_.AddAll(reaching_frames_); + destination->merge_labels_.Rewind(0); + destination->merge_labels_.AddAll(merge_labels_); destination->entry_frame_ = entry_frame_; destination->entry_label_ = entry_label_; - destination->is_bound_ = is_bound_; - destination->is_linked_ = is_linked_; destination->expected_height_ = expected_height_; } void BreakTarget::Jump() { - ASSERT(cgen_ != NULL); - ASSERT(cgen_->has_valid_frame()); + ASSERT(cgen()->has_valid_frame()); // Drop leftover statement state from the frame before merging. - cgen_->frame()->ForgetElements(cgen_->frame()->height() - expected_height_); + cgen()->frame()->ForgetElements(cgen()->frame()->height() - expected_height_); DoJump(); } void BreakTarget::Jump(Result* arg) { - ASSERT(cgen_ != NULL); - ASSERT(cgen_->has_valid_frame()); + ASSERT(cgen()->has_valid_frame()); // Drop leftover statement state from the frame before merging. - cgen_->frame()->ForgetElements(cgen_->frame()->height() - expected_height_); - cgen_->frame()->Push(arg); + cgen()->frame()->ForgetElements(cgen()->frame()->height() - expected_height_); + cgen()->frame()->Push(arg); DoJump(); } void BreakTarget::Branch(Condition cc, Hint hint) { - ASSERT(cgen_ != NULL); - ASSERT(cgen_->has_valid_frame()); + ASSERT(cgen()->has_valid_frame()); - int count = cgen_->frame()->height() - expected_height_; + int count = cgen()->frame()->height() - expected_height_; if (count > 0) { // We negate and branch here rather than using DoBranch's negate // and branch. This gives us a hook to remove statement state // from the frame. - JumpTarget fall_through(cgen_); + JumpTarget fall_through; // Branch to fall through will not negate, because it is a // forward-only target. fall_through.Branch(NegateCondition(cc), NegateHint(hint)); @@ -646,7 +533,6 @@ void BreakTarget::Branch(Condition cc, Hint hint) { void BreakTarget::Bind(int mergable_elements) { #ifdef DEBUG - ASSERT(cgen_ != NULL); // All the forward-reaching frames should have been adjusted at the // jumps to this target. for (int i = 0; i < reaching_frames_.length(); i++) { @@ -657,8 +543,9 @@ void BreakTarget::Bind(int mergable_elements) { // Drop leftover statement state from the frame before merging, even // on the fall through. This is so we can bind the return target // with state on the frame. - if (cgen_->has_valid_frame()) { - cgen_->frame()->ForgetElements(cgen_->frame()->height() - expected_height_); + if (cgen()->has_valid_frame()) { + int count = cgen()->frame()->height() - expected_height_; + cgen()->frame()->ForgetElements(count); } DoBind(mergable_elements); } @@ -666,7 +553,6 @@ void BreakTarget::Bind(int mergable_elements) { void BreakTarget::Bind(Result* arg, int mergable_elements) { #ifdef DEBUG - ASSERT(cgen_ != NULL); // All the forward-reaching frames should have been adjusted at the // jumps to this target. for (int i = 0; i < reaching_frames_.length(); i++) { @@ -677,12 +563,13 @@ void BreakTarget::Bind(Result* arg, int mergable_elements) { // Drop leftover statement state from the frame before merging, even // on the fall through. This is so we can bind the return target // with state on the frame. - if (cgen_->has_valid_frame()) { - cgen_->frame()->ForgetElements(cgen_->frame()->height() - expected_height_); - cgen_->frame()->Push(arg); + if (cgen()->has_valid_frame()) { + int count = cgen()->frame()->height() - expected_height_; + cgen()->frame()->ForgetElements(count); + cgen()->frame()->Push(arg); } DoBind(mergable_elements); - *arg = cgen_->frame()->Pop(); + *arg = cgen()->frame()->Pop(); } @@ -699,36 +586,23 @@ ShadowTarget::ShadowTarget(BreakTarget* shadowed) { // While shadowing this shadow target saves the state of the original. shadowed->CopyTo(this); - // The original's state is reset. We do not Unuse it because that - // would delete the expected frame and assert that the target is not - // linked. - shadowed->Reset(); - ASSERT(cgen_ != NULL); - ASSERT(cgen_->has_valid_frame()); - shadowed->set_expected_height(cgen_->frame()->height()); - - // Setting the code generator to null prevents the shadow target from - // being used until shadowing stops. - cgen_ = NULL; - masm_ = NULL; + // The original's state is reset. + shadowed->Unuse(); + ASSERT(cgen()->has_valid_frame()); + shadowed->set_expected_height(cgen()->frame()->height()); } void ShadowTarget::StopShadowing() { ASSERT(is_shadowing_); - // This target does not have a valid code generator yet. - cgen_ = other_target_->code_generator(); - ASSERT(cgen_ != NULL); - masm_ = cgen_->masm(); - // The states of this target, which was shadowed, and the original // target, which was shadowing, are swapped. BreakTarget temp; other_target_->CopyTo(&temp); CopyTo(other_target_); temp.CopyTo(this); - temp.Reset(); // So the destructor does not deallocate virtual frames. + temp.Unuse(); #ifdef DEBUG is_shadowing_ = false; |