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/code-stubs.h" | 5 #include "src/code-stubs.h" |
6 | 6 |
7 #include "src/bailout-reason.h" | 7 #include "src/bailout-reason.h" |
8 #include "src/crankshaft/hydrogen.h" | 8 #include "src/crankshaft/hydrogen.h" |
9 #include "src/crankshaft/lithium.h" | 9 #include "src/crankshaft/lithium.h" |
10 #include "src/field-index.h" | 10 #include "src/field-index.h" |
(...skipping 16 matching lines...) Expand all Loading... |
27 LChunk* chunk = LChunk::NewChunk(graph); | 27 LChunk* chunk = LChunk::NewChunk(graph); |
28 if (chunk == NULL) { | 28 if (chunk == NULL) { |
29 FATAL(GetBailoutReason(graph->info()->bailout_reason())); | 29 FATAL(GetBailoutReason(graph->info()->bailout_reason())); |
30 } | 30 } |
31 return chunk; | 31 return chunk; |
32 } | 32 } |
33 | 33 |
34 | 34 |
35 class CodeStubGraphBuilderBase : public HGraphBuilder { | 35 class CodeStubGraphBuilderBase : public HGraphBuilder { |
36 public: | 36 public: |
37 explicit CodeStubGraphBuilderBase(CompilationInfo* info) | 37 explicit CodeStubGraphBuilderBase(CompilationInfo* info, CodeStub* code_stub) |
38 : HGraphBuilder(info), | 38 : HGraphBuilder(info, code_stub->GetCallInterfaceDescriptor()), |
39 arguments_length_(NULL), | 39 arguments_length_(NULL), |
40 info_(info), | 40 info_(info), |
41 descriptor_(info->code_stub()), | 41 code_stub_(code_stub), |
| 42 descriptor_(code_stub), |
42 context_(NULL) { | 43 context_(NULL) { |
43 int parameter_count = GetParameterCount(); | 44 int parameter_count = GetParameterCount(); |
44 parameters_.Reset(new HParameter*[parameter_count]); | 45 parameters_.Reset(new HParameter*[parameter_count]); |
45 } | 46 } |
46 virtual bool BuildGraph(); | 47 virtual bool BuildGraph(); |
47 | 48 |
48 protected: | 49 protected: |
49 virtual HValue* BuildCodeStub() = 0; | 50 virtual HValue* BuildCodeStub() = 0; |
50 int GetParameterCount() const { return descriptor_.GetParameterCount(); } | 51 int GetParameterCount() const { return descriptor_.GetParameterCount(); } |
51 int GetRegisterParameterCount() const { | 52 int GetRegisterParameterCount() const { |
52 return descriptor_.GetRegisterParameterCount(); | 53 return descriptor_.GetRegisterParameterCount(); |
53 } | 54 } |
54 HParameter* GetParameter(int parameter) { | 55 HParameter* GetParameter(int parameter) { |
55 DCHECK(parameter < GetParameterCount()); | 56 DCHECK(parameter < GetParameterCount()); |
56 return parameters_[parameter]; | 57 return parameters_[parameter]; |
57 } | 58 } |
58 Representation GetParameterRepresentation(int parameter) { | 59 Representation GetParameterRepresentation(int parameter) { |
59 return RepresentationFromType(descriptor_.GetParameterType(parameter)); | 60 return RepresentationFromType(descriptor_.GetParameterType(parameter)); |
60 } | 61 } |
61 bool IsParameterCountRegister(int index) const { | 62 bool IsParameterCountRegister(int index) const { |
62 return descriptor_.GetRegisterParameter(index) | 63 return descriptor_.GetRegisterParameter(index) |
63 .is(descriptor_.stack_parameter_count()); | 64 .is(descriptor_.stack_parameter_count()); |
64 } | 65 } |
65 HValue* GetArgumentsLength() { | 66 HValue* GetArgumentsLength() { |
66 // This is initialized in BuildGraph() | 67 // This is initialized in BuildGraph() |
67 DCHECK(arguments_length_ != NULL); | 68 DCHECK(arguments_length_ != NULL); |
68 return arguments_length_; | 69 return arguments_length_; |
69 } | 70 } |
70 CompilationInfo* info() { return info_; } | 71 CompilationInfo* info() { return info_; } |
71 CodeStub* stub() { return info_->code_stub(); } | 72 CodeStub* stub() { return code_stub_; } |
72 HContext* context() { return context_; } | 73 HContext* context() { return context_; } |
73 Isolate* isolate() { return info_->isolate(); } | 74 Isolate* isolate() { return info_->isolate(); } |
74 | 75 |
75 HLoadNamedField* BuildLoadNamedField(HValue* object, FieldIndex index); | 76 HLoadNamedField* BuildLoadNamedField(HValue* object, FieldIndex index); |
76 void BuildStoreNamedField(HValue* object, HValue* value, FieldIndex index, | 77 void BuildStoreNamedField(HValue* object, HValue* value, FieldIndex index, |
77 Representation representation, | 78 Representation representation, |
78 bool transition_to_field); | 79 bool transition_to_field); |
79 | 80 |
80 enum ArgumentClass { | 81 enum ArgumentClass { |
81 NONE, | 82 NONE, |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
117 HValue* BuildToPrimitive(HValue* input, HValue* input_map); | 118 HValue* BuildToPrimitive(HValue* input, HValue* input_map); |
118 | 119 |
119 private: | 120 private: |
120 HValue* BuildArraySingleArgumentConstructor(JSArrayBuilder* builder); | 121 HValue* BuildArraySingleArgumentConstructor(JSArrayBuilder* builder); |
121 HValue* BuildArrayNArgumentsConstructor(JSArrayBuilder* builder, | 122 HValue* BuildArrayNArgumentsConstructor(JSArrayBuilder* builder, |
122 ElementsKind kind); | 123 ElementsKind kind); |
123 | 124 |
124 base::SmartArrayPointer<HParameter*> parameters_; | 125 base::SmartArrayPointer<HParameter*> parameters_; |
125 HValue* arguments_length_; | 126 HValue* arguments_length_; |
126 CompilationInfo* info_; | 127 CompilationInfo* info_; |
| 128 CodeStub* code_stub_; |
127 CodeStubDescriptor descriptor_; | 129 CodeStubDescriptor descriptor_; |
128 HContext* context_; | 130 HContext* context_; |
129 }; | 131 }; |
130 | 132 |
131 | 133 |
132 bool CodeStubGraphBuilderBase::BuildGraph() { | 134 bool CodeStubGraphBuilderBase::BuildGraph() { |
133 // Update the static counter each time a new code stub is generated. | 135 // Update the static counter each time a new code stub is generated. |
134 isolate()->counters()->code_stubs()->Increment(); | 136 isolate()->counters()->code_stubs()->Increment(); |
135 | 137 |
136 if (FLAG_trace_hydrogen_stubs) { | 138 if (FLAG_trace_hydrogen_stubs) { |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
207 stack_pop_count); | 209 stack_pop_count); |
208 FinishCurrentBlock(hreturn_instruction); | 210 FinishCurrentBlock(hreturn_instruction); |
209 } | 211 } |
210 return true; | 212 return true; |
211 } | 213 } |
212 | 214 |
213 | 215 |
214 template <class Stub> | 216 template <class Stub> |
215 class CodeStubGraphBuilder: public CodeStubGraphBuilderBase { | 217 class CodeStubGraphBuilder: public CodeStubGraphBuilderBase { |
216 public: | 218 public: |
217 explicit CodeStubGraphBuilder(CompilationInfo* info) | 219 explicit CodeStubGraphBuilder(CompilationInfo* info, CodeStub* stub) |
218 : CodeStubGraphBuilderBase(info) {} | 220 : CodeStubGraphBuilderBase(info, stub) {} |
219 | 221 |
220 protected: | 222 protected: |
221 virtual HValue* BuildCodeStub() { | 223 virtual HValue* BuildCodeStub() { |
222 if (casted_stub()->IsUninitialized()) { | 224 if (casted_stub()->IsUninitialized()) { |
223 return BuildCodeUninitializedStub(); | 225 return BuildCodeUninitializedStub(); |
224 } else { | 226 } else { |
225 return BuildCodeInitializedStub(); | 227 return BuildCodeInitializedStub(); |
226 } | 228 } |
227 } | 229 } |
228 | 230 |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
262 masm.enable_serializer(); | 264 masm.enable_serializer(); |
263 NoCurrentFrameScope scope(&masm); | 265 NoCurrentFrameScope scope(&masm); |
264 GenerateLightweightMiss(&masm, miss); | 266 GenerateLightweightMiss(&masm, miss); |
265 } | 267 } |
266 | 268 |
267 // Create the code object. | 269 // Create the code object. |
268 CodeDesc desc; | 270 CodeDesc desc; |
269 masm.GetCode(&desc); | 271 masm.GetCode(&desc); |
270 | 272 |
271 // Copy the generated code into a heap object. | 273 // Copy the generated code into a heap object. |
272 Code::Flags flags = Code::ComputeFlags( | |
273 GetCodeKind(), | |
274 GetICState(), | |
275 GetExtraICState(), | |
276 GetStubType()); | |
277 Handle<Code> new_object = factory->NewCode( | 274 Handle<Code> new_object = factory->NewCode( |
278 desc, flags, masm.CodeObject(), NeedsImmovableCode()); | 275 desc, GetCodeFlags(), masm.CodeObject(), NeedsImmovableCode()); |
279 return new_object; | 276 return new_object; |
280 } | 277 } |
281 | 278 |
282 | 279 |
283 template <class Stub> | 280 template <class Stub> |
284 static Handle<Code> DoGenerateCode(Stub* stub) { | 281 static Handle<Code> DoGenerateCode(Stub* stub) { |
285 Isolate* isolate = stub->isolate(); | 282 Isolate* isolate = stub->isolate(); |
286 CodeStubDescriptor descriptor(stub); | 283 CodeStubDescriptor descriptor(stub); |
287 | 284 |
288 // If we are uninitialized we can use a light-weight stub to enter | 285 // If we are uninitialized we can use a light-weight stub to enter |
289 // the runtime that is significantly faster than using the standard | 286 // the runtime that is significantly faster than using the standard |
290 // stub-failure deopt mechanism. | 287 // stub-failure deopt mechanism. |
291 if (stub->IsUninitialized() && descriptor.has_miss_handler()) { | 288 if (stub->IsUninitialized() && descriptor.has_miss_handler()) { |
292 DCHECK(!descriptor.stack_parameter_count().is_valid()); | 289 DCHECK(!descriptor.stack_parameter_count().is_valid()); |
293 return stub->GenerateLightweightMissCode(descriptor.miss_handler()); | 290 return stub->GenerateLightweightMissCode(descriptor.miss_handler()); |
294 } | 291 } |
295 base::ElapsedTimer timer; | 292 base::ElapsedTimer timer; |
296 if (FLAG_profile_hydrogen_code_stub_compilation) { | 293 if (FLAG_profile_hydrogen_code_stub_compilation) { |
297 timer.Start(); | 294 timer.Start(); |
298 } | 295 } |
299 Zone zone; | 296 Zone zone; |
300 CompilationInfo info(stub, isolate, &zone); | 297 CompilationInfo info(CodeStub::MajorName(stub->MajorKey()), isolate, &zone, |
301 CodeStubGraphBuilder<Stub> builder(&info); | 298 stub->GetCodeFlags()); |
| 299 // Parameter count is number of stack parameters. |
| 300 int parameter_count = descriptor.GetStackParameterCount(); |
| 301 if (descriptor.function_mode() == NOT_JS_FUNCTION_STUB_MODE) { |
| 302 parameter_count--; |
| 303 } |
| 304 info.set_parameter_count(parameter_count); |
| 305 CodeStubGraphBuilder<Stub> builder(&info, stub); |
302 LChunk* chunk = OptimizeGraph(builder.CreateGraph()); | 306 LChunk* chunk = OptimizeGraph(builder.CreateGraph()); |
303 Handle<Code> code = chunk->Codegen(); | 307 Handle<Code> code = chunk->Codegen(); |
304 if (FLAG_profile_hydrogen_code_stub_compilation) { | 308 if (FLAG_profile_hydrogen_code_stub_compilation) { |
305 OFStream os(stdout); | 309 OFStream os(stdout); |
306 os << "[Lazy compilation of " << stub << " took " | 310 os << "[Lazy compilation of " << stub << " took " |
307 << timer.Elapsed().InMillisecondsF() << " ms]" << std::endl; | 311 << timer.Elapsed().InMillisecondsF() << " ms]" << std::endl; |
308 } | 312 } |
309 return code; | 313 return code; |
310 } | 314 } |
311 | 315 |
(...skipping 1867 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2179 | 2183 |
2180 Handle<Code> RegExpConstructResultStub::GenerateCode() { | 2184 Handle<Code> RegExpConstructResultStub::GenerateCode() { |
2181 return DoGenerateCode(this); | 2185 return DoGenerateCode(this); |
2182 } | 2186 } |
2183 | 2187 |
2184 | 2188 |
2185 template <> | 2189 template <> |
2186 class CodeStubGraphBuilder<KeyedLoadGenericStub> | 2190 class CodeStubGraphBuilder<KeyedLoadGenericStub> |
2187 : public CodeStubGraphBuilderBase { | 2191 : public CodeStubGraphBuilderBase { |
2188 public: | 2192 public: |
2189 explicit CodeStubGraphBuilder(CompilationInfo* info) | 2193 explicit CodeStubGraphBuilder(CompilationInfo* info, CodeStub* stub) |
2190 : CodeStubGraphBuilderBase(info) {} | 2194 : CodeStubGraphBuilderBase(info, stub) {} |
2191 | 2195 |
2192 protected: | 2196 protected: |
2193 virtual HValue* BuildCodeStub(); | 2197 virtual HValue* BuildCodeStub(); |
2194 | 2198 |
2195 void BuildElementsKindLimitCheck(HGraphBuilder::IfBuilder* if_builder, | 2199 void BuildElementsKindLimitCheck(HGraphBuilder::IfBuilder* if_builder, |
2196 HValue* bit_field2, | 2200 HValue* bit_field2, |
2197 ElementsKind kind); | 2201 ElementsKind kind); |
2198 | 2202 |
2199 void BuildFastElementLoad(HGraphBuilder::IfBuilder* if_builder, | 2203 void BuildFastElementLoad(HGraphBuilder::IfBuilder* if_builder, |
2200 HValue* receiver, | 2204 HValue* receiver, |
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2426 return Pop(); | 2430 return Pop(); |
2427 } | 2431 } |
2428 | 2432 |
2429 | 2433 |
2430 Handle<Code> KeyedLoadGenericStub::GenerateCode() { | 2434 Handle<Code> KeyedLoadGenericStub::GenerateCode() { |
2431 return DoGenerateCode(this); | 2435 return DoGenerateCode(this); |
2432 } | 2436 } |
2433 | 2437 |
2434 } // namespace internal | 2438 } // namespace internal |
2435 } // namespace v8 | 2439 } // namespace v8 |
OLD | NEW |