[arm] Fix pushing of stale register in CallConstructStub.
authormstarzinger <mstarzinger@chromium.org>
Wed, 22 Jul 2015 08:49:34 +0000 (01:49 -0700)
committerCommit bot <commit-bot@chromium.org>
Wed, 22 Jul 2015 08:49:59 +0000 (08:49 +0000)
This fixes a recent regression where the register usually holding the
original receiver was pushed onto the stack even when the stub was not
compiled for super calls (i.e. IsSuperConstructorCall). This led to
untagged values being present in the stack frame.

R=jacob.bramley@arm.com
BUG=chromium:512573
LOG=N

Review URL: https://codereview.chromium.org/1241223003

Cr-Commit-Position: refs/heads/master@{#29785}

src/arm/code-stubs-arm.cc
src/arm64/code-stubs-arm64.cc

index a3360ea2165ee332757b9a8d926c7c416cc3198f..c1ead67482fd12a3ff1fb3bcfc7732cc77c68125 100644 (file)
@@ -2384,28 +2384,33 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
 }
 
 
-static void CallStubInRecordCallTarget(MacroAssembler* masm, CodeStub* stub) {
+static void CallStubInRecordCallTarget(MacroAssembler* masm, CodeStub* stub,
+                                       bool is_super) {
   // r0 : number of arguments to the construct function
   // r1 : the function to call
   // r2 : feedback vector
   // r3 : slot in feedback vector (Smi)
-  // r4 : original constructor
+  // r4 : original constructor (for IsSuperConstructorCall)
   FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
 
   // Number-of-arguments register must be smi-tagged to call out.
   __ SmiTag(r0);
   __ Push(r3, r2, r1, r0);
-  __ Push(r4);
+  if (is_super) {
+    __ Push(r4);
+  }
 
   __ CallStub(stub);
 
-  __ Pop(r4);
+  if (is_super) {
+    __ Pop(r4);
+  }
   __ Pop(r3, r2, r1, r0);
   __ SmiUntag(r0);
 }
 
 
-static void GenerateRecordCallTarget(MacroAssembler* masm) {
+static void GenerateRecordCallTarget(MacroAssembler* masm, bool is_super) {
   // Cache the called function in a feedback vector slot.  Cache states
   // are uninitialized, monomorphic (indicated by a JSFunction), and
   // megamorphic.
@@ -2413,7 +2418,7 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
   // r1 : the function to call
   // r2 : feedback vector
   // r3 : slot in feedback vector (Smi)
-  // r4 : original constructor
+  // r4 : original constructor (for IsSuperConstructorCall)
   Label initialize, done, miss, megamorphic, not_array_function;
 
   DCHECK_EQ(*TypeFeedbackVector::MegamorphicSentinel(masm->isolate()),
@@ -2488,14 +2493,14 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
     // Create an AllocationSite if we don't already have it, store it in the
     // slot.
     CreateAllocationSiteStub create_stub(masm->isolate());
-    CallStubInRecordCallTarget(masm, &create_stub);
+    CallStubInRecordCallTarget(masm, &create_stub, is_super);
     __ b(&done);
 
     __ bind(&not_array_function);
   }
 
   CreateWeakCellStub create_stub(masm->isolate());
-  CallStubInRecordCallTarget(masm, &create_stub);
+  CallStubInRecordCallTarget(masm, &create_stub, is_super);
   __ bind(&done);
 }
 
@@ -2628,7 +2633,7 @@ void CallConstructStub::Generate(MacroAssembler* masm) {
   __ b(ne, &slow);
 
   if (RecordCallTarget()) {
-    GenerateRecordCallTarget(masm);
+    GenerateRecordCallTarget(masm, IsSuperConstructorCall());
 
     __ add(r5, r2, Operand::PointerOffsetFromSmiKey(r3));
     if (FLAG_pretenuring_call_new) {
index da6bdb75c58fa180dcf5acb069d436ed57ae307e..1703d4bcbf80127d17a094e669316bbfdb1139bb 100644 (file)
@@ -2749,17 +2749,25 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
 static void CallStubInRecordCallTarget(MacroAssembler* masm, CodeStub* stub,
                                        Register argc, Register function,
                                        Register feedback_vector, Register index,
-                                       Register orig_construct) {
+                                       Register orig_construct, bool is_super) {
   FrameScope scope(masm, StackFrame::INTERNAL);
 
   // Number-of-arguments register must be smi-tagged to call out.
   __ SmiTag(argc);
-  __ Push(argc, function, feedback_vector, index, orig_construct);
+  if (is_super) {
+    __ Push(argc, function, feedback_vector, index, orig_construct);
+  } else {
+    __ Push(argc, function, feedback_vector, index);
+  }
 
   DCHECK(feedback_vector.Is(x2) && index.Is(x3));
   __ CallStub(stub);
 
-  __ Pop(orig_construct, index, feedback_vector, function, argc);
+  if (is_super) {
+    __ Pop(orig_construct, index, feedback_vector, function, argc);
+  } else {
+    __ Pop(index, feedback_vector, function, argc);
+  }
   __ SmiUntag(argc);
 }
 
@@ -2768,7 +2776,8 @@ static void GenerateRecordCallTarget(MacroAssembler* masm, Register argc,
                                      Register function,
                                      Register feedback_vector, Register index,
                                      Register orig_construct, Register scratch1,
-                                     Register scratch2, Register scratch3) {
+                                     Register scratch2, Register scratch3,
+                                     bool is_super) {
   ASM_LOCATION("GenerateRecordCallTarget");
   DCHECK(!AreAliased(scratch1, scratch2, scratch3, argc, function,
                      feedback_vector, index, orig_construct));
@@ -2778,7 +2787,7 @@ static void GenerateRecordCallTarget(MacroAssembler* masm, Register argc,
   //  function :        the function to call
   //  feedback_vector : the feedback vector
   //  index :           slot in feedback vector (smi)
-  //  orig_construct :  original constructor
+  //  orig_construct :  original constructor (for IsSuperConstructorCall)
   Label initialize, done, miss, megamorphic, not_array_function;
 
   DCHECK_EQ(*TypeFeedbackVector::MegamorphicSentinel(masm->isolate()),
@@ -2857,7 +2866,8 @@ static void GenerateRecordCallTarget(MacroAssembler* masm, Register argc,
     // slot.
     CreateAllocationSiteStub create_stub(masm->isolate());
     CallStubInRecordCallTarget(masm, &create_stub, argc, function,
-                               feedback_vector, index, orig_construct);
+                               feedback_vector, index, orig_construct,
+                               is_super);
     __ B(&done);
 
     __ Bind(&not_array_function);
@@ -2865,7 +2875,7 @@ static void GenerateRecordCallTarget(MacroAssembler* masm, Register argc,
 
   CreateWeakCellStub create_stub(masm->isolate());
   CallStubInRecordCallTarget(masm, &create_stub, argc, function,
-                             feedback_vector, index, orig_construct);
+                             feedback_vector, index, orig_construct, is_super);
   __ Bind(&done);
 }
 
@@ -3005,7 +3015,8 @@ void CallConstructStub::Generate(MacroAssembler* masm) {
                          &slow);
 
   if (RecordCallTarget()) {
-    GenerateRecordCallTarget(masm, x0, function, x2, x3, x4, x5, x11, x12);
+    GenerateRecordCallTarget(masm, x0, function, x2, x3, x4, x5, x11, x12,
+                             IsSuperConstructorCall());
 
     __ Add(x5, x2, Operand::UntagSmiAndScale(x3, kPointerSizeLog2));
     if (FLAG_pretenuring_call_new) {