| 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 |