[arm64] Address TODO in CallConstructStub::Generate.
authormstarzinger <mstarzinger@chromium.org>
Tue, 21 Jul 2015 13:24:22 +0000 (06:24 -0700)
committerCommit bot <commit-bot@chromium.org>
Tue, 21 Jul 2015 13:24:39 +0000 (13:24 +0000)
R=jacob.bramley@arm.com

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

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

src/arm64/code-stubs-arm64.cc
src/arm64/macro-assembler-arm64.cc
src/arm64/macro-assembler-arm64.h

index 2a728c2f92bfdefd2920aa5e0d4e042131c2736e..da6bdb75c58fa180dcf5acb069d436ed57ae307e 100644 (file)
@@ -2748,18 +2748,18 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
 
 static void CallStubInRecordCallTarget(MacroAssembler* masm, CodeStub* stub,
                                        Register argc, Register function,
-                                       Register feedback_vector,
-                                       Register index) {
+                                       Register feedback_vector, Register index,
+                                       Register orig_construct) {
   FrameScope scope(masm, StackFrame::INTERNAL);
 
   // Number-of-arguments register must be smi-tagged to call out.
   __ SmiTag(argc);
-  __ Push(argc, function, feedback_vector, index);
+  __ Push(argc, function, feedback_vector, index, orig_construct);
 
   DCHECK(feedback_vector.Is(x2) && index.Is(x3));
   __ CallStub(stub);
 
-  __ Pop(index, feedback_vector, function, argc);
+  __ Pop(orig_construct, index, feedback_vector, function, argc);
   __ SmiUntag(argc);
 }
 
@@ -2767,17 +2767,18 @@ static void CallStubInRecordCallTarget(MacroAssembler* masm, CodeStub* stub,
 static void GenerateRecordCallTarget(MacroAssembler* masm, Register argc,
                                      Register function,
                                      Register feedback_vector, Register index,
-                                     Register scratch1, Register scratch2,
-                                     Register scratch3) {
+                                     Register orig_construct, Register scratch1,
+                                     Register scratch2, Register scratch3) {
   ASM_LOCATION("GenerateRecordCallTarget");
   DCHECK(!AreAliased(scratch1, scratch2, scratch3, argc, function,
-                     feedback_vector, index));
+                     feedback_vector, index, orig_construct));
   // Cache the called function in a feedback vector slot. Cache states are
   // uninitialized, monomorphic (indicated by a JSFunction), and megamorphic.
   //  argc :            number of arguments to the construct function
   //  function :        the function to call
   //  feedback_vector : the feedback vector
   //  index :           slot in feedback vector (smi)
+  //  orig_construct :  original constructor
   Label initialize, done, miss, megamorphic, not_array_function;
 
   DCHECK_EQ(*TypeFeedbackVector::MegamorphicSentinel(masm->isolate()),
@@ -2856,7 +2857,7 @@ static void GenerateRecordCallTarget(MacroAssembler* masm, Register argc,
     // slot.
     CreateAllocationSiteStub create_stub(masm->isolate());
     CallStubInRecordCallTarget(masm, &create_stub, argc, function,
-                               feedback_vector, index);
+                               feedback_vector, index, orig_construct);
     __ B(&done);
 
     __ Bind(&not_array_function);
@@ -2864,7 +2865,7 @@ static void GenerateRecordCallTarget(MacroAssembler* masm, Register argc,
 
   CreateWeakCellStub create_stub(masm->isolate());
   CallStubInRecordCallTarget(masm, &create_stub, argc, function,
-                             feedback_vector, index);
+                             feedback_vector, index, orig_construct);
   __ Bind(&done);
 }
 
@@ -3004,14 +3005,7 @@ void CallConstructStub::Generate(MacroAssembler* masm) {
                          &slow);
 
   if (RecordCallTarget()) {
-    if (IsSuperConstructorCall()) {
-      __ Push(x4);
-    }
-    // TODO(mstarzinger): Consider tweaking target recording to avoid push/pop.
-    GenerateRecordCallTarget(masm, x0, function, x2, x3, x4, x5, x11);
-    if (IsSuperConstructorCall()) {
-      __ Pop(x4);
-    }
+    GenerateRecordCallTarget(masm, x0, function, x2, x3, x4, x5, x11, x12);
 
     __ Add(x5, x2, Operand::UntagSmiAndScale(x3, kPointerSizeLog2));
     if (FLAG_pretenuring_call_new) {
index 2a8f5725a81f282f98fb773a9c2a4b524be06788..a06f5433da95ede1df3cdfad2cf2cfd596798327 100644 (file)
@@ -907,6 +907,25 @@ void MacroAssembler::Pop(const CPURegister& dst0, const CPURegister& dst1,
 }
 
 
+void MacroAssembler::Pop(const CPURegister& dst0, const CPURegister& dst1,
+                         const CPURegister& dst2, const CPURegister& dst3,
+                         const CPURegister& dst4, const CPURegister& dst5,
+                         const CPURegister& dst6, const CPURegister& dst7) {
+  // It is not valid to pop into the same register more than once in one
+  // instruction, not even into the zero register.
+  DCHECK(!AreAliased(dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7));
+  DCHECK(AreSameSizeAndType(dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7));
+  DCHECK(dst0.IsValid());
+
+  int count = 5 + dst5.IsValid() + dst6.IsValid() + dst7.IsValid();
+  int size = dst0.SizeInBytes();
+
+  PopHelper(4, size, dst0, dst1, dst2, dst3);
+  PopHelper(count - 4, size, dst4, dst5, dst6, dst7);
+  PopPostamble(count, size);
+}
+
+
 void MacroAssembler::Push(const Register& src0, const FPRegister& src1) {
   int size = src0.SizeInBytes() + src1.SizeInBytes();
 
index 8d47272526ce0992e8b0e2020b326900ca5994ac..f9aa8aa8e2b2b95419179af2d1596a75ac337d0b 100644 (file)
@@ -569,6 +569,10 @@ class MacroAssembler : public Assembler {
             const CPURegister& src6 = NoReg, const CPURegister& src7 = NoReg);
   void Pop(const CPURegister& dst0, const CPURegister& dst1 = NoReg,
            const CPURegister& dst2 = NoReg, const CPURegister& dst3 = NoReg);
+  void Pop(const CPURegister& dst0, const CPURegister& dst1,
+           const CPURegister& dst2, const CPURegister& dst3,
+           const CPURegister& dst4, const CPURegister& dst5 = NoReg,
+           const CPURegister& dst6 = NoReg, const CPURegister& dst7 = NoReg);
   void Push(const Register& src0, const FPRegister& src1);
 
   // Alternative forms of Push and Pop, taking a RegList or CPURegList that