From 5e0f020d3abf2b091d760345fa911e32ac461fe5 Mon Sep 17 00:00:00 2001 From: "bmeurer@chromium.org" Date: Thu, 23 Jan 2014 08:36:22 +0000 Subject: [PATCH] Turn FastNewContextStub into a HydrogenCodeStub. R=svenpanne@chromium.org Review URL: https://codereview.chromium.org/145513002 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@18764 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/arm/code-stubs-arm.cc | 52 ++++++++------------------------------ src/arm/full-codegen-arm.cc | 10 +++++--- src/arm/lithium-codegen-arm.cc | 5 ++-- src/code-stubs-hydrogen.cc | 54 ++++++++++++++++++++++++++++++++++++++++ src/code-stubs.cc | 6 +++++ src/code-stubs.h | 21 ++++++++++++---- src/ia32/code-stubs-ia32.cc | 53 ++++++++------------------------------- src/ia32/full-codegen-ia32.cc | 10 +++++--- src/ia32/lithium-codegen-ia32.cc | 9 ++++--- src/isolate.cc | 1 + src/runtime.cc | 10 +------- src/x64/code-stubs-x64.cc | 52 ++++++++------------------------------ src/x64/full-codegen-x64.cc | 10 +++++--- src/x64/lithium-codegen-x64.cc | 9 ++++--- 14 files changed, 139 insertions(+), 163 deletions(-) diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc index 5cc02e4..12742fb 100644 --- a/src/arm/code-stubs-arm.cc +++ b/src/arm/code-stubs-arm.cc @@ -49,6 +49,16 @@ void FastNewClosureStub::InitializeInterfaceDescriptor( } +void FastNewContextStub::InitializeInterfaceDescriptor( + Isolate* isolate, + CodeStubInterfaceDescriptor* descriptor) { + static Register registers[] = { r1 }; + descriptor->register_param_count_ = 1; + descriptor->register_params_ = registers; + descriptor->deoptimization_handler_ = NULL; +} + + void ToNumberStub::InitializeInterfaceDescriptor( Isolate* isolate, CodeStubInterfaceDescriptor* descriptor) { @@ -461,48 +471,6 @@ void HydrogenCodeStub::GenerateLightweightMiss(MacroAssembler* masm) { } -void FastNewContextStub::Generate(MacroAssembler* masm) { - // Try to allocate the context in new space. - Label gc; - int length = slots_ + Context::MIN_CONTEXT_SLOTS; - - // Attempt to allocate the context in new space. - __ Allocate(FixedArray::SizeFor(length), r0, r1, r2, &gc, TAG_OBJECT); - - // Load the function from the stack. - __ ldr(r3, MemOperand(sp, 0)); - - // Set up the object header. - __ LoadRoot(r1, Heap::kFunctionContextMapRootIndex); - __ mov(r2, Operand(Smi::FromInt(length))); - __ str(r2, FieldMemOperand(r0, FixedArray::kLengthOffset)); - __ str(r1, FieldMemOperand(r0, HeapObject::kMapOffset)); - - // Set up the fixed slots, copy the global object from the previous context. - __ ldr(r2, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); - __ mov(r1, Operand(Smi::FromInt(0))); - __ str(r3, MemOperand(r0, Context::SlotOffset(Context::CLOSURE_INDEX))); - __ str(cp, MemOperand(r0, Context::SlotOffset(Context::PREVIOUS_INDEX))); - __ str(r1, MemOperand(r0, Context::SlotOffset(Context::EXTENSION_INDEX))); - __ str(r2, MemOperand(r0, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); - - // Initialize the rest of the slots to undefined. - __ LoadRoot(r1, Heap::kUndefinedValueRootIndex); - for (int i = Context::MIN_CONTEXT_SLOTS; i < length; i++) { - __ str(r1, MemOperand(r0, Context::SlotOffset(i))); - } - - // Remove the on-stack argument and return. - __ mov(cp, r0); - __ pop(); - __ Ret(); - - // Need to collect. Call into runtime system. - __ bind(&gc); - __ TailCallRuntime(Runtime::kNewFunctionContext, 1, 1); -} - - void FastNewBlockContextStub::Generate(MacroAssembler* masm) { // Stack layout on entry: // diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc index 32d7e60..2c9b275 100644 --- a/src/arm/full-codegen-arm.cc +++ b/src/arm/full-codegen-arm.cc @@ -202,20 +202,22 @@ void FullCodeGenerator::Generate() { if (heap_slots > 0) { // Argument to NewContext is the function, which is still in r1. Comment cmnt(masm_, "[ Allocate context"); - __ push(r1); if (FLAG_harmony_scoping && info->scope()->is_global_scope()) { + __ push(r1); __ Push(info->scope()->GetScopeInfo()); __ CallRuntime(Runtime::kNewGlobalContext, 2); } else if (heap_slots <= FastNewContextStub::kMaximumSlots) { FastNewContextStub stub(heap_slots); __ CallStub(&stub); } else { + __ push(r1); __ CallRuntime(Runtime::kNewFunctionContext, 1); } function_in_register = false; - // Context is returned in both r0 and cp. It replaces the context - // passed to us. It's saved in the stack and kept live in cp. - __ str(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); + // Context is returned in r0. It replaces the context passed to us. + // It's saved in the stack and kept live in cp. + __ mov(cp, r0); + __ str(r0, MemOperand(fp, StandardFrameConstants::kContextOffset)); // Copy any necessary parameters into the context. int num_parameters = info->scope()->num_parameters(); for (int i = 0; i < num_parameters; i++) { diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc index 37d5cf9..47be6cd 100644 --- a/src/arm/lithium-codegen-arm.cc +++ b/src/arm/lithium-codegen-arm.cc @@ -207,17 +207,18 @@ bool LCodeGen::GeneratePrologue() { if (heap_slots > 0) { Comment(";;; Allocate local context"); // Argument to NewContext is the function, which is in r1. - __ push(r1); if (heap_slots <= FastNewContextStub::kMaximumSlots) { FastNewContextStub stub(heap_slots); __ CallStub(&stub); } else { + __ push(r1); __ CallRuntime(Runtime::kNewFunctionContext, 1); } RecordSafepoint(Safepoint::kNoLazyDeopt); // Context is returned in both r0 and cp. It replaces the context // passed to us. It's saved in the stack and kept live in cp. - __ str(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); + __ mov(cp, r0); + __ str(r0, MemOperand(fp, StandardFrameConstants::kContextOffset)); // Copy any necessary parameters into the context. int num_parameters = scope()->num_parameters(); for (int i = 0; i < num_parameters; i++) { diff --git a/src/code-stubs-hydrogen.cc b/src/code-stubs-hydrogen.cc index 655213e..5b1ae39 100644 --- a/src/code-stubs-hydrogen.cc +++ b/src/code-stubs-hydrogen.cc @@ -1330,6 +1330,60 @@ Handle FastNewClosureStub::GenerateCode(Isolate* isolate) { template<> +HValue* CodeStubGraphBuilder::BuildCodeStub() { + int length = casted_stub()->slots() + Context::MIN_CONTEXT_SLOTS; + + // Get the function. + HParameter* function = GetParameter(FastNewContextStub::kFunction); + + // Allocate the context in new space. + HAllocate* function_context = Add( + Add(length * kPointerSize + FixedArray::kHeaderSize), + HType::Tagged(), NOT_TENURED, FIXED_ARRAY_TYPE); + + // Set up the object header. + AddStoreMapConstant(function_context, + isolate()->factory()->function_context_map()); + Add(function_context, + HObjectAccess::ForFixedArrayLength(), + Add(length)); + + // Set up the fixed slots. + Add(function_context, + HObjectAccess::ForContextSlot(Context::CLOSURE_INDEX), + function); + Add(function_context, + HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX), + context()); + Add(function_context, + HObjectAccess::ForContextSlot(Context::EXTENSION_INDEX), + graph()->GetConstant0()); + + // Copy the global object from the previous context. + HValue* global_object = Add( + context(), HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); + Add(function_context, + HObjectAccess::ForContextSlot( + Context::GLOBAL_OBJECT_INDEX), + global_object); + + // Initialize the rest of the slots to undefined. + for (int i = Context::MIN_CONTEXT_SLOTS; i < length; ++i) { + Add(function_context, + HObjectAccess::ForContextSlot(i), + graph()->GetConstantUndefined()); + } + + return function_context; +} + + +Handle FastNewContextStub::GenerateCode(Isolate* isolate) { + return DoGenerateCode(isolate, this); +} + + +template<> HValue* CodeStubGraphBuilder::BuildCodeStub() { HValue* receiver = GetParameter(0); HValue* key = GetParameter(1); diff --git a/src/code-stubs.cc b/src/code-stubs.cc index c5e00ea..a2da803 100644 --- a/src/code-stubs.cc +++ b/src/code-stubs.cc @@ -766,6 +766,12 @@ void FastNewClosureStub::InstallDescriptors(Isolate* isolate) { } +void FastNewContextStub::InstallDescriptors(Isolate* isolate) { + FastNewContextStub stub(FastNewContextStub::kMaximumSlots); + InstallDescriptor(isolate, &stub); +} + + // static void BinaryOpICStub::InstallDescriptors(Isolate* isolate) { BinaryOpICStub stub(Token::ADD, NO_OVERWRITE); diff --git a/src/code-stubs.h b/src/code-stubs.h index df39b5c..8fb74b5 100644 --- a/src/code-stubs.h +++ b/src/code-stubs.h @@ -556,7 +556,7 @@ class FastNewClosureStub : public HydrogenCodeStub { }; -class FastNewContextStub : public PlatformCodeStub { +class FastNewContextStub V8_FINAL : public HydrogenCodeStub { public: static const int kMaximumSlots = 64; @@ -564,13 +564,24 @@ class FastNewContextStub : public PlatformCodeStub { ASSERT(slots_ > 0 && slots_ <= kMaximumSlots); } - void Generate(MacroAssembler* masm); + virtual Handle GenerateCode(Isolate* isolate); + + virtual void InitializeInterfaceDescriptor( + Isolate* isolate, + CodeStubInterfaceDescriptor* descriptor); + + static void InstallDescriptors(Isolate* isolate); + + int slots() const { return slots_; } + + virtual Major MajorKey() V8_OVERRIDE { return FastNewContext; } + virtual int NotMissMinorKey() V8_OVERRIDE { return slots_; } + + // Parameters accessed via CodeStubGraphBuilder::GetParameter() + static const int kFunction = 0; private: int slots_; - - Major MajorKey() { return FastNewContext; } - int MinorKey() { return slots_; } }; diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc index 901f418..f21308f 100644 --- a/src/ia32/code-stubs-ia32.cc +++ b/src/ia32/code-stubs-ia32.cc @@ -54,6 +54,16 @@ void FastNewClosureStub::InitializeInterfaceDescriptor( } +void FastNewContextStub::InitializeInterfaceDescriptor( + Isolate* isolate, + CodeStubInterfaceDescriptor* descriptor) { + static Register registers[] = { edi }; + descriptor->register_param_count_ = 1; + descriptor->register_params_ = registers; + descriptor->deoptimization_handler_ = NULL; +} + + void ToNumberStub::InitializeInterfaceDescriptor( Isolate* isolate, CodeStubInterfaceDescriptor* descriptor) { @@ -441,49 +451,6 @@ void HydrogenCodeStub::GenerateLightweightMiss(MacroAssembler* masm) { } -void FastNewContextStub::Generate(MacroAssembler* masm) { - // Try to allocate the context in new space. - Label gc; - int length = slots_ + Context::MIN_CONTEXT_SLOTS; - __ Allocate((length * kPointerSize) + FixedArray::kHeaderSize, - eax, ebx, ecx, &gc, TAG_OBJECT); - - // Get the function from the stack. - __ mov(ecx, Operand(esp, 1 * kPointerSize)); - - // Set up the object header. - Factory* factory = masm->isolate()->factory(); - __ mov(FieldOperand(eax, HeapObject::kMapOffset), - factory->function_context_map()); - __ mov(FieldOperand(eax, Context::kLengthOffset), - Immediate(Smi::FromInt(length))); - - // Set up the fixed slots. - __ Set(ebx, Immediate(0)); // Set to NULL. - __ mov(Operand(eax, Context::SlotOffset(Context::CLOSURE_INDEX)), ecx); - __ mov(Operand(eax, Context::SlotOffset(Context::PREVIOUS_INDEX)), esi); - __ mov(Operand(eax, Context::SlotOffset(Context::EXTENSION_INDEX)), ebx); - - // Copy the global object from the previous context. - __ mov(ebx, Operand(esi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); - __ mov(Operand(eax, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)), ebx); - - // Initialize the rest of the slots to undefined. - __ mov(ebx, factory->undefined_value()); - for (int i = Context::MIN_CONTEXT_SLOTS; i < length; i++) { - __ mov(Operand(eax, Context::SlotOffset(i)), ebx); - } - - // Return and remove the on-stack parameter. - __ mov(esi, eax); - __ ret(1 * kPointerSize); - - // Need to collect. Call into runtime system. - __ bind(&gc); - __ TailCallRuntime(Runtime::kNewFunctionContext, 1, 1); -} - - void FastNewBlockContextStub::Generate(MacroAssembler* masm) { // Stack layout on entry: // diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc index 0f6c851..08686e3 100644 --- a/src/ia32/full-codegen-ia32.cc +++ b/src/ia32/full-codegen-ia32.cc @@ -182,20 +182,22 @@ void FullCodeGenerator::Generate() { if (heap_slots > 0) { Comment cmnt(masm_, "[ Allocate context"); // Argument to NewContext is the function, which is still in edi. - __ push(edi); if (FLAG_harmony_scoping && info->scope()->is_global_scope()) { + __ push(edi); __ Push(info->scope()->GetScopeInfo()); __ CallRuntime(Runtime::kNewGlobalContext, 2); } else if (heap_slots <= FastNewContextStub::kMaximumSlots) { FastNewContextStub stub(heap_slots); __ CallStub(&stub); } else { + __ push(edi); __ CallRuntime(Runtime::kNewFunctionContext, 1); } function_in_register = false; - // Context is returned in both eax and esi. It replaces the context - // passed to us. It's saved in the stack and kept live in esi. - __ mov(Operand(ebp, StandardFrameConstants::kContextOffset), esi); + // 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); + __ mov(Operand(ebp, StandardFrameConstants::kContextOffset), eax); // Copy parameters into context if necessary. int num_parameters = info->scope()->num_parameters(); diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc index d3b9d5b..05b6f3c 100644 --- a/src/ia32/lithium-codegen-ia32.cc +++ b/src/ia32/lithium-codegen-ia32.cc @@ -292,17 +292,18 @@ bool LCodeGen::GeneratePrologue() { if (heap_slots > 0) { Comment(";;; Allocate local context"); // Argument to NewContext is the function, which is still in edi. - __ push(edi); if (heap_slots <= FastNewContextStub::kMaximumSlots) { FastNewContextStub stub(heap_slots); __ CallStub(&stub); } else { + __ push(edi); __ CallRuntime(Runtime::kNewFunctionContext, 1); } RecordSafepoint(Safepoint::kNoLazyDeopt); - // Context is returned in both eax and esi. It replaces the context - // passed to us. It's saved in the stack and kept live in esi. - __ mov(Operand(ebp, StandardFrameConstants::kContextOffset), esi); + // 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); + __ mov(Operand(ebp, StandardFrameConstants::kContextOffset), eax); // Copy parameters into context if necessary. int num_parameters = scope()->num_parameters(); diff --git a/src/isolate.cc b/src/isolate.cc index 2c2c082..041fc59 100644 --- a/src/isolate.cc +++ b/src/isolate.cc @@ -2111,6 +2111,7 @@ bool Isolate::Init(Deserializer* des) { ArrayConstructorStubBase::InstallDescriptors(this); InternalArrayConstructorStubBase::InstallDescriptors(this); FastNewClosureStub::InstallDescriptors(this); + FastNewContextStub::InstallDescriptors(this); NumberToStringStub::InstallDescriptors(this); StringAddStub::InstallDescriptors(this); } diff --git a/src/runtime.cc b/src/runtime.cc index a61ec90..ce506ce 100644 --- a/src/runtime.cc +++ b/src/runtime.cc @@ -8869,7 +8869,6 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NewGlobalContext) { ASSERT(function->context() == isolate->context()); ASSERT(function->context()->global_object() == result->global_object()); - isolate->set_context(result); result->global_object()->set_global_context(result); return result; // non-failure @@ -8882,14 +8881,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NewFunctionContext) { CONVERT_ARG_CHECKED(JSFunction, function, 0); int length = function->shared()->scope_info()->ContextLength(); - Context* result; - MaybeObject* maybe_result = - isolate->heap()->AllocateFunctionContext(length, function); - if (!maybe_result->To(&result)) return maybe_result; - - isolate->set_context(result); - - return result; // non-failure + return isolate->heap()->AllocateFunctionContext(length, function); } diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc index 63076dc..6159d6f 100644 --- a/src/x64/code-stubs-x64.cc +++ b/src/x64/code-stubs-x64.cc @@ -50,6 +50,16 @@ void FastNewClosureStub::InitializeInterfaceDescriptor( } +void FastNewContextStub::InitializeInterfaceDescriptor( + Isolate* isolate, + CodeStubInterfaceDescriptor* descriptor) { + static Register registers[] = { rdi }; + descriptor->register_param_count_ = 1; + descriptor->register_params_ = registers; + descriptor->deoptimization_handler_ = NULL; +} + + void ToNumberStub::InitializeInterfaceDescriptor( Isolate* isolate, CodeStubInterfaceDescriptor* descriptor) { @@ -438,48 +448,6 @@ void HydrogenCodeStub::GenerateLightweightMiss(MacroAssembler* masm) { } -void FastNewContextStub::Generate(MacroAssembler* masm) { - // Try to allocate the context in new space. - Label gc; - int length = slots_ + Context::MIN_CONTEXT_SLOTS; - __ Allocate((length * kPointerSize) + FixedArray::kHeaderSize, - rax, rbx, rcx, &gc, TAG_OBJECT); - - // Get the function from the stack. - StackArgumentsAccessor args(rsp, 1, ARGUMENTS_DONT_CONTAIN_RECEIVER); - __ movp(rcx, args.GetArgumentOperand(0)); - - // Set up the object header. - __ LoadRoot(kScratchRegister, Heap::kFunctionContextMapRootIndex); - __ movp(FieldOperand(rax, HeapObject::kMapOffset), kScratchRegister); - __ Move(FieldOperand(rax, FixedArray::kLengthOffset), Smi::FromInt(length)); - - // Set up the fixed slots. - __ Set(rbx, 0); // Set to NULL. - __ movp(Operand(rax, Context::SlotOffset(Context::CLOSURE_INDEX)), rcx); - __ movp(Operand(rax, Context::SlotOffset(Context::PREVIOUS_INDEX)), rsi); - __ movp(Operand(rax, Context::SlotOffset(Context::EXTENSION_INDEX)), rbx); - - // Copy the global object from the previous context. - __ movp(rbx, Operand(rsi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); - __ movp(Operand(rax, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)), rbx); - - // Initialize the rest of the slots to undefined. - __ LoadRoot(rbx, Heap::kUndefinedValueRootIndex); - for (int i = Context::MIN_CONTEXT_SLOTS; i < length; i++) { - __ movp(Operand(rax, Context::SlotOffset(i)), rbx); - } - - // Return and remove the on-stack parameter. - __ movp(rsi, rax); - __ ret(1 * kPointerSize); - - // Need to collect. Call into runtime system. - __ bind(&gc); - __ TailCallRuntime(Runtime::kNewFunctionContext, 1, 1); -} - - void FastNewBlockContextStub::Generate(MacroAssembler* masm) { // Stack layout on entry: // diff --git a/src/x64/full-codegen-x64.cc b/src/x64/full-codegen-x64.cc index fb382d1..64df73f 100644 --- a/src/x64/full-codegen-x64.cc +++ b/src/x64/full-codegen-x64.cc @@ -182,20 +182,22 @@ void FullCodeGenerator::Generate() { if (heap_slots > 0) { Comment cmnt(masm_, "[ Allocate context"); // Argument to NewContext is the function, which is still in rdi. - __ push(rdi); if (FLAG_harmony_scoping && info->scope()->is_global_scope()) { + __ push(rdi); __ Push(info->scope()->GetScopeInfo()); __ CallRuntime(Runtime::kNewGlobalContext, 2); } else if (heap_slots <= FastNewContextStub::kMaximumSlots) { FastNewContextStub stub(heap_slots); __ CallStub(&stub); } else { + __ push(rdi); __ CallRuntime(Runtime::kNewFunctionContext, 1); } function_in_register = false; - // Context is returned in both rax and rsi. It replaces the context - // passed to us. It's saved in the stack and kept live in rsi. - __ movp(Operand(rbp, StandardFrameConstants::kContextOffset), rsi); + // Context is returned in rax. It replaces the context passed to us. + // It's saved in the stack and kept live in rsi. + __ movp(rsi, rax); + __ movp(Operand(rbp, StandardFrameConstants::kContextOffset), rax); // Copy any necessary parameters into the context. int num_parameters = info->scope()->num_parameters(); diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc index 30f6e05..e99c9e3 100644 --- a/src/x64/lithium-codegen-x64.cc +++ b/src/x64/lithium-codegen-x64.cc @@ -218,17 +218,18 @@ bool LCodeGen::GeneratePrologue() { if (heap_slots > 0) { Comment(";;; Allocate local context"); // Argument to NewContext is the function, which is still in rdi. - __ push(rdi); if (heap_slots <= FastNewContextStub::kMaximumSlots) { FastNewContextStub stub(heap_slots); __ CallStub(&stub); } else { + __ push(rdi); __ CallRuntime(Runtime::kNewFunctionContext, 1); } RecordSafepoint(Safepoint::kNoLazyDeopt); - // Context is returned in both rax and rsi. It replaces the context - // passed to us. It's saved in the stack and kept live in rsi. - __ movp(Operand(rbp, StandardFrameConstants::kContextOffset), rsi); + // Context is returned in rax. It replaces the context passed to us. + // It's saved in the stack and kept live in rsi. + __ movp(rsi, rax); + __ movp(Operand(rbp, StandardFrameConstants::kContextOffset), rax); // Copy any necessary parameters into the context. int num_parameters = scope()->num_parameters(); -- 2.7.4