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
This commit is contained in:
parent
02c02fe567
commit
5e0f020d3a
@ -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:
|
||||
//
|
||||
|
@ -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++) {
|
||||
|
@ -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++) {
|
||||
|
@ -1329,6 +1329,60 @@ Handle<Code> FastNewClosureStub::GenerateCode(Isolate* isolate) {
|
||||
}
|
||||
|
||||
|
||||
template<>
|
||||
HValue* CodeStubGraphBuilder<FastNewContextStub>::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<HAllocate>(
|
||||
Add<HConstant>(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<HStoreNamedField>(function_context,
|
||||
HObjectAccess::ForFixedArrayLength(),
|
||||
Add<HConstant>(length));
|
||||
|
||||
// Set up the fixed slots.
|
||||
Add<HStoreNamedField>(function_context,
|
||||
HObjectAccess::ForContextSlot(Context::CLOSURE_INDEX),
|
||||
function);
|
||||
Add<HStoreNamedField>(function_context,
|
||||
HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX),
|
||||
context());
|
||||
Add<HStoreNamedField>(function_context,
|
||||
HObjectAccess::ForContextSlot(Context::EXTENSION_INDEX),
|
||||
graph()->GetConstant0());
|
||||
|
||||
// Copy the global object from the previous context.
|
||||
HValue* global_object = Add<HLoadNamedField>(
|
||||
context(), HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX));
|
||||
Add<HStoreNamedField>(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<HStoreNamedField>(function_context,
|
||||
HObjectAccess::ForContextSlot(i),
|
||||
graph()->GetConstantUndefined());
|
||||
}
|
||||
|
||||
return function_context;
|
||||
}
|
||||
|
||||
|
||||
Handle<Code> FastNewContextStub::GenerateCode(Isolate* isolate) {
|
||||
return DoGenerateCode(isolate, this);
|
||||
}
|
||||
|
||||
|
||||
template<>
|
||||
HValue* CodeStubGraphBuilder<KeyedLoadDictionaryElementStub>::BuildCodeStub() {
|
||||
HValue* receiver = GetParameter(0);
|
||||
|
@ -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);
|
||||
|
@ -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<Code> 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_; }
|
||||
};
|
||||
|
||||
|
||||
|
@ -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:
|
||||
//
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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:
|
||||
//
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user