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 |