| Index: src/code-stubs-hydrogen.cc
|
| diff --git a/src/code-stubs-hydrogen.cc b/src/code-stubs-hydrogen.cc
|
| index 60ddf9b46288dfadc194f6d2ed973c93bb42ed0b..f8661566e041714a46ea5543405dca69507a4e66 100644
|
| --- a/src/code-stubs-hydrogen.cc
|
| +++ b/src/code-stubs-hydrogen.cc
|
| @@ -61,11 +61,7 @@ class CodeStubGraphBuilderBase : public HGraphBuilder {
|
| arguments_length_(NULL),
|
| info_(stub, isolate),
|
| context_(NULL) {
|
| - int major_key = stub->MajorKey();
|
| - descriptor_ = isolate->code_stub_interface_descriptor(major_key);
|
| - if (descriptor_->register_param_count_ < 0) {
|
| - stub->InitializeInterfaceDescriptor(isolate, descriptor_);
|
| - }
|
| + descriptor_ = stub->GetInterfaceDescriptor(isolate);
|
| parameters_.Reset(new HParameter*[descriptor_->register_param_count_]);
|
| }
|
| virtual bool BuildGraph();
|
| @@ -96,6 +92,9 @@ class CodeStubGraphBuilderBase : public HGraphBuilder {
|
|
|
|
|
| bool CodeStubGraphBuilderBase::BuildGraph() {
|
| + // Update the static counter each time a new code stub is generated.
|
| + isolate()->counters()->code_stubs()->Increment();
|
| +
|
| if (FLAG_trace_hydrogen) {
|
| const char* name = CodeStub::MajorName(stub()->MajorKey(), false);
|
| PrintF("-----------------------------------------------------------\n");
|
| @@ -176,16 +175,87 @@ class CodeStubGraphBuilder: public CodeStubGraphBuilderBase {
|
| : CodeStubGraphBuilderBase(Isolate::Current(), stub) {}
|
|
|
| protected:
|
| - virtual HValue* BuildCodeStub();
|
| + virtual HValue* BuildCodeStub() {
|
| + if (casted_stub()->IsMiss()) {
|
| + return BuildCodeInitializedStub();
|
| + } else {
|
| + return BuildCodeUninitializedStub();
|
| + }
|
| + }
|
| +
|
| + virtual HValue* BuildCodeInitializedStub() {
|
| + UNIMPLEMENTED();
|
| + return NULL;
|
| + }
|
| +
|
| + virtual HValue* BuildCodeUninitializedStub() {
|
| + // Force a deopt that falls back to the runtime.
|
| + HValue* undefined = graph()->GetConstantUndefined();
|
| + CheckBuilder builder(this);
|
| + builder.CheckNotUndefined(undefined);
|
| + builder.End();
|
| + return undefined;
|
| + }
|
| +
|
| Stub* casted_stub() { return static_cast<Stub*>(stub()); }
|
| };
|
|
|
|
|
| +Handle<Code> HydrogenCodeStub::GenerateLightweightMissCode(Isolate* isolate) {
|
| + Factory* factory = isolate->factory();
|
| +
|
| + // Generate the new code.
|
| + MacroAssembler masm(isolate, NULL, 256);
|
| +
|
| + {
|
| + // Update the static counter each time a new code stub is generated.
|
| + isolate->counters()->code_stubs()->Increment();
|
| +
|
| + // Nested stubs are not allowed for leaves.
|
| + AllowStubCallsScope allow_scope(&masm, false);
|
| +
|
| + // Generate the code for the stub.
|
| + masm.set_generating_stub(true);
|
| + NoCurrentFrameScope scope(&masm);
|
| + GenerateLightweightMiss(&masm);
|
| + }
|
| +
|
| + // Create the code object.
|
| + CodeDesc desc;
|
| + masm.GetCode(&desc);
|
| +
|
| + // Copy the generated code into a heap object.
|
| + Code::Flags flags = Code::ComputeFlags(
|
| + GetCodeKind(),
|
| + GetICState(),
|
| + GetExtraICState(),
|
| + GetStubType(), -1);
|
| + Handle<Code> new_object = factory->NewCode(
|
| + desc, flags, masm.CodeObject(), NeedsImmovableCode());
|
| + return new_object;
|
| +}
|
| +
|
| +
|
| template <class Stub>
|
| static Handle<Code> DoGenerateCode(Stub* stub) {
|
| - CodeStubGraphBuilder<Stub> builder(stub);
|
| - LChunk* chunk = OptimizeGraph(builder.CreateGraph());
|
| - return chunk->Codegen();
|
| + Isolate* isolate = Isolate::Current();
|
| + CodeStub::Major major_key =
|
| + static_cast<HydrogenCodeStub*>(stub)->MajorKey();
|
| + CodeStubInterfaceDescriptor* descriptor =
|
| + isolate->code_stub_interface_descriptor(major_key);
|
| + if (descriptor->register_param_count_ < 0) {
|
| + stub->InitializeInterfaceDescriptor(isolate, descriptor);
|
| + }
|
| + // The miss case without stack parameters can use a light-weight stub to enter
|
| + // the runtime that is significantly faster than using the standard
|
| + // stub-failure deopt mechanism.
|
| + if (stub->IsMiss() && descriptor->stack_parameter_count_ == NULL) {
|
| + return stub->GenerateLightweightMissCode(isolate);
|
| + } else {
|
| + CodeStubGraphBuilder<Stub> builder(stub);
|
| + LChunk* chunk = OptimizeGraph(builder.CreateGraph());
|
| + return chunk->Codegen();
|
| + }
|
| }
|
|
|
|
|
| @@ -248,9 +318,7 @@ HValue* CodeStubGraphBuilder<FastCloneShallowArrayStub>::BuildCodeStub() {
|
|
|
|
|
| Handle<Code> FastCloneShallowArrayStub::GenerateCode() {
|
| - CodeStubGraphBuilder<FastCloneShallowArrayStub> builder(this);
|
| - LChunk* chunk = OptimizeGraph(builder.CreateGraph());
|
| - return chunk->Codegen();
|
| + return DoGenerateCode(this);
|
| }
|
|
|
|
|
|
|