| Index: src/jump-target.cc
|
| ===================================================================
|
| --- src/jump-target.cc (revision 1481)
|
| +++ src/jump-target.cc (working copy)
|
| @@ -37,23 +37,48 @@
|
|
|
| JumpTarget::JumpTarget(CodeGenerator* cgen, Directionality direction)
|
| : cgen_(cgen),
|
| - masm_(cgen == NULL ? NULL : cgen->masm()),
|
| direction_(direction),
|
| reaching_frames_(0),
|
| merge_labels_(0),
|
| entry_frame_(NULL),
|
| is_bound_(false),
|
| is_linked_(false) {
|
| + ASSERT(cgen != NULL);
|
| + Initialize(cgen, direction);
|
| }
|
|
|
|
|
| +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;
|
| +}
|
| +
|
| +
|
| void JumpTarget::Unuse() {
|
| ASSERT(!is_linked());
|
| - entry_label_.Unuse();
|
| +#ifdef DEBUG
|
| + for (int i = 0; i < reaching_frames_.length(); i++) {
|
| + ASSERT(reaching_frames_[i] == NULL);
|
| + }
|
| +#endif
|
| delete entry_frame_;
|
| - entry_frame_ = NULL;
|
| - is_bound_ = false;
|
| - is_linked_ = false;
|
| +
|
| + Reset();
|
| }
|
|
|
|
|
| @@ -501,16 +526,10 @@
|
| // -------------------------------------------------------------------------
|
| // BreakTarget implementation.
|
|
|
| -BreakTarget::BreakTarget() : JumpTarget(NULL, FORWARD_ONLY) {
|
| -}
|
| -
|
| -
|
| void BreakTarget::Initialize(CodeGenerator* cgen, Directionality direction) {
|
| - ASSERT(cgen != NULL);
|
| - ASSERT(cgen_ == NULL);
|
| - cgen_ = cgen;
|
| - masm_ = cgen->masm();
|
| - direction_ = direction;
|
| + JumpTarget::Initialize(cgen, direction);
|
| + ASSERT(cgen_->has_valid_frame());
|
| + expected_height_ = cgen_->frame()->height();
|
| }
|
|
|
|
|
| @@ -530,9 +549,61 @@
|
| 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());
|
| +
|
| + // This is a break target so drop leftover statement state from the
|
| + // frame before merging.
|
| + cgen_->frame()->ForgetElements(cgen_->frame()->height() - expected_height_);
|
| + JumpTarget::Jump();
|
| +}
|
| +
|
| +
|
| +void BreakTarget::Branch(Condition cc, Hint hint) {
|
| + ASSERT(cgen_ != NULL);
|
| + ASSERT(cgen_->has_valid_frame());
|
| +
|
| + int count = cgen_->frame()->height() - expected_height_;
|
| + if (count > 0) {
|
| + // We negate and branch here rather than using
|
| + // JumpTarget::Branch's negate and branch. This gives us a hook
|
| + // to remove statement state from the frame.
|
| + JumpTarget fall_through(cgen_);
|
| + // Branch to fall through will not negate, because it is a
|
| + // forward-only target.
|
| + fall_through.Branch(NegateCondition(cc), NegateHint(hint));
|
| + Jump(); // May emit merge code here.
|
| + fall_through.Bind();
|
| + } else {
|
| + JumpTarget::Branch(cc, hint);
|
| + }
|
| +}
|
| +
|
| +
|
| +void BreakTarget::Bind(int mergable_elements) {
|
| +#ifdef DEBUG
|
| + ASSERT(mergable_elements == kAllElements);
|
| + ASSERT(cgen_ != NULL);
|
| + for (int i = 0; i < reaching_frames_.length(); i++) {
|
| + ASSERT(reaching_frames_[i]->height() == expected_height_);
|
| + }
|
| +#endif
|
| +
|
| + // This is a break target so drop leftover statement state from the
|
| + // frame before merging.
|
| + if (cgen_->has_valid_frame()) {
|
| + int count = cgen_->frame()->height() - expected_height_;
|
| + cgen_->frame()->ForgetElements(count);
|
| + }
|
| + JumpTarget::Bind(mergable_elements);
|
| +}
|
| +
|
| +
|
| // -------------------------------------------------------------------------
|
| // ShadowTarget implementation.
|
|
|
| @@ -546,15 +617,19 @@
|
| // 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. We do not Unuse it because that
|
| - // would delete the expected frame and assert that the target is not
|
| - // linked.
|
| - shadowed->Reset();
|
| }
|
|
|
|
|
|
|