Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(191)

Side by Side Diff: src/hydrogen.cc

Issue 14344004: Fix bugs in IfBuilder and improve functionality (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Add GotoNoSimulate Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« src/hydrogen.h ('K') | « src/hydrogen.h ('k') | src/ia32/lithium-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698