OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
176 void HBasicBlock::Finish(HControlInstruction* end) { | 176 void HBasicBlock::Finish(HControlInstruction* end) { |
177 ASSERT(!IsFinished()); | 177 ASSERT(!IsFinished()); |
178 AddInstruction(end); | 178 AddInstruction(end); |
179 end_ = end; | 179 end_ = end; |
180 for (HSuccessorIterator it(end); !it.Done(); it.Advance()) { | 180 for (HSuccessorIterator it(end); !it.Done(); it.Advance()) { |
181 it.Current()->RegisterPredecessor(this); | 181 it.Current()->RegisterPredecessor(this); |
182 } | 182 } |
183 } | 183 } |
184 | 184 |
185 | 185 |
186 void HBasicBlock::Goto(HBasicBlock* block, FunctionState* state) { | 186 void HBasicBlock::Goto(HBasicBlock* block, |
187 FunctionState* state, | |
188 bool add_simulate) { | |
187 bool drop_extra = state != NULL && | 189 bool drop_extra = state != NULL && |
188 state->inlining_kind() == DROP_EXTRA_ON_RETURN; | 190 state->inlining_kind() == DROP_EXTRA_ON_RETURN; |
189 | 191 |
190 if (block->IsInlineReturnTarget()) { | 192 if (block->IsInlineReturnTarget()) { |
191 AddInstruction(new(zone()) HLeaveInlined()); | 193 AddInstruction(new(zone()) HLeaveInlined()); |
192 last_environment_ = last_environment()->DiscardInlined(drop_extra); | 194 last_environment_ = last_environment()->DiscardInlined(drop_extra); |
193 } | 195 } |
194 | 196 |
195 AddSimulate(BailoutId::None()); | 197 if (add_simulate) AddSimulate(BailoutId::None()); |
196 HGoto* instr = new(zone()) HGoto(block); | 198 HGoto* instr = new(zone()) HGoto(block); |
197 Finish(instr); | 199 Finish(instr); |
198 } | 200 } |
199 | 201 |
200 | 202 |
201 void HBasicBlock::AddLeaveInlined(HValue* return_value, | 203 void HBasicBlock::AddLeaveInlined(HValue* return_value, |
202 FunctionState* state) { | 204 FunctionState* state) { |
203 HBasicBlock* target = state->function_return(); | 205 HBasicBlock* target = state->function_return(); |
204 bool drop_extra = state->inlining_kind() == DROP_EXTRA_ON_RETURN; | 206 bool drop_extra = state->inlining_kind() == DROP_EXTRA_ON_RETURN; |
205 | 207 |
(...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
633 } | 635 } |
634 | 636 |
635 | 637 |
636 DEFINE_GET_CONSTANT(True, true, HType::Boolean(), true) | 638 DEFINE_GET_CONSTANT(True, true, HType::Boolean(), true) |
637 DEFINE_GET_CONSTANT(False, false, HType::Boolean(), false) | 639 DEFINE_GET_CONSTANT(False, false, HType::Boolean(), false) |
638 DEFINE_GET_CONSTANT(Hole, the_hole, HType::Tagged(), false) | 640 DEFINE_GET_CONSTANT(Hole, the_hole, HType::Tagged(), false) |
639 | 641 |
640 #undef DEFINE_GET_CONSTANT | 642 #undef DEFINE_GET_CONSTANT |
641 | 643 |
642 | 644 |
643 HGraphBuilder::CheckBuilder::CheckBuilder(HGraphBuilder* builder, BailoutId id) | 645 HGraphBuilder::CheckBuilder::CheckBuilder(HGraphBuilder* builder) |
644 : builder_(builder), | 646 : builder_(builder), |
645 finished_(false), | 647 finished_(false) { |
646 id_(id) { | |
647 HEnvironment* env = builder->environment(); | 648 HEnvironment* env = builder->environment(); |
648 failure_block_ = builder->CreateBasicBlock(env->CopyWithoutHistory()); | 649 failure_block_ = builder->CreateBasicBlock(env->Copy()); |
649 merge_block_ = builder->CreateBasicBlock(env->CopyWithoutHistory()); | 650 merge_block_ = builder->CreateBasicBlock(env->Copy()); |
650 } | 651 } |
651 | 652 |
652 | 653 |
653 HValue* HGraphBuilder::CheckBuilder::CheckNotUndefined(HValue* value) { | 654 HValue* HGraphBuilder::CheckBuilder::CheckNotUndefined(HValue* value) { |
654 HEnvironment* env = builder_->environment(); | 655 HEnvironment* env = builder_->environment(); |
655 HIsNilAndBranch* compare = | 656 HCompareObjectEqAndBranch* compare = |
656 new(zone()) HIsNilAndBranch(value, kStrictEquality, kUndefinedValue); | 657 new(zone()) HCompareObjectEqAndBranch( |
658 value, | |
659 builder_->graph()->GetConstantUndefined()); | |
657 HBasicBlock* success_block = | 660 HBasicBlock* success_block = |
658 builder_->CreateBasicBlock(env->CopyWithoutHistory()); | 661 builder_->CreateBasicBlock(env->Copy()); |
Michael Starzinger
2013/04/18 10:30:21
nit: Should fit into one line now. Also three more
danno
2013/04/18 10:44:04
Done.
| |
659 HBasicBlock* failure_block = | 662 HBasicBlock* failure_block = |
660 builder_->CreateBasicBlock(env->CopyWithoutHistory()); | 663 builder_->CreateBasicBlock(env->Copy()); |
661 compare->SetSuccessorAt(0, failure_block); | 664 compare->SetSuccessorAt(0, failure_block); |
662 compare->SetSuccessorAt(1, success_block); | 665 compare->SetSuccessorAt(1, success_block); |
663 failure_block->Goto(failure_block_); | 666 failure_block->GotoNoSimulate(failure_block_); |
664 builder_->current_block()->Finish(compare); | 667 builder_->current_block()->Finish(compare); |
665 builder_->set_current_block(success_block); | 668 builder_->set_current_block(success_block); |
666 return compare; | 669 return compare; |
667 } | 670 } |
668 | 671 |
669 | 672 |
670 HValue* HGraphBuilder::CheckBuilder::CheckIntegerCompare(HValue* left, | 673 HValue* HGraphBuilder::CheckBuilder::CheckIntegerCompare(HValue* left, |
671 HValue* right, | 674 HValue* right, |
672 Token::Value op) { | 675 Token::Value op) { |
673 HEnvironment* env = builder_->environment(); | 676 HEnvironment* env = builder_->environment(); |
674 HCompareIDAndBranch* compare = | 677 HCompareIDAndBranch* compare = |
675 new(zone()) HCompareIDAndBranch(left, right, op); | 678 new(zone()) HCompareIDAndBranch(left, right, op); |
676 compare->AssumeRepresentation(Representation::Integer32()); | 679 compare->AssumeRepresentation(Representation::Integer32()); |
677 HBasicBlock* success_block = | 680 HBasicBlock* success_block = |
678 builder_->CreateBasicBlock(env->CopyWithoutHistory()); | 681 builder_->CreateBasicBlock(env->Copy()); |
679 HBasicBlock* failure_block = | 682 HBasicBlock* failure_block = |
680 builder_->CreateBasicBlock(env->CopyWithoutHistory()); | 683 builder_->CreateBasicBlock(env->Copy()); |
681 compare->SetSuccessorAt(0, success_block); | 684 compare->SetSuccessorAt(0, success_block); |
682 compare->SetSuccessorAt(1, failure_block); | 685 compare->SetSuccessorAt(1, failure_block); |
683 failure_block->Goto(failure_block_); | 686 failure_block->GotoNoSimulate(failure_block_); |
684 builder_->current_block()->Finish(compare); | 687 builder_->current_block()->Finish(compare); |
685 builder_->set_current_block(success_block); | 688 builder_->set_current_block(success_block); |
686 return compare; | 689 return compare; |
687 } | 690 } |
688 | 691 |
689 | 692 |
690 HValue* HGraphBuilder::CheckBuilder::CheckIntegerEq(HValue* left, | 693 HValue* HGraphBuilder::CheckBuilder::CheckIntegerEq(HValue* left, |
691 HValue* right) { | 694 HValue* right) { |
692 return CheckIntegerCompare(left, right, Token::EQ); | 695 return CheckIntegerCompare(left, right, Token::EQ); |
693 } | 696 } |
694 | 697 |
695 | 698 |
696 void HGraphBuilder::CheckBuilder::End() { | 699 void HGraphBuilder::CheckBuilder::End() { |
697 ASSERT(!finished_); | 700 ASSERT(!finished_); |
698 builder_->current_block()->Goto(merge_block_); | 701 builder_->current_block()->GotoNoSimulate(merge_block_); |
699 failure_block_->FinishExitWithDeoptimization(HDeoptimize::kUseAll); | 702 if (failure_block_->HasPredecessor()) { |
700 failure_block_->SetJoinId(id_); | 703 failure_block_->FinishExitWithDeoptimization(HDeoptimize::kUseAll); |
704 } | |
701 builder_->set_current_block(merge_block_); | 705 builder_->set_current_block(merge_block_); |
702 merge_block_->SetJoinId(id_); | |
703 finished_ = true; | 706 finished_ = true; |
704 } | 707 } |
705 | 708 |
706 | 709 |
707 HConstant* HGraph::GetInvalidContext() { | 710 HConstant* HGraph::GetInvalidContext() { |
708 return GetConstantInt32(&constant_invalid_context_, 0xFFFFC0C7); | 711 return GetConstantInt32(&constant_invalid_context_, 0xFFFFC0C7); |
709 } | 712 } |
710 | 713 |
711 | 714 |
712 HGraphBuilder::IfBuilder::IfBuilder(HGraphBuilder* builder, BailoutId id) | 715 HGraphBuilder::IfBuilder::IfBuilder(HGraphBuilder* builder, int position) |
713 : builder_(builder), | 716 : builder_(builder), |
717 position_(position), | |
714 finished_(false), | 718 finished_(false), |
719 did_then_(false), | |
715 did_else_(false), | 720 did_else_(false), |
716 id_(id) { | 721 deopt_then_(false), |
722 deopt_else_(false), | |
723 did_and_(false), | |
724 did_or_(false), | |
725 captured_(false), | |
726 needs_compare_(true), | |
727 split_edge_merge_block_(NULL) { | |
717 HEnvironment* env = builder->environment(); | 728 HEnvironment* env = builder->environment(); |
718 first_true_block_ = builder->CreateBasicBlock(env->Copy()); | 729 first_true_block_ = builder->CreateBasicBlock(env->Copy()); |
719 last_true_block_ = NULL; | 730 last_true_block_ = NULL; |
720 first_false_block_ = builder->CreateBasicBlock(env->Copy()); | 731 first_false_block_ = builder->CreateBasicBlock(env->Copy()); |
721 } | 732 } |
722 | 733 |
723 | 734 |
724 HInstruction* HGraphBuilder::IfBuilder::BeginIf( | 735 HGraphBuilder::IfBuilder::IfBuilder( |
736 HGraphBuilder* builder, | |
737 IfContinuation* continuation) | |
738 : builder_(builder), | |
739 position_(RelocInfo::kNoPosition), | |
740 finished_(false), | |
741 did_then_(false), | |
742 did_else_(false), | |
743 deopt_then_(false), | |
744 deopt_else_(false), | |
745 did_and_(false), | |
746 did_or_(false), | |
747 captured_(false), | |
748 needs_compare_(false), | |
749 first_true_block_(NULL), | |
750 first_false_block_(NULL), | |
751 split_edge_merge_block_(NULL), | |
752 merge_block_(NULL) { | |
753 continuation->Continue(&first_true_block_, | |
754 &first_false_block_, | |
755 &position_); | |
756 } | |
757 | |
758 | |
759 HInstruction* HGraphBuilder::IfBuilder::IfCompare( | |
725 HValue* left, | 760 HValue* left, |
726 HValue* right, | 761 HValue* right, |
727 Token::Value token, | 762 Token::Value token, |
728 Representation input_representation) { | 763 Representation input_representation) { |
729 HCompareIDAndBranch* compare = | 764 HCompareIDAndBranch* compare = |
730 new(zone()) HCompareIDAndBranch(left, right, token); | 765 new(zone()) HCompareIDAndBranch(left, right, token); |
731 compare->set_observed_input_representation(input_representation, | 766 compare->set_observed_input_representation(input_representation, |
732 input_representation); | 767 input_representation); |
733 compare->ChangeRepresentation(input_representation); | 768 compare->ChangeRepresentation(input_representation); |
734 compare->SetSuccessorAt(0, first_true_block_); | 769 AddCompare(compare); |
735 compare->SetSuccessorAt(1, first_false_block_); | |
736 builder_->current_block()->Finish(compare); | |
737 builder_->set_current_block(first_true_block_); | |
738 return compare; | 770 return compare; |
739 } | 771 } |
740 | 772 |
741 | 773 |
742 HInstruction* HGraphBuilder::IfBuilder::BeginIfObjectsEqual( | 774 HInstruction* HGraphBuilder::IfBuilder::IfCompareMap(HValue* left, |
743 HValue* left, | 775 Handle<Map> map) { |
744 HValue* right) { | 776 HCompareMap* compare = |
745 HCompareObjectEqAndBranch* compare = | 777 new(zone()) HCompareMap(left, map, |
746 new(zone()) HCompareObjectEqAndBranch(left, right); | 778 first_true_block_, first_false_block_); |
747 compare->SetSuccessorAt(0, first_true_block_); | 779 AddCompare(compare); |
748 compare->SetSuccessorAt(1, first_false_block_); | |
749 builder_->current_block()->Finish(compare); | |
750 builder_->set_current_block(first_true_block_); | |
751 return compare; | 780 return compare; |
752 } | 781 } |
753 | 782 |
754 | 783 |
755 HInstruction* HGraphBuilder::IfBuilder::BeginIfMapEquals(HValue* value, | 784 void HGraphBuilder::IfBuilder::AddCompare(HControlInstruction* compare) { |
756 Handle<Map> map) { | 785 if (split_edge_merge_block_ != NULL) { |
757 HCompareMap* compare = new(zone()) | 786 HEnvironment* env = first_false_block_->last_environment(); |
758 HCompareMap(value, map, first_true_block_, first_false_block_); | 787 HBasicBlock* split_edge = |
788 builder_->CreateBasicBlock(env->Copy()); | |
789 if (did_or_) { | |
790 compare->SetSuccessorAt(0, split_edge); | |
791 compare->SetSuccessorAt(1, first_false_block_); | |
792 } else { | |
793 compare->SetSuccessorAt(0, first_true_block_); | |
794 compare->SetSuccessorAt(1, split_edge); | |
795 } | |
796 split_edge->GotoNoSimulate(split_edge_merge_block_); | |
797 } else { | |
798 compare->SetSuccessorAt(0, first_true_block_); | |
799 compare->SetSuccessorAt(1, first_false_block_); | |
800 } | |
759 builder_->current_block()->Finish(compare); | 801 builder_->current_block()->Finish(compare); |
760 builder_->set_current_block(first_true_block_); | 802 needs_compare_ = false; |
761 return compare; | |
762 } | 803 } |
763 | 804 |
764 | 805 |
765 void HGraphBuilder::IfBuilder::BeginElse() { | 806 void HGraphBuilder::IfBuilder::Or() { |
807 ASSERT(!did_and_); | |
808 did_or_ = true; | |
809 HEnvironment* env = first_false_block_->last_environment(); | |
810 if (split_edge_merge_block_ == NULL) { | |
811 split_edge_merge_block_ = | |
812 builder_->CreateBasicBlock(env->Copy()); | |
813 first_true_block_->GotoNoSimulate(split_edge_merge_block_); | |
814 first_true_block_ = split_edge_merge_block_; | |
815 } | |
816 builder_->set_current_block(first_false_block_); | |
817 first_false_block_ = builder_->CreateBasicBlock(env->Copy()); | |
818 } | |
819 | |
820 | |
821 void HGraphBuilder::IfBuilder::And() { | |
822 ASSERT(!did_or_); | |
823 did_and_ = true; | |
824 HEnvironment* env = first_false_block_->last_environment(); | |
825 if (split_edge_merge_block_ == NULL) { | |
826 split_edge_merge_block_ = | |
827 builder_->CreateBasicBlock(env->Copy()); | |
828 first_false_block_->GotoNoSimulate(split_edge_merge_block_); | |
829 first_false_block_ = split_edge_merge_block_; | |
830 } | |
831 builder_->set_current_block(first_true_block_); | |
832 first_true_block_ = builder_->CreateBasicBlock(env->Copy()); | |
833 } | |
834 | |
835 | |
836 void HGraphBuilder::IfBuilder::CaptureContinuation( | |
837 IfContinuation* continuation) { | |
838 ASSERT(!finished_); | |
839 ASSERT(!captured_); | |
840 HBasicBlock* true_block = last_true_block_ == NULL | |
841 ? first_true_block_ | |
842 : last_true_block_; | |
843 HBasicBlock* false_block = | |
844 did_else_ ? builder_->current_block() : first_false_block_; | |
845 continuation->Capture(true_block, false_block, position_); | |
846 captured_ = true; | |
847 End(); | |
848 } | |
849 | |
850 | |
851 void HGraphBuilder::IfBuilder::Then() { | |
852 ASSERT(!captured_); | |
853 ASSERT(!finished_); | |
854 did_then_ = true; | |
855 if (needs_compare_) { | |
856 // Handle if's without any expressions, they jump directly to the "else" | |
857 // branch. | |
858 builder_->current_block()->GotoNoSimulate(first_false_block_); | |
859 first_true_block_ = NULL; | |
860 } | |
861 builder_->set_current_block(first_true_block_); | |
862 } | |
863 | |
864 | |
865 void HGraphBuilder::IfBuilder::Else() { | |
866 ASSERT(did_then_); | |
867 ASSERT(!captured_); | |
868 ASSERT(!finished_); | |
766 last_true_block_ = builder_->current_block(); | 869 last_true_block_ = builder_->current_block(); |
767 ASSERT(!last_true_block_->IsFinished()); | 870 ASSERT(first_true_block_ == NULL || !last_true_block_->IsFinished()); |
768 builder_->set_current_block(first_false_block_); | 871 builder_->set_current_block(first_false_block_); |
769 did_else_ = true; | 872 did_else_ = true; |
770 } | 873 } |
771 | 874 |
772 | 875 |
876 void HGraphBuilder::IfBuilder::Deopt() { | |
877 ASSERT(!(did_then_ ^ did_else_)); | |
878 HBasicBlock* block = builder_->current_block(); | |
879 block->FinishExitWithDeoptimization(HDeoptimize::kUseAll); | |
880 if (did_else_) { | |
881 first_false_block_ = NULL; | |
882 did_else_ = false; | |
883 } else { | |
884 first_true_block_ = NULL; | |
885 } | |
886 } | |
887 | |
888 | |
773 void HGraphBuilder::IfBuilder::End() { | 889 void HGraphBuilder::IfBuilder::End() { |
774 ASSERT(!finished_); | 890 if (!captured_) { |
775 if (!did_else_) BeginElse(); | 891 ASSERT(did_then_); |
776 ASSERT(!last_true_block_->IsFinished()); | 892 if (!did_else_) { |
777 HBasicBlock* last_false_block = builder_->current_block(); | 893 last_true_block_ = builder_->current_block(); |
778 ASSERT(!last_false_block->IsFinished()); | 894 } |
779 HEnvironment* merge_env = | 895 if (first_true_block_ == NULL) { |
780 last_true_block_->last_environment()->CopyWithoutHistory(); | 896 // Deopt on true. Nothing to do, just continue the else block. |
781 merge_block_ = builder_->CreateBasicBlock(merge_env); | 897 } else if (first_false_block_ == NULL) { |
782 last_true_block_->Goto(merge_block_); | 898 builder_->set_current_block(last_true_block_); |
783 last_false_block->Goto(merge_block_); | 899 } else { |
784 merge_block_->SetJoinId(id_); | 900 HEnvironment* merge_env = |
785 builder_->set_current_block(merge_block_); | 901 last_true_block_->last_environment()->Copy(); |
902 merge_block_ = builder_->CreateBasicBlock(merge_env); | |
903 ASSERT(!finished_); | |
904 if (!did_else_) Else(); | |
905 ASSERT(!last_true_block_->IsFinished()); | |
906 HBasicBlock* last_false_block = builder_->current_block(); | |
907 ASSERT(!last_false_block->IsFinished()); | |
908 last_true_block_->GotoNoSimulate(merge_block_); | |
909 last_false_block->GotoNoSimulate(merge_block_); | |
910 builder_->set_current_block(merge_block_); | |
911 } | |
912 } | |
786 finished_ = true; | 913 finished_ = true; |
787 } | 914 } |
788 | 915 |
789 | 916 |
790 HGraphBuilder::LoopBuilder::LoopBuilder(HGraphBuilder* builder, | 917 HGraphBuilder::LoopBuilder::LoopBuilder(HGraphBuilder* builder, |
791 HValue* context, | 918 HValue* context, |
792 LoopBuilder::Direction direction, | 919 LoopBuilder::Direction direction) |
793 BailoutId id) | |
794 : builder_(builder), | 920 : builder_(builder), |
795 context_(context), | 921 context_(context), |
796 direction_(direction), | 922 direction_(direction), |
797 id_(id), | |
798 finished_(false) { | 923 finished_(false) { |
799 header_block_ = builder->CreateLoopHeaderBlock(); | 924 header_block_ = builder->CreateLoopHeaderBlock(); |
800 body_block_ = NULL; | 925 body_block_ = NULL; |
801 exit_block_ = NULL; | 926 exit_block_ = NULL; |
802 } | 927 } |
803 | 928 |
804 | 929 |
805 HValue* HGraphBuilder::LoopBuilder::BeginBody( | 930 HValue* HGraphBuilder::LoopBuilder::BeginBody( |
806 HValue* initial, | 931 HValue* initial, |
807 HValue* terminating, | 932 HValue* terminating, |
808 Token::Value token, | 933 Token::Value token, |
809 Representation input_representation) { | 934 Representation input_representation) { |
810 HEnvironment* env = builder_->environment(); | 935 HEnvironment* env = builder_->environment(); |
811 phi_ = new(zone()) HPhi(env->values()->length(), zone()); | 936 phi_ = new(zone()) HPhi(env->values()->length(), zone()); |
812 header_block_->AddPhi(phi_); | 937 header_block_->AddPhi(phi_); |
813 phi_->AddInput(initial); | 938 phi_->AddInput(initial); |
814 phi_->ChangeRepresentation(Representation::Integer32()); | 939 phi_->ChangeRepresentation(Representation::Integer32()); |
815 env->Push(initial); | 940 env->Push(initial); |
816 builder_->current_block()->Goto(header_block_); | 941 builder_->current_block()->GotoNoSimulate(header_block_); |
817 | 942 |
818 HEnvironment* body_env = env->Copy(); | 943 HEnvironment* body_env = env->Copy(); |
819 HEnvironment* exit_env = env->Copy(); | 944 HEnvironment* exit_env = env->Copy(); |
820 body_block_ = builder_->CreateBasicBlock(body_env); | 945 body_block_ = builder_->CreateBasicBlock(body_env); |
821 exit_block_ = builder_->CreateBasicBlock(exit_env); | 946 exit_block_ = builder_->CreateBasicBlock(exit_env); |
822 // Remove the phi from the expression stack | 947 // Remove the phi from the expression stack |
823 body_env->Pop(); | 948 body_env->Pop(); |
824 | 949 |
825 builder_->set_current_block(header_block_); | 950 builder_->set_current_block(header_block_); |
826 HCompareIDAndBranch* compare = | 951 HCompareIDAndBranch* compare = |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
860 } else { | 985 } else { |
861 increment_ = HSub::New(zone(), context_, phi_, one); | 986 increment_ = HSub::New(zone(), context_, phi_, one); |
862 } | 987 } |
863 increment_->ClearFlag(HValue::kCanOverflow); | 988 increment_->ClearFlag(HValue::kCanOverflow); |
864 increment_->ChangeRepresentation(Representation::Integer32()); | 989 increment_->ChangeRepresentation(Representation::Integer32()); |
865 builder_->AddInstruction(increment_); | 990 builder_->AddInstruction(increment_); |
866 } | 991 } |
867 | 992 |
868 // Push the new increment value on the expression stack to merge into the phi. | 993 // Push the new increment value on the expression stack to merge into the phi. |
869 builder_->environment()->Push(increment_); | 994 builder_->environment()->Push(increment_); |
870 builder_->current_block()->Goto(header_block_); | 995 builder_->current_block()->GotoNoSimulate(header_block_); |
871 header_block_->loop_information()->RegisterBackEdge(body_block_); | 996 header_block_->loop_information()->RegisterBackEdge(body_block_); |
872 header_block_->SetJoinId(id_); | |
873 | 997 |
874 builder_->set_current_block(exit_block_); | 998 builder_->set_current_block(exit_block_); |
875 // Pop the phi from the expression stack | 999 // Pop the phi from the expression stack |
876 builder_->environment()->Pop(); | 1000 builder_->environment()->Pop(); |
877 finished_ = true; | 1001 finished_ = true; |
878 } | 1002 } |
879 | 1003 |
880 | 1004 |
881 HGraph* HGraphBuilder::CreateGraph() { | 1005 HGraph* HGraphBuilder::CreateGraph() { |
882 graph_ = new(zone()) HGraph(info_); | 1006 graph_ = new(zone()) HGraph(info_); |
(...skipping 14 matching lines...) Expand all Loading... | |
897 } | 1021 } |
898 return instr; | 1022 return instr; |
899 } | 1023 } |
900 | 1024 |
901 | 1025 |
902 void HGraphBuilder::AddSimulate(BailoutId id, | 1026 void HGraphBuilder::AddSimulate(BailoutId id, |
903 RemovableSimulate removable) { | 1027 RemovableSimulate removable) { |
904 ASSERT(current_block() != NULL); | 1028 ASSERT(current_block() != NULL); |
905 ASSERT(no_side_effects_scope_count_ == 0); | 1029 ASSERT(no_side_effects_scope_count_ == 0); |
906 current_block()->AddSimulate(id, removable); | 1030 current_block()->AddSimulate(id, removable); |
907 environment()->set_ast_id(id); | |
908 } | 1031 } |
909 | 1032 |
910 | 1033 |
911 HBoundsCheck* HGraphBuilder::AddBoundsCheck(HValue* index, | 1034 HBoundsCheck* HGraphBuilder::AddBoundsCheck(HValue* index, |
912 HValue* length, | 1035 HValue* length, |
913 BoundsCheckKeyMode key_mode, | 1036 BoundsCheckKeyMode key_mode, |
914 Representation r) { | 1037 Representation r) { |
915 if (!index->type().IsSmi()) { | 1038 if (!index->type().IsSmi()) { |
916 index = new(graph()->zone()) HCheckSmiOrInt32(index); | 1039 index = new(graph()->zone()) HCheckSmiOrInt32(index); |
917 AddInstruction(HCheckSmiOrInt32::cast(index)); | 1040 AddInstruction(HCheckSmiOrInt32::cast(index)); |
(...skipping 30 matching lines...) Expand all Loading... | |
948 | 1071 |
949 HBasicBlock* HGraphBuilder::CreateLoopHeaderBlock() { | 1072 HBasicBlock* HGraphBuilder::CreateLoopHeaderBlock() { |
950 HBasicBlock* header = graph()->CreateBasicBlock(); | 1073 HBasicBlock* header = graph()->CreateBasicBlock(); |
951 HEnvironment* entry_env = environment()->CopyAsLoopHeader(header); | 1074 HEnvironment* entry_env = environment()->CopyAsLoopHeader(header); |
952 header->SetInitialEnvironment(entry_env); | 1075 header->SetInitialEnvironment(entry_env); |
953 header->AttachLoopInformation(); | 1076 header->AttachLoopInformation(); |
954 return header; | 1077 return header; |
955 } | 1078 } |
956 | 1079 |
957 | 1080 |
1081 HValue* HGraphBuilder::BuildCheckNonSmi(HValue* obj) { | |
1082 HCheckNonSmi* check = new(zone()) HCheckNonSmi(obj); | |
1083 AddInstruction(check); | |
1084 return check; | |
1085 } | |
1086 | |
1087 | |
1088 HValue* HGraphBuilder::BuildCheckMap(HValue* obj, | |
1089 Handle<Map> map) { | |
1090 HCheckMaps* check = new(zone()) HCheckMaps(obj, map, zone()); | |
1091 AddInstruction(check); | |
1092 return check; | |
1093 } | |
1094 | |
1095 | |
958 HInstruction* HGraphBuilder::BuildExternalArrayElementAccess( | 1096 HInstruction* HGraphBuilder::BuildExternalArrayElementAccess( |
959 HValue* external_elements, | 1097 HValue* external_elements, |
960 HValue* checked_key, | 1098 HValue* checked_key, |
961 HValue* val, | 1099 HValue* val, |
962 HValue* dependency, | 1100 HValue* dependency, |
963 ElementsKind elements_kind, | 1101 ElementsKind elements_kind, |
964 bool is_store) { | 1102 bool is_store) { |
965 Zone* zone = this->zone(); | 1103 Zone* zone = this->zone(); |
966 if (is_store) { | 1104 if (is_store) { |
967 ASSERT(val != NULL); | 1105 ASSERT(val != NULL); |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1042 elements_kind); | 1180 elements_kind); |
1043 } | 1181 } |
1044 | 1182 |
1045 | 1183 |
1046 HValue* HGraphBuilder::BuildCheckForCapacityGrow(HValue* object, | 1184 HValue* HGraphBuilder::BuildCheckForCapacityGrow(HValue* object, |
1047 HValue* elements, | 1185 HValue* elements, |
1048 ElementsKind kind, | 1186 ElementsKind kind, |
1049 HValue* length, | 1187 HValue* length, |
1050 HValue* key, | 1188 HValue* key, |
1051 bool is_js_array) { | 1189 bool is_js_array) { |
1052 BailoutId ast_id = environment()->ast_id(); | |
1053 Zone* zone = this->zone(); | 1190 Zone* zone = this->zone(); |
1054 IfBuilder length_checker(this, ast_id); | 1191 IfBuilder length_checker(this); |
1055 | 1192 |
1056 length_checker.BeginIf(length, key, Token::EQ); | 1193 length_checker.IfCompare(length, key, Token::EQ); |
1194 length_checker.Then(); | |
1057 | 1195 |
1058 HValue* current_capacity = | 1196 HValue* current_capacity = |
1059 AddInstruction(new(zone) HFixedArrayBaseLength(elements)); | 1197 AddInstruction(new(zone) HFixedArrayBaseLength(elements)); |
1060 | 1198 |
1061 IfBuilder capacity_checker(this, ast_id); | 1199 IfBuilder capacity_checker(this); |
1062 | 1200 |
1063 capacity_checker.BeginIf(length, current_capacity, Token::EQ); | 1201 capacity_checker.IfCompare(length, current_capacity, Token::EQ); |
1202 capacity_checker.Then(); | |
1064 | 1203 |
1065 HValue* context = environment()->LookupContext(); | 1204 HValue* context = environment()->LookupContext(); |
1066 | 1205 |
1067 HValue* new_capacity = | 1206 HValue* new_capacity = |
1068 BuildNewElementsCapacity(context, current_capacity); | 1207 BuildNewElementsCapacity(context, current_capacity); |
1069 | 1208 |
1070 HValue* new_elements = BuildGrowElementsCapacity(object, elements, | 1209 HValue* new_elements = BuildGrowElementsCapacity(object, elements, |
1071 kind, length, | 1210 kind, length, |
1072 new_capacity, ast_id); | 1211 new_capacity); |
1073 | 1212 |
1074 environment()->Push(new_elements); | 1213 environment()->Push(new_elements); |
1075 capacity_checker.BeginElse(); | 1214 capacity_checker.Else(); |
1076 | 1215 |
1077 environment()->Push(elements); | 1216 environment()->Push(elements); |
1078 capacity_checker.End(); | 1217 capacity_checker.End(); |
1079 | 1218 |
1080 if (is_js_array) { | 1219 if (is_js_array) { |
1081 HValue* new_length = AddInstruction( | 1220 HValue* new_length = AddInstruction( |
1082 HAdd::New(zone, context, length, graph_->GetConstant1())); | 1221 HAdd::New(zone, context, length, graph_->GetConstant1())); |
1083 new_length->ChangeRepresentation(Representation::Integer32()); | 1222 new_length->ChangeRepresentation(Representation::Integer32()); |
1084 new_length->ClearFlag(HValue::kCanOverflow); | 1223 new_length->ClearFlag(HValue::kCanOverflow); |
1085 | 1224 |
1086 Factory* factory = isolate()->factory(); | 1225 Factory* factory = isolate()->factory(); |
1087 HInstruction* length_store = AddInstruction(new(zone) HStoreNamedField( | 1226 HInstruction* length_store = AddInstruction(new(zone) HStoreNamedField( |
1088 object, | 1227 object, |
1089 factory->length_field_string(), | 1228 factory->length_field_string(), |
1090 new_length, true, | 1229 new_length, true, |
1091 JSArray::kLengthOffset)); | 1230 JSArray::kLengthOffset)); |
1092 length_store->SetGVNFlag(kChangesArrayLengths); | 1231 length_store->SetGVNFlag(kChangesArrayLengths); |
1093 } | 1232 } |
1094 | 1233 |
1095 length_checker.BeginElse(); | 1234 length_checker.Else(); |
1096 | 1235 |
1097 AddBoundsCheck(key, length, ALLOW_SMI_KEY); | 1236 AddBoundsCheck(key, length, ALLOW_SMI_KEY); |
1098 environment()->Push(elements); | 1237 environment()->Push(elements); |
1099 | 1238 |
1100 length_checker.End(); | 1239 length_checker.End(); |
1101 | 1240 |
1102 return environment()->Pop(); | 1241 return environment()->Pop(); |
1103 } | 1242 } |
1104 | 1243 |
1105 | 1244 |
1106 HValue* HGraphBuilder::BuildCopyElementsOnWrite(HValue* object, | 1245 HValue* HGraphBuilder::BuildCopyElementsOnWrite(HValue* object, |
1107 HValue* elements, | 1246 HValue* elements, |
1108 ElementsKind kind, | 1247 ElementsKind kind, |
1109 HValue* length) { | 1248 HValue* length) { |
1110 BailoutId ast_id = environment()->ast_id(); | |
1111 Zone* zone = this->zone(); | 1249 Zone* zone = this->zone(); |
1112 Heap* heap = isolate()->heap(); | 1250 Heap* heap = isolate()->heap(); |
1113 | 1251 |
1114 IfBuilder cow_checker(this, ast_id); | 1252 IfBuilder cow_checker(this); |
1115 | 1253 |
1116 cow_checker.BeginIfMapEquals(elements, | 1254 cow_checker.IfCompareMap(elements, |
1117 Handle<Map>(heap->fixed_cow_array_map())); | 1255 Handle<Map>(heap->fixed_cow_array_map())); |
1256 cow_checker.Then(); | |
1118 | 1257 |
1119 HValue* capacity = | 1258 HValue* capacity = |
1120 AddInstruction(new(zone) HFixedArrayBaseLength(elements)); | 1259 AddInstruction(new(zone) HFixedArrayBaseLength(elements)); |
1121 | 1260 |
1122 HValue* new_elements = BuildGrowElementsCapacity(object, elements, | 1261 HValue* new_elements = BuildGrowElementsCapacity(object, elements, |
1123 kind, length, | 1262 kind, length, capacity); |
1124 capacity, ast_id); | |
1125 | 1263 |
1126 environment()->Push(new_elements); | 1264 environment()->Push(new_elements); |
1127 | 1265 |
1128 cow_checker.BeginElse(); | 1266 cow_checker.Else(); |
1129 | 1267 |
1130 environment()->Push(elements); | 1268 environment()->Push(elements); |
1131 | 1269 |
1132 cow_checker.End(); | 1270 cow_checker.End(); |
1133 | 1271 |
1134 return environment()->Pop(); | 1272 return environment()->Pop(); |
1135 } | 1273 } |
1136 | 1274 |
1137 | 1275 |
1138 HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess( | 1276 HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess( |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1173 HInstruction* length = NULL; | 1311 HInstruction* length = NULL; |
1174 if (is_js_array) { | 1312 if (is_js_array) { |
1175 length = AddInstruction( | 1313 length = AddInstruction( |
1176 HLoadNamedField::NewArrayLength(zone, object, mapcheck, HType::Smi())); | 1314 HLoadNamedField::NewArrayLength(zone, object, mapcheck, HType::Smi())); |
1177 } else { | 1315 } else { |
1178 length = AddInstruction(new(zone) HFixedArrayBaseLength(elements)); | 1316 length = AddInstruction(new(zone) HFixedArrayBaseLength(elements)); |
1179 } | 1317 } |
1180 HValue* checked_key = NULL; | 1318 HValue* checked_key = NULL; |
1181 if (IsExternalArrayElementsKind(elements_kind)) { | 1319 if (IsExternalArrayElementsKind(elements_kind)) { |
1182 if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) { | 1320 if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) { |
1321 NoObservableSideEffectsScope no_effects(this); | |
1183 HLoadExternalArrayPointer* external_elements = | 1322 HLoadExternalArrayPointer* external_elements = |
1184 new(zone) HLoadExternalArrayPointer(elements); | 1323 new(zone) HLoadExternalArrayPointer(elements); |
1185 AddInstruction(external_elements); | 1324 AddInstruction(external_elements); |
1186 BailoutId previous_id = environment()->ast_id(); | 1325 IfBuilder length_checker(this); |
1187 ASSERT(!previous_id.IsNone()); | 1326 length_checker.IfCompare(key, length, Token::LT); |
1188 IfBuilder length_checker(this, previous_id); | 1327 length_checker.Then(); |
1189 length_checker.BeginIf(key, length, Token::LT); | 1328 CheckBuilder negative_checker(this); |
1190 CheckBuilder negative_checker(this, previous_id); | |
1191 HValue* bounds_check = negative_checker.CheckIntegerCompare( | 1329 HValue* bounds_check = negative_checker.CheckIntegerCompare( |
1192 key, graph()->GetConstant0(), Token::GTE); | 1330 key, graph()->GetConstant0(), Token::GTE); |
1193 negative_checker.End(); | 1331 negative_checker.End(); |
1194 HInstruction* result = BuildExternalArrayElementAccess( | 1332 HInstruction* result = BuildExternalArrayElementAccess( |
1195 external_elements, key, val, bounds_check, | 1333 external_elements, key, val, bounds_check, |
1196 elements_kind, is_store); | 1334 elements_kind, is_store); |
1197 AddInstruction(result); | 1335 AddInstruction(result); |
1198 length_checker.End(); | 1336 length_checker.End(); |
1199 return result; | 1337 return result; |
1200 } else { | 1338 } else { |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1243 } | 1381 } |
1244 } | 1382 } |
1245 return AddInstruction( | 1383 return AddInstruction( |
1246 BuildFastElementAccess(elements, checked_key, val, mapcheck, | 1384 BuildFastElementAccess(elements, checked_key, val, mapcheck, |
1247 elements_kind, is_store, store_mode)); | 1385 elements_kind, is_store, store_mode)); |
1248 } | 1386 } |
1249 | 1387 |
1250 | 1388 |
1251 HValue* HGraphBuilder::BuildAllocateElements(HValue* context, | 1389 HValue* HGraphBuilder::BuildAllocateElements(HValue* context, |
1252 ElementsKind kind, | 1390 ElementsKind kind, |
1253 HValue* capacity, | 1391 HValue* capacity) { |
1254 BailoutId ast_id) { | |
1255 Zone* zone = this->zone(); | 1392 Zone* zone = this->zone(); |
1256 | 1393 |
1257 int elements_size = IsFastDoubleElementsKind(kind) | 1394 int elements_size = IsFastDoubleElementsKind(kind) |
1258 ? kDoubleSize : kPointerSize; | 1395 ? kDoubleSize : kPointerSize; |
1259 HConstant* elements_size_value = | 1396 HConstant* elements_size_value = |
1260 new(zone) HConstant(elements_size, Representation::Integer32()); | 1397 new(zone) HConstant(elements_size, Representation::Integer32()); |
1261 AddInstruction(elements_size_value); | 1398 AddInstruction(elements_size_value); |
1262 HValue* mul = AddInstruction( | 1399 HValue* mul = AddInstruction( |
1263 HMul::New(zone, context, capacity, elements_size_value)); | 1400 HMul::New(zone, context, capacity, elements_size_value)); |
1264 mul->ChangeRepresentation(Representation::Integer32()); | 1401 mul->ChangeRepresentation(Representation::Integer32()); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1308 HInstruction* store_length = | 1445 HInstruction* store_length = |
1309 new(zone) HStoreNamedField(elements, fixed_array_length_field_name, | 1446 new(zone) HStoreNamedField(elements, fixed_array_length_field_name, |
1310 capacity, true, FixedArray::kLengthOffset); | 1447 capacity, true, FixedArray::kLengthOffset); |
1311 AddInstruction(store_length); | 1448 AddInstruction(store_length); |
1312 } | 1449 } |
1313 | 1450 |
1314 | 1451 |
1315 HValue* HGraphBuilder::BuildAllocateAndInitializeElements(HValue* context, | 1452 HValue* HGraphBuilder::BuildAllocateAndInitializeElements(HValue* context, |
1316 ElementsKind kind, | 1453 ElementsKind kind, |
1317 HValue* capacity) { | 1454 HValue* capacity) { |
1318 BailoutId ast_id = environment()->ast_id(); | |
1319 HValue* new_elements = | 1455 HValue* new_elements = |
Michael Starzinger
2013/04/18 10:30:21
nit: Should fit into one line now.
danno
2013/04/18 10:44:04
Done.
| |
1320 BuildAllocateElements(context, kind, capacity, ast_id); | 1456 BuildAllocateElements(context, kind, capacity); |
1321 BuildInitializeElements(new_elements, kind, capacity); | 1457 BuildInitializeElements(new_elements, kind, capacity); |
1322 return new_elements; | 1458 return new_elements; |
1323 } | 1459 } |
1324 | 1460 |
1325 | 1461 |
1326 HInstruction* HGraphBuilder::BuildStoreMap(HValue* object, | 1462 HInstruction* HGraphBuilder::BuildStoreMap(HValue* object, |
1327 HValue* map) { | 1463 HValue* map) { |
1328 Zone* zone = this->zone(); | 1464 Zone* zone = this->zone(); |
1329 Factory* factory = isolate()->factory(); | 1465 Factory* factory = isolate()->factory(); |
1330 Handle<String> map_field_name = factory->map_field_string(); | 1466 Handle<String> map_field_name = factory->map_field_string(); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1387 AddInstruction(new(zone) | 1523 AddInstruction(new(zone) |
1388 HBoundsCheck(length, max_size_constant, | 1524 HBoundsCheck(length, max_size_constant, |
1389 DONT_ALLOW_SMI_KEY, Representation::Integer32())); | 1525 DONT_ALLOW_SMI_KEY, Representation::Integer32())); |
1390 } | 1526 } |
1391 | 1527 |
1392 | 1528 |
1393 HValue* HGraphBuilder::BuildGrowElementsCapacity(HValue* object, | 1529 HValue* HGraphBuilder::BuildGrowElementsCapacity(HValue* object, |
1394 HValue* elements, | 1530 HValue* elements, |
1395 ElementsKind kind, | 1531 ElementsKind kind, |
1396 HValue* length, | 1532 HValue* length, |
1397 HValue* new_capacity, | 1533 HValue* new_capacity) { |
1398 BailoutId ast_id) { | |
1399 Zone* zone = this->zone(); | 1534 Zone* zone = this->zone(); |
1400 HValue* context = environment()->LookupContext(); | 1535 HValue* context = environment()->LookupContext(); |
1401 | 1536 |
1402 BuildNewSpaceArrayCheck(new_capacity, kind); | 1537 BuildNewSpaceArrayCheck(new_capacity, kind); |
1403 | 1538 |
1404 HValue* new_elements = | 1539 HValue* new_elements = |
1405 BuildAllocateAndInitializeElements(context, kind, new_capacity); | 1540 BuildAllocateAndInitializeElements(context, kind, new_capacity); |
1406 | 1541 |
1407 BuildCopyElements(context, elements, kind, | 1542 BuildCopyElements(context, elements, kind, |
1408 new_elements, kind, | 1543 new_elements, kind, |
1409 length, new_capacity, ast_id); | 1544 length, new_capacity); |
1410 | 1545 |
1411 Factory* factory = isolate()->factory(); | 1546 Factory* factory = isolate()->factory(); |
1412 HInstruction* elements_store = AddInstruction(new(zone) HStoreNamedField( | 1547 HInstruction* elements_store = AddInstruction(new(zone) HStoreNamedField( |
1413 object, | 1548 object, |
1414 factory->elements_field_string(), | 1549 factory->elements_field_string(), |
1415 new_elements, true, | 1550 new_elements, true, |
1416 JSArray::kElementsOffset)); | 1551 JSArray::kElementsOffset)); |
1417 elements_store->SetGVNFlag(kChangesElementsPointer); | 1552 elements_store->SetGVNFlag(kChangesElementsPointer); |
1418 | 1553 |
1419 return new_elements; | 1554 return new_elements; |
1420 } | 1555 } |
1421 | 1556 |
1422 | 1557 |
1423 void HGraphBuilder::BuildFillElementsWithHole(HValue* context, | 1558 void HGraphBuilder::BuildFillElementsWithHole(HValue* context, |
1424 HValue* elements, | 1559 HValue* elements, |
1425 ElementsKind elements_kind, | 1560 ElementsKind elements_kind, |
1426 HValue* from, | 1561 HValue* from, |
1427 HValue* to, | 1562 HValue* to) { |
1428 BailoutId ast_id) { | |
1429 // Fast elements kinds need to be initialized in case statements below cause | 1563 // Fast elements kinds need to be initialized in case statements below cause |
1430 // a garbage collection. | 1564 // a garbage collection. |
1431 Factory* factory = isolate()->factory(); | 1565 Factory* factory = isolate()->factory(); |
1432 | 1566 |
1433 double nan_double = FixedDoubleArray::hole_nan_as_double(); | 1567 double nan_double = FixedDoubleArray::hole_nan_as_double(); |
1434 Zone* zone = this->zone(); | 1568 Zone* zone = this->zone(); |
1435 HValue* hole = IsFastSmiOrObjectElementsKind(elements_kind) | 1569 HValue* hole = IsFastSmiOrObjectElementsKind(elements_kind) |
1436 ? AddInstruction(new(zone) HConstant(factory->the_hole_value(), | 1570 ? AddInstruction(new(zone) HConstant(factory->the_hole_value(), |
1437 Representation::Tagged())) | 1571 Representation::Tagged())) |
1438 : AddInstruction(new(zone) HConstant(nan_double, | 1572 : AddInstruction(new(zone) HConstant(nan_double, |
1439 Representation::Double())); | 1573 Representation::Double())); |
1440 | 1574 |
1441 LoopBuilder builder(this, context, LoopBuilder::kPostIncrement, ast_id); | 1575 LoopBuilder builder(this, context, LoopBuilder::kPostIncrement); |
1442 | 1576 |
1443 HValue* key = builder.BeginBody(from, to, Token::LT); | 1577 HValue* key = builder.BeginBody(from, to, Token::LT); |
1444 | 1578 |
1445 AddInstruction(new(zone) HStoreKeyed(elements, key, hole, elements_kind)); | 1579 AddInstruction(new(zone) HStoreKeyed(elements, key, hole, elements_kind)); |
1446 | 1580 |
1447 builder.EndBody(); | 1581 builder.EndBody(); |
1448 } | 1582 } |
1449 | 1583 |
1450 | 1584 |
1451 void HGraphBuilder::BuildCopyElements(HValue* context, | 1585 void HGraphBuilder::BuildCopyElements(HValue* context, |
1452 HValue* from_elements, | 1586 HValue* from_elements, |
1453 ElementsKind from_elements_kind, | 1587 ElementsKind from_elements_kind, |
1454 HValue* to_elements, | 1588 HValue* to_elements, |
1455 ElementsKind to_elements_kind, | 1589 ElementsKind to_elements_kind, |
1456 HValue* length, | 1590 HValue* length, |
1457 HValue* capacity, | 1591 HValue* capacity) { |
1458 BailoutId ast_id) { | |
1459 bool pre_fill_with_holes = | 1592 bool pre_fill_with_holes = |
1460 IsFastDoubleElementsKind(from_elements_kind) && | 1593 IsFastDoubleElementsKind(from_elements_kind) && |
1461 IsFastObjectElementsKind(to_elements_kind); | 1594 IsFastObjectElementsKind(to_elements_kind); |
1462 | 1595 |
1463 if (pre_fill_with_holes) { | 1596 if (pre_fill_with_holes) { |
1464 // If the copy might trigger a GC, make sure that the FixedArray is | 1597 // If the copy might trigger a GC, make sure that the FixedArray is |
1465 // pre-initialized with holes to make sure that it's always in a consistent | 1598 // pre-initialized with holes to make sure that it's always in a consistent |
1466 // state. | 1599 // state. |
1467 BuildFillElementsWithHole(context, to_elements, to_elements_kind, | 1600 BuildFillElementsWithHole(context, to_elements, to_elements_kind, |
1468 graph()->GetConstant0(), capacity, ast_id); | 1601 graph()->GetConstant0(), capacity); |
1469 } | 1602 } |
1470 | 1603 |
1471 LoopBuilder builder(this, context, LoopBuilder::kPostIncrement, ast_id); | 1604 LoopBuilder builder(this, context, LoopBuilder::kPostIncrement); |
1472 | 1605 |
1473 HValue* key = builder.BeginBody(graph()->GetConstant0(), length, Token::LT); | 1606 HValue* key = builder.BeginBody(graph()->GetConstant0(), length, Token::LT); |
1474 | 1607 |
1475 HValue* element = | 1608 HValue* element = |
1476 AddInstruction(new(zone()) HLoadKeyed(from_elements, key, NULL, | 1609 AddInstruction(new(zone()) HLoadKeyed(from_elements, key, NULL, |
1477 from_elements_kind, | 1610 from_elements_kind, |
1478 ALLOW_RETURN_HOLE)); | 1611 ALLOW_RETURN_HOLE)); |
1479 | 1612 |
1480 AddInstruction(new(zone()) HStoreKeyed(to_elements, key, element, | 1613 AddInstruction(new(zone()) HStoreKeyed(to_elements, key, element, |
1481 to_elements_kind)); | 1614 to_elements_kind)); |
1482 | 1615 |
1483 builder.EndBody(); | 1616 builder.EndBody(); |
1484 | 1617 |
1485 if (!pre_fill_with_holes && length != capacity) { | 1618 if (!pre_fill_with_holes && length != capacity) { |
1486 // Fill unused capacity with the hole. | 1619 // Fill unused capacity with the hole. |
1487 BuildFillElementsWithHole(context, to_elements, to_elements_kind, | 1620 BuildFillElementsWithHole(context, to_elements, to_elements_kind, |
1488 key, capacity, ast_id); | 1621 key, capacity); |
1489 } | 1622 } |
1490 } | 1623 } |
1491 | 1624 |
1492 | 1625 |
1493 HValue* HGraphBuilder::BuildCloneShallowArray(HContext* context, | 1626 HValue* HGraphBuilder::BuildCloneShallowArray(HContext* context, |
1494 HValue* boilerplate, | 1627 HValue* boilerplate, |
1495 AllocationSiteMode mode, | 1628 AllocationSiteMode mode, |
1496 ElementsKind kind, | 1629 ElementsKind kind, |
1497 int length) { | 1630 int length) { |
1498 Zone* zone = this->zone(); | 1631 Zone* zone = this->zone(); |
(...skipping 2605 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4104 HBasicBlock* empty_true = owner()->graph()->CreateBasicBlock(); | 4237 HBasicBlock* empty_true = owner()->graph()->CreateBasicBlock(); |
4105 HBasicBlock* empty_false = owner()->graph()->CreateBasicBlock(); | 4238 HBasicBlock* empty_false = owner()->graph()->CreateBasicBlock(); |
4106 instr->SetSuccessorAt(0, empty_true); | 4239 instr->SetSuccessorAt(0, empty_true); |
4107 instr->SetSuccessorAt(1, empty_false); | 4240 instr->SetSuccessorAt(1, empty_false); |
4108 owner()->current_block()->Finish(instr); | 4241 owner()->current_block()->Finish(instr); |
4109 HBasicBlock* join = owner()->CreateJoin(empty_true, empty_false, ast_id); | 4242 HBasicBlock* join = owner()->CreateJoin(empty_true, empty_false, ast_id); |
4110 owner()->set_current_block(join); | 4243 owner()->set_current_block(join); |
4111 } | 4244 } |
4112 | 4245 |
4113 | 4246 |
4247 void EffectContext::ReturnContinuation(IfContinuation* continuation, | |
4248 BailoutId ast_id) { | |
4249 HBasicBlock* true_branch = NULL; | |
4250 HBasicBlock* false_branch = NULL; | |
4251 continuation->Continue(&true_branch, &false_branch, NULL); | |
4252 if (!continuation->IsTrueReachable()) { | |
4253 owner()->set_current_block(false_branch); | |
4254 } else if (!continuation->IsFalseReachable()) { | |
4255 owner()->set_current_block(true_branch); | |
4256 } else { | |
4257 HBasicBlock* join = owner()->CreateJoin(true_branch, false_branch, ast_id); | |
4258 owner()->set_current_block(join); | |
4259 } | |
4260 } | |
4261 | |
4262 | |
4114 void ValueContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) { | 4263 void ValueContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) { |
4115 ASSERT(!instr->IsControlInstruction()); | 4264 ASSERT(!instr->IsControlInstruction()); |
4116 if (!arguments_allowed() && instr->CheckFlag(HValue::kIsArguments)) { | 4265 if (!arguments_allowed() && instr->CheckFlag(HValue::kIsArguments)) { |
4117 return owner()->Bailout("bad value context for arguments object value"); | 4266 return owner()->Bailout("bad value context for arguments object value"); |
4118 } | 4267 } |
4119 owner()->AddInstruction(instr); | 4268 owner()->AddInstruction(instr); |
4120 owner()->Push(instr); | 4269 owner()->Push(instr); |
4121 if (instr->HasObservableSideEffects()) { | 4270 if (instr->HasObservableSideEffects()) { |
4122 owner()->AddSimulate(ast_id, REMOVABLE_SIMULATE); | 4271 owner()->AddSimulate(ast_id, REMOVABLE_SIMULATE); |
4123 } | 4272 } |
(...skipping 13 matching lines...) Expand all Loading... | |
4137 owner()->set_current_block(materialize_true); | 4286 owner()->set_current_block(materialize_true); |
4138 owner()->Push(owner()->graph()->GetConstantTrue()); | 4287 owner()->Push(owner()->graph()->GetConstantTrue()); |
4139 owner()->set_current_block(materialize_false); | 4288 owner()->set_current_block(materialize_false); |
4140 owner()->Push(owner()->graph()->GetConstantFalse()); | 4289 owner()->Push(owner()->graph()->GetConstantFalse()); |
4141 HBasicBlock* join = | 4290 HBasicBlock* join = |
4142 owner()->CreateJoin(materialize_true, materialize_false, ast_id); | 4291 owner()->CreateJoin(materialize_true, materialize_false, ast_id); |
4143 owner()->set_current_block(join); | 4292 owner()->set_current_block(join); |
4144 } | 4293 } |
4145 | 4294 |
4146 | 4295 |
4296 void ValueContext::ReturnContinuation(IfContinuation* continuation, | |
4297 BailoutId ast_id) { | |
4298 HBasicBlock* materialize_true = NULL; | |
4299 HBasicBlock* materialize_false = NULL; | |
4300 continuation->Continue(&materialize_true, &materialize_false, NULL); | |
4301 if (continuation->IsTrueReachable()) { | |
4302 owner()->set_current_block(materialize_true); | |
4303 owner()->Push(owner()->graph()->GetConstantTrue()); | |
4304 owner()->set_current_block(materialize_true); | |
4305 } | |
4306 if (continuation->IsFalseReachable()) { | |
4307 owner()->set_current_block(materialize_false); | |
4308 owner()->Push(owner()->graph()->GetConstantFalse()); | |
4309 owner()->set_current_block(materialize_false); | |
4310 } | |
4311 if (continuation->TrueAndFalseReachable()) { | |
4312 HBasicBlock* join = | |
4313 owner()->CreateJoin(materialize_true, materialize_false, ast_id); | |
4314 owner()->set_current_block(join); | |
4315 } | |
4316 } | |
4317 | |
4318 | |
4147 void TestContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) { | 4319 void TestContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) { |
4148 ASSERT(!instr->IsControlInstruction()); | 4320 ASSERT(!instr->IsControlInstruction()); |
4149 HOptimizedGraphBuilder* builder = owner(); | 4321 HOptimizedGraphBuilder* builder = owner(); |
4150 builder->AddInstruction(instr); | 4322 builder->AddInstruction(instr); |
4151 // We expect a simulate after every expression with side effects, though | 4323 // We expect a simulate after every expression with side effects, though |
4152 // this one isn't actually needed (and wouldn't work if it were targeted). | 4324 // this one isn't actually needed (and wouldn't work if it were targeted). |
4153 if (instr->HasObservableSideEffects()) { | 4325 if (instr->HasObservableSideEffects()) { |
4154 builder->Push(instr); | 4326 builder->Push(instr); |
4155 builder->AddSimulate(ast_id, REMOVABLE_SIMULATE); | 4327 builder->AddSimulate(ast_id, REMOVABLE_SIMULATE); |
4156 builder->Pop(); | 4328 builder->Pop(); |
4157 } | 4329 } |
4158 BuildBranch(instr); | 4330 BuildBranch(instr); |
4159 } | 4331 } |
4160 | 4332 |
4161 | 4333 |
4162 void TestContext::ReturnControl(HControlInstruction* instr, BailoutId ast_id) { | 4334 void TestContext::ReturnControl(HControlInstruction* instr, BailoutId ast_id) { |
4163 ASSERT(!instr->HasObservableSideEffects()); | 4335 ASSERT(!instr->HasObservableSideEffects()); |
4164 HBasicBlock* empty_true = owner()->graph()->CreateBasicBlock(); | 4336 HBasicBlock* empty_true = owner()->graph()->CreateBasicBlock(); |
4165 HBasicBlock* empty_false = owner()->graph()->CreateBasicBlock(); | 4337 HBasicBlock* empty_false = owner()->graph()->CreateBasicBlock(); |
4166 instr->SetSuccessorAt(0, empty_true); | 4338 instr->SetSuccessorAt(0, empty_true); |
4167 instr->SetSuccessorAt(1, empty_false); | 4339 instr->SetSuccessorAt(1, empty_false); |
4168 owner()->current_block()->Finish(instr); | 4340 owner()->current_block()->Finish(instr); |
4169 empty_true->Goto(if_true(), owner()->function_state()); | 4341 empty_true->Goto(if_true(), owner()->function_state()); |
4170 empty_false->Goto(if_false(), owner()->function_state()); | 4342 empty_false->Goto(if_false(), owner()->function_state()); |
4171 owner()->set_current_block(NULL); | 4343 owner()->set_current_block(NULL); |
4172 } | 4344 } |
4173 | 4345 |
4174 | 4346 |
4347 void TestContext::ReturnContinuation(IfContinuation* continuation, | |
4348 BailoutId ast_id) { | |
4349 HBasicBlock* true_branch = NULL; | |
4350 HBasicBlock* false_branch = NULL; | |
4351 continuation->Continue(&true_branch, &false_branch, NULL); | |
4352 if (continuation->IsTrueReachable()) { | |
4353 true_branch->Goto(if_true(), owner()->function_state()); | |
4354 } | |
4355 if (continuation->IsFalseReachable()) { | |
4356 false_branch->Goto(if_false(), owner()->function_state()); | |
4357 } | |
4358 owner()->set_current_block(NULL); | |
4359 } | |
4360 | |
4361 | |
4175 void TestContext::BuildBranch(HValue* value) { | 4362 void TestContext::BuildBranch(HValue* value) { |
4176 // We expect the graph to be in edge-split form: there is no edge that | 4363 // We expect the graph to be in edge-split form: there is no edge that |
4177 // connects a branch node to a join node. We conservatively ensure that | 4364 // connects a branch node to a join node. We conservatively ensure that |
4178 // property by always adding an empty block on the outgoing edges of this | 4365 // property by always adding an empty block on the outgoing edges of this |
4179 // branch. | 4366 // branch. |
4180 HOptimizedGraphBuilder* builder = owner(); | 4367 HOptimizedGraphBuilder* builder = owner(); |
4181 if (value != NULL && value->CheckFlag(HValue::kIsArguments)) { | 4368 if (value != NULL && value->CheckFlag(HValue::kIsArguments)) { |
4182 builder->Bailout("arguments object value in a test context"); | 4369 builder->Bailout("arguments object value in a test context"); |
4183 } | 4370 } |
4184 if (value->IsConstant()) { | 4371 if (value->IsConstant()) { |
(...skipping 2623 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6808 CHECK_ALIVE(VisitForValue(expr->value())); | 6995 CHECK_ALIVE(VisitForValue(expr->value())); |
6809 HValue* value = Pop(); | 6996 HValue* value = Pop(); |
6810 HValue* key = Pop(); | 6997 HValue* key = Pop(); |
6811 HValue* object = Pop(); | 6998 HValue* object = Pop(); |
6812 bool has_side_effects = false; | 6999 bool has_side_effects = false; |
6813 HandleKeyedElementAccess(object, key, value, expr, expr->AssignmentId(), | 7000 HandleKeyedElementAccess(object, key, value, expr, expr->AssignmentId(), |
6814 expr->position(), | 7001 expr->position(), |
6815 true, // is_store | 7002 true, // is_store |
6816 &has_side_effects); | 7003 &has_side_effects); |
6817 Push(value); | 7004 Push(value); |
6818 ASSERT(has_side_effects); // Stores always have side effects. | |
6819 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE); | 7005 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE); |
6820 return ast_context()->ReturnValue(Pop()); | 7006 return ast_context()->ReturnValue(Pop()); |
6821 } | 7007 } |
6822 } | 7008 } |
6823 | 7009 |
6824 | 7010 |
6825 // Because not every expression has a position and there is not common | 7011 // Because not every expression has a position and there is not common |
6826 // superclass of Assignment and CountOperation, we cannot just pass the | 7012 // superclass of Assignment and CountOperation, we cannot just pass the |
6827 // owning expression instead of position and ast_id separately. | 7013 // owning expression instead of position and ast_id separately. |
6828 void HOptimizedGraphBuilder::HandleGlobalVariableAssignment( | 7014 void HOptimizedGraphBuilder::HandleGlobalVariableAssignment( |
(...skipping 4864 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
11693 } | 11879 } |
11694 } | 11880 } |
11695 | 11881 |
11696 #ifdef DEBUG | 11882 #ifdef DEBUG |
11697 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 11883 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
11698 if (allocator_ != NULL) allocator_->Verify(); | 11884 if (allocator_ != NULL) allocator_->Verify(); |
11699 #endif | 11885 #endif |
11700 } | 11886 } |
11701 | 11887 |
11702 } } // namespace v8::internal | 11888 } } // namespace v8::internal |
OLD | NEW |