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

Side by Side Diff: src/hydrogen.cc

Issue 19528003: Unify SoftDeoptimize and Deoptimize hydrogen instructions (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Use defaults for Add<HDeoptimize> Created 7 years, 5 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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 ASSERT(last_environment() != NULL); 139 ASSERT(last_environment() != NULL);
140 ASSERT(!last_environment()->ast_id().IsNone()); 140 ASSERT(!last_environment()->ast_id().IsNone());
141 HBlockEntry* entry = new(zone()) HBlockEntry(); 141 HBlockEntry* entry = new(zone()) HBlockEntry();
142 entry->InitializeAsFirst(this); 142 entry->InitializeAsFirst(this);
143 first_ = last_ = entry; 143 first_ = last_ = entry;
144 } 144 }
145 instr->InsertAfter(last_); 145 instr->InsertAfter(last_);
146 } 146 }
147 147
148 148
149 HDeoptimize* HBasicBlock::CreateDeoptimize(
150 HDeoptimize::UseEnvironment has_uses) {
151 ASSERT(HasEnvironment());
152 if (has_uses == HDeoptimize::kNoUses)
153 return new(zone()) HDeoptimize(0, 0, 0, zone());
154
155 HEnvironment* environment = last_environment();
156 int first_local_index = environment->first_local_index();
157 int first_expression_index = environment->first_expression_index();
158 HDeoptimize* instr = new(zone()) HDeoptimize(
159 environment->length(), first_local_index, first_expression_index, zone());
160 for (int i = 0; i < environment->length(); i++) {
161 HValue* val = environment->values()->at(i);
162 instr->AddEnvironmentValue(val, zone());
163 }
164
165 return instr;
166 }
167
168
169 HSimulate* HBasicBlock::CreateSimulate(BailoutId ast_id, 149 HSimulate* HBasicBlock::CreateSimulate(BailoutId ast_id,
170 RemovableSimulate removable) { 150 RemovableSimulate removable) {
171 ASSERT(HasEnvironment()); 151 ASSERT(HasEnvironment());
172 HEnvironment* environment = last_environment(); 152 HEnvironment* environment = last_environment();
173 ASSERT(ast_id.IsNone() || 153 ASSERT(ast_id.IsNone() ||
174 ast_id == BailoutId::StubEntry() || 154 ast_id == BailoutId::StubEntry() ||
175 environment->closure()->shared()->VerifyBailoutId(ast_id)); 155 environment->closure()->shared()->VerifyBailoutId(ast_id));
176 156
177 int push_count = environment->push_count(); 157 int push_count = environment->push_count();
178 int pop_count = environment->pop_count(); 158 int pop_count = environment->pop_count();
(...skipping 514 matching lines...) Expand 10 before | Expand all | Expand 10 after
693 if (constant == GetConstantHole()) return true; 673 if (constant == GetConstantHole()) return true;
694 if (constant == GetConstantNull()) return true; 674 if (constant == GetConstantNull()) return true;
695 return false; 675 return false;
696 } 676 }
697 677
698 678
699 HGraphBuilder::IfBuilder::IfBuilder(HGraphBuilder* builder, int position) 679 HGraphBuilder::IfBuilder::IfBuilder(HGraphBuilder* builder, int position)
700 : builder_(builder), 680 : builder_(builder),
701 position_(position), 681 position_(position),
702 finished_(false), 682 finished_(false),
683 deopt_then_(false),
684 deopt_else_(false),
703 did_then_(false), 685 did_then_(false),
704 did_else_(false), 686 did_else_(false),
705 did_and_(false), 687 did_and_(false),
706 did_or_(false), 688 did_or_(false),
707 captured_(false), 689 captured_(false),
708 needs_compare_(true), 690 needs_compare_(true),
709 split_edge_merge_block_(NULL) { 691 split_edge_merge_block_(NULL),
692 merge_block_(NULL) {
710 HEnvironment* env = builder->environment(); 693 HEnvironment* env = builder->environment();
711 first_true_block_ = builder->CreateBasicBlock(env->Copy()); 694 first_true_block_ = builder->CreateBasicBlock(env->Copy());
712 last_true_block_ = NULL; 695 last_true_block_ = NULL;
713 first_false_block_ = builder->CreateBasicBlock(env->Copy()); 696 first_false_block_ = builder->CreateBasicBlock(env->Copy());
714 } 697 }
715 698
716 699
717 HGraphBuilder::IfBuilder::IfBuilder( 700 HGraphBuilder::IfBuilder::IfBuilder(
718 HGraphBuilder* builder, 701 HGraphBuilder* builder,
719 HIfContinuation* continuation) 702 HIfContinuation* continuation)
720 : builder_(builder), 703 : builder_(builder),
721 position_(RelocInfo::kNoPosition), 704 position_(RelocInfo::kNoPosition),
722 finished_(false), 705 finished_(false),
706 deopt_then_(false),
707 deopt_else_(false),
723 did_then_(false), 708 did_then_(false),
724 did_else_(false), 709 did_else_(false),
725 did_and_(false), 710 did_and_(false),
726 did_or_(false), 711 did_or_(false),
727 captured_(false), 712 captured_(false),
728 needs_compare_(false), 713 needs_compare_(false),
729 first_true_block_(NULL), 714 first_true_block_(NULL),
730 first_false_block_(NULL), 715 first_false_block_(NULL),
731 split_edge_merge_block_(NULL), 716 split_edge_merge_block_(NULL),
732 merge_block_(NULL) { 717 merge_block_(NULL) {
Jakob Kummerow 2013/07/22 16:53:12 nit: unnecessary whitespace change
danno 2013/07/23 12:18:14 Done.
733 continuation->Continue(&first_true_block_, 718 continuation->Continue(&first_true_block_,
734 &first_false_block_, 719 &first_false_block_,
735 &position_); 720 &position_);
736 } 721 }
737 722
738 723
739 void HGraphBuilder::IfBuilder::AddCompare(HControlInstruction* compare) { 724 void HGraphBuilder::IfBuilder::AddCompare(HControlInstruction* compare) {
740 if (split_edge_merge_block_ != NULL) { 725 if (split_edge_merge_block_ != NULL) {
741 HEnvironment* env = first_false_block_->last_environment(); 726 HEnvironment* env = first_false_block_->last_environment();
742 HBasicBlock* split_edge = 727 HBasicBlock* split_edge =
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
829 ASSERT(!captured_); 814 ASSERT(!captured_);
830 ASSERT(!finished_); 815 ASSERT(!finished_);
831 last_true_block_ = builder_->current_block(); 816 last_true_block_ = builder_->current_block();
832 ASSERT(first_true_block_ == NULL || !last_true_block_->IsFinished()); 817 ASSERT(first_true_block_ == NULL || !last_true_block_->IsFinished());
833 builder_->set_current_block(first_false_block_); 818 builder_->set_current_block(first_false_block_);
834 did_else_ = true; 819 did_else_ = true;
835 } 820 }
836 821
837 822
838 void HGraphBuilder::IfBuilder::Deopt() { 823 void HGraphBuilder::IfBuilder::Deopt() {
839 HBasicBlock* block = builder_->current_block(); 824 ASSERT(did_then_);
840 block->FinishExitWithDeoptimization(HDeoptimize::kUseAll);
841 builder_->set_current_block(NULL);
842 if (did_else_) { 825 if (did_else_) {
843 first_false_block_ = NULL; 826 deopt_else_ = true;
844 } else { 827 } else {
845 first_true_block_ = NULL; 828 deopt_then_ = true;
846 } 829 }
830 builder_->Add<HDeoptimize>(Deoptimizer::EAGER);
847 } 831 }
848 832
849 833
850 void HGraphBuilder::IfBuilder::Return(HValue* value) { 834 void HGraphBuilder::IfBuilder::Return(HValue* value) {
851 HBasicBlock* block = builder_->current_block(); 835 HBasicBlock* block = builder_->current_block();
852 HValue* context = builder_->environment()->LookupContext(); 836 HValue* context = builder_->environment()->LookupContext();
853 HValue* parameter_count = builder_->graph()->GetConstantMinus1(); 837 HValue* parameter_count = builder_->graph()->GetConstantMinus1();
854 block->FinishExit(new(zone()) HReturn(value, context, parameter_count)); 838 block->FinishExit(new(zone()) HReturn(value, context, parameter_count));
855 builder_->set_current_block(NULL); 839 builder_->set_current_block(NULL);
856 if (did_else_) { 840 if (did_else_) {
857 first_false_block_ = NULL; 841 first_false_block_ = NULL;
858 } else { 842 } else {
859 first_true_block_ = NULL; 843 first_true_block_ = NULL;
860 } 844 }
861 } 845 }
862 846
863 847
864 void HGraphBuilder::IfBuilder::End() { 848 void HGraphBuilder::IfBuilder::End() {
865 if (!captured_) { 849 if (!captured_) {
866 ASSERT(did_then_); 850 ASSERT(did_then_);
867 if (!did_else_) { 851 if (!did_else_) {
868 last_true_block_ = builder_->current_block(); 852 last_true_block_ = builder_->current_block();
869 } 853 }
870 if (first_true_block_ == NULL) { 854 if (first_true_block_ == NULL) {
871 // Deopt on true. Nothing to do, just continue the false block. 855 // Deopt on true. Nothing to do, just continue the false block.
Jakob Kummerow 2013/07/22 16:53:12 s/Deopt/Return/ ?
danno 2013/07/23 12:18:14 Done.
872 } else if (first_false_block_ == NULL) { 856 } else if (first_false_block_ == NULL) {
873 // Deopt on false. Nothing to do except switching to the true block. 857 // Deopt on false. Nothing to do except switching to the true block.
874 builder_->set_current_block(last_true_block_); 858 builder_->set_current_block(last_true_block_);
875 } else { 859 } else {
876 HEnvironment* merge_env = last_true_block_->last_environment()->Copy(); 860 HEnvironment* merge_env = last_true_block_->last_environment()->Copy();
877 merge_block_ = builder_->CreateBasicBlock(merge_env); 861 merge_block_ = builder_->CreateBasicBlock(merge_env);
878 ASSERT(!finished_); 862 ASSERT(!finished_);
879 if (!did_else_) Else(); 863 if (!did_else_) Else();
880 ASSERT(!last_true_block_->IsFinished()); 864 ASSERT(!last_true_block_->IsFinished());
881 HBasicBlock* last_false_block = builder_->current_block(); 865 HBasicBlock* last_false_block = builder_->current_block();
882 ASSERT(!last_false_block->IsFinished()); 866 ASSERT(!last_false_block->IsFinished());
867 if (deopt_then_) {
868 builder_->PadEnvironmentForContinuation(last_true_block_,
Jakob Kummerow 2013/07/22 16:53:12 IIUC, this call never does anything, because merge
danno 2013/07/23 12:18:14 Done.
869 merge_block_);
870 }
883 last_true_block_->GotoNoSimulate(merge_block_); 871 last_true_block_->GotoNoSimulate(merge_block_);
872 if (deopt_else_) {
873 builder_->PadEnvironmentForContinuation(last_false_block,
874 merge_block_);
875 }
884 last_false_block->GotoNoSimulate(merge_block_); 876 last_false_block->GotoNoSimulate(merge_block_);
885 builder_->set_current_block(merge_block_); 877 builder_->set_current_block(merge_block_);
886 } 878 }
887 } 879 }
888 finished_ = true; 880 finished_ = true;
889 } 881 }
890 882
891 883
892 HGraphBuilder::LoopBuilder::LoopBuilder(HGraphBuilder* builder, 884 HGraphBuilder::LoopBuilder::LoopBuilder(HGraphBuilder* builder,
893 HValue* context, 885 HValue* context,
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
984 HInstruction* HGraphBuilder::AddInstruction(HInstruction* instr) { 976 HInstruction* HGraphBuilder::AddInstruction(HInstruction* instr) {
985 ASSERT(current_block() != NULL); 977 ASSERT(current_block() != NULL);
986 current_block()->AddInstruction(instr); 978 current_block()->AddInstruction(instr);
987 if (no_side_effects_scope_count_ > 0) { 979 if (no_side_effects_scope_count_ > 0) {
988 instr->SetFlag(HValue::kHasNoObservableSideEffects); 980 instr->SetFlag(HValue::kHasNoObservableSideEffects);
989 } 981 }
990 return instr; 982 return instr;
991 } 983 }
992 984
993 985
994 void HGraphBuilder::AddSimulate(BailoutId id,
995 RemovableSimulate removable) {
996 ASSERT(current_block() != NULL);
997 ASSERT(no_side_effects_scope_count_ == 0);
998 current_block()->AddSimulate(id, removable);
999 }
1000
1001
1002 HReturn* HGraphBuilder::AddReturn(HValue* value) {
1003 HValue* context = environment()->LookupContext();
1004 int num_parameters = graph()->info()->num_parameters();
1005 HValue* params = Add<HConstant>(num_parameters);
1006 HReturn* return_instruction = new(graph()->zone())
1007 HReturn(value, context, params);
1008 current_block()->FinishExit(return_instruction);
1009 return return_instruction;
1010 }
1011
1012
1013 void HGraphBuilder::AddSoftDeoptimize(SoftDeoptimizeMode mode) {
1014 isolate()->counters()->soft_deopts_requested()->Increment();
1015 if (FLAG_always_opt && mode == CAN_OMIT_SOFT_DEOPT) return;
1016 if (current_block()->IsDeoptimizing()) return;
1017 Add<HSoftDeoptimize>();
1018 isolate()->counters()->soft_deopts_inserted()->Increment();
1019 current_block()->MarkAsDeoptimizing();
1020 graph()->set_has_soft_deoptimize(true);
1021 }
1022
1023
1024 HBasicBlock* HGraphBuilder::CreateBasicBlock(HEnvironment* env) { 986 HBasicBlock* HGraphBuilder::CreateBasicBlock(HEnvironment* env) {
1025 HBasicBlock* b = graph()->CreateBasicBlock(); 987 HBasicBlock* b = graph()->CreateBasicBlock();
1026 b->SetInitialEnvironment(env); 988 b->SetInitialEnvironment(env);
1027 return b; 989 return b;
1028 } 990 }
1029 991
1030 992
1031 HBasicBlock* HGraphBuilder::CreateLoopHeaderBlock() { 993 HBasicBlock* HGraphBuilder::CreateLoopHeaderBlock() {
1032 HBasicBlock* header = graph()->CreateBasicBlock(); 994 HBasicBlock* header = graph()->CreateBasicBlock();
1033 HEnvironment* entry_env = environment()->CopyAsLoopHeader(header); 995 HEnvironment* entry_env = environment()->CopyAsLoopHeader(header);
1034 header->SetInitialEnvironment(entry_env); 996 header->SetInitialEnvironment(entry_env);
1035 header->AttachLoopInformation(); 997 header->AttachLoopInformation();
1036 return header; 998 return header;
1037 } 999 }
1038 1000
1039 1001
1040 HValue* HGraphBuilder::BuildCheckHeapObject(HValue* obj) { 1002 HValue* HGraphBuilder::BuildCheckHeapObject(HValue* obj) {
1041 if (obj->type().IsHeapObject()) return obj; 1003 if (obj->type().IsHeapObject()) return obj;
1042 return Add<HCheckHeapObject>(obj); 1004 return Add<HCheckHeapObject>(obj);
1043 } 1005 }
1044 1006
1045 1007
1008 void HGraphBuilder::FinishExitWithHardDeoptimization(
1009 HBasicBlock* continuation) {
1010 PadEnvironmentForContinuation(current_block(), continuation);
1011 Add<HDeoptimize>(Deoptimizer::EAGER);
1012 if (no_side_effects_scope_count_ > 0) {
1013 current_block()->GotoNoSimulate(continuation);
1014 } else {
1015 current_block()->Goto(continuation);
1016 }
1017 }
1018
1019
1020 void HGraphBuilder::PadEnvironmentForContinuation(
1021 HBasicBlock* from,
1022 HBasicBlock* continuation) {
1023 if (continuation->last_environment() != NULL) {
1024 // When merging from a deopt block to a continuation, resolve differences in
1025 // environment by pushing undefined so that the environment match during the
Jakob Kummerow 2013/07/22 16:53:12 nit: "the environments match"
danno 2013/07/23 12:18:14 Done.
1026 // join. Popping values isn't allowed, that would kill the live ranges of
1027 // values that might be needed after the deopt.
1028 int continuation_env_length = continuation->last_environment()->length();
1029 ASSERT(continuation_env_length >= from->last_environment()->length());
1030 while (continuation_env_length > from->last_environment()->length()) {
1031 from->last_environment()->Push(graph()->GetConstantUndefined());
1032 }
1033 } else {
1034 ASSERT(continuation->predecessors()->length() == 0);
1035 }
1036 }
1037
1038
1046 HValue* HGraphBuilder::BuildCheckMap(HValue* obj, 1039 HValue* HGraphBuilder::BuildCheckMap(HValue* obj,
1047 Handle<Map> map) { 1040 Handle<Map> map) {
Jakob Kummerow 2013/07/22 16:53:12 nit: fits on last line?
danno 2013/07/23 12:18:14 Done.
1048 HCheckMaps* check = HCheckMaps::New(obj, map, zone()); 1041 HCheckMaps* check = HCheckMaps::New(obj, map, zone());
1049 AddInstruction(check); 1042 AddInstruction(check);
1050 return check; 1043 return check;
1051 } 1044 }
1052 1045
1053 1046
1054 HInstruction* HGraphBuilder::BuildExternalArrayElementAccess( 1047 HInstruction* HGraphBuilder::BuildExternalArrayElementAccess(
1055 HValue* external_elements, 1048 HValue* external_elements,
1056 HValue* checked_key, 1049 HValue* checked_key,
1057 HValue* val, 1050 HValue* val,
(...skipping 664 matching lines...) Expand 10 before | Expand all | Expand 10 after
1722 1715
1723 switch (operation) { 1716 switch (operation) {
1724 default: 1717 default:
1725 UNREACHABLE(); 1718 UNREACHABLE();
1726 case Token::SUB: { 1719 case Token::SUB: {
1727 HInstruction* instr = 1720 HInstruction* instr =
1728 HMul::New(zone(), environment()->LookupContext(), 1721 HMul::New(zone(), environment()->LookupContext(),
1729 input, graph()->GetConstantMinus1()); 1722 input, graph()->GetConstantMinus1());
1730 Representation rep = Representation::FromType(type); 1723 Representation rep = Representation::FromType(type);
1731 if (type->Is(Type::None())) { 1724 if (type->Is(Type::None())) {
1732 AddSoftDeoptimize(); 1725 Add<HDeoptimize>();
Jakob Kummerow 2013/07/22 16:53:12 I'm not a fan of this parameterless convenience me
danno 2013/07/23 12:18:14 Done.
1733 } 1726 }
1734 if (instr->IsBinaryOperation()) { 1727 if (instr->IsBinaryOperation()) {
1735 HBinaryOperation* binop = HBinaryOperation::cast(instr); 1728 HBinaryOperation* binop = HBinaryOperation::cast(instr);
1736 binop->set_observed_input_representation(1, rep); 1729 binop->set_observed_input_representation(1, rep);
1737 binop->set_observed_input_representation(2, rep); 1730 binop->set_observed_input_representation(2, rep);
1738 } 1731 }
1739 return instr; 1732 return instr;
1740 } 1733 }
1741 case Token::BIT_NOT: 1734 case Token::BIT_NOT:
1742 if (type->Is(Type::None())) { 1735 if (type->Is(Type::None())) {
1743 AddSoftDeoptimize(); 1736 Add<HDeoptimize>();
1744 } 1737 }
1745 return new(zone()) HBitNot(input); 1738 return new(zone()) HBitNot(input);
1746 } 1739 }
1747 } 1740 }
1748 1741
1749 1742
1750 void HGraphBuilder::BuildCompareNil( 1743 void HGraphBuilder::BuildCompareNil(
1751 HValue* value, 1744 HValue* value,
1752 Handle<Type> type, 1745 Handle<Type> type,
1753 int position, 1746 int position,
(...skipping 887 matching lines...) Expand 10 before | Expand all | Expand 10 after
2641 2634
2642 void TestContext::ReturnValue(HValue* value) { 2635 void TestContext::ReturnValue(HValue* value) {
2643 BuildBranch(value); 2636 BuildBranch(value);
2644 } 2637 }
2645 2638
2646 2639
2647 void EffectContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) { 2640 void EffectContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) {
2648 ASSERT(!instr->IsControlInstruction()); 2641 ASSERT(!instr->IsControlInstruction());
2649 owner()->AddInstruction(instr); 2642 owner()->AddInstruction(instr);
2650 if (instr->HasObservableSideEffects()) { 2643 if (instr->HasObservableSideEffects()) {
2651 owner()->AddSimulate(ast_id, REMOVABLE_SIMULATE); 2644 owner()->Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
2652 } 2645 }
2653 } 2646 }
2654 2647
2655 2648
2656 void EffectContext::ReturnControl(HControlInstruction* instr, 2649 void EffectContext::ReturnControl(HControlInstruction* instr,
2657 BailoutId ast_id) { 2650 BailoutId ast_id) {
2658 ASSERT(!instr->HasObservableSideEffects()); 2651 ASSERT(!instr->HasObservableSideEffects());
2659 HBasicBlock* empty_true = owner()->graph()->CreateBasicBlock(); 2652 HBasicBlock* empty_true = owner()->graph()->CreateBasicBlock();
2660 HBasicBlock* empty_false = owner()->graph()->CreateBasicBlock(); 2653 HBasicBlock* empty_false = owner()->graph()->CreateBasicBlock();
2661 instr->SetSuccessorAt(0, empty_true); 2654 instr->SetSuccessorAt(0, empty_true);
(...skipping 21 matching lines...) Expand all
2683 2676
2684 2677
2685 void ValueContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) { 2678 void ValueContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) {
2686 ASSERT(!instr->IsControlInstruction()); 2679 ASSERT(!instr->IsControlInstruction());
2687 if (!arguments_allowed() && instr->CheckFlag(HValue::kIsArguments)) { 2680 if (!arguments_allowed() && instr->CheckFlag(HValue::kIsArguments)) {
2688 return owner()->Bailout("bad value context for arguments object value"); 2681 return owner()->Bailout("bad value context for arguments object value");
2689 } 2682 }
2690 owner()->AddInstruction(instr); 2683 owner()->AddInstruction(instr);
2691 owner()->Push(instr); 2684 owner()->Push(instr);
2692 if (instr->HasObservableSideEffects()) { 2685 if (instr->HasObservableSideEffects()) {
2693 owner()->AddSimulate(ast_id, REMOVABLE_SIMULATE); 2686 owner()->Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
2694 } 2687 }
2695 } 2688 }
2696 2689
2697 2690
2698 void ValueContext::ReturnControl(HControlInstruction* instr, BailoutId ast_id) { 2691 void ValueContext::ReturnControl(HControlInstruction* instr, BailoutId ast_id) {
2699 ASSERT(!instr->HasObservableSideEffects()); 2692 ASSERT(!instr->HasObservableSideEffects());
2700 if (!arguments_allowed() && instr->CheckFlag(HValue::kIsArguments)) { 2693 if (!arguments_allowed() && instr->CheckFlag(HValue::kIsArguments)) {
2701 return owner()->Bailout("bad value context for arguments object value"); 2694 return owner()->Bailout("bad value context for arguments object value");
2702 } 2695 }
2703 HBasicBlock* materialize_false = owner()->graph()->CreateBasicBlock(); 2696 HBasicBlock* materialize_false = owner()->graph()->CreateBasicBlock();
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
2739 2732
2740 2733
2741 void TestContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) { 2734 void TestContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) {
2742 ASSERT(!instr->IsControlInstruction()); 2735 ASSERT(!instr->IsControlInstruction());
2743 HOptimizedGraphBuilder* builder = owner(); 2736 HOptimizedGraphBuilder* builder = owner();
2744 builder->AddInstruction(instr); 2737 builder->AddInstruction(instr);
2745 // We expect a simulate after every expression with side effects, though 2738 // We expect a simulate after every expression with side effects, though
2746 // this one isn't actually needed (and wouldn't work if it were targeted). 2739 // this one isn't actually needed (and wouldn't work if it were targeted).
2747 if (instr->HasObservableSideEffects()) { 2740 if (instr->HasObservableSideEffects()) {
2748 builder->Push(instr); 2741 builder->Push(instr);
2749 builder->AddSimulate(ast_id, REMOVABLE_SIMULATE); 2742 builder->Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
2750 builder->Pop(); 2743 builder->Pop();
2751 } 2744 }
2752 BuildBranch(instr); 2745 BuildBranch(instr);
2753 } 2746 }
2754 2747
2755 2748
2756 void TestContext::ReturnControl(HControlInstruction* instr, BailoutId ast_id) { 2749 void TestContext::ReturnControl(HControlInstruction* instr, BailoutId ast_id) {
2757 ASSERT(!instr->HasObservableSideEffects()); 2750 ASSERT(!instr->HasObservableSideEffects());
2758 HBasicBlock* empty_true = owner()->graph()->CreateBasicBlock(); 2751 HBasicBlock* empty_true = owner()->graph()->CreateBasicBlock();
2759 HBasicBlock* empty_false = owner()->graph()->CreateBasicBlock(); 2752 HBasicBlock* empty_false = owner()->graph()->CreateBasicBlock();
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
2927 current_block()->Goto(body_entry); 2920 current_block()->Goto(body_entry);
2928 body_entry->SetJoinId(BailoutId::FunctionEntry()); 2921 body_entry->SetJoinId(BailoutId::FunctionEntry());
2929 set_current_block(body_entry); 2922 set_current_block(body_entry);
2930 2923
2931 // Handle implicit declaration of the function name in named function 2924 // Handle implicit declaration of the function name in named function
2932 // expressions before other declarations. 2925 // expressions before other declarations.
2933 if (scope->is_function_scope() && scope->function() != NULL) { 2926 if (scope->is_function_scope() && scope->function() != NULL) {
2934 VisitVariableDeclaration(scope->function()); 2927 VisitVariableDeclaration(scope->function());
2935 } 2928 }
2936 VisitDeclarations(scope->declarations()); 2929 VisitDeclarations(scope->declarations());
2937 AddSimulate(BailoutId::Declarations()); 2930 Add<HSimulate>(BailoutId::Declarations());
2938 2931
2939 HValue* context = environment()->LookupContext(); 2932 HValue* context = environment()->LookupContext();
2940 Add<HStackCheck>(context, HStackCheck::kFunctionEntry); 2933 Add<HStackCheck>(context, HStackCheck::kFunctionEntry);
2941 2934
2942 VisitStatements(current_info()->function()->body()); 2935 VisitStatements(current_info()->function()->body());
2943 if (HasStackOverflow()) return false; 2936 if (HasStackOverflow()) return false;
2944 2937
2945 if (current_block() != NULL) { 2938 if (current_block() != NULL) {
2946 AddReturn(graph()->GetConstantUndefined()); 2939 Add<HReturn>(graph()->GetConstantUndefined());
2947 set_current_block(NULL); 2940 set_current_block(NULL);
2948 } 2941 }
2949 2942
2950 // If the checksum of the number of type info changes is the same as the 2943 // If the checksum of the number of type info changes is the same as the
2951 // last time this function was compiled, then this recompile is likely not 2944 // last time this function was compiled, then this recompile is likely not
2952 // due to missing/inadequate type feedback, but rather too aggressive 2945 // due to missing/inadequate type feedback, but rather too aggressive
2953 // optimization. Disable optimistic LICM in that case. 2946 // optimization. Disable optimistic LICM in that case.
2954 Handle<Code> unoptimized_code(current_info()->shared_info()->code()); 2947 Handle<Code> unoptimized_code(current_info()->shared_info()->code());
2955 ASSERT(unoptimized_code->kind() == Code::FUNCTION); 2948 ASSERT(unoptimized_code->kind() == Code::FUNCTION);
2956 Handle<TypeFeedbackInfo> type_info( 2949 Handle<TypeFeedbackInfo> type_info(
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after
3226 ASSERT(current_block() != NULL); 3219 ASSERT(current_block() != NULL);
3227 ASSERT(current_block()->HasPredecessor()); 3220 ASSERT(current_block()->HasPredecessor());
3228 } 3221 }
3229 3222
3230 3223
3231 void HOptimizedGraphBuilder::VisitIfStatement(IfStatement* stmt) { 3224 void HOptimizedGraphBuilder::VisitIfStatement(IfStatement* stmt) {
3232 ASSERT(!HasStackOverflow()); 3225 ASSERT(!HasStackOverflow());
3233 ASSERT(current_block() != NULL); 3226 ASSERT(current_block() != NULL);
3234 ASSERT(current_block()->HasPredecessor()); 3227 ASSERT(current_block()->HasPredecessor());
3235 if (stmt->condition()->ToBooleanIsTrue()) { 3228 if (stmt->condition()->ToBooleanIsTrue()) {
3236 AddSimulate(stmt->ThenId()); 3229 Add<HSimulate>(stmt->ThenId());
3237 Visit(stmt->then_statement()); 3230 Visit(stmt->then_statement());
3238 } else if (stmt->condition()->ToBooleanIsFalse()) { 3231 } else if (stmt->condition()->ToBooleanIsFalse()) {
3239 AddSimulate(stmt->ElseId()); 3232 Add<HSimulate>(stmt->ElseId());
3240 Visit(stmt->else_statement()); 3233 Visit(stmt->else_statement());
3241 } else { 3234 } else {
3242 HBasicBlock* cond_true = graph()->CreateBasicBlock(); 3235 HBasicBlock* cond_true = graph()->CreateBasicBlock();
3243 HBasicBlock* cond_false = graph()->CreateBasicBlock(); 3236 HBasicBlock* cond_false = graph()->CreateBasicBlock();
3244 CHECK_BAILOUT(VisitForControl(stmt->condition(), cond_true, cond_false)); 3237 CHECK_BAILOUT(VisitForControl(stmt->condition(), cond_true, cond_false));
3245 3238
3246 if (cond_true->HasPredecessor()) { 3239 if (cond_true->HasPredecessor()) {
3247 cond_true->SetJoinId(stmt->ThenId()); 3240 cond_true->SetJoinId(stmt->ThenId());
3248 set_current_block(cond_true); 3241 set_current_block(cond_true);
3249 CHECK_BAILOUT(Visit(stmt->then_statement())); 3242 CHECK_BAILOUT(Visit(stmt->then_statement()));
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
3336 void HOptimizedGraphBuilder::VisitReturnStatement(ReturnStatement* stmt) { 3329 void HOptimizedGraphBuilder::VisitReturnStatement(ReturnStatement* stmt) {
3337 ASSERT(!HasStackOverflow()); 3330 ASSERT(!HasStackOverflow());
3338 ASSERT(current_block() != NULL); 3331 ASSERT(current_block() != NULL);
3339 ASSERT(current_block()->HasPredecessor()); 3332 ASSERT(current_block()->HasPredecessor());
3340 FunctionState* state = function_state(); 3333 FunctionState* state = function_state();
3341 AstContext* context = call_context(); 3334 AstContext* context = call_context();
3342 if (context == NULL) { 3335 if (context == NULL) {
3343 // Not an inlined return, so an actual one. 3336 // Not an inlined return, so an actual one.
3344 CHECK_ALIVE(VisitForValue(stmt->expression())); 3337 CHECK_ALIVE(VisitForValue(stmt->expression()));
3345 HValue* result = environment()->Pop(); 3338 HValue* result = environment()->Pop();
3346 AddReturn(result); 3339 Add<HReturn>(result);
3347 } else if (state->inlining_kind() == CONSTRUCT_CALL_RETURN) { 3340 } else if (state->inlining_kind() == CONSTRUCT_CALL_RETURN) {
3348 // Return from an inlined construct call. In a test context the return value 3341 // Return from an inlined construct call. In a test context the return value
3349 // will always evaluate to true, in a value context the return value needs 3342 // will always evaluate to true, in a value context the return value needs
3350 // to be a JSObject. 3343 // to be a JSObject.
3351 if (context->IsTest()) { 3344 if (context->IsTest()) {
3352 TestContext* test = TestContext::cast(context); 3345 TestContext* test = TestContext::cast(context);
3353 CHECK_ALIVE(VisitForEffect(stmt->expression())); 3346 CHECK_ALIVE(VisitForEffect(stmt->expression()));
3354 current_block()->Goto(test->if_true(), state); 3347 current_block()->Goto(test->if_true(), state);
3355 } else if (context->IsEffect()) { 3348 } else if (context->IsEffect()) {
3356 CHECK_ALIVE(VisitForEffect(stmt->expression())); 3349 CHECK_ALIVE(VisitForEffect(stmt->expression()));
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
3428 } 3421 }
3429 3422
3430 ASSERT(stmt->switch_type() != SwitchStatement::UNKNOWN_SWITCH); 3423 ASSERT(stmt->switch_type() != SwitchStatement::UNKNOWN_SWITCH);
3431 if (stmt->switch_type() == SwitchStatement::GENERIC_SWITCH) { 3424 if (stmt->switch_type() == SwitchStatement::GENERIC_SWITCH) {
3432 return Bailout("SwitchStatement: mixed or non-literal switch labels"); 3425 return Bailout("SwitchStatement: mixed or non-literal switch labels");
3433 } 3426 }
3434 3427
3435 HValue* context = environment()->LookupContext(); 3428 HValue* context = environment()->LookupContext();
3436 3429
3437 CHECK_ALIVE(VisitForValue(stmt->tag())); 3430 CHECK_ALIVE(VisitForValue(stmt->tag()));
3438 AddSimulate(stmt->EntryId()); 3431 Add<HSimulate>(stmt->EntryId());
3439 HValue* tag_value = Pop(); 3432 HValue* tag_value = Pop();
3440 HBasicBlock* first_test_block = current_block(); 3433 HBasicBlock* first_test_block = current_block();
3441 3434
3442 HUnaryControlInstruction* string_check = NULL; 3435 HUnaryControlInstruction* string_check = NULL;
3443 HBasicBlock* not_string_block = NULL; 3436 HBasicBlock* not_string_block = NULL;
3444 3437
3445 // Test switch's tag value if all clauses are string literals 3438 // Test switch's tag value if all clauses are string literals
3446 if (stmt->switch_type() == SwitchStatement::STRING_SWITCH) { 3439 if (stmt->switch_type() == SwitchStatement::STRING_SWITCH) {
3447 string_check = new(zone()) HIsStringAndBranch(tag_value); 3440 string_check = new(zone()) HIsStringAndBranch(tag_value);
3448 first_test_block = graph()->CreateBasicBlock(); 3441 first_test_block = graph()->CreateBasicBlock();
(...skipping 19 matching lines...) Expand all
3468 CHECK_ALIVE(VisitForValue(clause->label())); 3461 CHECK_ALIVE(VisitForValue(clause->label()));
3469 HValue* label_value = Pop(); 3462 HValue* label_value = Pop();
3470 3463
3471 HBasicBlock* next_test_block = graph()->CreateBasicBlock(); 3464 HBasicBlock* next_test_block = graph()->CreateBasicBlock();
3472 HBasicBlock* body_block = graph()->CreateBasicBlock(); 3465 HBasicBlock* body_block = graph()->CreateBasicBlock();
3473 3466
3474 HControlInstruction* compare; 3467 HControlInstruction* compare;
3475 3468
3476 if (stmt->switch_type() == SwitchStatement::SMI_SWITCH) { 3469 if (stmt->switch_type() == SwitchStatement::SMI_SWITCH) {
3477 if (!clause->compare_type()->Is(Type::Smi())) { 3470 if (!clause->compare_type()->Is(Type::Smi())) {
3478 AddSoftDeoptimize(); 3471 Add<HDeoptimize>();
3479 } 3472 }
3480 3473
3481 HCompareNumericAndBranch* compare_ = 3474 HCompareNumericAndBranch* compare_ =
3482 new(zone()) HCompareNumericAndBranch(tag_value, 3475 new(zone()) HCompareNumericAndBranch(tag_value,
3483 label_value, 3476 label_value,
3484 Token::EQ_STRICT); 3477 Token::EQ_STRICT);
3485 compare_->set_observed_input_representation( 3478 compare_->set_observed_input_representation(
3486 Representation::Smi(), Representation::Smi()); 3479 Representation::Smi(), Representation::Smi());
3487 compare = compare_; 3480 compare = compare_;
3488 } else { 3481 } else {
(...skipping 29 matching lines...) Expand all
3518 CaseClause* clause = clauses->at(i); 3511 CaseClause* clause = clauses->at(i);
3519 3512
3520 // Identify the block where normal (non-fall-through) control flow 3513 // Identify the block where normal (non-fall-through) control flow
3521 // goes to. 3514 // goes to.
3522 HBasicBlock* normal_block = NULL; 3515 HBasicBlock* normal_block = NULL;
3523 if (clause->is_default()) { 3516 if (clause->is_default()) {
3524 if (last_block != NULL) { 3517 if (last_block != NULL) {
3525 normal_block = last_block; 3518 normal_block = last_block;
3526 last_block = NULL; // Cleared to indicate we've handled it. 3519 last_block = NULL; // Cleared to indicate we've handled it.
3527 } 3520 }
3528 } else if (!curr_test_block->end()->IsDeoptimize()) { 3521 } else {
3529 normal_block = curr_test_block->end()->FirstSuccessor(); 3522 normal_block = curr_test_block->end()->FirstSuccessor();
3530 curr_test_block = curr_test_block->end()->SecondSuccessor(); 3523 curr_test_block = curr_test_block->end()->SecondSuccessor();
3531 } 3524 }
3532 3525
3533 // Identify a block to emit the body into. 3526 // Identify a block to emit the body into.
3534 if (normal_block == NULL) { 3527 if (normal_block == NULL) {
3535 if (fall_through_block == NULL) { 3528 if (fall_through_block == NULL) {
3536 // (a) Unreachable. 3529 // (a) Unreachable.
3537 if (clause->is_default()) { 3530 if (clause->is_default()) {
3538 continue; // Might still be reachable clause bodies. 3531 continue; // Might still be reachable clause bodies.
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
3572 break_block->SetJoinId(stmt->ExitId()); 3565 break_block->SetJoinId(stmt->ExitId());
3573 set_current_block(break_block); 3566 set_current_block(break_block);
3574 } 3567 }
3575 } 3568 }
3576 3569
3577 3570
3578 void HOptimizedGraphBuilder::VisitLoopBody(IterationStatement* stmt, 3571 void HOptimizedGraphBuilder::VisitLoopBody(IterationStatement* stmt,
3579 HBasicBlock* loop_entry, 3572 HBasicBlock* loop_entry,
3580 BreakAndContinueInfo* break_info) { 3573 BreakAndContinueInfo* break_info) {
3581 BreakAndContinueScope push(break_info, this); 3574 BreakAndContinueScope push(break_info, this);
3582 AddSimulate(stmt->StackCheckId()); 3575 Add<HSimulate>(stmt->StackCheckId());
3583 HValue* context = environment()->LookupContext(); 3576 HValue* context = environment()->LookupContext();
3584 HStackCheck* stack_check = Add<HStackCheck>( 3577 HStackCheck* stack_check = Add<HStackCheck>(
3585 context, HStackCheck::kBackwardsBranch); 3578 context, HStackCheck::kBackwardsBranch);
3586 ASSERT(loop_entry->IsLoopHeader()); 3579 ASSERT(loop_entry->IsLoopHeader());
3587 loop_entry->loop_information()->set_stack_check(stack_check); 3580 loop_entry->loop_information()->set_stack_check(stack_check);
3588 CHECK_BAILOUT(Visit(stmt->body())); 3581 CHECK_BAILOUT(Visit(stmt->body()));
3589 } 3582 }
3590 3583
3591 3584
3592 void HOptimizedGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) { 3585 void HOptimizedGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) {
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
3733 return Bailout("ForInStatement with non-local each variable"); 3726 return Bailout("ForInStatement with non-local each variable");
3734 } 3727 }
3735 3728
3736 Variable* each_var = stmt->each()->AsVariableProxy()->var(); 3729 Variable* each_var = stmt->each()->AsVariableProxy()->var();
3737 3730
3738 CHECK_ALIVE(VisitForValue(stmt->enumerable())); 3731 CHECK_ALIVE(VisitForValue(stmt->enumerable()));
3739 HValue* enumerable = Top(); // Leave enumerable at the top. 3732 HValue* enumerable = Top(); // Leave enumerable at the top.
3740 3733
3741 HInstruction* map = Add<HForInPrepareMap>( 3734 HInstruction* map = Add<HForInPrepareMap>(
3742 environment()->LookupContext(), enumerable); 3735 environment()->LookupContext(), enumerable);
3743 AddSimulate(stmt->PrepareId()); 3736 Add<HSimulate>(stmt->PrepareId());
3744 3737
3745 HInstruction* array = Add<HForInCacheArray>( 3738 HInstruction* array = Add<HForInCacheArray>(
3746 enumerable, map, DescriptorArray::kEnumCacheBridgeCacheIndex); 3739 enumerable, map, DescriptorArray::kEnumCacheBridgeCacheIndex);
3747 3740
3748 HInstruction* enum_length = Add<HMapEnumLength>(map); 3741 HInstruction* enum_length = Add<HMapEnumLength>(map);
3749 3742
3750 HInstruction* start_index = Add<HConstant>(0); 3743 HInstruction* start_index = Add<HConstant>(0);
3751 3744
3752 Push(map); 3745 Push(map);
3753 Push(array); 3746 Push(array);
(...skipping 576 matching lines...) Expand 10 before | Expand all | Expand 10 after
4330 Handle<JSObject> holder; 4323 Handle<JSObject> holder;
4331 ASSERT(!LookupSetter(map, name, &setter, &holder)); 4324 ASSERT(!LookupSetter(map, name, &setter, &holder));
4332 #endif 4325 #endif
4333 CHECK_ALIVE(store = BuildStoreNamedMonomorphic(literal, 4326 CHECK_ALIVE(store = BuildStoreNamedMonomorphic(literal,
4334 name, 4327 name,
4335 value, 4328 value,
4336 map)); 4329 map));
4337 } 4330 }
4338 AddInstruction(store); 4331 AddInstruction(store);
4339 if (store->HasObservableSideEffects()) { 4332 if (store->HasObservableSideEffects()) {
4340 AddSimulate(key->id(), REMOVABLE_SIMULATE); 4333 Add<HSimulate>(key->id(), REMOVABLE_SIMULATE);
4341 } 4334 }
4342 } else { 4335 } else {
4343 CHECK_ALIVE(VisitForEffect(value)); 4336 CHECK_ALIVE(VisitForEffect(value));
4344 } 4337 }
4345 break; 4338 break;
4346 } 4339 }
4347 // Fall through. 4340 // Fall through.
4348 case ObjectLiteral::Property::PROTOTYPE: 4341 case ObjectLiteral::Property::PROTOTYPE:
4349 case ObjectLiteral::Property::SETTER: 4342 case ObjectLiteral::Property::SETTER:
4350 case ObjectLiteral::Property::GETTER: 4343 case ObjectLiteral::Property::GETTER:
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
4495 HStoreKeyed* instr = Add<HStoreKeyed>(elements, key, value, 4488 HStoreKeyed* instr = Add<HStoreKeyed>(elements, key, value,
4496 boilerplate_elements_kind); 4489 boilerplate_elements_kind);
4497 instr->SetUninitialized(uninitialized); 4490 instr->SetUninitialized(uninitialized);
4498 break; 4491 break;
4499 } 4492 }
4500 default: 4493 default:
4501 UNREACHABLE(); 4494 UNREACHABLE();
4502 break; 4495 break;
4503 } 4496 }
4504 4497
4505 AddSimulate(expr->GetIdForElement(i)); 4498 Add<HSimulate>(expr->GetIdForElement(i));
4506 } 4499 }
4507 4500
4508 Drop(1); // array literal index 4501 Drop(1); // array literal index
4509 return ast_context()->ReturnValue(Pop()); 4502 return ast_context()->ReturnValue(Pop());
4510 } 4503 }
4511 4504
4512 4505
4513 // Sets the lookup result and returns true if the load/store can be inlined. 4506 // Sets the lookup result and returns true if the load/store can be inlined.
4514 static bool ComputeLoadStoreField(Handle<Map> type, 4507 static bool ComputeLoadStoreField(Handle<Map> type,
4515 Handle<String> name, 4508 Handle<String> name,
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after
4826 AddInstruction(HCheckMaps::New(object, types, zone())); 4819 AddInstruction(HCheckMaps::New(object, types, zone()));
4827 HInstruction* store; 4820 HInstruction* store;
4828 CHECK_ALIVE_OR_RETURN( 4821 CHECK_ALIVE_OR_RETURN(
4829 store = BuildStoreNamedField( 4822 store = BuildStoreNamedField(
4830 object, name, store_value, types->at(count - 1), &lookup), 4823 object, name, store_value, types->at(count - 1), &lookup),
4831 true); 4824 true);
4832 if (result_value != NULL) Push(result_value); 4825 if (result_value != NULL) Push(result_value);
4833 Push(store_value); 4826 Push(store_value);
4834 store->set_position(position); 4827 store->set_position(position);
4835 AddInstruction(store); 4828 AddInstruction(store);
4836 AddSimulate(assignment_id); 4829 Add<HSimulate>(assignment_id);
4837 if (result_value != NULL) Drop(1); 4830 if (result_value != NULL) Drop(1);
4838 ast_context()->ReturnValue(Pop()); 4831 ast_context()->ReturnValue(Pop());
4839 return true; 4832 return true;
4840 } 4833 }
4841 4834
4842 4835
4843 void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedField( 4836 void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedField(
4844 BailoutId id, 4837 BailoutId id,
4845 int position, 4838 int position,
4846 BailoutId assignment_id, 4839 BailoutId assignment_id,
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
4889 current_block()->Goto(join); 4882 current_block()->Goto(join);
4890 4883
4891 set_current_block(if_false); 4884 set_current_block(if_false);
4892 } 4885 }
4893 } 4886 }
4894 4887
4895 // Finish up. Unconditionally deoptimize if we've handled all the maps we 4888 // Finish up. Unconditionally deoptimize if we've handled all the maps we
4896 // know about and do not want to handle ones we've never seen. Otherwise 4889 // know about and do not want to handle ones we've never seen. Otherwise
4897 // use a generic IC. 4890 // use a generic IC.
4898 if (count == types->length() && FLAG_deoptimize_uncommon_cases) { 4891 if (count == types->length() && FLAG_deoptimize_uncommon_cases) {
4899 current_block()->FinishExitWithDeoptimization(HDeoptimize::kNoUses); 4892 FinishExitWithHardDeoptimization(join);
4900 } else { 4893 } else {
4901 HInstruction* instr = BuildStoreNamedGeneric(object, name, store_value); 4894 HInstruction* instr = BuildStoreNamedGeneric(object, name, store_value);
4902 instr->set_position(position); 4895 instr->set_position(position);
4903 AddInstruction(instr); 4896 AddInstruction(instr);
4904 4897
4905 if (join != NULL) { 4898 if (join != NULL) {
4906 if (!ast_context()->IsEffect()) { 4899 if (!ast_context()->IsEffect()) {
4907 if (result_value != NULL) Push(result_value); 4900 if (result_value != NULL) Push(result_value);
4908 Push(store_value); 4901 Push(store_value);
4909 } 4902 }
4910 current_block()->Goto(join); 4903 current_block()->Goto(join);
4911 } else { 4904 } else {
4912 // The HSimulate for the store should not see the stored value in 4905 // The HSimulate for the store should not see the stored value in
4913 // effect contexts (it is not materialized at expr->id() in the 4906 // effect contexts (it is not materialized at expr->id() in the
4914 // unoptimized code). 4907 // unoptimized code).
4915 if (instr->HasObservableSideEffects()) { 4908 if (instr->HasObservableSideEffects()) {
4916 if (ast_context()->IsEffect()) { 4909 if (ast_context()->IsEffect()) {
4917 AddSimulate(id, REMOVABLE_SIMULATE); 4910 Add<HSimulate>(id, REMOVABLE_SIMULATE);
4918 } else { 4911 } else {
4919 if (result_value != NULL) Push(result_value); 4912 if (result_value != NULL) Push(result_value);
4920 Push(store_value); 4913 Push(store_value);
4921 AddSimulate(id, REMOVABLE_SIMULATE); 4914 Add<HSimulate>(id, REMOVABLE_SIMULATE);
4922 Drop(result_value != NULL ? 2 : 1); 4915 Drop(result_value != NULL ? 2 : 1);
4923 } 4916 }
4924 } 4917 }
4925 return ast_context()->ReturnValue( 4918 return ast_context()->ReturnValue(
4926 result_value != NULL ? result_value : store_value); 4919 result_value != NULL ? result_value : store_value);
4927 } 4920 }
4928 } 4921 }
4929 4922
4930 ASSERT(join != NULL); 4923 ASSERT(join != NULL);
4931 join->SetJoinId(id); 4924 join->SetJoinId(id);
4932 set_current_block(join); 4925 set_current_block(join);
4933 if (!ast_context()->IsEffect()) { 4926 if (!ast_context()->IsEffect()) {
4934 if (result_value != NULL) Drop(1); 4927 if (result_value != NULL) Drop(1);
4935 ast_context()->ReturnValue(Pop()); 4928 ast_context()->ReturnValue(Pop());
4936 } 4929 }
4937 } 4930 }
4938 4931
4939 4932
4940 void HOptimizedGraphBuilder::HandlePropertyAssignment(Assignment* expr) { 4933 void HOptimizedGraphBuilder::HandlePropertyAssignment(Assignment* expr) {
4941 Property* prop = expr->target()->AsProperty(); 4934 Property* prop = expr->target()->AsProperty();
4942 ASSERT(prop != NULL); 4935 ASSERT(prop != NULL);
4943 CHECK_ALIVE(VisitForValue(prop->obj())); 4936 CHECK_ALIVE(VisitForValue(prop->obj()));
4944 4937
4945 if (prop->key()->IsPropertyName()) { 4938 if (prop->key()->IsPropertyName()) {
4946 // Named store. 4939 // Named store.
4947 CHECK_ALIVE(VisitForValue(expr->value())); 4940 CHECK_ALIVE(VisitForValue(expr->value()));
4948 HValue* value = environment()->ExpressionStackAt(0); 4941 HValue* value = environment()->ExpressionStackAt(0);
4949 HValue* object = environment()->ExpressionStackAt(1); 4942 HValue* object = environment()->ExpressionStackAt(1);
4950 4943
4951 if (expr->IsUninitialized()) AddSoftDeoptimize(); 4944 if (expr->IsUninitialized()) Add<HDeoptimize>();
4952 return BuildStoreNamed(expr, expr->id(), expr->position(), 4945 return BuildStoreNamed(expr, expr->id(), expr->position(),
4953 expr->AssignmentId(), prop, object, value); 4946 expr->AssignmentId(), prop, object, value);
4954 } else { 4947 } else {
4955 // Keyed store. 4948 // Keyed store.
4956 CHECK_ALIVE(VisitForValue(prop->key())); 4949 CHECK_ALIVE(VisitForValue(prop->key()));
4957 CHECK_ALIVE(VisitForValue(expr->value())); 4950 CHECK_ALIVE(VisitForValue(expr->value()));
4958 HValue* value = environment()->ExpressionStackAt(0); 4951 HValue* value = environment()->ExpressionStackAt(0);
4959 HValue* key = environment()->ExpressionStackAt(1); 4952 HValue* key = environment()->ExpressionStackAt(1);
4960 HValue* object = environment()->ExpressionStackAt(2); 4953 HValue* object = environment()->ExpressionStackAt(2);
4961 bool has_side_effects = false; 4954 bool has_side_effects = false;
4962 HandleKeyedElementAccess(object, key, value, expr, expr->AssignmentId(), 4955 HandleKeyedElementAccess(object, key, value, expr, expr->AssignmentId(),
4963 expr->position(), 4956 expr->position(),
4964 true, // is_store 4957 true, // is_store
4965 &has_side_effects); 4958 &has_side_effects);
4966 Drop(3); 4959 Drop(3);
4967 Push(value); 4960 Push(value);
4968 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE); 4961 Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE);
4969 return ast_context()->ReturnValue(Pop()); 4962 return ast_context()->ReturnValue(Pop());
4970 } 4963 }
4971 } 4964 }
4972 4965
4973 4966
4974 // Because not every expression has a position and there is not common 4967 // Because not every expression has a position and there is not common
4975 // superclass of Assignment and CountOperation, we cannot just pass the 4968 // superclass of Assignment and CountOperation, we cannot just pass the
4976 // owning expression instead of position and ast_id separately. 4969 // owning expression instead of position and ast_id separately.
4977 void HOptimizedGraphBuilder::HandleGlobalVariableAssignment( 4970 void HOptimizedGraphBuilder::HandleGlobalVariableAssignment(
4978 Variable* var, 4971 Variable* var,
4979 HValue* value, 4972 HValue* value,
4980 int position, 4973 int position,
4981 BailoutId ast_id) { 4974 BailoutId ast_id) {
4982 LookupResult lookup(isolate()); 4975 LookupResult lookup(isolate());
4983 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, true); 4976 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, true);
4984 if (type == kUseCell) { 4977 if (type == kUseCell) {
4985 Handle<GlobalObject> global(current_info()->global_object()); 4978 Handle<GlobalObject> global(current_info()->global_object());
4986 Handle<PropertyCell> cell(global->GetPropertyCell(&lookup)); 4979 Handle<PropertyCell> cell(global->GetPropertyCell(&lookup));
4987 if (cell->type()->IsConstant()) { 4980 if (cell->type()->IsConstant()) {
4988 IfBuilder builder(this); 4981 IfBuilder builder(this);
4989 HValue* constant = Add<HConstant>(cell->type()->AsConstant()); 4982 HValue* constant = Add<HConstant>(cell->type()->AsConstant());
4990 if (cell->type()->AsConstant()->IsNumber()) { 4983 if (cell->type()->AsConstant()->IsNumber()) {
4991 builder.If<HCompareNumericAndBranch>(value, constant, Token::EQ); 4984 builder.If<HCompareNumericAndBranch>(value, constant, Token::EQ);
4992 } else { 4985 } else {
4993 builder.If<HCompareObjectEqAndBranch>(value, constant); 4986 builder.If<HCompareObjectEqAndBranch>(value, constant);
4994 } 4987 }
4995 builder.Then(); 4988 builder.Then();
4996 builder.Else(); 4989 builder.Else();
4997 AddSoftDeoptimize(MUST_EMIT_SOFT_DEOPT); 4990 Add<HDeoptimize>(Deoptimizer::EAGER);
4998 builder.End(); 4991 builder.End();
4999 } 4992 }
5000 HInstruction* instr = 4993 HInstruction* instr =
5001 Add<HStoreGlobalCell>(value, cell, lookup.GetPropertyDetails()); 4994 Add<HStoreGlobalCell>(value, cell, lookup.GetPropertyDetails());
5002 instr->set_position(position); 4995 instr->set_position(position);
5003 if (instr->HasObservableSideEffects()) { 4996 if (instr->HasObservableSideEffects()) {
5004 AddSimulate(ast_id, REMOVABLE_SIMULATE); 4997 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
5005 } 4998 }
5006 } else { 4999 } else {
5007 HValue* context = environment()->LookupContext(); 5000 HValue* context = environment()->LookupContext();
5008 HGlobalObject* global_object = Add<HGlobalObject>(context); 5001 HGlobalObject* global_object = Add<HGlobalObject>(context);
5009 HStoreGlobalGeneric* instr = 5002 HStoreGlobalGeneric* instr =
5010 Add<HStoreGlobalGeneric>(context, global_object, var->name(), 5003 Add<HStoreGlobalGeneric>(context, global_object, var->name(),
5011 value, function_strict_mode_flag()); 5004 value, function_strict_mode_flag());
5012 instr->set_position(position); 5005 instr->set_position(position);
5013 ASSERT(instr->HasObservableSideEffects()); 5006 ASSERT(instr->HasObservableSideEffects());
5014 AddSimulate(ast_id, REMOVABLE_SIMULATE); 5007 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
5015 } 5008 }
5016 } 5009 }
5017 5010
5018 5011
5019 void HOptimizedGraphBuilder::BuildStoreNamed(Expression* expr, 5012 void HOptimizedGraphBuilder::BuildStoreNamed(Expression* expr,
5020 BailoutId id, 5013 BailoutId id,
5021 int position, 5014 int position,
5022 BailoutId assignment_id, 5015 BailoutId assignment_id,
5023 Property* prop, 5016 Property* prop,
5024 HValue* object, 5017 HValue* object,
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
5067 } else { 5060 } else {
5068 Drop(2); 5061 Drop(2);
5069 instr = BuildStoreNamedGeneric(object, name, store_value); 5062 instr = BuildStoreNamedGeneric(object, name, store_value);
5070 } 5063 }
5071 5064
5072 if (result_value != NULL) Push(result_value); 5065 if (result_value != NULL) Push(result_value);
5073 Push(store_value); 5066 Push(store_value);
5074 instr->set_position(position); 5067 instr->set_position(position);
5075 AddInstruction(instr); 5068 AddInstruction(instr);
5076 if (instr->HasObservableSideEffects()) { 5069 if (instr->HasObservableSideEffects()) {
5077 AddSimulate(assignment_id, REMOVABLE_SIMULATE); 5070 Add<HSimulate>(assignment_id, REMOVABLE_SIMULATE);
5078 } 5071 }
5079 if (result_value != NULL) Drop(1); 5072 if (result_value != NULL) Drop(1);
5080 return ast_context()->ReturnValue(Pop()); 5073 return ast_context()->ReturnValue(Pop());
5081 } 5074 }
5082 5075
5083 5076
5084 void HOptimizedGraphBuilder::HandleCompoundAssignment(Assignment* expr) { 5077 void HOptimizedGraphBuilder::HandleCompoundAssignment(Assignment* expr) {
5085 Expression* target = expr->target(); 5078 Expression* target = expr->target();
5086 VariableProxy* proxy = target->AsVariableProxy(); 5079 VariableProxy* proxy = target->AsVariableProxy();
5087 Property* prop = target->AsProperty(); 5080 Property* prop = target->AsProperty();
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
5145 // perform checks here 5138 // perform checks here
5146 UNREACHABLE(); 5139 UNREACHABLE();
5147 default: 5140 default:
5148 mode = HStoreContextSlot::kNoCheck; 5141 mode = HStoreContextSlot::kNoCheck;
5149 } 5142 }
5150 5143
5151 HValue* context = BuildContextChainWalk(var); 5144 HValue* context = BuildContextChainWalk(var);
5152 HStoreContextSlot* instr = Add<HStoreContextSlot>(context, var->index(), 5145 HStoreContextSlot* instr = Add<HStoreContextSlot>(context, var->index(),
5153 mode, Top()); 5146 mode, Top());
5154 if (instr->HasObservableSideEffects()) { 5147 if (instr->HasObservableSideEffects()) {
5155 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE); 5148 Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE);
5156 } 5149 }
5157 break; 5150 break;
5158 } 5151 }
5159 5152
5160 case Variable::LOOKUP: 5153 case Variable::LOOKUP:
5161 return Bailout("compound assignment to lookup slot"); 5154 return Bailout("compound assignment to lookup slot");
5162 } 5155 }
5163 return ast_context()->ReturnValue(Pop()); 5156 return ast_context()->ReturnValue(Pop());
5164 5157
5165 } else if (prop != NULL) { 5158 } else if (prop != NULL) {
(...skipping 20 matching lines...) Expand all
5186 load = BuildCallGetter(object, map, getter, holder); 5179 load = BuildCallGetter(object, map, getter, holder);
5187 } else { 5180 } else {
5188 load = BuildLoadNamedMonomorphic(object, name, prop, map); 5181 load = BuildLoadNamedMonomorphic(object, name, prop, map);
5189 } 5182 }
5190 } else if (types != NULL && types->length() > 1) { 5183 } else if (types != NULL && types->length() > 1) {
5191 load = TryLoadPolymorphicAsMonomorphic(prop, object, types, name); 5184 load = TryLoadPolymorphicAsMonomorphic(prop, object, types, name);
5192 } 5185 }
5193 if (load == NULL) load = BuildLoadNamedGeneric(object, name, prop); 5186 if (load == NULL) load = BuildLoadNamedGeneric(object, name, prop);
5194 PushAndAdd(load); 5187 PushAndAdd(load);
5195 if (load->HasObservableSideEffects()) { 5188 if (load->HasObservableSideEffects()) {
5196 AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE); 5189 Add<HSimulate>(prop->LoadId(), REMOVABLE_SIMULATE);
5197 } 5190 }
5198 5191
5199 CHECK_ALIVE(VisitForValue(expr->value())); 5192 CHECK_ALIVE(VisitForValue(expr->value()));
5200 HValue* right = Pop(); 5193 HValue* right = Pop();
5201 HValue* left = Pop(); 5194 HValue* left = Pop();
5202 5195
5203 HInstruction* instr = BuildBinaryOperation(operation, left, right); 5196 HInstruction* instr = BuildBinaryOperation(operation, left, right);
5204 PushAndAdd(instr); 5197 PushAndAdd(instr);
5205 if (instr->HasObservableSideEffects()) { 5198 if (instr->HasObservableSideEffects()) {
5206 AddSimulate(operation->id(), REMOVABLE_SIMULATE); 5199 Add<HSimulate>(operation->id(), REMOVABLE_SIMULATE);
5207 } 5200 }
5208 5201
5209 return BuildStoreNamed(prop, expr->id(), expr->position(), 5202 return BuildStoreNamed(prop, expr->id(), expr->position(),
5210 expr->AssignmentId(), prop, object, instr); 5203 expr->AssignmentId(), prop, object, instr);
5211 } else { 5204 } else {
5212 // Keyed property. 5205 // Keyed property.
5213 CHECK_ALIVE(VisitForValue(prop->obj())); 5206 CHECK_ALIVE(VisitForValue(prop->obj()));
5214 CHECK_ALIVE(VisitForValue(prop->key())); 5207 CHECK_ALIVE(VisitForValue(prop->key()));
5215 HValue* obj = environment()->ExpressionStackAt(1); 5208 HValue* obj = environment()->ExpressionStackAt(1);
5216 HValue* key = environment()->ExpressionStackAt(0); 5209 HValue* key = environment()->ExpressionStackAt(0);
5217 5210
5218 bool has_side_effects = false; 5211 bool has_side_effects = false;
5219 HValue* load = HandleKeyedElementAccess( 5212 HValue* load = HandleKeyedElementAccess(
5220 obj, key, NULL, prop, prop->LoadId(), RelocInfo::kNoPosition, 5213 obj, key, NULL, prop, prop->LoadId(), RelocInfo::kNoPosition,
5221 false, // is_store 5214 false, // is_store
5222 &has_side_effects); 5215 &has_side_effects);
5223 Push(load); 5216 Push(load);
5224 if (has_side_effects) AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE); 5217 if (has_side_effects) Add<HSimulate>(prop->LoadId(), REMOVABLE_SIMULATE);
5225 5218
5226 CHECK_ALIVE(VisitForValue(expr->value())); 5219 CHECK_ALIVE(VisitForValue(expr->value()));
5227 HValue* right = Pop(); 5220 HValue* right = Pop();
5228 HValue* left = Pop(); 5221 HValue* left = Pop();
5229 5222
5230 HInstruction* instr = BuildBinaryOperation(operation, left, right); 5223 HInstruction* instr = BuildBinaryOperation(operation, left, right);
5231 PushAndAdd(instr); 5224 PushAndAdd(instr);
5232 if (instr->HasObservableSideEffects()) { 5225 if (instr->HasObservableSideEffects()) {
5233 AddSimulate(operation->id(), REMOVABLE_SIMULATE); 5226 Add<HSimulate>(operation->id(), REMOVABLE_SIMULATE);
5234 } 5227 }
5235 5228
5236 HandleKeyedElementAccess(obj, key, instr, expr, expr->AssignmentId(), 5229 HandleKeyedElementAccess(obj, key, instr, expr, expr->AssignmentId(),
5237 RelocInfo::kNoPosition, 5230 RelocInfo::kNoPosition,
5238 true, // is_store 5231 true, // is_store
5239 &has_side_effects); 5232 &has_side_effects);
5240 5233
5241 // Drop the simulated receiver, key, and value. Return the value. 5234 // Drop the simulated receiver, key, and value. Return the value.
5242 Drop(3); 5235 Drop(3);
5243 Push(instr); 5236 Push(instr);
5244 ASSERT(has_side_effects); // Stores always have side effects. 5237 ASSERT(has_side_effects); // Stores always have side effects.
5245 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE); 5238 Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE);
5246 return ast_context()->ReturnValue(Pop()); 5239 return ast_context()->ReturnValue(Pop());
5247 } 5240 }
5248 5241
5249 } else { 5242 } else {
5250 return Bailout("invalid lhs in compound assignment"); 5243 return Bailout("invalid lhs in compound assignment");
5251 } 5244 }
5252 } 5245 }
5253 5246
5254 5247
5255 void HOptimizedGraphBuilder::VisitAssignment(Assignment* expr) { 5248 void HOptimizedGraphBuilder::VisitAssignment(Assignment* expr) {
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
5357 } else { 5350 } else {
5358 ASSERT(expr->op() == Token::INIT_CONST); 5351 ASSERT(expr->op() == Token::INIT_CONST);
5359 5352
5360 mode = HStoreContextSlot::kCheckIgnoreAssignment; 5353 mode = HStoreContextSlot::kCheckIgnoreAssignment;
5361 } 5354 }
5362 5355
5363 HValue* context = BuildContextChainWalk(var); 5356 HValue* context = BuildContextChainWalk(var);
5364 HStoreContextSlot* instr = Add<HStoreContextSlot>(context, var->index(), 5357 HStoreContextSlot* instr = Add<HStoreContextSlot>(context, var->index(),
5365 mode, Top()); 5358 mode, Top());
5366 if (instr->HasObservableSideEffects()) { 5359 if (instr->HasObservableSideEffects()) {
5367 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE); 5360 Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE);
5368 } 5361 }
5369 return ast_context()->ReturnValue(Pop()); 5362 return ast_context()->ReturnValue(Pop());
5370 } 5363 }
5371 5364
5372 case Variable::LOOKUP: 5365 case Variable::LOOKUP:
5373 return Bailout("assignment to LOOKUP variable"); 5366 return Bailout("assignment to LOOKUP variable");
5374 } 5367 }
5375 } else { 5368 } else {
5376 return Bailout("invalid left-hand side in assignment"); 5369 return Bailout("invalid left-hand side in assignment");
5377 } 5370 }
(...skipping 13 matching lines...) Expand all
5391 // We don't optimize functions with invalid left-hand sides in 5384 // We don't optimize functions with invalid left-hand sides in
5392 // assignments, count operations, or for-in. Consequently throw can 5385 // assignments, count operations, or for-in. Consequently throw can
5393 // currently only occur in an effect context. 5386 // currently only occur in an effect context.
5394 ASSERT(ast_context()->IsEffect()); 5387 ASSERT(ast_context()->IsEffect());
5395 CHECK_ALIVE(VisitForValue(expr->exception())); 5388 CHECK_ALIVE(VisitForValue(expr->exception()));
5396 5389
5397 HValue* context = environment()->LookupContext(); 5390 HValue* context = environment()->LookupContext();
5398 HValue* value = environment()->Pop(); 5391 HValue* value = environment()->Pop();
5399 HThrow* instr = Add<HThrow>(context, value); 5392 HThrow* instr = Add<HThrow>(context, value);
5400 instr->set_position(expr->position()); 5393 instr->set_position(expr->position());
5401 AddSimulate(expr->id()); 5394 Add<HSimulate>(expr->id());
5402 current_block()->FinishExit(new(zone()) HAbnormalExit); 5395 current_block()->FinishExit(new(zone()) HAbnormalExit);
5403 set_current_block(NULL); 5396 set_current_block(NULL);
5404 } 5397 }
5405 5398
5406 5399
5407 HLoadNamedField* HGraphBuilder::BuildLoadNamedField( 5400 HLoadNamedField* HGraphBuilder::BuildLoadNamedField(
5408 HValue* object, 5401 HValue* object,
5409 HObjectAccess access, 5402 HObjectAccess access,
5410 Representation representation) { 5403 Representation representation) {
5411 bool load_double = false; 5404 bool load_double = false;
(...skipping 11 matching lines...) Expand all
5423 } 5416 }
5424 return field; 5417 return field;
5425 } 5418 }
5426 5419
5427 5420
5428 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedGeneric( 5421 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedGeneric(
5429 HValue* object, 5422 HValue* object,
5430 Handle<String> name, 5423 Handle<String> name,
5431 Property* expr) { 5424 Property* expr) {
5432 if (expr->IsUninitialized()) { 5425 if (expr->IsUninitialized()) {
5433 AddSoftDeoptimize(); 5426 Add<HDeoptimize>();
5434 } 5427 }
5435 HValue* context = environment()->LookupContext(); 5428 HValue* context = environment()->LookupContext();
5436 return new(zone()) HLoadNamedGeneric(context, object, name); 5429 return new(zone()) HLoadNamedGeneric(context, object, name);
5437 } 5430 }
5438 5431
5439 5432
5440 HInstruction* HOptimizedGraphBuilder::BuildCallGetter( 5433 HInstruction* HOptimizedGraphBuilder::BuildCallGetter(
5441 HValue* object, 5434 HValue* object,
5442 Handle<Map> map, 5435 Handle<Map> map,
5443 Handle<JSFunction> getter, 5436 Handle<JSFunction> getter,
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after
5709 HLoadExternalArrayPointer* external_elements = NULL; 5702 HLoadExternalArrayPointer* external_elements = NULL;
5710 HInstruction* checked_key = NULL; 5703 HInstruction* checked_key = NULL;
5711 5704
5712 // Generated code assumes that FAST_* and DICTIONARY_ELEMENTS ElementsKinds 5705 // Generated code assumes that FAST_* and DICTIONARY_ELEMENTS ElementsKinds
5713 // are handled before external arrays. 5706 // are handled before external arrays.
5714 STATIC_ASSERT(FAST_SMI_ELEMENTS < FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND); 5707 STATIC_ASSERT(FAST_SMI_ELEMENTS < FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND);
5715 STATIC_ASSERT(FAST_HOLEY_ELEMENTS < FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND); 5708 STATIC_ASSERT(FAST_HOLEY_ELEMENTS < FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND);
5716 STATIC_ASSERT(FAST_DOUBLE_ELEMENTS < FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND); 5709 STATIC_ASSERT(FAST_DOUBLE_ELEMENTS < FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND);
5717 STATIC_ASSERT(DICTIONARY_ELEMENTS < FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND); 5710 STATIC_ASSERT(DICTIONARY_ELEMENTS < FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND);
5718 5711
5712 NoObservableSideEffectsScope scope(this);
5713
5719 for (ElementsKind elements_kind = FIRST_ELEMENTS_KIND; 5714 for (ElementsKind elements_kind = FIRST_ELEMENTS_KIND;
5720 elements_kind <= LAST_ELEMENTS_KIND; 5715 elements_kind <= LAST_ELEMENTS_KIND;
5721 elements_kind = ElementsKind(elements_kind + 1)) { 5716 elements_kind = ElementsKind(elements_kind + 1)) {
5722 // After having handled FAST_* and DICTIONARY_ELEMENTS, we need to add some 5717 // After having handled FAST_* and DICTIONARY_ELEMENTS, we need to add some
5723 // code that's executed for all external array cases. 5718 // code that's executed for all external array cases.
5724 STATIC_ASSERT(LAST_EXTERNAL_ARRAY_ELEMENTS_KIND == 5719 STATIC_ASSERT(LAST_EXTERNAL_ARRAY_ELEMENTS_KIND ==
5725 LAST_ELEMENTS_KIND); 5720 LAST_ELEMENTS_KIND);
5726 if (elements_kind == FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND 5721 if (elements_kind == FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND
5727 && todo_external_array) { 5722 && todo_external_array) {
5728 HInstruction* length = AddLoadFixedArrayLength(elements); 5723 HInstruction* length = AddLoadFixedArrayLength(elements);
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
5807 if (position != RelocInfo::kNoPosition) access->set_position(position); 5802 if (position != RelocInfo::kNoPosition) access->set_position(position);
5808 if (!is_store) { 5803 if (!is_store) {
5809 Push(access); 5804 Push(access);
5810 } 5805 }
5811 current_block()->GotoNoSimulate(join); 5806 current_block()->GotoNoSimulate(join);
5812 set_current_block(if_false); 5807 set_current_block(if_false);
5813 } 5808 }
5814 } 5809 }
5815 5810
5816 // Deopt if none of the cases matched. 5811 // Deopt if none of the cases matched.
5817 current_block()->FinishExitWithDeoptimization(HDeoptimize::kNoUses); 5812 FinishExitWithHardDeoptimization(join);
5818 set_current_block(join); 5813 set_current_block(join);
5819 return is_store ? NULL : Pop(); 5814 return is_store ? NULL : Pop();
5820 } 5815 }
5821 5816
5822 5817
5823 HValue* HOptimizedGraphBuilder::HandleKeyedElementAccess( 5818 HValue* HOptimizedGraphBuilder::HandleKeyedElementAccess(
5824 HValue* obj, 5819 HValue* obj,
5825 HValue* key, 5820 HValue* key,
5826 HValue* val, 5821 HValue* val,
5827 Expression* expr, 5822 Expression* expr,
(...skipping 15 matching lines...) Expand all
5843 obj, key, val, NULL, map, is_store, expr->GetStoreMode()); 5838 obj, key, val, NULL, map, is_store, expr->GetStoreMode());
5844 } 5839 }
5845 } else if (expr->GetReceiverTypes() != NULL && 5840 } else if (expr->GetReceiverTypes() != NULL &&
5846 !expr->GetReceiverTypes()->is_empty()) { 5841 !expr->GetReceiverTypes()->is_empty()) {
5847 return HandlePolymorphicElementAccess( 5842 return HandlePolymorphicElementAccess(
5848 obj, key, val, expr, ast_id, position, is_store, 5843 obj, key, val, expr, ast_id, position, is_store,
5849 expr->GetStoreMode(), has_side_effects); 5844 expr->GetStoreMode(), has_side_effects);
5850 } else { 5845 } else {
5851 if (is_store) { 5846 if (is_store) {
5852 if (expr->IsAssignment() && expr->AsAssignment()->IsUninitialized()) { 5847 if (expr->IsAssignment() && expr->AsAssignment()->IsUninitialized()) {
5853 AddSoftDeoptimize(); 5848 Add<HDeoptimize>();
5854 } 5849 }
5855 instr = BuildStoreKeyedGeneric(obj, key, val); 5850 instr = BuildStoreKeyedGeneric(obj, key, val);
5856 } else { 5851 } else {
5857 if (expr->AsProperty()->IsUninitialized()) { 5852 if (expr->AsProperty()->IsUninitialized()) {
5858 AddSoftDeoptimize(); 5853 Add<HDeoptimize>();
5859 } 5854 }
5860 instr = BuildLoadKeyedGeneric(obj, key); 5855 instr = BuildLoadKeyedGeneric(obj, key);
5861 } 5856 }
5862 AddInstruction(instr); 5857 AddInstruction(instr);
5863 } 5858 }
5864 if (position != RelocInfo::kNoPosition) instr->set_position(position); 5859 if (position != RelocInfo::kNoPosition) instr->set_position(position);
5865 *has_side_effects = instr->HasObservableSideEffects(); 5860 *has_side_effects = instr->HasObservableSideEffects();
5866 return instr; 5861 return instr;
5867 } 5862 }
5868 5863
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
6027 HValue* key = Pop(); 6022 HValue* key = Pop();
6028 HValue* obj = Pop(); 6023 HValue* obj = Pop();
6029 6024
6030 bool has_side_effects = false; 6025 bool has_side_effects = false;
6031 HValue* load = HandleKeyedElementAccess( 6026 HValue* load = HandleKeyedElementAccess(
6032 obj, key, NULL, expr, expr->id(), expr->position(), 6027 obj, key, NULL, expr, expr->id(), expr->position(),
6033 false, // is_store 6028 false, // is_store
6034 &has_side_effects); 6029 &has_side_effects);
6035 if (has_side_effects) { 6030 if (has_side_effects) {
6036 if (ast_context()->IsEffect()) { 6031 if (ast_context()->IsEffect()) {
6037 AddSimulate(expr->id(), REMOVABLE_SIMULATE); 6032 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE);
6038 } else { 6033 } else {
6039 Push(load); 6034 Push(load);
6040 AddSimulate(expr->id(), REMOVABLE_SIMULATE); 6035 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE);
6041 Drop(1); 6036 Drop(1);
6042 } 6037 }
6043 } 6038 }
6044 return ast_context()->ReturnValue(load); 6039 return ast_context()->ReturnValue(load);
6045 } 6040 }
6046 instr->set_position(expr->position()); 6041 instr->set_position(expr->position());
6047 return ast_context()->ReturnInstruction(instr, expr->id()); 6042 return ast_context()->ReturnInstruction(instr, expr->id());
6048 } 6043 }
6049 6044
6050 6045
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
6132 } 6127 }
6133 6128
6134 if (!TryInlineCall(expr)) { 6129 if (!TryInlineCall(expr)) {
6135 int argument_count = expr->arguments()->length() + 1; // Includes receiver. 6130 int argument_count = expr->arguments()->length() + 1; // Includes receiver.
6136 HCallConstantFunction* call = 6131 HCallConstantFunction* call =
6137 new(zone()) HCallConstantFunction(expr->target(), argument_count); 6132 new(zone()) HCallConstantFunction(expr->target(), argument_count);
6138 call->set_position(expr->position()); 6133 call->set_position(expr->position());
6139 PreProcessCall(call); 6134 PreProcessCall(call);
6140 AddInstruction(call); 6135 AddInstruction(call);
6141 if (!ast_context()->IsEffect()) Push(call); 6136 if (!ast_context()->IsEffect()) Push(call);
6142 AddSimulate(expr->id(), REMOVABLE_SIMULATE); 6137 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE);
6143 if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop()); 6138 if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop());
6144 } 6139 }
6145 6140
6146 return true; 6141 return true;
6147 } 6142 }
6148 6143
6149 6144
6150 void HOptimizedGraphBuilder::HandlePolymorphicCallNamed( 6145 void HOptimizedGraphBuilder::HandlePolymorphicCallNamed(
6151 Call* expr, 6146 Call* expr,
6152 HValue* receiver, 6147 HValue* receiver,
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
6264 } 6259 }
6265 6260
6266 if (current_block() != NULL) current_block()->Goto(join); 6261 if (current_block() != NULL) current_block()->Goto(join);
6267 set_current_block(if_false); 6262 set_current_block(if_false);
6268 } 6263 }
6269 6264
6270 // Finish up. Unconditionally deoptimize if we've handled all the maps we 6265 // Finish up. Unconditionally deoptimize if we've handled all the maps we
6271 // know about and do not want to handle ones we've never seen. Otherwise 6266 // know about and do not want to handle ones we've never seen. Otherwise
6272 // use a generic IC. 6267 // use a generic IC.
6273 if (ordered_functions == types->length() && FLAG_deoptimize_uncommon_cases) { 6268 if (ordered_functions == types->length() && FLAG_deoptimize_uncommon_cases) {
6274 current_block()->FinishExitWithDeoptimization(HDeoptimize::kNoUses); 6269 FinishExitWithHardDeoptimization(join);
6275 } else { 6270 } else {
6276 HValue* context = environment()->LookupContext(); 6271 HValue* context = environment()->LookupContext();
6277 HCallNamed* call = new(zone()) HCallNamed(context, name, argument_count); 6272 HCallNamed* call = new(zone()) HCallNamed(context, name, argument_count);
6278 call->set_position(expr->position()); 6273 call->set_position(expr->position());
6279 PreProcessCall(call); 6274 PreProcessCall(call);
6280 6275
6281 if (join != NULL) { 6276 if (join != NULL) {
6282 AddInstruction(call); 6277 AddInstruction(call);
6283 if (!ast_context()->IsEffect()) Push(call); 6278 if (!ast_context()->IsEffect()) Push(call);
6284 current_block()->Goto(join); 6279 current_block()->Goto(join);
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after
6522 #if V8_TARGET_ARCH_IA32 6517 #if V8_TARGET_ARCH_IA32
6523 // IA32 only, overwrite the caller's context in the deoptimization 6518 // IA32 only, overwrite the caller's context in the deoptimization
6524 // environment with the correct one. 6519 // environment with the correct one.
6525 // 6520 //
6526 // TODO(kmillikin): implement the same inlining on other platforms so we 6521 // TODO(kmillikin): implement the same inlining on other platforms so we
6527 // can remove the unsightly ifdefs in this function. 6522 // can remove the unsightly ifdefs in this function.
6528 HConstant* context = Add<HConstant>(Handle<Context>(target->context())); 6523 HConstant* context = Add<HConstant>(Handle<Context>(target->context()));
6529 inner_env->BindContext(context); 6524 inner_env->BindContext(context);
6530 #endif 6525 #endif
6531 6526
6532 AddSimulate(return_id); 6527 Add<HSimulate>(return_id);
6533 current_block()->UpdateEnvironment(inner_env); 6528 current_block()->UpdateEnvironment(inner_env);
6534 HArgumentsObject* arguments_object = NULL; 6529 HArgumentsObject* arguments_object = NULL;
6535 6530
6536 // If the function uses arguments object create and bind one, also copy 6531 // If the function uses arguments object create and bind one, also copy
6537 // current arguments values to use them for materialization. 6532 // current arguments values to use them for materialization.
6538 if (function->scope()->arguments() != NULL) { 6533 if (function->scope()->arguments() != NULL) {
6539 ASSERT(function->scope()->arguments()->IsStackAllocated()); 6534 ASSERT(function->scope()->arguments()->IsStackAllocated());
6540 HEnvironment* arguments_env = inner_env->arguments_environment(); 6535 HEnvironment* arguments_env = inner_env->arguments_environment();
6541 int arguments_count = arguments_env->parameter_count(); 6536 int arguments_count = arguments_env->parameter_count();
6542 arguments_object = Add<HArgumentsObject>(arguments_count, zone()); 6537 arguments_object = Add<HArgumentsObject>(arguments_count, zone());
(...skipping 1165 matching lines...) Expand 10 before | Expand all | Expand 10 after
7708 } 7703 }
7709 } 7704 }
7710 } 7705 }
7711 7706
7712 HValue* context = BuildContextChainWalk(var); 7707 HValue* context = BuildContextChainWalk(var);
7713 HStoreContextSlot::Mode mode = IsLexicalVariableMode(var->mode()) 7708 HStoreContextSlot::Mode mode = IsLexicalVariableMode(var->mode())
7714 ? HStoreContextSlot::kCheckDeoptimize : HStoreContextSlot::kNoCheck; 7709 ? HStoreContextSlot::kCheckDeoptimize : HStoreContextSlot::kNoCheck;
7715 HStoreContextSlot* instr = Add<HStoreContextSlot>(context, var->index(), 7710 HStoreContextSlot* instr = Add<HStoreContextSlot>(context, var->index(),
7716 mode, after); 7711 mode, after);
7717 if (instr->HasObservableSideEffects()) { 7712 if (instr->HasObservableSideEffects()) {
7718 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE); 7713 Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE);
7719 } 7714 }
7720 break; 7715 break;
7721 } 7716 }
7722 7717
7723 case Variable::LOOKUP: 7718 case Variable::LOOKUP:
7724 return Bailout("lookup variable in count operation"); 7719 return Bailout("lookup variable in count operation");
7725 } 7720 }
7726 7721
7727 } else { 7722 } else {
7728 // Argument of the count operation is a property. 7723 // Argument of the count operation is a property.
(...skipping 22 matching lines...) Expand all
7751 load = BuildCallGetter(object, map, getter, holder); 7746 load = BuildCallGetter(object, map, getter, holder);
7752 } else { 7747 } else {
7753 load = BuildLoadNamedMonomorphic(object, name, prop, map); 7748 load = BuildLoadNamedMonomorphic(object, name, prop, map);
7754 } 7749 }
7755 } else if (types != NULL && types->length() > 1) { 7750 } else if (types != NULL && types->length() > 1) {
7756 load = TryLoadPolymorphicAsMonomorphic(prop, object, types, name); 7751 load = TryLoadPolymorphicAsMonomorphic(prop, object, types, name);
7757 } 7752 }
7758 if (load == NULL) load = BuildLoadNamedGeneric(object, name, prop); 7753 if (load == NULL) load = BuildLoadNamedGeneric(object, name, prop);
7759 PushAndAdd(load); 7754 PushAndAdd(load);
7760 if (load->HasObservableSideEffects()) { 7755 if (load->HasObservableSideEffects()) {
7761 AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE); 7756 Add<HSimulate>(prop->LoadId(), REMOVABLE_SIMULATE);
7762 } 7757 }
7763 7758
7764 after = BuildIncrement(returns_original_input, expr); 7759 after = BuildIncrement(returns_original_input, expr);
7765 7760
7766 HValue* result = returns_original_input ? Pop() : NULL; 7761 HValue* result = returns_original_input ? Pop() : NULL;
7767 7762
7768 return BuildStoreNamed(prop, expr->id(), expr->position(), 7763 return BuildStoreNamed(prop, expr->id(), expr->position(),
7769 expr->AssignmentId(), prop, object, after, result); 7764 expr->AssignmentId(), prop, object, after, result);
7770 } else { 7765 } else {
7771 // Keyed property. 7766 // Keyed property.
7772 if (returns_original_input) Push(graph()->GetConstantUndefined()); 7767 if (returns_original_input) Push(graph()->GetConstantUndefined());
7773 7768
7774 CHECK_ALIVE(VisitForValue(prop->obj())); 7769 CHECK_ALIVE(VisitForValue(prop->obj()));
7775 CHECK_ALIVE(VisitForValue(prop->key())); 7770 CHECK_ALIVE(VisitForValue(prop->key()));
7776 HValue* obj = environment()->ExpressionStackAt(1); 7771 HValue* obj = environment()->ExpressionStackAt(1);
7777 HValue* key = environment()->ExpressionStackAt(0); 7772 HValue* key = environment()->ExpressionStackAt(0);
7778 7773
7779 bool has_side_effects = false; 7774 bool has_side_effects = false;
7780 HValue* load = HandleKeyedElementAccess( 7775 HValue* load = HandleKeyedElementAccess(
7781 obj, key, NULL, prop, prop->LoadId(), RelocInfo::kNoPosition, 7776 obj, key, NULL, prop, prop->LoadId(), RelocInfo::kNoPosition,
7782 false, // is_store 7777 false, // is_store
7783 &has_side_effects); 7778 &has_side_effects);
7784 Push(load); 7779 Push(load);
7785 if (has_side_effects) AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE); 7780 if (has_side_effects) Add<HSimulate>(prop->LoadId(), REMOVABLE_SIMULATE);
7786 7781
7787 after = BuildIncrement(returns_original_input, expr); 7782 after = BuildIncrement(returns_original_input, expr);
7788 input = environment()->ExpressionStackAt(0); 7783 input = environment()->ExpressionStackAt(0);
7789 7784
7790 HandleKeyedElementAccess(obj, key, after, expr, expr->AssignmentId(), 7785 HandleKeyedElementAccess(obj, key, after, expr, expr->AssignmentId(),
7791 RelocInfo::kNoPosition, 7786 RelocInfo::kNoPosition,
7792 true, // is_store 7787 true, // is_store
7793 &has_side_effects); 7788 &has_side_effects);
7794 7789
7795 // Drop the key and the original value from the bailout environment. 7790 // Drop the key and the original value from the bailout environment.
7796 // Overwrite the receiver with the result of the operation, and the 7791 // Overwrite the receiver with the result of the operation, and the
7797 // placeholder with the original value if necessary. 7792 // placeholder with the original value if necessary.
7798 Drop(2); 7793 Drop(2);
7799 environment()->SetExpressionStackAt(0, after); 7794 environment()->SetExpressionStackAt(0, after);
7800 if (returns_original_input) environment()->SetExpressionStackAt(1, input); 7795 if (returns_original_input) environment()->SetExpressionStackAt(1, input);
7801 ASSERT(has_side_effects); // Stores always have side effects. 7796 ASSERT(has_side_effects); // Stores always have side effects.
7802 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE); 7797 Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE);
7803 } 7798 }
7804 } 7799 }
7805 7800
7806 Drop(returns_original_input ? 2 : 1); 7801 Drop(returns_original_input ? 2 : 1);
7807 return ast_context()->ReturnValue(expr->is_postfix() ? input : after); 7802 return ast_context()->ReturnValue(expr->is_postfix() ? input : after);
7808 } 7803 }
7809 7804
7810 7805
7811 HInstruction* HOptimizedGraphBuilder::BuildStringCharCodeAt( 7806 HInstruction* HOptimizedGraphBuilder::BuildStringCharCodeAt(
7812 HValue* context, 7807 HValue* context,
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
7898 HValue* context = environment()->LookupContext(); 7893 HValue* context = environment()->LookupContext();
7899 Handle<Type> left_type = expr->left()->bounds().lower; 7894 Handle<Type> left_type = expr->left()->bounds().lower;
7900 Handle<Type> right_type = expr->right()->bounds().lower; 7895 Handle<Type> right_type = expr->right()->bounds().lower;
7901 Handle<Type> result_type = expr->bounds().lower; 7896 Handle<Type> result_type = expr->bounds().lower;
7902 Maybe<int> fixed_right_arg = expr->fixed_right_arg(); 7897 Maybe<int> fixed_right_arg = expr->fixed_right_arg();
7903 Representation left_rep = Representation::FromType(left_type); 7898 Representation left_rep = Representation::FromType(left_type);
7904 Representation right_rep = Representation::FromType(right_type); 7899 Representation right_rep = Representation::FromType(right_type);
7905 Representation result_rep = Representation::FromType(result_type); 7900 Representation result_rep = Representation::FromType(result_type);
7906 7901
7907 if (left_type->Is(Type::None())) { 7902 if (left_type->Is(Type::None())) {
7908 AddSoftDeoptimize(); 7903 Add<HDeoptimize>();
7909 // TODO(rossberg): we should be able to get rid of non-continuous defaults. 7904 // TODO(rossberg): we should be able to get rid of non-continuous defaults.
7910 left_type = handle(Type::Any(), isolate()); 7905 left_type = handle(Type::Any(), isolate());
7911 } 7906 }
7912 if (right_type->Is(Type::None())) { 7907 if (right_type->Is(Type::None())) {
7913 AddSoftDeoptimize(); 7908 Add<HDeoptimize>();
7914 right_type = handle(Type::Any(), isolate()); 7909 right_type = handle(Type::Any(), isolate());
7915 } 7910 }
7916 HInstruction* instr = NULL; 7911 HInstruction* instr = NULL;
7917 switch (expr->op()) { 7912 switch (expr->op()) {
7918 case Token::ADD: 7913 case Token::ADD:
7919 if (left_type->Is(Type::String()) && right_type->Is(Type::String())) { 7914 if (left_type->Is(Type::String()) && right_type->Is(Type::String())) {
7920 BuildCheckHeapObject(left); 7915 BuildCheckHeapObject(left);
7921 AddInstruction(HCheckInstanceType::NewIsString(left, zone())); 7916 AddInstruction(HCheckInstanceType::NewIsString(left, zone()));
7922 BuildCheckHeapObject(right); 7917 BuildCheckHeapObject(right);
7923 AddInstruction(HCheckInstanceType::NewIsString(right, zone())); 7918 AddInstruction(HCheckInstanceType::NewIsString(right, zone()));
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after
8253 // TODO(olivf) InvokeFunction produces a check for the parameter count, 8248 // TODO(olivf) InvokeFunction produces a check for the parameter count,
8254 // even though we are certain to pass the correct number of arguments here. 8249 // even though we are certain to pass the correct number of arguments here.
8255 HInstruction* result = new(zone()) HInvokeFunction(context, function, 2); 8250 HInstruction* result = new(zone()) HInvokeFunction(context, function, 2);
8256 result->set_position(expr->position()); 8251 result->set_position(expr->position());
8257 return ast_context()->ReturnInstruction(result, expr->id()); 8252 return ast_context()->ReturnInstruction(result, expr->id());
8258 } 8253 }
8259 8254
8260 // Cases handled below depend on collected type feedback. They should 8255 // Cases handled below depend on collected type feedback. They should
8261 // soft deoptimize when there is no type feedback. 8256 // soft deoptimize when there is no type feedback.
8262 if (combined_type->Is(Type::None())) { 8257 if (combined_type->Is(Type::None())) {
8263 AddSoftDeoptimize(); 8258 Add<HDeoptimize>();
8264 combined_type = left_type = right_type = handle(Type::Any(), isolate()); 8259 combined_type = left_type = right_type = handle(Type::Any(), isolate());
8265 } 8260 }
8266 8261
8267 if (combined_type->Is(Type::Receiver())) { 8262 if (combined_type->Is(Type::Receiver())) {
8268 switch (op) { 8263 switch (op) {
8269 case Token::EQ: 8264 case Token::EQ:
8270 case Token::EQ_STRICT: { 8265 case Token::EQ_STRICT: {
8271 // Can we get away with map check and not instance type check? 8266 // Can we get away with map check and not instance type check?
8272 if (combined_type->IsClass()) { 8267 if (combined_type->IsClass()) {
8273 Handle<Map> map = combined_type->AsClass(); 8268 Handle<Map> map = combined_type->AsClass();
(...skipping 479 matching lines...) Expand 10 before | Expand all | Expand 10 after
8753 environment()->Bind(variable, value); 8748 environment()->Bind(variable, value);
8754 } 8749 }
8755 break; 8750 break;
8756 case Variable::CONTEXT: 8751 case Variable::CONTEXT:
8757 if (hole_init) { 8752 if (hole_init) {
8758 HValue* value = graph()->GetConstantHole(); 8753 HValue* value = graph()->GetConstantHole();
8759 HValue* context = environment()->LookupContext(); 8754 HValue* context = environment()->LookupContext();
8760 HStoreContextSlot* store = Add<HStoreContextSlot>( 8755 HStoreContextSlot* store = Add<HStoreContextSlot>(
8761 context, variable->index(), HStoreContextSlot::kNoCheck, value); 8756 context, variable->index(), HStoreContextSlot::kNoCheck, value);
8762 if (store->HasObservableSideEffects()) { 8757 if (store->HasObservableSideEffects()) {
8763 AddSimulate(proxy->id(), REMOVABLE_SIMULATE); 8758 Add<HSimulate>(proxy->id(), REMOVABLE_SIMULATE);
8764 } 8759 }
8765 } 8760 }
8766 break; 8761 break;
8767 case Variable::LOOKUP: 8762 case Variable::LOOKUP:
8768 return Bailout("unsupported lookup slot in declaration"); 8763 return Bailout("unsupported lookup slot in declaration");
8769 } 8764 }
8770 } 8765 }
8771 8766
8772 8767
8773 void HOptimizedGraphBuilder::VisitFunctionDeclaration( 8768 void HOptimizedGraphBuilder::VisitFunctionDeclaration(
(...skipping 17 matching lines...) Expand all
8791 BindIfLive(variable, value); 8786 BindIfLive(variable, value);
8792 break; 8787 break;
8793 } 8788 }
8794 case Variable::CONTEXT: { 8789 case Variable::CONTEXT: {
8795 CHECK_ALIVE(VisitForValue(declaration->fun())); 8790 CHECK_ALIVE(VisitForValue(declaration->fun()));
8796 HValue* value = Pop(); 8791 HValue* value = Pop();
8797 HValue* context = environment()->LookupContext(); 8792 HValue* context = environment()->LookupContext();
8798 HStoreContextSlot* store = Add<HStoreContextSlot>( 8793 HStoreContextSlot* store = Add<HStoreContextSlot>(
8799 context, variable->index(), HStoreContextSlot::kNoCheck, value); 8794 context, variable->index(), HStoreContextSlot::kNoCheck, value);
8800 if (store->HasObservableSideEffects()) { 8795 if (store->HasObservableSideEffects()) {
8801 AddSimulate(proxy->id(), REMOVABLE_SIMULATE); 8796 Add<HSimulate>(proxy->id(), REMOVABLE_SIMULATE);
8802 } 8797 }
8803 break; 8798 break;
8804 } 8799 }
8805 case Variable::LOOKUP: 8800 case Variable::LOOKUP:
8806 return Bailout("unsupported lookup slot in declaration"); 8801 return Bailout("unsupported lookup slot in declaration");
8807 } 8802 }
8808 } 8803 }
8809 8804
8810 8805
8811 void HOptimizedGraphBuilder::VisitModuleDeclaration( 8806 void HOptimizedGraphBuilder::VisitModuleDeclaration(
(...skipping 1177 matching lines...) Expand 10 before | Expand all | Expand 10 after
9989 if (ShouldProduceTraceOutput()) { 9984 if (ShouldProduceTraceOutput()) {
9990 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 9985 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
9991 } 9986 }
9992 9987
9993 #ifdef DEBUG 9988 #ifdef DEBUG
9994 graph_->Verify(false); // No full verify. 9989 graph_->Verify(false); // No full verify.
9995 #endif 9990 #endif
9996 } 9991 }
9997 9992
9998 } } // namespace v8::internal 9993 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698