Reviewers: Weiliang,
Message:
PTAL
Description:
X87: Switch CallConstructStub to take new.target in register.
original commit message:
This changes the calling convention of the CallConstructStub to take
the original constructor (i.e. new.target in JS-speak) in a register
instead of magically via the operand stack. For optimizing compilers
the operand stack doesn't exist, hence cannot be peeked into.
BUG=
Please review this at https://codereview.chromium.org/1235273003/
Base URL: https://chromium.googlesource.com/v8/v8.git@master
Affected files (+30, -22 lines):
M src/x87/builtins-x87.cc
M src/x87/code-stubs-x87.cc
M src/x87/full-codegen-x87.cc
M src/x87/interface-descriptors-x87.cc
Index: src/x87/builtins-x87.cc
diff --git a/src/x87/builtins-x87.cc b/src/x87/builtins-x87.cc
index
2e2bcd3603a9f76ef32025e7a8fc2464b9bf1680..1036effcacd4bbef88f72e0780ce6349ed056120
100644
--- a/src/x87/builtins-x87.cc
+++ b/src/x87/builtins-x87.cc
@@ -1172,8 +1172,7 @@ static void Generate_ConstructHelper(MacroAssembler*
masm) {
const int kIndexOffset = kLimitOffset - 1 * kPointerSize;
__ Push(eax); // limit
__ push(Immediate(0)); // index
- // Push newTarget and callee functions
- __ push(Operand(ebp, kNewTargetOffset));
+ // Push the constructor function as callee.
__ push(Operand(ebp, kFunctionOffset));
// Loop over the arguments array, pushing each value to the stack
@@ -1183,13 +1182,12 @@ static void
Generate_ConstructHelper(MacroAssembler* masm) {
// Use undefined feedback vector
__ LoadRoot(ebx, Heap::kUndefinedValueRootIndex);
__ mov(edi, Operand(ebp, kFunctionOffset));
+ __ mov(ecx, Operand(ebp, kNewTargetOffset));
// Call the function.
CallConstructStub stub(masm->isolate(), SUPER_CONSTRUCTOR_CALL);
__ call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL);
- __ Drop(1);
-
// Leave internal frame.
}
// remove this, target, arguments, and newTarget
Index: src/x87/code-stubs-x87.cc
diff --git a/src/x87/code-stubs-x87.cc b/src/x87/code-stubs-x87.cc
index
959160a4827ad9529faac3d2bbbcd29d295f3a81..9eae32ab2f122a65ec800e165ec247fc5b156b2f
100644
--- a/src/x87/code-stubs-x87.cc
+++ b/src/x87/code-stubs-x87.cc
@@ -1834,11 +1834,15 @@ void CallFunctionStub::Generate(MacroAssembler*
masm) {
void CallConstructStub::Generate(MacroAssembler* masm) {
// eax : number of arguments
// ebx : feedback vector
- // edx : (only if ebx is not the megamorphic symbol) slot in feedback
- // vector (Smi)
+ // ecx : original constructor (for IsSuperConstructorCall)
+ // edx : slot in feedback vector (Smi, for RecordCallTarget)
// edi : constructor function
Label slow, non_function_call;
+ if (IsSuperConstructorCall()) {
+ __ push(ecx);
+ }
+
// Check that function is not a smi.
__ JumpIfSmi(edi, &non_function_call);
// Check that function is a JSFunction.
@@ -1871,7 +1875,7 @@ void CallConstructStub::Generate(MacroAssembler*
masm) {
}
if (IsSuperConstructorCall()) {
- __ mov(edx, Operand(esp, eax, times_pointer_size, 2 * kPointerSize));
+ __ pop(edx);
} else {
// Pass original constructor to construct stub.
__ mov(edx, edi);
@@ -1888,6 +1892,7 @@ void CallConstructStub::Generate(MacroAssembler*
masm) {
// edi: called object
// eax: number of arguments
// ecx: object map
+ // esp[0]: original receiver
Label do_call;
__ bind(&slow);
__ CmpInstanceType(ecx, JS_FUNCTION_PROXY_TYPE);
@@ -1898,6 +1903,9 @@ void CallConstructStub::Generate(MacroAssembler*
masm) {
__ bind(&non_function_call);
__ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR);
__ bind(&do_call);
+ if (IsSuperConstructorCall()) {
+ __ Drop(1);
+ }
// Set expected number of arguments to zero (not changing eax).
__ Move(ebx, Immediate(0));
Handle<Code> arguments_adaptor =
Index: src/x87/full-codegen-x87.cc
diff --git a/src/x87/full-codegen-x87.cc b/src/x87/full-codegen-x87.cc
index
f113bb073aabeb554922641013f61f03e3221565..a885c78a3fa7b397c3843e3a39c4b355728e7446
100644
--- a/src/x87/full-codegen-x87.cc
+++ b/src/x87/full-codegen-x87.cc
@@ -3262,9 +3262,6 @@ void
FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
expr->expression()->AsSuperCallReference();
DCHECK_NOT_NULL(super_call_ref);
- VariableProxy* new_target_proxy = super_call_ref->new_target_var();
- VisitForStackValue(new_target_proxy);
-
EmitLoadSuperConstructor(super_call_ref);
__ push(result_register());
@@ -3279,6 +3276,10 @@ void
FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
// constructor invocation.
SetConstructCallPosition(expr);
+ // Load original constructor into ecx.
+ VisitForAccumulatorValue(super_call_ref->new_target_var());
+ __ mov(ecx, result_register());
+
// Load function and argument count into edi and eax.
__ Move(eax, Immediate(arg_count));
__ mov(edi, Operand(esp, arg_count * kPointerSize));
@@ -3299,8 +3300,6 @@ void
FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
CallConstructStub stub(isolate(), SUPER_CALL_RECORD_TARGET);
__ call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL);
- __ Drop(1);
-
RecordJSReturnSite(expr);
EmitInitializeThisAfterSuper(super_call_ref, expr->CallFeedbackICSlot());
@@ -4225,11 +4224,14 @@ void
FullCodeGenerator::EmitDefaultConstructorCallSuper(CallRuntime* expr) {
__ CallRuntime(Runtime::kGetPrototype, 1);
__ push(result_register());
+ // Load original constructor into ecx.
+ __ mov(ecx, Operand(esp, 1 * kPointerSize));
+
// Check if the calling frame is an arguments adaptor frame.
Label adaptor_frame, args_set_up, runtime;
__ mov(edx, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
- __ mov(ecx, Operand(edx, StandardFrameConstants::kContextOffset));
- __ cmp(ecx, Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
+ __ mov(ebx, Operand(edx, StandardFrameConstants::kContextOffset));
+ __ cmp(ebx, Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
__ j(equal, &adaptor_frame);
// default constructor has no arguments, so no adaptor frame means no
args.
__ mov(eax, Immediate(0));
@@ -4238,17 +4240,17 @@ void
FullCodeGenerator::EmitDefaultConstructorCallSuper(CallRuntime* expr) {
// Copy arguments from adaptor frame.
{
__ bind(&adaptor_frame);
- __ mov(ecx, Operand(edx,
ArgumentsAdaptorFrameConstants::kLengthOffset));
- __ SmiUntag(ecx);
+ __ mov(ebx, Operand(edx,
ArgumentsAdaptorFrameConstants::kLengthOffset));
+ __ SmiUntag(ebx);
- __ mov(eax, ecx);
- __ lea(edx, Operand(edx, ecx, times_pointer_size,
+ __ mov(eax, ebx);
+ __ lea(edx, Operand(edx, ebx, times_pointer_size,
StandardFrameConstants::kCallerSPOffset));
Label loop;
__ bind(&loop);
__ push(Operand(edx, -1 * kPointerSize));
__ sub(edx, Immediate(kPointerSize));
- __ dec(ecx);
+ __ dec(ebx);
__ j(not_zero, &loop);
}
Index: src/x87/interface-descriptors-x87.cc
diff --git a/src/x87/interface-descriptors-x87.cc
b/src/x87/interface-descriptors-x87.cc
index
09ea37c67e84178ab2a582a7e9d8b5810981e736..279b42677c1e84cf0b09561935a05ff3508313cd
100644
--- a/src/x87/interface-descriptors-x87.cc
+++ b/src/x87/interface-descriptors-x87.cc
@@ -170,12 +170,12 @@ void
CallConstructDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
// eax : number of arguments
// ebx : feedback vector
- // edx : (only if ebx is not the megamorphic symbol) slot in feedback
- // vector (Smi)
+ // ecx : original constructor (for IsSuperConstructorCall)
+ // edx : slot in feedback vector (Smi, for RecordCallTarget)
// edi : constructor function
// TODO(turbofan): So far we don't gather type feedback and hence skip
the
// slot parameter, but ArrayConstructStub needs the vector to be
undefined.
- Register registers[] = {eax, edi, ebx};
+ Register registers[] = {eax, edi, ecx, ebx};
data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
}
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.