OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
76 NO_REGISTERS, | 76 NO_REGISTERS, |
77 TOS_REG | 77 TOS_REG |
78 }; | 78 }; |
79 | 79 |
80 explicit FullCodeGenerator(MacroAssembler* masm) | 80 explicit FullCodeGenerator(MacroAssembler* masm) |
81 : masm_(masm), | 81 : masm_(masm), |
82 info_(NULL), | 82 info_(NULL), |
83 scope_(NULL), | 83 scope_(NULL), |
84 nesting_stack_(NULL), | 84 nesting_stack_(NULL), |
85 loop_depth_(0), | 85 loop_depth_(0), |
86 stack_height_(0), | |
87 context_(NULL), | 86 context_(NULL), |
88 bailout_entries_(0), | 87 bailout_entries_(0), |
89 stack_checks_(2), // There's always at least one. | 88 stack_checks_(2), // There's always at least one. |
90 forward_bailout_stack_(NULL), | 89 forward_bailout_stack_(NULL), |
91 forward_bailout_pending_(NULL) { | 90 forward_bailout_pending_(NULL) { |
92 } | 91 } |
93 | 92 |
94 static bool MakeCode(CompilationInfo* info); | 93 static bool MakeCode(CompilationInfo* info); |
95 | 94 |
96 void Generate(CompilationInfo* info); | 95 void Generate(CompilationInfo* info); |
(...skipping 435 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
532 void ExitFinallyBlock(); | 531 void ExitFinallyBlock(); |
533 | 532 |
534 // Loop nesting counter. | 533 // Loop nesting counter. |
535 int loop_depth() { return loop_depth_; } | 534 int loop_depth() { return loop_depth_; } |
536 void increment_loop_depth() { loop_depth_++; } | 535 void increment_loop_depth() { loop_depth_++; } |
537 void decrement_loop_depth() { | 536 void decrement_loop_depth() { |
538 ASSERT(loop_depth_ > 0); | 537 ASSERT(loop_depth_ > 0); |
539 loop_depth_--; | 538 loop_depth_--; |
540 } | 539 } |
541 | 540 |
542 #if defined(V8_TARGET_ARCH_IA32) | |
543 int stack_height() { return stack_height_; } | |
544 void set_stack_height(int depth) { stack_height_ = depth; } | |
545 void increment_stack_height() { stack_height_++; } | |
546 void increment_stack_height(int delta) { stack_height_ += delta; } | |
547 void decrement_stack_height() { | |
548 if (FLAG_verify_stack_height) { | |
549 ASSERT(stack_height_ > 0); | |
550 } | |
551 stack_height_--; | |
552 } | |
553 void decrement_stack_height(int delta) { | |
554 stack_height_-= delta; | |
555 if (FLAG_verify_stack_height) { | |
556 ASSERT(stack_height_ >= 0); | |
557 } | |
558 } | |
559 // Call this function only if FLAG_verify_stack_height is true. | |
560 void verify_stack_height(); // Generates a runtime check of esp - ebp. | |
561 #else | |
562 int stack_height() { return 0; } | |
563 void set_stack_height(int depth) {} | |
564 void increment_stack_height() {} | |
565 void increment_stack_height(int delta) {} | |
566 void decrement_stack_height() {} | |
567 void decrement_stack_height(int delta) {} | |
568 void verify_stack_height() {} | |
569 #endif // V8_TARGET_ARCH_IA32 | |
570 | |
571 MacroAssembler* masm() { return masm_; } | 541 MacroAssembler* masm() { return masm_; } |
572 | 542 |
573 class ExpressionContext; | 543 class ExpressionContext; |
574 const ExpressionContext* context() { return context_; } | 544 const ExpressionContext* context() { return context_; } |
575 void set_new_context(const ExpressionContext* context) { context_ = context; } | 545 void set_new_context(const ExpressionContext* context) { context_ = context; } |
576 | 546 |
577 Handle<Script> script() { return info_->script(); } | 547 Handle<Script> script() { return info_->script(); } |
578 bool is_eval() { return info_->is_eval(); } | 548 bool is_eval() { return info_->is_eval(); } |
579 bool is_native() { return info_->is_native(); } | 549 bool is_native() { return info_->is_native(); } |
580 bool is_strict_mode() { | 550 bool is_strict_mode() { |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
623 | 593 |
624 class ExpressionContext BASE_EMBEDDED { | 594 class ExpressionContext BASE_EMBEDDED { |
625 public: | 595 public: |
626 explicit ExpressionContext(FullCodeGenerator* codegen) | 596 explicit ExpressionContext(FullCodeGenerator* codegen) |
627 : masm_(codegen->masm()), old_(codegen->context()), codegen_(codegen) { | 597 : masm_(codegen->masm()), old_(codegen->context()), codegen_(codegen) { |
628 codegen->set_new_context(this); | 598 codegen->set_new_context(this); |
629 } | 599 } |
630 | 600 |
631 virtual ~ExpressionContext() { | 601 virtual ~ExpressionContext() { |
632 codegen_->set_new_context(old_); | 602 codegen_->set_new_context(old_); |
633 if (FLAG_verify_stack_height) { | |
634 ASSERT_EQ(expected_stack_height_, codegen()->stack_height()); | |
635 codegen()->verify_stack_height(); | |
636 } | |
637 } | 603 } |
638 | 604 |
639 Isolate* isolate() const { return codegen_->isolate(); } | 605 Isolate* isolate() const { return codegen_->isolate(); } |
640 | 606 |
641 // Convert constant control flow (true or false) to the result expected for | 607 // Convert constant control flow (true or false) to the result expected for |
642 // this expression context. | 608 // this expression context. |
643 virtual void Plug(bool flag) const = 0; | 609 virtual void Plug(bool flag) const = 0; |
644 | 610 |
645 // Emit code to convert a pure value (in a register, known variable | 611 // Emit code to convert a pure value (in a register, known variable |
646 // location, as a literal, or on top of the stack) into the result | 612 // location, as a literal, or on top of the stack) into the result |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
680 virtual bool IsStackValue() const { return false; } | 646 virtual bool IsStackValue() const { return false; } |
681 | 647 |
682 // Returns true if we are branching on the value rather than materializing | 648 // Returns true if we are branching on the value rather than materializing |
683 // it. Only used for asserts. | 649 // it. Only used for asserts. |
684 virtual bool IsTest() const { return false; } | 650 virtual bool IsTest() const { return false; } |
685 | 651 |
686 protected: | 652 protected: |
687 FullCodeGenerator* codegen() const { return codegen_; } | 653 FullCodeGenerator* codegen() const { return codegen_; } |
688 MacroAssembler* masm() const { return masm_; } | 654 MacroAssembler* masm() const { return masm_; } |
689 MacroAssembler* masm_; | 655 MacroAssembler* masm_; |
690 int expected_stack_height_; // The expected stack height esp - ebp on exit. | |
691 | 656 |
692 private: | 657 private: |
693 const ExpressionContext* old_; | 658 const ExpressionContext* old_; |
694 FullCodeGenerator* codegen_; | 659 FullCodeGenerator* codegen_; |
695 }; | 660 }; |
696 | 661 |
697 class AccumulatorValueContext : public ExpressionContext { | 662 class AccumulatorValueContext : public ExpressionContext { |
698 public: | 663 public: |
699 explicit AccumulatorValueContext(FullCodeGenerator* codegen) | 664 explicit AccumulatorValueContext(FullCodeGenerator* codegen) |
700 : ExpressionContext(codegen) { | 665 : ExpressionContext(codegen) { } |
701 expected_stack_height_ = codegen->stack_height(); | |
702 } | |
703 | 666 |
704 virtual void Plug(bool flag) const; | 667 virtual void Plug(bool flag) const; |
705 virtual void Plug(Register reg) const; | 668 virtual void Plug(Register reg) const; |
706 virtual void Plug(Label* materialize_true, Label* materialize_false) const; | 669 virtual void Plug(Label* materialize_true, Label* materialize_false) const; |
707 virtual void Plug(Variable* var) const; | 670 virtual void Plug(Variable* var) const; |
708 virtual void Plug(Handle<Object> lit) const; | 671 virtual void Plug(Handle<Object> lit) const; |
709 virtual void Plug(Heap::RootListIndex) const; | 672 virtual void Plug(Heap::RootListIndex) const; |
710 virtual void PlugTOS() const; | 673 virtual void PlugTOS() const; |
711 virtual void DropAndPlug(int count, Register reg) const; | 674 virtual void DropAndPlug(int count, Register reg) const; |
712 virtual void PrepareTest(Label* materialize_true, | 675 virtual void PrepareTest(Label* materialize_true, |
713 Label* materialize_false, | 676 Label* materialize_false, |
714 Label** if_true, | 677 Label** if_true, |
715 Label** if_false, | 678 Label** if_false, |
716 Label** fall_through) const; | 679 Label** fall_through) const; |
717 virtual bool IsAccumulatorValue() const { return true; } | 680 virtual bool IsAccumulatorValue() const { return true; } |
718 }; | 681 }; |
719 | 682 |
720 class StackValueContext : public ExpressionContext { | 683 class StackValueContext : public ExpressionContext { |
721 public: | 684 public: |
722 explicit StackValueContext(FullCodeGenerator* codegen) | 685 explicit StackValueContext(FullCodeGenerator* codegen) |
723 : ExpressionContext(codegen) { | 686 : ExpressionContext(codegen) { } |
724 expected_stack_height_ = codegen->stack_height() + 1; | |
725 } | |
726 | 687 |
727 virtual void Plug(bool flag) const; | 688 virtual void Plug(bool flag) const; |
728 virtual void Plug(Register reg) const; | 689 virtual void Plug(Register reg) const; |
729 virtual void Plug(Label* materialize_true, Label* materialize_false) const; | 690 virtual void Plug(Label* materialize_true, Label* materialize_false) const; |
730 virtual void Plug(Variable* var) const; | 691 virtual void Plug(Variable* var) const; |
731 virtual void Plug(Handle<Object> lit) const; | 692 virtual void Plug(Handle<Object> lit) const; |
732 virtual void Plug(Heap::RootListIndex) const; | 693 virtual void Plug(Heap::RootListIndex) const; |
733 virtual void PlugTOS() const; | 694 virtual void PlugTOS() const; |
734 virtual void DropAndPlug(int count, Register reg) const; | 695 virtual void DropAndPlug(int count, Register reg) const; |
735 virtual void PrepareTest(Label* materialize_true, | 696 virtual void PrepareTest(Label* materialize_true, |
736 Label* materialize_false, | 697 Label* materialize_false, |
737 Label** if_true, | 698 Label** if_true, |
738 Label** if_false, | 699 Label** if_false, |
739 Label** fall_through) const; | 700 Label** fall_through) const; |
740 virtual bool IsStackValue() const { return true; } | 701 virtual bool IsStackValue() const { return true; } |
741 }; | 702 }; |
742 | 703 |
743 class TestContext : public ExpressionContext { | 704 class TestContext : public ExpressionContext { |
744 public: | 705 public: |
745 TestContext(FullCodeGenerator* codegen, | 706 TestContext(FullCodeGenerator* codegen, |
746 Expression* condition, | 707 Expression* condition, |
747 Label* true_label, | 708 Label* true_label, |
748 Label* false_label, | 709 Label* false_label, |
749 Label* fall_through) | 710 Label* fall_through) |
750 : ExpressionContext(codegen), | 711 : ExpressionContext(codegen), |
751 condition_(condition), | 712 condition_(condition), |
752 true_label_(true_label), | 713 true_label_(true_label), |
753 false_label_(false_label), | 714 false_label_(false_label), |
754 fall_through_(fall_through) { | 715 fall_through_(fall_through) { } |
755 expected_stack_height_ = codegen->stack_height(); | |
756 } | |
757 | 716 |
758 static const TestContext* cast(const ExpressionContext* context) { | 717 static const TestContext* cast(const ExpressionContext* context) { |
759 ASSERT(context->IsTest()); | 718 ASSERT(context->IsTest()); |
760 return reinterpret_cast<const TestContext*>(context); | 719 return reinterpret_cast<const TestContext*>(context); |
761 } | 720 } |
762 | 721 |
763 Expression* condition() const { return condition_; } | 722 Expression* condition() const { return condition_; } |
764 Label* true_label() const { return true_label_; } | 723 Label* true_label() const { return true_label_; } |
765 Label* false_label() const { return false_label_; } | 724 Label* false_label() const { return false_label_; } |
766 Label* fall_through() const { return fall_through_; } | 725 Label* fall_through() const { return fall_through_; } |
(...skipping 16 matching lines...) Expand all Loading... |
783 private: | 742 private: |
784 Expression* condition_; | 743 Expression* condition_; |
785 Label* true_label_; | 744 Label* true_label_; |
786 Label* false_label_; | 745 Label* false_label_; |
787 Label* fall_through_; | 746 Label* fall_through_; |
788 }; | 747 }; |
789 | 748 |
790 class EffectContext : public ExpressionContext { | 749 class EffectContext : public ExpressionContext { |
791 public: | 750 public: |
792 explicit EffectContext(FullCodeGenerator* codegen) | 751 explicit EffectContext(FullCodeGenerator* codegen) |
793 : ExpressionContext(codegen) { | 752 : ExpressionContext(codegen) { } |
794 expected_stack_height_ = codegen->stack_height(); | |
795 } | |
796 | |
797 | 753 |
798 virtual void Plug(bool flag) const; | 754 virtual void Plug(bool flag) const; |
799 virtual void Plug(Register reg) const; | 755 virtual void Plug(Register reg) const; |
800 virtual void Plug(Label* materialize_true, Label* materialize_false) const; | 756 virtual void Plug(Label* materialize_true, Label* materialize_false) const; |
801 virtual void Plug(Variable* var) const; | 757 virtual void Plug(Variable* var) const; |
802 virtual void Plug(Handle<Object> lit) const; | 758 virtual void Plug(Handle<Object> lit) const; |
803 virtual void Plug(Heap::RootListIndex) const; | 759 virtual void Plug(Heap::RootListIndex) const; |
804 virtual void PlugTOS() const; | 760 virtual void PlugTOS() const; |
805 virtual void DropAndPlug(int count, Register reg) const; | 761 virtual void DropAndPlug(int count, Register reg) const; |
806 virtual void PrepareTest(Label* materialize_true, | 762 virtual void PrepareTest(Label* materialize_true, |
807 Label* materialize_false, | 763 Label* materialize_false, |
808 Label** if_true, | 764 Label** if_true, |
809 Label** if_false, | 765 Label** if_false, |
810 Label** fall_through) const; | 766 Label** fall_through) const; |
811 virtual bool IsEffect() const { return true; } | 767 virtual bool IsEffect() const { return true; } |
812 }; | 768 }; |
813 | 769 |
814 MacroAssembler* masm_; | 770 MacroAssembler* masm_; |
815 CompilationInfo* info_; | 771 CompilationInfo* info_; |
816 Scope* scope_; | 772 Scope* scope_; |
817 Label return_label_; | 773 Label return_label_; |
818 NestedStatement* nesting_stack_; | 774 NestedStatement* nesting_stack_; |
819 int loop_depth_; | 775 int loop_depth_; |
820 int stack_height_; | |
821 const ExpressionContext* context_; | 776 const ExpressionContext* context_; |
822 ZoneList<BailoutEntry> bailout_entries_; | 777 ZoneList<BailoutEntry> bailout_entries_; |
823 ZoneList<BailoutEntry> stack_checks_; | 778 ZoneList<BailoutEntry> stack_checks_; |
824 ForwardBailoutStack* forward_bailout_stack_; | 779 ForwardBailoutStack* forward_bailout_stack_; |
825 ForwardBailoutStack* forward_bailout_pending_; | 780 ForwardBailoutStack* forward_bailout_pending_; |
826 | 781 |
827 friend class NestedStatement; | 782 friend class NestedStatement; |
828 | 783 |
829 DISALLOW_COPY_AND_ASSIGN(FullCodeGenerator); | 784 DISALLOW_COPY_AND_ASSIGN(FullCodeGenerator); |
830 }; | 785 }; |
831 | 786 |
832 | 787 |
833 } } // namespace v8::internal | 788 } } // namespace v8::internal |
834 | 789 |
835 #endif // V8_FULL_CODEGEN_H_ | 790 #endif // V8_FULL_CODEGEN_H_ |
OLD | NEW |