OLD | NEW |
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 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
141 ASSERT(last_environment() != NULL); | 141 ASSERT(last_environment() != NULL); |
142 ASSERT(!last_environment()->ast_id().IsNone()); | 142 ASSERT(!last_environment()->ast_id().IsNone()); |
143 HBlockEntry* entry = new(zone()) HBlockEntry(); | 143 HBlockEntry* entry = new(zone()) HBlockEntry(); |
144 entry->InitializeAsFirst(this); | 144 entry->InitializeAsFirst(this); |
145 first_ = last_ = entry; | 145 first_ = last_ = entry; |
146 } | 146 } |
147 instr->InsertAfter(last_); | 147 instr->InsertAfter(last_); |
148 } | 148 } |
149 | 149 |
150 | 150 |
| 151 HPhi* HBasicBlock::AddNewPhi(int merged_index) { |
| 152 if (graph()->IsInsideNoSideEffectsScope()) { |
| 153 merged_index = HPhi::kInvalidMergedIndex; |
| 154 } |
| 155 HPhi* phi = new(zone()) HPhi(merged_index, zone()); |
| 156 AddPhi(phi); |
| 157 return phi; |
| 158 } |
| 159 |
| 160 |
151 HSimulate* HBasicBlock::CreateSimulate(BailoutId ast_id, | 161 HSimulate* HBasicBlock::CreateSimulate(BailoutId ast_id, |
152 RemovableSimulate removable) { | 162 RemovableSimulate removable) { |
153 ASSERT(HasEnvironment()); | 163 ASSERT(HasEnvironment()); |
154 HEnvironment* environment = last_environment(); | 164 HEnvironment* environment = last_environment(); |
155 ASSERT(ast_id.IsNone() || | 165 ASSERT(ast_id.IsNone() || |
156 ast_id == BailoutId::StubEntry() || | 166 ast_id == BailoutId::StubEntry() || |
157 environment->closure()->shared()->VerifyBailoutId(ast_id)); | 167 environment->closure()->shared()->VerifyBailoutId(ast_id)); |
158 | 168 |
159 int push_count = environment->push_count(); | 169 int push_count = environment->push_count(); |
160 int pop_count = environment->pop_count(); | 170 int pop_count = environment->pop_count(); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
196 FunctionState* state, | 206 FunctionState* state, |
197 bool add_simulate) { | 207 bool add_simulate) { |
198 bool drop_extra = state != NULL && | 208 bool drop_extra = state != NULL && |
199 state->inlining_kind() == DROP_EXTRA_ON_RETURN; | 209 state->inlining_kind() == DROP_EXTRA_ON_RETURN; |
200 | 210 |
201 if (block->IsInlineReturnTarget()) { | 211 if (block->IsInlineReturnTarget()) { |
202 AddInstruction(new(zone()) HLeaveInlined()); | 212 AddInstruction(new(zone()) HLeaveInlined()); |
203 UpdateEnvironment(last_environment()->DiscardInlined(drop_extra)); | 213 UpdateEnvironment(last_environment()->DiscardInlined(drop_extra)); |
204 } | 214 } |
205 | 215 |
206 if (add_simulate) AddSimulate(BailoutId::None()); | 216 if (add_simulate) AddNewSimulate(BailoutId::None()); |
207 HGoto* instr = new(zone()) HGoto(block); | 217 HGoto* instr = new(zone()) HGoto(block); |
208 Finish(instr); | 218 Finish(instr); |
209 } | 219 } |
210 | 220 |
211 | 221 |
212 void HBasicBlock::AddLeaveInlined(HValue* return_value, | 222 void HBasicBlock::AddLeaveInlined(HValue* return_value, |
213 FunctionState* state) { | 223 FunctionState* state) { |
214 HBasicBlock* target = state->function_return(); | 224 HBasicBlock* target = state->function_return(); |
215 bool drop_extra = state->inlining_kind() == DROP_EXTRA_ON_RETURN; | 225 bool drop_extra = state->inlining_kind() == DROP_EXTRA_ON_RETURN; |
216 | 226 |
217 ASSERT(target->IsInlineReturnTarget()); | 227 ASSERT(target->IsInlineReturnTarget()); |
218 ASSERT(return_value != NULL); | 228 ASSERT(return_value != NULL); |
219 AddInstruction(new(zone()) HLeaveInlined()); | 229 AddInstruction(new(zone()) HLeaveInlined()); |
220 UpdateEnvironment(last_environment()->DiscardInlined(drop_extra)); | 230 UpdateEnvironment(last_environment()->DiscardInlined(drop_extra)); |
221 last_environment()->Push(return_value); | 231 last_environment()->Push(return_value); |
222 AddSimulate(BailoutId::None()); | 232 AddNewSimulate(BailoutId::None()); |
223 HGoto* instr = new(zone()) HGoto(target); | 233 HGoto* instr = new(zone()) HGoto(target); |
224 Finish(instr); | 234 Finish(instr); |
225 } | 235 } |
226 | 236 |
227 | 237 |
228 void HBasicBlock::SetInitialEnvironment(HEnvironment* env) { | 238 void HBasicBlock::SetInitialEnvironment(HEnvironment* env) { |
229 ASSERT(!HasEnvironment()); | 239 ASSERT(!HasEnvironment()); |
230 ASSERT(first() == NULL); | 240 ASSERT(first() == NULL); |
231 UpdateEnvironment(env); | 241 UpdateEnvironment(env); |
232 } | 242 } |
(...skipping 664 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
897 body_block_ = NULL; | 907 body_block_ = NULL; |
898 exit_block_ = NULL; | 908 exit_block_ = NULL; |
899 } | 909 } |
900 | 910 |
901 | 911 |
902 HValue* HGraphBuilder::LoopBuilder::BeginBody( | 912 HValue* HGraphBuilder::LoopBuilder::BeginBody( |
903 HValue* initial, | 913 HValue* initial, |
904 HValue* terminating, | 914 HValue* terminating, |
905 Token::Value token) { | 915 Token::Value token) { |
906 HEnvironment* env = builder_->environment(); | 916 HEnvironment* env = builder_->environment(); |
907 phi_ = new(zone()) HPhi(env->values()->length(), zone()); | 917 phi_ = header_block_->AddNewPhi(env->values()->length()); |
908 header_block_->AddPhi(phi_); | |
909 phi_->AddInput(initial); | 918 phi_->AddInput(initial); |
910 env->Push(initial); | 919 env->Push(initial); |
911 builder_->current_block()->GotoNoSimulate(header_block_); | 920 builder_->current_block()->GotoNoSimulate(header_block_); |
912 | 921 |
913 HEnvironment* body_env = env->Copy(); | 922 HEnvironment* body_env = env->Copy(); |
914 HEnvironment* exit_env = env->Copy(); | 923 HEnvironment* exit_env = env->Copy(); |
915 body_block_ = builder_->CreateBasicBlock(body_env); | 924 body_block_ = builder_->CreateBasicBlock(body_env); |
916 exit_block_ = builder_->CreateBasicBlock(exit_env); | 925 exit_block_ = builder_->CreateBasicBlock(exit_env); |
917 // Remove the phi from the expression stack | 926 // Remove the phi from the expression stack |
918 body_env->Pop(); | 927 body_env->Pop(); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
975 set_current_block(graph()->entry_block()); | 984 set_current_block(graph()->entry_block()); |
976 if (!BuildGraph()) return NULL; | 985 if (!BuildGraph()) return NULL; |
977 graph()->FinalizeUniqueValueIds(); | 986 graph()->FinalizeUniqueValueIds(); |
978 return graph_; | 987 return graph_; |
979 } | 988 } |
980 | 989 |
981 | 990 |
982 HInstruction* HGraphBuilder::AddInstruction(HInstruction* instr) { | 991 HInstruction* HGraphBuilder::AddInstruction(HInstruction* instr) { |
983 ASSERT(current_block() != NULL); | 992 ASSERT(current_block() != NULL); |
984 current_block()->AddInstruction(instr); | 993 current_block()->AddInstruction(instr); |
985 if (no_side_effects_scope_count_ > 0) { | 994 if (graph()->IsInsideNoSideEffectsScope()) { |
986 instr->SetFlag(HValue::kHasNoObservableSideEffects); | 995 instr->SetFlag(HValue::kHasNoObservableSideEffects); |
987 } | 996 } |
988 return instr; | 997 return instr; |
989 } | 998 } |
990 | 999 |
991 | 1000 |
992 void HGraphBuilder::AddIncrementCounter(StatsCounter* counter, | 1001 void HGraphBuilder::AddIncrementCounter(StatsCounter* counter, |
993 HValue* context) { | 1002 HValue* context) { |
994 if (FLAG_native_code_counters && counter->Enabled()) { | 1003 if (FLAG_native_code_counters && counter->Enabled()) { |
995 HValue* reference = Add<HConstant>(ExternalReference(counter)); | 1004 HValue* reference = Add<HConstant>(ExternalReference(counter)); |
996 HValue* old_value = Add<HLoadNamedField>(reference, | 1005 HValue* old_value = Add<HLoadNamedField>(reference, |
997 HObjectAccess::ForCounter()); | 1006 HObjectAccess::ForCounter()); |
998 HValue* new_value = Add<HAdd>(old_value, graph()->GetConstant1()); | 1007 HValue* new_value = Add<HAdd>(old_value, graph()->GetConstant1()); |
999 new_value->ClearFlag(HValue::kCanOverflow); // Ignore counter overflow | 1008 new_value->ClearFlag(HValue::kCanOverflow); // Ignore counter overflow |
1000 Add<HStoreNamedField>(reference, HObjectAccess::ForCounter(), | 1009 Add<HStoreNamedField>(reference, HObjectAccess::ForCounter(), |
1001 new_value); | 1010 new_value); |
1002 } | 1011 } |
1003 } | 1012 } |
1004 | 1013 |
1005 | 1014 |
1006 void HGraphBuilder::AddSimulate(BailoutId id, | 1015 void HGraphBuilder::AddSimulate(BailoutId id, |
1007 RemovableSimulate removable) { | 1016 RemovableSimulate removable) { |
1008 ASSERT(current_block() != NULL); | 1017 ASSERT(current_block() != NULL); |
1009 ASSERT(no_side_effects_scope_count_ == 0); | 1018 ASSERT(!graph()->IsInsideNoSideEffectsScope()); |
1010 current_block()->AddSimulate(id, removable); | 1019 current_block()->AddNewSimulate(id, removable); |
1011 } | 1020 } |
1012 | 1021 |
1013 | 1022 |
1014 HBasicBlock* HGraphBuilder::CreateBasicBlock(HEnvironment* env) { | 1023 HBasicBlock* HGraphBuilder::CreateBasicBlock(HEnvironment* env) { |
1015 HBasicBlock* b = graph()->CreateBasicBlock(); | 1024 HBasicBlock* b = graph()->CreateBasicBlock(); |
1016 b->SetInitialEnvironment(env); | 1025 b->SetInitialEnvironment(env); |
1017 return b; | 1026 return b; |
1018 } | 1027 } |
1019 | 1028 |
1020 | 1029 |
1021 HBasicBlock* HGraphBuilder::CreateLoopHeaderBlock() { | 1030 HBasicBlock* HGraphBuilder::CreateLoopHeaderBlock() { |
1022 HBasicBlock* header = graph()->CreateBasicBlock(); | 1031 HBasicBlock* header = graph()->CreateBasicBlock(); |
1023 HEnvironment* entry_env = environment()->CopyAsLoopHeader(header); | 1032 HEnvironment* entry_env = environment()->CopyAsLoopHeader(header); |
1024 header->SetInitialEnvironment(entry_env); | 1033 header->SetInitialEnvironment(entry_env); |
1025 header->AttachLoopInformation(); | 1034 header->AttachLoopInformation(); |
1026 return header; | 1035 return header; |
1027 } | 1036 } |
1028 | 1037 |
1029 | 1038 |
1030 HValue* HGraphBuilder::BuildCheckHeapObject(HValue* obj) { | 1039 HValue* HGraphBuilder::BuildCheckHeapObject(HValue* obj) { |
1031 if (obj->type().IsHeapObject()) return obj; | 1040 if (obj->type().IsHeapObject()) return obj; |
1032 return Add<HCheckHeapObject>(obj); | 1041 return Add<HCheckHeapObject>(obj); |
1033 } | 1042 } |
1034 | 1043 |
1035 | 1044 |
1036 void HGraphBuilder::FinishExitWithHardDeoptimization( | 1045 void HGraphBuilder::FinishExitWithHardDeoptimization( |
1037 HBasicBlock* continuation) { | 1046 HBasicBlock* continuation) { |
1038 PadEnvironmentForContinuation(current_block(), continuation); | 1047 PadEnvironmentForContinuation(current_block(), continuation); |
1039 Add<HDeoptimize>(Deoptimizer::EAGER); | 1048 Add<HDeoptimize>(Deoptimizer::EAGER); |
1040 if (no_side_effects_scope_count_ > 0) { | 1049 if (graph()->IsInsideNoSideEffectsScope()) { |
1041 current_block()->GotoNoSimulate(continuation); | 1050 current_block()->GotoNoSimulate(continuation); |
1042 } else { | 1051 } else { |
1043 current_block()->Goto(continuation); | 1052 current_block()->Goto(continuation); |
1044 } | 1053 } |
1045 } | 1054 } |
1046 | 1055 |
1047 | 1056 |
1048 void HGraphBuilder::PadEnvironmentForContinuation( | 1057 void HGraphBuilder::PadEnvironmentForContinuation( |
1049 HBasicBlock* from, | 1058 HBasicBlock* from, |
1050 HBasicBlock* continuation) { | 1059 HBasicBlock* continuation) { |
(...skipping 991 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2042 phi_list_(NULL), | 2051 phi_list_(NULL), |
2043 uint32_instructions_(NULL), | 2052 uint32_instructions_(NULL), |
2044 osr_(NULL), | 2053 osr_(NULL), |
2045 info_(info), | 2054 info_(info), |
2046 zone_(info->zone()), | 2055 zone_(info->zone()), |
2047 is_recursive_(false), | 2056 is_recursive_(false), |
2048 use_optimistic_licm_(false), | 2057 use_optimistic_licm_(false), |
2049 has_soft_deoptimize_(false), | 2058 has_soft_deoptimize_(false), |
2050 depends_on_empty_array_proto_elements_(false), | 2059 depends_on_empty_array_proto_elements_(false), |
2051 type_change_checksum_(0), | 2060 type_change_checksum_(0), |
2052 maximum_environment_size_(0) { | 2061 maximum_environment_size_(0), |
| 2062 no_side_effects_scope_count_(0) { |
2053 if (info->IsStub()) { | 2063 if (info->IsStub()) { |
2054 HydrogenCodeStub* stub = info->code_stub(); | 2064 HydrogenCodeStub* stub = info->code_stub(); |
2055 CodeStubInterfaceDescriptor* descriptor = | 2065 CodeStubInterfaceDescriptor* descriptor = |
2056 stub->GetInterfaceDescriptor(isolate_); | 2066 stub->GetInterfaceDescriptor(isolate_); |
2057 start_environment_ = | 2067 start_environment_ = |
2058 new(zone_) HEnvironment(zone_, descriptor->environment_length()); | 2068 new(zone_) HEnvironment(zone_, descriptor->environment_length()); |
2059 } else { | 2069 } else { |
2060 start_environment_ = | 2070 start_environment_ = |
2061 new(zone_) HEnvironment(NULL, info->scope(), info->closure(), zone_); | 2071 new(zone_) HEnvironment(NULL, info->scope(), info->closure(), zone_); |
2062 } | 2072 } |
(...skipping 7145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9208 ASSERT(!block->IsLoopHeader()); | 9218 ASSERT(!block->IsLoopHeader()); |
9209 ASSERT(values_.length() == other->values_.length()); | 9219 ASSERT(values_.length() == other->values_.length()); |
9210 | 9220 |
9211 int length = values_.length(); | 9221 int length = values_.length(); |
9212 for (int i = 0; i < length; ++i) { | 9222 for (int i = 0; i < length; ++i) { |
9213 HValue* value = values_[i]; | 9223 HValue* value = values_[i]; |
9214 if (value != NULL && value->IsPhi() && value->block() == block) { | 9224 if (value != NULL && value->IsPhi() && value->block() == block) { |
9215 // There is already a phi for the i'th value. | 9225 // There is already a phi for the i'th value. |
9216 HPhi* phi = HPhi::cast(value); | 9226 HPhi* phi = HPhi::cast(value); |
9217 // Assert index is correct and that we haven't missed an incoming edge. | 9227 // Assert index is correct and that we haven't missed an incoming edge. |
9218 ASSERT(phi->merged_index() == i); | 9228 ASSERT(phi->merged_index() == i || !phi->HasMergedIndex()); |
9219 ASSERT(phi->OperandCount() == block->predecessors()->length()); | 9229 ASSERT(phi->OperandCount() == block->predecessors()->length()); |
9220 phi->AddInput(other->values_[i]); | 9230 phi->AddInput(other->values_[i]); |
9221 } else if (values_[i] != other->values_[i]) { | 9231 } else if (values_[i] != other->values_[i]) { |
9222 // There is a fresh value on the incoming edge, a phi is needed. | 9232 // There is a fresh value on the incoming edge, a phi is needed. |
9223 ASSERT(values_[i] != NULL && other->values_[i] != NULL); | 9233 ASSERT(values_[i] != NULL && other->values_[i] != NULL); |
9224 HPhi* phi = new(zone()) HPhi(i, zone()); | 9234 HPhi* phi = block->AddNewPhi(i); |
9225 HValue* old_value = values_[i]; | 9235 HValue* old_value = values_[i]; |
9226 for (int j = 0; j < block->predecessors()->length(); j++) { | 9236 for (int j = 0; j < block->predecessors()->length(); j++) { |
9227 phi->AddInput(old_value); | 9237 phi->AddInput(old_value); |
9228 } | 9238 } |
9229 phi->AddInput(other->values_[i]); | 9239 phi->AddInput(other->values_[i]); |
9230 this->values_[i] = phi; | 9240 this->values_[i] = phi; |
9231 block->AddPhi(phi); | |
9232 } | 9241 } |
9233 } | 9242 } |
9234 } | 9243 } |
9235 | 9244 |
9236 | 9245 |
9237 void HEnvironment::Bind(int index, HValue* value) { | 9246 void HEnvironment::Bind(int index, HValue* value) { |
9238 ASSERT(value != NULL); | 9247 ASSERT(value != NULL); |
9239 assigned_variables_.Add(index, zone()); | 9248 assigned_variables_.Add(index, zone()); |
9240 values_[index] = value; | 9249 values_[index] = value; |
9241 } | 9250 } |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9282 HEnvironment* HEnvironment::CopyWithoutHistory() const { | 9291 HEnvironment* HEnvironment::CopyWithoutHistory() const { |
9283 HEnvironment* result = Copy(); | 9292 HEnvironment* result = Copy(); |
9284 result->ClearHistory(); | 9293 result->ClearHistory(); |
9285 return result; | 9294 return result; |
9286 } | 9295 } |
9287 | 9296 |
9288 | 9297 |
9289 HEnvironment* HEnvironment::CopyAsLoopHeader(HBasicBlock* loop_header) const { | 9298 HEnvironment* HEnvironment::CopyAsLoopHeader(HBasicBlock* loop_header) const { |
9290 HEnvironment* new_env = Copy(); | 9299 HEnvironment* new_env = Copy(); |
9291 for (int i = 0; i < values_.length(); ++i) { | 9300 for (int i = 0; i < values_.length(); ++i) { |
9292 HPhi* phi = new(zone()) HPhi(i, zone()); | 9301 HPhi* phi = loop_header->AddNewPhi(i); |
9293 phi->AddInput(values_[i]); | 9302 phi->AddInput(values_[i]); |
9294 new_env->values_[i] = phi; | 9303 new_env->values_[i] = phi; |
9295 loop_header->AddPhi(phi); | |
9296 } | 9304 } |
9297 new_env->ClearHistory(); | 9305 new_env->ClearHistory(); |
9298 return new_env; | 9306 return new_env; |
9299 } | 9307 } |
9300 | 9308 |
9301 | 9309 |
9302 HEnvironment* HEnvironment::CreateStubEnvironment(HEnvironment* outer, | 9310 HEnvironment* HEnvironment::CreateStubEnvironment(HEnvironment* outer, |
9303 Handle<JSFunction> target, | 9311 Handle<JSFunction> target, |
9304 FrameType frame_type, | 9312 FrameType frame_type, |
9305 int arguments) const { | 9313 int arguments) const { |
(...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9707 if (ShouldProduceTraceOutput()) { | 9715 if (ShouldProduceTraceOutput()) { |
9708 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 9716 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
9709 } | 9717 } |
9710 | 9718 |
9711 #ifdef DEBUG | 9719 #ifdef DEBUG |
9712 graph_->Verify(false); // No full verify. | 9720 graph_->Verify(false); // No full verify. |
9713 #endif | 9721 #endif |
9714 } | 9722 } |
9715 | 9723 |
9716 } } // namespace v8::internal | 9724 } } // namespace v8::internal |
OLD | NEW |