Reviewers: dstence, michael_dawson, Michael Starzinger,

Description:
PPC: Switch CallConstructStub to take new.target in register.

Port 1d9d895754e1d1cf824c11a9cce5e495fa47d5e2

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.

[email protected], [email protected], [email protected]
BUG=

Please review this at https://codereview.chromium.org/1230103004/

Base URL: https://chromium.googlesource.com/v8/v8.git@master

Affected files (+25, -21 lines):
  M src/ppc/builtins-ppc.cc
  M src/ppc/code-stubs-ppc.cc
  M src/ppc/full-codegen-ppc.cc
  M src/ppc/interface-descriptors-ppc.cc


Index: src/ppc/builtins-ppc.cc
diff --git a/src/ppc/builtins-ppc.cc b/src/ppc/builtins-ppc.cc
index 20d9b57e190fb0fa6680c88966e99b744bcb68f2..b17ebab135ff6785ed53f6dec43e47829c9ed73e 100644
--- a/src/ppc/builtins-ppc.cc
+++ b/src/ppc/builtins-ppc.cc
@@ -1539,9 +1539,7 @@ static void Generate_ConstructHelper(MacroAssembler* masm) {
         StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize);
     __ li(r4, Operand::Zero());
     __ Push(r3, r4);  // limit and initial index.
-    // Push newTarget and callee functions
-    __ LoadP(r3, MemOperand(fp, kNewTargetOffset));
-    __ push(r3);
+    // Push the constructor function as callee
     __ LoadP(r3, MemOperand(fp, kFunctionOffset));
     __ push(r3);

@@ -1552,13 +1550,12 @@ static void Generate_ConstructHelper(MacroAssembler* masm) {
     // Use undefined feedback vector
     __ LoadRoot(r5, Heap::kUndefinedValueRootIndex);
     __ LoadP(r4, MemOperand(fp, kFunctionOffset));
+    __ LoadP(r7, MemOperand(fp, kNewTargetOffset));

     // Call the function.
     CallConstructStub stub(masm->isolate(), SUPER_CONSTRUCTOR_CALL);
     __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL);

-    __ Drop(1);
-
     // Leave internal frame.
   }
   __ addi(sp, sp, Operand(kStackSize * kPointerSize));
Index: src/ppc/code-stubs-ppc.cc
diff --git a/src/ppc/code-stubs-ppc.cc b/src/ppc/code-stubs-ppc.cc
index e7c11e7bc621cf2c9e363797f81505f56e405a3d..61e510d03c784514d1a18da036f02329ce2bf13c 100644
--- a/src/ppc/code-stubs-ppc.cc
+++ b/src/ppc/code-stubs-ppc.cc
@@ -2788,18 +2788,25 @@ void CallConstructStub::Generate(MacroAssembler* masm) {
   // r3 : number of arguments
   // r4 : the function to call
   // r5 : feedback vector
-  // r6 : (only if r5 is not the megamorphic symbol) slot in feedback
-  //      vector (Smi)
+  // r6 : slot in feedback vector (Smi, for RecordCallTarget)
+  // r7 : original constructor (for IsSuperConstructorCall)
   Label slow, non_function_call;

   // Check that the function is not a smi.
   __ JumpIfSmi(r4, &non_function_call);
   // Check that the function is a JSFunction.
-  __ CompareObjectType(r4, r7, r7, JS_FUNCTION_TYPE);
+  __ CompareObjectType(r4, r8, r8, JS_FUNCTION_TYPE);
   __ bne(&slow);

   if (RecordCallTarget()) {
+    if (IsSuperConstructorCall()) {
+      __ push(r7);
+    }
+ // TODO(mstarzinger): Consider tweaking target recording to avoid push/pop.
     GenerateRecordCallTarget(masm);
+    if (IsSuperConstructorCall()) {
+      __ pop(r7);
+    }

     __ SmiToPtrArrayOffset(r8, r6);
     __ add(r8, r5, r8);
@@ -2829,9 +2836,7 @@ void CallConstructStub::Generate(MacroAssembler* masm) {

   // Pass function as original constructor.
   if (IsSuperConstructorCall()) {
-    __ ShiftLeftImm(r7, r3, Operand(kPointerSizeLog2));
-    __ addi(r7, r7, Operand(kPointerSize));
-    __ LoadPX(r6, MemOperand(sp, r7));
+    __ mr(r6, r7);
   } else {
     __ mr(r6, r4);
   }
@@ -2846,11 +2851,11 @@ void CallConstructStub::Generate(MacroAssembler* masm) {

   // r3: number of arguments
   // r4: called object
-  // r7: object type
+  // r8: object type
   Label do_call;
   __ bind(&slow);
   STATIC_ASSERT(JS_FUNCTION_PROXY_TYPE < 0xffffu);
-  __ cmpi(r7, Operand(JS_FUNCTION_PROXY_TYPE));
+  __ cmpi(r8, Operand(JS_FUNCTION_PROXY_TYPE));
   __ bne(&non_function_call);
   __ GetBuiltinFunction(r4, Builtins::CALL_FUNCTION_PROXY_AS_CONSTRUCTOR);
   __ b(&do_call);
Index: src/ppc/full-codegen-ppc.cc
diff --git a/src/ppc/full-codegen-ppc.cc b/src/ppc/full-codegen-ppc.cc
index 455cc1e3fc7f6ac64e5543452f1b170d3368315d..86288cf86237d60fa7324f4dbde29613e96a6ebd 100644
--- a/src/ppc/full-codegen-ppc.cc
+++ b/src/ppc/full-codegen-ppc.cc
@@ -3384,9 +3384,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());

@@ -3401,6 +3398,10 @@ void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
   // constructor invocation.
   SetConstructCallPosition(expr);

+  // Load original constructor into r7.
+  VisitForAccumulatorValue(super_call_ref->new_target_var());
+  __ mr(r7, result_register());
+
   // Load function and argument count into r1 and r0.
   __ mov(r3, Operand(arg_count));
   __ LoadP(r4, MemOperand(sp, arg_count * kPointerSize));
@@ -3421,8 +3422,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());
@@ -4343,6 +4342,9 @@ void FullCodeGenerator::EmitDefaultConstructorCallSuper(CallRuntime* expr) {
   __ mr(r4, result_register());
   __ Push(r4);

+  // Load original constructor into r7.
+  __ LoadP(r7, MemOperand(sp, 1 * kPointerSize));
+
   // Check if the calling frame is an arguments adaptor frame.
   Label adaptor_frame, args_set_up, runtime;
   __ LoadP(r5, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
Index: src/ppc/interface-descriptors-ppc.cc
diff --git a/src/ppc/interface-descriptors-ppc.cc b/src/ppc/interface-descriptors-ppc.cc index 8d1bfca90bafb38173e3f5f22a5343e808cf7270..9bcbf9cfccb370b7ade194ebf2df6ef7894e431c 100644
--- a/src/ppc/interface-descriptors-ppc.cc
+++ b/src/ppc/interface-descriptors-ppc.cc
@@ -169,11 +169,11 @@ void CallConstructDescriptor::InitializePlatformSpecific(
   // r3 : number of arguments
   // r4 : the function to call
   // r5 : feedback vector
-  // r6 : (only if r5 is not the megamorphic symbol) slot in feedback
-  //      vector (Smi)
+  // r6 : slot in feedback vector (Smi, for RecordCallTarget)
+  // r7 : 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[] = {r3, r4, r5};
+  Register registers[] = {r3, r4, r7, r5};
   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.

Reply via email to