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 |