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

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

Powered by Google App Engine
This is Rietveld 408576698