| OLD | NEW |
| 1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 19 matching lines...) Expand all Loading... |
| 30 #include "codegen.h" | 30 #include "codegen.h" |
| 31 #include "jump-target.h" | 31 #include "jump-target.h" |
| 32 | 32 |
| 33 namespace v8 { namespace internal { | 33 namespace v8 { namespace internal { |
| 34 | 34 |
| 35 // ------------------------------------------------------------------------- | 35 // ------------------------------------------------------------------------- |
| 36 // JumpTarget implementation. | 36 // JumpTarget implementation. |
| 37 | 37 |
| 38 JumpTarget::JumpTarget(CodeGenerator* cgen, Directionality direction) | 38 JumpTarget::JumpTarget(CodeGenerator* cgen, Directionality direction) |
| 39 : cgen_(cgen), | 39 : cgen_(cgen), |
| 40 masm_(cgen == NULL ? NULL : cgen->masm()), | |
| 41 direction_(direction), | 40 direction_(direction), |
| 42 reaching_frames_(0), | 41 reaching_frames_(0), |
| 43 merge_labels_(0), | 42 merge_labels_(0), |
| 44 entry_frame_(NULL), | 43 entry_frame_(NULL), |
| 45 is_bound_(false), | 44 is_bound_(false), |
| 46 is_linked_(false) { | 45 is_linked_(false) { |
| 46 ASSERT(cgen != NULL); |
| 47 Initialize(cgen, direction); |
| 48 } |
| 49 |
| 50 |
| 51 JumpTarget::JumpTarget() |
| 52 : cgen_(NULL), |
| 53 masm_(NULL), |
| 54 direction_(FORWARD_ONLY), |
| 55 reaching_frames_(0), |
| 56 merge_labels_(0), |
| 57 entry_frame_(NULL), |
| 58 is_bound_(false), |
| 59 is_linked_(false) { |
| 47 } | 60 } |
| 48 | 61 |
| 49 | 62 |
| 50 void JumpTarget::Unuse() { | 63 void JumpTarget::Initialize(CodeGenerator* cgen, Directionality direction) { |
| 51 ASSERT(!is_linked()); | 64 ASSERT(cgen != NULL); |
| 52 entry_label_.Unuse(); | 65 ASSERT(cgen_ == NULL); |
| 53 delete entry_frame_; | 66 cgen_ = cgen; |
| 54 entry_frame_ = NULL; | 67 masm_ = cgen->masm(); |
| 55 is_bound_ = false; | 68 direction_ = direction; |
| 56 is_linked_ = false; | |
| 57 } | 69 } |
| 58 | 70 |
| 59 | 71 |
| 72 void JumpTarget::Unuse() { |
| 73 ASSERT(!is_linked()); |
| 74 #ifdef DEBUG |
| 75 for (int i = 0; i < reaching_frames_.length(); i++) { |
| 76 ASSERT(reaching_frames_[i] == NULL); |
| 77 } |
| 78 #endif |
| 79 delete entry_frame_; |
| 80 |
| 81 Reset(); |
| 82 } |
| 83 |
| 84 |
| 60 void JumpTarget::Reset() { | 85 void JumpTarget::Reset() { |
| 61 reaching_frames_.Clear(); | 86 reaching_frames_.Clear(); |
| 62 merge_labels_.Clear(); | 87 merge_labels_.Clear(); |
| 63 entry_frame_ = NULL; | 88 entry_frame_ = NULL; |
| 64 entry_label_.Unuse(); | 89 entry_label_.Unuse(); |
| 65 is_bound_ = false; | 90 is_bound_ = false; |
| 66 is_linked_ = false; | 91 is_linked_ = false; |
| 67 } | 92 } |
| 68 | 93 |
| 69 | 94 |
| (...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 494 ASSERT(reaching_frames_.length() == merge_labels_.length()); | 519 ASSERT(reaching_frames_.length() == merge_labels_.length()); |
| 495 Label fresh; | 520 Label fresh; |
| 496 merge_labels_.Add(fresh); | 521 merge_labels_.Add(fresh); |
| 497 reaching_frames_.Add(frame); | 522 reaching_frames_.Add(frame); |
| 498 } | 523 } |
| 499 | 524 |
| 500 | 525 |
| 501 // ------------------------------------------------------------------------- | 526 // ------------------------------------------------------------------------- |
| 502 // BreakTarget implementation. | 527 // BreakTarget implementation. |
| 503 | 528 |
| 504 BreakTarget::BreakTarget() : JumpTarget(NULL, FORWARD_ONLY) { | 529 void BreakTarget::Initialize(CodeGenerator* cgen, Directionality direction) { |
| 530 JumpTarget::Initialize(cgen, direction); |
| 531 ASSERT(cgen_->has_valid_frame()); |
| 532 expected_height_ = cgen_->frame()->height(); |
| 505 } | 533 } |
| 506 | 534 |
| 507 | 535 |
| 508 void BreakTarget::Initialize(CodeGenerator* cgen, Directionality direction) { | |
| 509 ASSERT(cgen != NULL); | |
| 510 ASSERT(cgen_ == NULL); | |
| 511 cgen_ = cgen; | |
| 512 masm_ = cgen->masm(); | |
| 513 direction_ = direction; | |
| 514 } | |
| 515 | |
| 516 | |
| 517 void BreakTarget::CopyTo(BreakTarget* destination) { | 536 void BreakTarget::CopyTo(BreakTarget* destination) { |
| 518 ASSERT(destination != NULL); | 537 ASSERT(destination != NULL); |
| 519 destination->cgen_ = cgen_; | 538 destination->cgen_ = cgen_; |
| 520 destination->masm_ = masm_; | 539 destination->masm_ = masm_; |
| 521 destination->direction_ = direction_; | 540 destination->direction_ = direction_; |
| 522 destination->reaching_frames_.Clear(); | 541 destination->reaching_frames_.Clear(); |
| 523 destination->merge_labels_.Clear(); | 542 destination->merge_labels_.Clear(); |
| 524 ASSERT(reaching_frames_.length() == merge_labels_.length()); | 543 ASSERT(reaching_frames_.length() == merge_labels_.length()); |
| 525 for (int i = 0; i < reaching_frames_.length(); i++) { | 544 for (int i = 0; i < reaching_frames_.length(); i++) { |
| 526 destination->reaching_frames_.Add(reaching_frames_[i]); | 545 destination->reaching_frames_.Add(reaching_frames_[i]); |
| 527 destination->merge_labels_.Add(merge_labels_[i]); | 546 destination->merge_labels_.Add(merge_labels_[i]); |
| 528 } | 547 } |
| 529 destination->entry_frame_ = entry_frame_; | 548 destination->entry_frame_ = entry_frame_; |
| 530 destination->entry_label_ = entry_label_; | 549 destination->entry_label_ = entry_label_; |
| 531 destination->is_bound_ = is_bound_; | 550 destination->is_bound_ = is_bound_; |
| 532 destination->is_linked_ = is_linked_; | 551 destination->is_linked_ = is_linked_; |
| 552 destination->expected_height_ = expected_height_; |
| 553 } |
| 554 |
| 555 |
| 556 void BreakTarget::Jump() { |
| 557 ASSERT(cgen_ != NULL); |
| 558 ASSERT(cgen_->has_valid_frame()); |
| 559 |
| 560 // This is a break target so drop leftover statement state from the |
| 561 // frame before merging. |
| 562 cgen_->frame()->ForgetElements(cgen_->frame()->height() - expected_height_); |
| 563 JumpTarget::Jump(); |
| 564 } |
| 565 |
| 566 |
| 567 void BreakTarget::Branch(Condition cc, Hint hint) { |
| 568 ASSERT(cgen_ != NULL); |
| 569 ASSERT(cgen_->has_valid_frame()); |
| 570 |
| 571 int count = cgen_->frame()->height() - expected_height_; |
| 572 if (count > 0) { |
| 573 // We negate and branch here rather than using |
| 574 // JumpTarget::Branch's negate and branch. This gives us a hook |
| 575 // to remove statement state from the frame. |
| 576 JumpTarget fall_through(cgen_); |
| 577 // Branch to fall through will not negate, because it is a |
| 578 // forward-only target. |
| 579 fall_through.Branch(NegateCondition(cc), NegateHint(hint)); |
| 580 Jump(); // May emit merge code here. |
| 581 fall_through.Bind(); |
| 582 } else { |
| 583 JumpTarget::Branch(cc, hint); |
| 584 } |
| 585 } |
| 586 |
| 587 |
| 588 void BreakTarget::Bind(int mergable_elements) { |
| 589 #ifdef DEBUG |
| 590 ASSERT(mergable_elements == kAllElements); |
| 591 ASSERT(cgen_ != NULL); |
| 592 for (int i = 0; i < reaching_frames_.length(); i++) { |
| 593 ASSERT(reaching_frames_[i]->height() == expected_height_); |
| 594 } |
| 595 #endif |
| 596 |
| 597 // This is a break target so drop leftover statement state from the |
| 598 // frame before merging. |
| 599 if (cgen_->has_valid_frame()) { |
| 600 int count = cgen_->frame()->height() - expected_height_; |
| 601 cgen_->frame()->ForgetElements(count); |
| 602 } |
| 603 JumpTarget::Bind(mergable_elements); |
| 533 } | 604 } |
| 534 | 605 |
| 535 | 606 |
| 536 // ------------------------------------------------------------------------- | 607 // ------------------------------------------------------------------------- |
| 537 // ShadowTarget implementation. | 608 // ShadowTarget implementation. |
| 538 | 609 |
| 539 ShadowTarget::ShadowTarget(BreakTarget* shadowed) { | 610 ShadowTarget::ShadowTarget(BreakTarget* shadowed) { |
| 540 ASSERT(shadowed != NULL); | 611 ASSERT(shadowed != NULL); |
| 541 other_target_ = shadowed; | 612 other_target_ = shadowed; |
| 542 | 613 |
| 543 #ifdef DEBUG | 614 #ifdef DEBUG |
| 544 is_shadowing_ = true; | 615 is_shadowing_ = true; |
| 545 #endif | 616 #endif |
| 546 // While shadowing this shadow target saves the state of the original. | 617 // While shadowing this shadow target saves the state of the original. |
| 547 shadowed->CopyTo(this); | 618 shadowed->CopyTo(this); |
| 548 | 619 |
| 620 // The original's state is reset. We do not Unuse it because that |
| 621 // would delete the expected frame and assert that the target is not |
| 622 // linked. |
| 623 shadowed->Reset(); |
| 624 ASSERT(cgen_ != NULL); |
| 625 ASSERT(cgen_->has_valid_frame()); |
| 626 shadowed->set_expected_height(cgen_->frame()->height()); |
| 627 |
| 549 // Setting the code generator to null prevents the shadow target from | 628 // Setting the code generator to null prevents the shadow target from |
| 550 // being used until shadowing stops. | 629 // being used until shadowing stops. |
| 551 cgen_ = NULL; | 630 cgen_ = NULL; |
| 552 masm_ = NULL; | 631 masm_ = NULL; |
| 553 | 632 |
| 554 // The original's state is reset. We do not Unuse it because that | |
| 555 // would delete the expected frame and assert that the target is not | |
| 556 // linked. | |
| 557 shadowed->Reset(); | |
| 558 } | 633 } |
| 559 | 634 |
| 560 | 635 |
| 561 void ShadowTarget::StopShadowing() { | 636 void ShadowTarget::StopShadowing() { |
| 562 ASSERT(is_shadowing_); | 637 ASSERT(is_shadowing_); |
| 563 | 638 |
| 564 // This target does not have a valid code generator yet. | 639 // This target does not have a valid code generator yet. |
| 565 cgen_ = other_target_->code_generator(); | 640 cgen_ = other_target_->code_generator(); |
| 566 ASSERT(cgen_ != NULL); | 641 ASSERT(cgen_ != NULL); |
| 567 masm_ = cgen_->masm(); | 642 masm_ = cgen_->masm(); |
| 568 | 643 |
| 569 // The states of this target, which was shadowed, and the original | 644 // The states of this target, which was shadowed, and the original |
| 570 // target, which was shadowing, are swapped. | 645 // target, which was shadowing, are swapped. |
| 571 BreakTarget temp; | 646 BreakTarget temp; |
| 572 other_target_->CopyTo(&temp); | 647 other_target_->CopyTo(&temp); |
| 573 CopyTo(other_target_); | 648 CopyTo(other_target_); |
| 574 temp.CopyTo(this); | 649 temp.CopyTo(this); |
| 575 temp.Reset(); // So the destructor does not deallocate virtual frames. | 650 temp.Reset(); // So the destructor does not deallocate virtual frames. |
| 576 | 651 |
| 577 #ifdef DEBUG | 652 #ifdef DEBUG |
| 578 is_shadowing_ = false; | 653 is_shadowing_ = false; |
| 579 #endif | 654 #endif |
| 580 } | 655 } |
| 581 | 656 |
| 582 | 657 |
| 583 } } // namespace v8::internal | 658 } } // namespace v8::internal |
| OLD | NEW |