From c0c3d866fb824290c24d4c2a14414019d844515f Mon Sep 17 00:00:00 2001 From: "chunyang.dai" Date: Mon, 7 Sep 2015 00:48:48 -0700 Subject: [PATCH] X87: Crankshaft is now able to compile top level code even if there is a ScriptContext. port 29ebcc32052d486cbc1933ac4738aa5cb68aa851 (r30496). original commit message: This CL introduces HPrologue instruction which does the context allocation work and supports deoptimization. BUG= Review URL: https://codereview.chromium.org/1308743005 Cr-Commit-Position: refs/heads/master@{#30606} --- src/full-codegen/x87/full-codegen-x87.cc | 5 ++++ src/x87/lithium-codegen-x87.cc | 33 ++++++++++++++---------- src/x87/lithium-x87.cc | 7 ++++- src/x87/lithium-x87.h | 7 +++++ 4 files changed, 38 insertions(+), 14 deletions(-) diff --git a/src/full-codegen/x87/full-codegen-x87.cc b/src/full-codegen/x87/full-codegen-x87.cc index b8ac90660..ccf5ef4ef 100644 --- a/src/full-codegen/x87/full-codegen-x87.cc +++ b/src/full-codegen/x87/full-codegen-x87.cc @@ -229,6 +229,11 @@ void FullCodeGenerator::Generate() { } } + PrepareForBailoutForId(BailoutId::Prologue(), NO_REGISTERS); + // Function register is trashed in case we bailout here. But since that + // could happen only when we allocate a context the value of + // |function_in_register| is correct. + // Possibly set up a local binding to the this function which is used in // derived constructors with super calls. Variable* this_function_var = scope()->this_function_var(); diff --git a/src/x87/lithium-codegen-x87.cc b/src/x87/lithium-codegen-x87.cc index bd2e08440..3c2471627 100644 --- a/src/x87/lithium-codegen-x87.cc +++ b/src/x87/lithium-codegen-x87.cc @@ -215,16 +215,27 @@ bool LCodeGen::GeneratePrologue() { } } } + return !is_aborted(); +} + + +void LCodeGen::DoPrologue(LPrologue* instr) { + Comment(";;; Prologue begin"); // Possibly allocate a local context. - int heap_slots = info_->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; - if (heap_slots > 0) { + if (info_->num_heap_slots() > 0) { Comment(";;; Allocate local context"); bool need_write_barrier = true; // Argument to NewContext is the function, which is still in edi. - DCHECK(!info()->scope()->is_script_scope()); - if (heap_slots <= FastNewContextStub::kMaximumSlots) { - FastNewContextStub stub(isolate(), heap_slots); + int slots = info_->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; + Safepoint::DeoptMode deopt_mode = Safepoint::kNoLazyDeopt; + if (info()->scope()->is_script_scope()) { + __ push(edi); + __ Push(info()->scope()->GetScopeInfo(info()->isolate())); + __ CallRuntime(Runtime::kNewScriptContext, 2); + deopt_mode = Safepoint::kLazyDeopt; + } else if (slots <= FastNewContextStub::kMaximumSlots) { + FastNewContextStub stub(isolate(), slots); __ CallStub(&stub); // Result of FastNewContextStub is always in new space. need_write_barrier = false; @@ -232,7 +243,8 @@ bool LCodeGen::GeneratePrologue() { __ push(edi); __ CallRuntime(Runtime::kNewFunctionContext, 1); } - RecordSafepoint(Safepoint::kNoLazyDeopt); + RecordSafepoint(deopt_mode); + // Context is returned in eax. It replaces the context passed to us. // It's saved in the stack and kept live in esi. __ mov(esi, eax); @@ -268,13 +280,8 @@ bool LCodeGen::GeneratePrologue() { // Initailize FPU state. __ fninit(); - // Trace the call. - if (FLAG_trace && info()->IsOptimizing()) { - // We have not executed any compiled code yet, so esi still holds the - // incoming context. - __ CallRuntime(Runtime::kTraceEnter, 0); - } - return !is_aborted(); + + Comment(";;; Prologue end"); } diff --git a/src/x87/lithium-x87.cc b/src/x87/lithium-x87.cc index 1e60a44be..472d9c588 100644 --- a/src/x87/lithium-x87.cc +++ b/src/x87/lithium-x87.cc @@ -973,7 +973,7 @@ void LChunkBuilder::AddInstruction(LInstruction* instr, } chunk_->AddInstruction(instr, current_block_); - if (instr->IsCall()) { + if (instr->IsCall() || instr->IsPrologue()) { HValue* hydrogen_value_for_lazy_bailout = hydrogen_val; if (hydrogen_val->HasObservableSideEffects()) { HSimulate* sim = HSimulate::cast(hydrogen_val->next()); @@ -987,6 +987,11 @@ void LChunkBuilder::AddInstruction(LInstruction* instr, } +LInstruction* LChunkBuilder::DoPrologue(HPrologue* instr) { + return new (zone()) LPrologue(); +} + + LInstruction* LChunkBuilder::DoGoto(HGoto* instr) { return new(zone()) LGoto(instr->FirstSuccessor()); } diff --git a/src/x87/lithium-x87.h b/src/x87/lithium-x87.h index e4ef6af84..19aa42070 100644 --- a/src/x87/lithium-x87.h +++ b/src/x87/lithium-x87.h @@ -134,6 +134,7 @@ class LCodeGen; V(OsrEntry) \ V(Parameter) \ V(Power) \ + V(Prologue) \ V(PushArgument) \ V(RegExpLiteral) \ V(Return) \ @@ -410,6 +411,12 @@ class LGoto final : public LTemplateInstruction<0, 0, 0> { }; +class LPrologue final : public LTemplateInstruction<0, 0, 0> { + public: + DECLARE_CONCRETE_INSTRUCTION(Prologue, "prologue") +}; + + class LLazyBailout final : public LTemplateInstruction<0, 0, 0> { public: DECLARE_CONCRETE_INSTRUCTION(LazyBailout, "lazy-bailout") -- 2.34.1