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.

Reply via email to