| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #include "src/code-stubs.h" | 7 #include "src/code-stubs.h" |
| 8 #include "src/field-index.h" | 8 #include "src/field-index.h" |
| 9 #include "src/hydrogen.h" | 9 #include "src/hydrogen.h" |
| 10 #include "src/lithium.h" | 10 #include "src/lithium.h" |
| (...skipping 21 matching lines...) Expand all Loading... |
| 32 | 32 |
| 33 | 33 |
| 34 class CodeStubGraphBuilderBase : public HGraphBuilder { | 34 class CodeStubGraphBuilderBase : public HGraphBuilder { |
| 35 public: | 35 public: |
| 36 CodeStubGraphBuilderBase(Isolate* isolate, HydrogenCodeStub* stub) | 36 CodeStubGraphBuilderBase(Isolate* isolate, HydrogenCodeStub* stub) |
| 37 : HGraphBuilder(&info_), | 37 : HGraphBuilder(&info_), |
| 38 arguments_length_(NULL), | 38 arguments_length_(NULL), |
| 39 info_(stub, isolate), | 39 info_(stub, isolate), |
| 40 context_(NULL) { | 40 context_(NULL) { |
| 41 descriptor_ = stub->GetInterfaceDescriptor(); | 41 descriptor_ = stub->GetInterfaceDescriptor(); |
| 42 parameters_.Reset(new HParameter*[descriptor_->register_param_count_]); | 42 parameters_.Reset(new HParameter*[descriptor_->register_param_count()]); |
| 43 } | 43 } |
| 44 virtual bool BuildGraph(); | 44 virtual bool BuildGraph(); |
| 45 | 45 |
| 46 protected: | 46 protected: |
| 47 virtual HValue* BuildCodeStub() = 0; | 47 virtual HValue* BuildCodeStub() = 0; |
| 48 HParameter* GetParameter(int parameter) { | 48 HParameter* GetParameter(int parameter) { |
| 49 ASSERT(parameter < descriptor_->register_param_count_); | 49 ASSERT(parameter < descriptor_->register_param_count()); |
| 50 return parameters_[parameter]; | 50 return parameters_[parameter]; |
| 51 } | 51 } |
| 52 HValue* GetArgumentsLength() { | 52 HValue* GetArgumentsLength() { |
| 53 // This is initialized in BuildGraph() | 53 // This is initialized in BuildGraph() |
| 54 ASSERT(arguments_length_ != NULL); | 54 ASSERT(arguments_length_ != NULL); |
| 55 return arguments_length_; | 55 return arguments_length_; |
| 56 } | 56 } |
| 57 CompilationInfo* info() { return &info_; } | 57 CompilationInfo* info() { return &info_; } |
| 58 HydrogenCodeStub* stub() { return info_.code_stub(); } | 58 HydrogenCodeStub* stub() { return info_.code_stub(); } |
| 59 HContext* context() { return context_; } | 59 HContext* context() { return context_; } |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 109 // Update the static counter each time a new code stub is generated. | 109 // Update the static counter each time a new code stub is generated. |
| 110 isolate()->counters()->code_stubs()->Increment(); | 110 isolate()->counters()->code_stubs()->Increment(); |
| 111 | 111 |
| 112 if (FLAG_trace_hydrogen_stubs) { | 112 if (FLAG_trace_hydrogen_stubs) { |
| 113 const char* name = CodeStub::MajorName(stub()->MajorKey(), false); | 113 const char* name = CodeStub::MajorName(stub()->MajorKey(), false); |
| 114 PrintF("-----------------------------------------------------------\n"); | 114 PrintF("-----------------------------------------------------------\n"); |
| 115 PrintF("Compiling stub %s using hydrogen\n", name); | 115 PrintF("Compiling stub %s using hydrogen\n", name); |
| 116 isolate()->GetHTracer()->TraceCompilation(&info_); | 116 isolate()->GetHTracer()->TraceCompilation(&info_); |
| 117 } | 117 } |
| 118 | 118 |
| 119 int param_count = descriptor_->register_param_count_; | 119 int param_count = descriptor_->register_param_count(); |
| 120 HEnvironment* start_environment = graph()->start_environment(); | 120 HEnvironment* start_environment = graph()->start_environment(); |
| 121 HBasicBlock* next_block = CreateBasicBlock(start_environment); | 121 HBasicBlock* next_block = CreateBasicBlock(start_environment); |
| 122 Goto(next_block); | 122 Goto(next_block); |
| 123 next_block->SetJoinId(BailoutId::StubEntry()); | 123 next_block->SetJoinId(BailoutId::StubEntry()); |
| 124 set_current_block(next_block); | 124 set_current_block(next_block); |
| 125 | 125 |
| 126 bool runtime_stack_params = descriptor_->stack_parameter_count_.is_valid(); | 126 bool runtime_stack_params = descriptor_->stack_parameter_count().is_valid(); |
| 127 HInstruction* stack_parameter_count = NULL; | 127 HInstruction* stack_parameter_count = NULL; |
| 128 for (int i = 0; i < param_count; ++i) { | 128 for (int i = 0; i < param_count; ++i) { |
| 129 Representation r = descriptor_->register_param_representations_ == NULL | 129 Representation r = descriptor_->GetRegisterParameterRepresentation(i); |
| 130 ? Representation::Tagged() | |
| 131 : descriptor_->register_param_representations_[i]; | |
| 132 HParameter* param = Add<HParameter>(i, HParameter::REGISTER_PARAMETER, r); | 130 HParameter* param = Add<HParameter>(i, HParameter::REGISTER_PARAMETER, r); |
| 133 start_environment->Bind(i, param); | 131 start_environment->Bind(i, param); |
| 134 parameters_[i] = param; | 132 parameters_[i] = param; |
| 135 if (descriptor_->IsParameterCountRegister(i)) { | 133 if (descriptor_->IsParameterCountRegister(i)) { |
| 136 param->set_type(HType::Smi()); | 134 param->set_type(HType::Smi()); |
| 137 stack_parameter_count = param; | 135 stack_parameter_count = param; |
| 138 arguments_length_ = stack_parameter_count; | 136 arguments_length_ = stack_parameter_count; |
| 139 } | 137 } |
| 140 } | 138 } |
| 141 | 139 |
| 142 ASSERT(!runtime_stack_params || arguments_length_ != NULL); | 140 ASSERT(!runtime_stack_params || arguments_length_ != NULL); |
| 143 if (!runtime_stack_params) { | 141 if (!runtime_stack_params) { |
| 144 stack_parameter_count = graph()->GetConstantMinus1(); | 142 stack_parameter_count = graph()->GetConstantMinus1(); |
| 145 arguments_length_ = graph()->GetConstant0(); | 143 arguments_length_ = graph()->GetConstant0(); |
| 146 } | 144 } |
| 147 | 145 |
| 148 context_ = Add<HContext>(); | 146 context_ = Add<HContext>(); |
| 149 start_environment->BindContext(context_); | 147 start_environment->BindContext(context_); |
| 150 | 148 |
| 151 Add<HSimulate>(BailoutId::StubEntry()); | 149 Add<HSimulate>(BailoutId::StubEntry()); |
| 152 | 150 |
| 153 NoObservableSideEffectsScope no_effects(this); | 151 NoObservableSideEffectsScope no_effects(this); |
| 154 | 152 |
| 155 HValue* return_value = BuildCodeStub(); | 153 HValue* return_value = BuildCodeStub(); |
| 156 | 154 |
| 157 // We might have extra expressions to pop from the stack in addition to the | 155 // We might have extra expressions to pop from the stack in addition to the |
| 158 // arguments above. | 156 // arguments above. |
| 159 HInstruction* stack_pop_count = stack_parameter_count; | 157 HInstruction* stack_pop_count = stack_parameter_count; |
| 160 if (descriptor_->function_mode_ == JS_FUNCTION_STUB_MODE) { | 158 if (descriptor_->function_mode() == JS_FUNCTION_STUB_MODE) { |
| 161 if (!stack_parameter_count->IsConstant() && | 159 if (!stack_parameter_count->IsConstant() && |
| 162 descriptor_->hint_stack_parameter_count_ < 0) { | 160 descriptor_->hint_stack_parameter_count() < 0) { |
| 163 HInstruction* constant_one = graph()->GetConstant1(); | 161 HInstruction* constant_one = graph()->GetConstant1(); |
| 164 stack_pop_count = AddUncasted<HAdd>(stack_parameter_count, constant_one); | 162 stack_pop_count = AddUncasted<HAdd>(stack_parameter_count, constant_one); |
| 165 stack_pop_count->ClearFlag(HValue::kCanOverflow); | 163 stack_pop_count->ClearFlag(HValue::kCanOverflow); |
| 166 // TODO(mvstanton): verify that stack_parameter_count+1 really fits in a | 164 // TODO(mvstanton): verify that stack_parameter_count+1 really fits in a |
| 167 // smi. | 165 // smi. |
| 168 } else { | 166 } else { |
| 169 int count = descriptor_->hint_stack_parameter_count_; | 167 int count = descriptor_->hint_stack_parameter_count(); |
| 170 stack_pop_count = Add<HConstant>(count); | 168 stack_pop_count = Add<HConstant>(count); |
| 171 } | 169 } |
| 172 } | 170 } |
| 173 | 171 |
| 174 if (current_block() != NULL) { | 172 if (current_block() != NULL) { |
| 175 HReturn* hreturn_instruction = New<HReturn>(return_value, | 173 HReturn* hreturn_instruction = New<HReturn>(return_value, |
| 176 stack_pop_count); | 174 stack_pop_count); |
| 177 FinishCurrentBlock(hreturn_instruction); | 175 FinishCurrentBlock(hreturn_instruction); |
| 178 } | 176 } |
| 179 return true; | 177 return true; |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 246 } | 244 } |
| 247 | 245 |
| 248 | 246 |
| 249 template <class Stub> | 247 template <class Stub> |
| 250 static Handle<Code> DoGenerateCode(Stub* stub) { | 248 static Handle<Code> DoGenerateCode(Stub* stub) { |
| 251 Isolate* isolate = stub->isolate(); | 249 Isolate* isolate = stub->isolate(); |
| 252 CodeStub::Major major_key = | 250 CodeStub::Major major_key = |
| 253 static_cast<HydrogenCodeStub*>(stub)->MajorKey(); | 251 static_cast<HydrogenCodeStub*>(stub)->MajorKey(); |
| 254 CodeStubInterfaceDescriptor* descriptor = | 252 CodeStubInterfaceDescriptor* descriptor = |
| 255 isolate->code_stub_interface_descriptor(major_key); | 253 isolate->code_stub_interface_descriptor(major_key); |
| 256 if (descriptor->register_param_count_ < 0) { | 254 if (!descriptor->initialized()) { |
| 257 stub->InitializeInterfaceDescriptor(descriptor); | 255 stub->InitializeInterfaceDescriptor(descriptor); |
| 258 } | 256 } |
| 259 | 257 |
| 260 // If we are uninitialized we can use a light-weight stub to enter | 258 // If we are uninitialized we can use a light-weight stub to enter |
| 261 // the runtime that is significantly faster than using the standard | 259 // the runtime that is significantly faster than using the standard |
| 262 // stub-failure deopt mechanism. | 260 // stub-failure deopt mechanism. |
| 263 if (stub->IsUninitialized() && descriptor->has_miss_handler()) { | 261 if (stub->IsUninitialized() && descriptor->has_miss_handler()) { |
| 264 ASSERT(!descriptor->stack_parameter_count_.is_valid()); | 262 ASSERT(!descriptor->stack_parameter_count().is_valid()); |
| 265 return stub->GenerateLightweightMissCode(); | 263 return stub->GenerateLightweightMissCode(); |
| 266 } | 264 } |
| 267 ElapsedTimer timer; | 265 ElapsedTimer timer; |
| 268 if (FLAG_profile_hydrogen_code_stub_compilation) { | 266 if (FLAG_profile_hydrogen_code_stub_compilation) { |
| 269 timer.Start(); | 267 timer.Start(); |
| 270 } | 268 } |
| 271 CodeStubGraphBuilder<Stub> builder(isolate, stub); | 269 CodeStubGraphBuilder<Stub> builder(isolate, stub); |
| 272 LChunk* chunk = OptimizeGraph(builder.CreateGraph()); | 270 LChunk* chunk = OptimizeGraph(builder.CreateGraph()); |
| 273 Handle<Code> code = chunk->Codegen(); | 271 Handle<Code> code = chunk->Codegen(); |
| 274 if (FLAG_profile_hydrogen_code_stub_compilation) { | 272 if (FLAG_profile_hydrogen_code_stub_compilation) { |
| (...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 532 | 530 |
| 533 | 531 |
| 534 Handle<Code> CreateAllocationSiteStub::GenerateCode() { | 532 Handle<Code> CreateAllocationSiteStub::GenerateCode() { |
| 535 return DoGenerateCode(this); | 533 return DoGenerateCode(this); |
| 536 } | 534 } |
| 537 | 535 |
| 538 | 536 |
| 539 template <> | 537 template <> |
| 540 HValue* CodeStubGraphBuilder<KeyedLoadFastElementStub>::BuildCodeStub() { | 538 HValue* CodeStubGraphBuilder<KeyedLoadFastElementStub>::BuildCodeStub() { |
| 541 HInstruction* load = BuildUncheckedMonomorphicElementAccess( | 539 HInstruction* load = BuildUncheckedMonomorphicElementAccess( |
| 542 GetParameter(0), GetParameter(1), NULL, | 540 GetParameter(KeyedLoadIC::kReceiverIndex), |
| 543 casted_stub()->is_js_array(), casted_stub()->elements_kind(), | 541 GetParameter(KeyedLoadIC::kNameIndex), |
| 544 LOAD, NEVER_RETURN_HOLE, STANDARD_STORE); | 542 NULL, |
| 543 casted_stub()->is_js_array(), |
| 544 casted_stub()->elements_kind(), |
| 545 LOAD, |
| 546 NEVER_RETURN_HOLE, |
| 547 STANDARD_STORE); |
| 545 return load; | 548 return load; |
| 546 } | 549 } |
| 547 | 550 |
| 548 | 551 |
| 549 Handle<Code> KeyedLoadFastElementStub::GenerateCode() { | 552 Handle<Code> KeyedLoadFastElementStub::GenerateCode() { |
| 550 return DoGenerateCode(this); | 553 return DoGenerateCode(this); |
| 551 } | 554 } |
| 552 | 555 |
| 553 | 556 |
| 554 HLoadNamedField* CodeStubGraphBuilderBase::BuildLoadNamedField( | 557 HLoadNamedField* CodeStubGraphBuilderBase::BuildLoadNamedField( |
| (...skipping 809 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1364 } | 1367 } |
| 1365 | 1368 |
| 1366 | 1369 |
| 1367 Handle<Code> FastNewContextStub::GenerateCode() { | 1370 Handle<Code> FastNewContextStub::GenerateCode() { |
| 1368 return DoGenerateCode(this); | 1371 return DoGenerateCode(this); |
| 1369 } | 1372 } |
| 1370 | 1373 |
| 1371 | 1374 |
| 1372 template<> | 1375 template<> |
| 1373 HValue* CodeStubGraphBuilder<KeyedLoadDictionaryElementStub>::BuildCodeStub() { | 1376 HValue* CodeStubGraphBuilder<KeyedLoadDictionaryElementStub>::BuildCodeStub() { |
| 1374 HValue* receiver = GetParameter(0); | 1377 HValue* receiver = GetParameter(KeyedLoadIC::kReceiverIndex); |
| 1375 HValue* key = GetParameter(1); | 1378 HValue* key = GetParameter(KeyedLoadIC::kNameIndex); |
| 1376 | 1379 |
| 1377 Add<HCheckSmi>(key); | 1380 Add<HCheckSmi>(key); |
| 1378 | 1381 |
| 1379 HValue* elements = AddLoadElements(receiver); | 1382 HValue* elements = AddLoadElements(receiver); |
| 1380 | 1383 |
| 1381 HValue* hash = BuildElementIndexHash(key); | 1384 HValue* hash = BuildElementIndexHash(key); |
| 1382 | 1385 |
| 1383 return BuildUncheckedDictionaryElementLoad(receiver, elements, key, hash); | 1386 return BuildUncheckedDictionaryElementLoad(receiver, elements, key, hash); |
| 1384 } | 1387 } |
| 1385 | 1388 |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1497 BuildElementsKindLimitCheck(if_builder, bit_field2, kind); | 1500 BuildElementsKindLimitCheck(if_builder, bit_field2, kind); |
| 1498 | 1501 |
| 1499 Push(BuildUncheckedMonomorphicElementAccess(receiver, key, NULL, | 1502 Push(BuildUncheckedMonomorphicElementAccess(receiver, key, NULL, |
| 1500 false, kind, | 1503 false, kind, |
| 1501 LOAD, NEVER_RETURN_HOLE, | 1504 LOAD, NEVER_RETURN_HOLE, |
| 1502 STANDARD_STORE)); | 1505 STANDARD_STORE)); |
| 1503 } | 1506 } |
| 1504 | 1507 |
| 1505 | 1508 |
| 1506 HValue* CodeStubGraphBuilder<KeyedLoadGenericElementStub>::BuildCodeStub() { | 1509 HValue* CodeStubGraphBuilder<KeyedLoadGenericElementStub>::BuildCodeStub() { |
| 1507 HValue* receiver = GetParameter(0); | 1510 HValue* receiver = GetParameter(KeyedLoadIC::kReceiverIndex); |
| 1508 HValue* key = GetParameter(1); | 1511 HValue* key = GetParameter(KeyedLoadIC::kNameIndex); |
| 1509 | 1512 |
| 1510 // Split into a smi/integer case and unique string case. | 1513 // Split into a smi/integer case and unique string case. |
| 1511 HIfContinuation index_name_split_continuation(graph()->CreateBasicBlock(), | 1514 HIfContinuation index_name_split_continuation(graph()->CreateBasicBlock(), |
| 1512 graph()->CreateBasicBlock()); | 1515 graph()->CreateBasicBlock()); |
| 1513 | 1516 |
| 1514 BuildKeyedIndexCheck(key, &index_name_split_continuation); | 1517 BuildKeyedIndexCheck(key, &index_name_split_continuation); |
| 1515 | 1518 |
| 1516 IfBuilder index_name_split(this, &index_name_split_continuation); | 1519 IfBuilder index_name_split(this, &index_name_split_continuation); |
| 1517 index_name_split.Then(); | 1520 index_name_split.Then(); |
| 1518 { | 1521 { |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1701 return Pop(); | 1704 return Pop(); |
| 1702 } | 1705 } |
| 1703 | 1706 |
| 1704 | 1707 |
| 1705 Handle<Code> KeyedLoadGenericElementStub::GenerateCode() { | 1708 Handle<Code> KeyedLoadGenericElementStub::GenerateCode() { |
| 1706 return DoGenerateCode(this); | 1709 return DoGenerateCode(this); |
| 1707 } | 1710 } |
| 1708 | 1711 |
| 1709 | 1712 |
| 1710 } } // namespace v8::internal | 1713 } } // namespace v8::internal |
| OLD | NEW |