Reviewers: mvstanton,
Message:
Note that this only contains the ARM port, but I wanted to get your general
opinion on this early, before doing the ports.
Description:
Switch CallConstructStub to take new.target in register.
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 exists, hence cannot be peeked into.
[email protected]
Please review this at https://codereview.chromium.org/1237813002/
Base URL: https://chromium.googlesource.com/v8/v8.git@master
Affected files (+41, -38 lines):
M src/arm/builtins-arm.cc
M src/arm/code-stubs-arm.cc
M src/arm/full-codegen-arm.cc
M src/arm/interface-descriptors-arm.cc
M src/arm64/interface-descriptors-arm64.cc
M src/compiler/js-generic-lowering.cc
M src/ia32/interface-descriptors-ia32.cc
M src/mips/interface-descriptors-mips.cc
M src/mips64/interface-descriptors-mips64.cc
M src/x64/interface-descriptors-x64.cc
Index: src/arm/builtins-arm.cc
diff --git a/src/arm/builtins-arm.cc b/src/arm/builtins-arm.cc
index
d08216c74adb878f70dbfe0dc9f87eaac1ef7c0a..3f0177457af12ea2816f7fb318255ae6d7a4d3c3
100644
--- a/src/arm/builtins-arm.cc
+++ b/src/arm/builtins-arm.cc
@@ -1503,9 +1503,7 @@ static void Generate_ConstructHelper(MacroAssembler*
masm) {
__ push(r0); // limit
__ mov(r1, Operand::Zero()); // initial index
__ push(r1);
- // Push newTarget and callee functions
- __ ldr(r0, MemOperand(fp, kNewTargetOffset));
- __ push(r0);
+ // Push the constructor function as callee.
__ ldr(r0, MemOperand(fp, kFunctionOffset));
__ push(r0);
@@ -1516,13 +1514,12 @@ static void
Generate_ConstructHelper(MacroAssembler* masm) {
// Use undefined feedback vector
__ LoadRoot(r2, Heap::kUndefinedValueRootIndex);
__ ldr(r1, MemOperand(fp, kFunctionOffset));
+ __ ldr(r4, MemOperand(fp, kNewTargetOffset));
// Call the function.
CallConstructStub stub(masm->isolate(), SUPER_CONSTRUCTOR_CALL);
__ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL);
- __ Drop(1);
-
// Leave internal frame.
}
__ add(sp, sp, Operand(kStackSize * kPointerSize));
Index: src/arm/code-stubs-arm.cc
diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc
index
005fb97513d0277325c9ff516612aeb922f1949c..c71a6e3efebfb95188eae188fd514f396a458e0d
100644
--- a/src/arm/code-stubs-arm.cc
+++ b/src/arm/code-stubs-arm.cc
@@ -2607,18 +2607,24 @@ void CallConstructStub::Generate(MacroAssembler*
masm) {
// r0 : number of arguments
// r1 : the function to call
// r2 : feedback vector
- // r3 : (only if r2 is not the megamorphic symbol) slot in feedback
- // vector (Smi)
+ // r3 : slot in feedback vector (Smi, for RecordCallTarget)
+ // r4 : original constructor (for IsSuperConstructorCall)
Label slow, non_function_call;
// Check that the function is not a smi.
__ JumpIfSmi(r1, &non_function_call);
// Check that the function is a JSFunction.
- __ CompareObjectType(r1, r4, r4, JS_FUNCTION_TYPE);
+ __ CompareObjectType(r1, r5, r5, JS_FUNCTION_TYPE);
__ b(ne, &slow);
if (RecordCallTarget()) {
+ if (IsSuperConstructorCall()) {
+ __ push(r4);
+ }
GenerateRecordCallTarget(masm);
+ if (IsSuperConstructorCall()) {
+ __ pop(r4);
+ }
__ add(r5, r2, Operand::PointerOffsetFromSmiKey(r3));
if (FLAG_pretenuring_call_new) {
@@ -2642,9 +2648,7 @@ void CallConstructStub::Generate(MacroAssembler*
masm) {
// Pass function as original constructor.
if (IsSuperConstructorCall()) {
- __ mov(r4, Operand(1 * kPointerSize));
- __ add(r4, r4, Operand(r0, LSL, kPointerSizeLog2));
- __ ldr(r3, MemOperand(sp, r4));
+ __ mov(r3, r4);
} else {
__ mov(r3, r1);
}
@@ -2658,10 +2662,10 @@ void CallConstructStub::Generate(MacroAssembler*
masm) {
// r0: number of arguments
// r1: called object
- // r4: object type
+ // r5: object type
Label do_call;
__ bind(&slow);
- __ cmp(r4, Operand(JS_FUNCTION_PROXY_TYPE));
+ __ cmp(r5, Operand(JS_FUNCTION_PROXY_TYPE));
__ b(ne, &non_function_call);
__ GetBuiltinFunction(r1, Builtins::CALL_FUNCTION_PROXY_AS_CONSTRUCTOR);
__ jmp(&do_call);
Index: src/arm/full-codegen-arm.cc
diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc
index
2ed37e4196c86b64e7492ffa87770f858e55cfd6..7eb88a43f762a8986e74588c4bbf46e617349f85
100644
--- a/src/arm/full-codegen-arm.cc
+++ b/src/arm/full-codegen-arm.cc
@@ -3386,9 +3386,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());
@@ -3403,6 +3400,10 @@ void
FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
// constructor invocation.
SetConstructCallPosition(expr);
+ // Load original constructor into r4.
+ VisitForAccumulatorValue(super_call_ref->new_target_var());
+ __ mov(r4, result_register());
+
// Load function and argument count into r1 and r0.
__ mov(r0, Operand(arg_count));
__ ldr(r1, MemOperand(sp, arg_count * kPointerSize));
@@ -3423,8 +3424,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());
@@ -4335,6 +4334,9 @@ void
FullCodeGenerator::EmitDefaultConstructorCallSuper(CallRuntime* expr) {
__ CallRuntime(Runtime::kGetPrototype, 1);
__ Push(result_register());
+ // Load original constructor into r4.
+ __ ldr(r4, MemOperand(sp, 1 * kPointerSize));
+
// Check if the calling frame is an arguments adaptor frame.
Label adaptor_frame, args_set_up, runtime;
__ ldr(r2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
Index: src/arm/interface-descriptors-arm.cc
diff --git a/src/arm/interface-descriptors-arm.cc
b/src/arm/interface-descriptors-arm.cc
index
f65b6d272d7679e2b4114b0a835262dfa10e98a8..76ad3ba39c2aa56854589f36a3eb2bf032b52cc0
100644
--- a/src/arm/interface-descriptors-arm.cc
+++ b/src/arm/interface-descriptors-arm.cc
@@ -169,11 +169,11 @@ void
CallConstructDescriptor::InitializePlatformSpecific(
// r0 : number of arguments
// r1 : the function to call
// r2 : feedback vector
- // r3 : (only if r2 is not the megamorphic symbol) slot in feedback
- // vector (Smi)
+ // r3 : slot in feedback vector (Smi, for RecordCallTarget)
+ // r4 : original constructor (for IsSuperConstructorCall)
// 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[] = {r0, r1, r2};
+ Register registers[] = {r0, r1, r4, r2};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
Index: src/arm64/interface-descriptors-arm64.cc
diff --git a/src/arm64/interface-descriptors-arm64.cc
b/src/arm64/interface-descriptors-arm64.cc
index
d6aa2573d05c12482f3f16a6aea6aaf4af3d60c0..d175de307cfb1fad118bf386b7c5a68d5515c426
100644
--- a/src/arm64/interface-descriptors-arm64.cc
+++ b/src/arm64/interface-descriptors-arm64.cc
@@ -192,10 +192,11 @@ void
CallConstructDescriptor::InitializePlatformSpecific(
// x0 : number of arguments
// x1 : the function to call
// x2 : feedback vector
- // x3 : slot in feedback vector (smi) (if r2 is not the megamorphic
symbol)
+ // x3 : slot in feedback vector (Smi, for RecordCallTarget)
+ // x4 : original constructor (for IsSuperConstructorCall)
// 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[] = {x0, x1, x2};
+ Register registers[] = {x0, x1, x4, x2};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
Index: src/compiler/js-generic-lowering.cc
diff --git a/src/compiler/js-generic-lowering.cc
b/src/compiler/js-generic-lowering.cc
index
4915b75d06f4d93e009472dcf84c66974e6d9541..84ee3933e22a28ba715417ed7222fdca7aa117bd
100644
--- a/src/compiler/js-generic-lowering.cc
+++ b/src/compiler/js-generic-lowering.cc
@@ -549,9 +549,8 @@ void JSGenericLowering::LowerJSCallConstruct(Node*
node) {
node->InsertInput(zone(), 0, stub_code);
node->InsertInput(zone(), 1, jsgraph()->Int32Constant(arity - 2));
node->InsertInput(zone(), 2, actual_construct);
- // TODO(mstarzinger): Pass original constructor in register.
- CHECK_EQ(actual_construct, original_construct);
- node->InsertInput(zone(), 3, jsgraph()->UndefinedConstant());
+ node->InsertInput(zone(), 3, original_construct);
+ node->InsertInput(zone(), 4, jsgraph()->UndefinedConstant());
node->set_op(common()->Call(desc));
}
Index: src/ia32/interface-descriptors-ia32.cc
diff --git a/src/ia32/interface-descriptors-ia32.cc
b/src/ia32/interface-descriptors-ia32.cc
index
9c87d324f192bdf2777a6d118035b9d734800bde..fda6de1de6fd7b25fd8ad7a16798343f5dbcb7f4
100644
--- a/src/ia32/interface-descriptors-ia32.cc
+++ b/src/ia32/interface-descriptors-ia32.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);
}
Index: src/mips/interface-descriptors-mips.cc
diff --git a/src/mips/interface-descriptors-mips.cc
b/src/mips/interface-descriptors-mips.cc
index
55b86c03b1da3d94aa0f0ed19bfafc07a8e97158..71be512d7bc0fa3142d7c9014265eb6095f2a690
100644
--- a/src/mips/interface-descriptors-mips.cc
+++ b/src/mips/interface-descriptors-mips.cc
@@ -169,11 +169,11 @@ void
CallConstructDescriptor::InitializePlatformSpecific(
// a0 : number of arguments
// a1 : the function to call
// a2 : feedback vector
- // a3 : (only if a2 is not the megamorphic symbol) slot in feedback
- // vector (Smi)
+ // a3 : slot in feedback vector (Smi, for RecordCallTarget)
+ // t0 : original constructor (for IsSuperConstructorCall)
// 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[] = {a0, a1, a2};
+ Register registers[] = {a0, a1, t0, a2};
data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
}
Index: src/mips64/interface-descriptors-mips64.cc
diff --git a/src/mips64/interface-descriptors-mips64.cc
b/src/mips64/interface-descriptors-mips64.cc
index
cb596af41478143721020bc6c4da338ab817b751..495d93768dde12f4d8d86f574be61183641e9ceb
100644
--- a/src/mips64/interface-descriptors-mips64.cc
+++ b/src/mips64/interface-descriptors-mips64.cc
@@ -169,11 +169,11 @@ void
CallConstructDescriptor::InitializePlatformSpecific(
// a0 : number of arguments
// a1 : the function to call
// a2 : feedback vector
- // a3 : (only if a2 is not the megamorphic symbol) slot in feedback
- // vector (Smi)
+ // a3 : slot in feedback vector (Smi, for RecordCallTarget)
+ // t0 : original constructor (for IsSuperConstructorCall)
// 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[] = {a0, a1, a2};
+ Register registers[] = {a0, a1, t0, a2};
data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
}
Index: src/x64/interface-descriptors-x64.cc
diff --git a/src/x64/interface-descriptors-x64.cc
b/src/x64/interface-descriptors-x64.cc
index
36f7ea66ff87a8937898b411980f41be99a13a30..40bff24f5128e246e361eac4c4fee96948b37c00
100644
--- a/src/x64/interface-descriptors-x64.cc
+++ b/src/x64/interface-descriptors-x64.cc
@@ -171,12 +171,12 @@ void
CallConstructDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
// rax : number of arguments
// rbx : feedback vector
- // rdx : (only if rbx is not the megamorphic symbol) slot in feedback
- // vector (Smi)
+ // rcx : original constructor (for IsSuperConstructorCall)
+ // rdx : slot in feedback vector (Smi, for RecordCallTarget)
// rdi : 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[] = {rax, rdi, rbx};
+ Register registers[] = {rax, rdi, rcx, rbx};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
--
--
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.