Unifying the handling of storing and loading from safepoint stack
authorager@chromium.org <ager@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 21 Feb 2011 11:29:45 +0000 (11:29 +0000)
committerager@chromium.org <ager@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 21 Feb 2011 11:29:45 +0000 (11:29 +0000)
slots across architectures.

Review URL: http://codereview.chromium.org/6541051

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@6862 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

13 files changed:
src/arm/code-stubs-arm.cc
src/arm/lithium-codegen-arm.cc
src/arm/macro-assembler-arm.cc
src/arm/macro-assembler-arm.h
src/ia32/assembler-ia32.h
src/ia32/lithium-codegen-ia32.cc
src/ia32/macro-assembler-ia32.cc
src/ia32/macro-assembler-ia32.h
src/x64/assembler-x64.cc
src/x64/assembler-x64.h
src/x64/lithium-codegen-x64.cc
src/x64/macro-assembler-x64.cc
src/x64/macro-assembler-x64.h

index 7aec20637b32d20eb47dfd06edf5ba77b90e5b7a..5e4387f85ac65d381f562db7125a67b5a87bf598 100644 (file)
@@ -3710,7 +3710,7 @@ void InstanceofStub::Generate(MacroAssembler* masm) {
 
     // The offset was stored in r4 safepoint slot.
     // (See LCodeGen::DoDeferredLInstanceOfKnownGlobal)
-    __ ldr(scratch, MacroAssembler::SafepointRegisterSlot(r4));
+    __ LoadFromSafepointRegisterSlot(scratch, r4);
     __ sub(inline_site, lr, scratch);
     // Get the map location in scratch and patch it.
     __ GetRelocatedValueLocation(inline_site, scratch);
index 9e78beb16267f8d17cdb1f895d593a51c7d897a0..b973592ed52e4864de713b94a3d9af71153d5110 100644 (file)
@@ -926,7 +926,7 @@ void LCodeGen::DoDeferredBinaryOpStub(LTemplateInstruction<1, 2, T>* instr,
                                          0,
                                          Safepoint::kNoDeoptimizationIndex);
   // Overwrite the stored value of r0 with the result of the stub.
-  __ StoreToSafepointRegistersAndDoublesSlot(r0);
+  __ StoreToSafepointRegistersAndDoublesSlot(r0, r0);
   __ PopSafepointRegistersAndDoubles();
 }
 
@@ -1940,7 +1940,7 @@ void LCodeGen::DoDeferredLInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
   __ bind(&before_push_delta);
   __ BlockConstPoolFor(kAdditionalDelta);
   __ mov(temp, Operand(delta * kPointerSize));
-  __ StoreToSafepointRegisterSlot(temp);
+  __ StoreToSafepointRegisterSlot(temp, temp);
   __ Call(stub.GetCode(), RelocInfo::CODE_TARGET);
   ASSERT_EQ(kAdditionalDelta,
             masm_->InstructionsGeneratedSince(&before_push_delta));
@@ -1948,7 +1948,7 @@ void LCodeGen::DoDeferredLInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
       instr->pointer_map(), 0, Safepoint::kNoDeoptimizationIndex);
   // Put the result value into the result register slot and
   // restore all registers.
-  __ StoreToSafepointRegisterSlot(result);
+  __ StoreToSafepointRegisterSlot(result, result);
 
   __ PopSafepointRegisters();
 }
@@ -2481,7 +2481,7 @@ void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) {
   // Set the pointer to the new heap number in tmp.
   if (!tmp1.is(r0)) __ mov(tmp1, Operand(r0));
   // Restore input_reg after call to runtime.
-  __ LoadFromSafepointRegisterSlot(input);
+  __ LoadFromSafepointRegisterSlot(input, input);
   __ ldr(exponent, FieldMemOperand(input, HeapNumber::kExponentOffset));
 
   __ bind(&allocated);
@@ -2492,7 +2492,7 @@ void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) {
   __ ldr(tmp2, FieldMemOperand(input, HeapNumber::kMantissaOffset));
   __ str(tmp2, FieldMemOperand(tmp1, HeapNumber::kMantissaOffset));
 
-  __ str(tmp1, masm()->SafepointRegisterSlot(input));
+  __ StoreToSafepointRegisterSlot(tmp1, input);
   __ PopSafepointRegisters();
 
   __ bind(&done);
@@ -2950,8 +2950,7 @@ void LCodeGen::DoDeferredStringCharCodeAt(LStringCharCodeAt* instr) {
     __ AbortIfNotSmi(r0);
   }
   __ SmiUntag(r0);
-  MemOperand result_stack_slot = masm()->SafepointRegisterSlot(result);
-  __ str(r0, result_stack_slot);
+  __ StoreToSafepointRegisterSlot(r0, result);
   __ PopSafepointRegisters();
 }
 
@@ -3032,9 +3031,7 @@ void LCodeGen::DoDeferredNumberTagI(LNumberTagI* instr) {
   // register is stored, as this register is in the pointer map, but contains an
   // integer value.
   __ mov(ip, Operand(0));
-  int reg_stack_index = __ SafepointRegisterStackIndex(reg.code());
-  __ str(ip, MemOperand(sp, reg_stack_index * kPointerSize));
-
+  __ StoreToSafepointRegisterSlot(ip, reg);
   __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber);
   RecordSafepointWithRegisters(
       instr->pointer_map(), 0, Safepoint::kNoDeoptimizationIndex);
@@ -3045,7 +3042,7 @@ void LCodeGen::DoDeferredNumberTagI(LNumberTagI* instr) {
   __ bind(&done);
   __ sub(ip, reg, Operand(kHeapObjectTag));
   __ vstr(dbl_scratch, ip, HeapNumber::kValueOffset);
-  __ str(reg, MemOperand(sp, reg_stack_index * kPointerSize));
+  __ StoreToSafepointRegisterSlot(reg, reg);
   __ PopSafepointRegisters();
 }
 
@@ -3090,8 +3087,7 @@ void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) {
   __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber);
   RecordSafepointWithRegisters(
       instr->pointer_map(), 0, Safepoint::kNoDeoptimizationIndex);
-  int reg_stack_index = __ SafepointRegisterStackIndex(reg.code());
-  __ str(r0, MemOperand(sp, reg_stack_index * kPointerSize));
+  __ StoreToSafepointRegisterSlot(r0, reg);
   __ PopSafepointRegisters();
 }
 
index eb850cd948f891927b063c8a1e8af1afe4c69145..aa5822fa543c894fc6307c88c344795fa5f5be0c 100644 (file)
@@ -485,18 +485,19 @@ void MacroAssembler::PopSafepointRegistersAndDoubles() {
   PopSafepointRegisters();
 }
 
-void MacroAssembler::StoreToSafepointRegistersAndDoublesSlot(Register reg) {
-  str(reg, SafepointRegistersAndDoublesSlot(reg));
+void MacroAssembler::StoreToSafepointRegistersAndDoublesSlot(Register src,
+                                                             Register dst) {
+  str(src, SafepointRegistersAndDoublesSlot(dst));
 }
 
 
-void MacroAssembler::StoreToSafepointRegisterSlot(Register reg) {
-  str(reg, SafepointRegisterSlot(reg));
+void MacroAssembler::StoreToSafepointRegisterSlot(Register src, Register dst) {
+  str(src, SafepointRegisterSlot(dst));
 }
 
 
-void MacroAssembler::LoadFromSafepointRegisterSlot(Register reg) {
-  ldr(reg, SafepointRegisterSlot(reg));
+void MacroAssembler::LoadFromSafepointRegisterSlot(Register dst, Register src) {
+  ldr(dst, SafepointRegisterSlot(src));
 }
 
 
index 354662da32a4384c294ef866f32c5f6752691424..06709f435484b767925027bc66013c7a50257704 100644 (file)
@@ -240,12 +240,13 @@ class MacroAssembler: public Assembler {
   void PopSafepointRegisters();
   void PushSafepointRegistersAndDoubles();
   void PopSafepointRegistersAndDoubles();
-  void StoreToSafepointRegisterSlot(Register reg);
-  void StoreToSafepointRegistersAndDoublesSlot(Register reg);
-  void LoadFromSafepointRegisterSlot(Register reg);
-  static int SafepointRegisterStackIndex(int reg_code);
-  static MemOperand SafepointRegisterSlot(Register reg);
-  static MemOperand SafepointRegistersAndDoublesSlot(Register reg);
+  // Store value in register src in the safepoint stack slot for
+  // register dst.
+  void StoreToSafepointRegisterSlot(Register src, Register dst);
+  void StoreToSafepointRegistersAndDoublesSlot(Register src, Register dst);
+  // Load the value of the src register from its safepoint stack slot
+  // into register dst.
+  void LoadFromSafepointRegisterSlot(Register dst, Register src);
 
   // Load two consecutive registers with two consecutive memory locations.
   void Ldrd(Register dst1,
@@ -883,10 +884,19 @@ class MacroAssembler: public Assembler {
                            Register scratch1,
                            Register scratch2);
 
+  // Compute memory operands for safepoint stack slots.
+  static int SafepointRegisterStackIndex(int reg_code);
+  MemOperand SafepointRegisterSlot(Register reg);
+  MemOperand SafepointRegistersAndDoublesSlot(Register reg);
+
   bool generating_stub_;
   bool allow_stub_calls_;
   // This handle will be patched with the code object on installation.
   Handle<Object> code_object_;
+
+  // Needs access to SafepointRegisterStackIndex for optimized frame
+  // traversal.
+  friend class OptimizedFrame;
 };
 
 
index 91bcb573df245899a8ab71310904f1855509dd7c..7661e0489b91ca2de4db9af835ed5d2c5c782d20 100644 (file)
@@ -183,13 +183,6 @@ const XMMRegister xmm7 = { 7 };
 typedef XMMRegister DoubleRegister;
 
 
-// Index of register used in pusha/popa.
-// Order of pushed registers: eax, ecx, edx, ebx, esp, ebp, esi, and edi.
-inline int EspIndexForPushAll(Register reg) {
-  return Register::kNumRegisters - 1 - reg.code();
-}
-
-
 enum Condition {
   // any value < 0 is considered no_condition
   no_condition  = -1,
index 478f8a3eb14d595a52ff8389424680dcfa7179a1..286c3eee1f3270524f776abcb97e97ef0c4ae72c 100644 (file)
@@ -1836,7 +1836,7 @@ void LCodeGen::DoDeferredLInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
   Label before_push_delta;
   __ bind(&before_push_delta);
   __ mov(temp, Immediate(delta));
-  __ mov(Operand(esp, EspIndexForPushAll(temp) * kPointerSize), temp);
+  __ StoreToSafepointRegisterSlot(temp, temp);
   __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
   __ call(stub.GetCode(), RelocInfo::CODE_TARGET);
   ASSERT_EQ(kAdditionalDelta,
@@ -1844,8 +1844,7 @@ void LCodeGen::DoDeferredLInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
   RecordSafepointWithRegisters(
       instr->pointer_map(), 0, Safepoint::kNoDeoptimizationIndex);
   // Put the result value into the eax slot and restore all registers.
-  __ mov(Operand(esp, EspIndexForPushAll(eax) * kPointerSize), eax);
-
+  __ StoreToSafepointRegisterSlot(eax, eax);
   __ PopSafepointRegisters();
 }
 
@@ -2360,7 +2359,7 @@ void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) {
   if (!tmp.is(eax)) __ mov(tmp, eax);
 
   // Restore input_reg after call to runtime.
-  __ mov(input_reg, Operand(esp, EspIndexForPushAll(input_reg) * kPointerSize));
+  __ LoadFromSafepointRegisterSlot(input_reg, input_reg);
 
   __ bind(&allocated);
   __ mov(tmp2, FieldOperand(input_reg, HeapNumber::kExponentOffset));
@@ -2368,7 +2367,7 @@ void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) {
   __ mov(FieldOperand(tmp, HeapNumber::kExponentOffset), tmp2);
   __ mov(tmp2, FieldOperand(input_reg, HeapNumber::kMantissaOffset));
   __ mov(FieldOperand(tmp, HeapNumber::kMantissaOffset), tmp2);
-  __ mov(Operand(esp, EspIndexForPushAll(input_reg) * kPointerSize), tmp);
+  __ StoreToSafepointRegisterSlot(input_reg, tmp);
 
   __ bind(&done);
   __ PopSafepointRegisters();
@@ -2923,7 +2922,7 @@ void LCodeGen::DoDeferredStringCharCodeAt(LStringCharCodeAt* instr) {
     __ AbortIfNotSmi(eax);
   }
   __ SmiUntag(eax);
-  __ mov(Operand(esp, EspIndexForPushAll(result) * kPointerSize), eax);
+  __ StoreToSafepointRegisterSlot(result, eax);
   __ PopSafepointRegisters();
 }
 
@@ -2991,7 +2990,7 @@ void LCodeGen::DoDeferredNumberTagI(LNumberTagI* instr) {
   // TODO(3095996): Put a valid pointer value in the stack slot where the result
   // register is stored, as this register is in the pointer map, but contains an
   // integer value.
-  __ mov(Operand(esp, EspIndexForPushAll(reg) * kPointerSize), Immediate(0));
+  __ StoreToSafepointRegisterSlot(reg, Immediate(0));
 
   __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
   __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber);
@@ -3003,7 +3002,7 @@ void LCodeGen::DoDeferredNumberTagI(LNumberTagI* instr) {
   // number.
   __ bind(&done);
   __ movdbl(FieldOperand(reg, HeapNumber::kValueOffset), xmm0);
-  __ mov(Operand(esp, EspIndexForPushAll(reg) * kPointerSize), reg);
+  __ StoreToSafepointRegisterSlot(reg, reg);
   __ PopSafepointRegisters();
 }
 
@@ -3045,7 +3044,7 @@ void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) {
   __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber);
   RecordSafepointWithRegisters(
       instr->pointer_map(), 0, Safepoint::kNoDeoptimizationIndex);
-  __ mov(Operand(esp, EspIndexForPushAll(reg) * kPointerSize), eax);
+  __ StoreToSafepointRegisterSlot(reg, eax);
   __ PopSafepointRegisters();
 }
 
index 7f93b843d4fbf8846032d4680910153555c15278..91b6651fe03776bb31cbc7ea56c36f9f949e952c 100644 (file)
@@ -1654,6 +1654,28 @@ void MacroAssembler::LoadGlobalFunctionInitialMap(Register function,
 }
 
 
+// Store the value in register src in the safepoint register stack
+// slot for register dst.
+void MacroAssembler::StoreToSafepointRegisterSlot(Register dst, Register src) {
+  mov(SafepointRegisterSlot(dst), src);
+}
+
+
+void MacroAssembler::StoreToSafepointRegisterSlot(Register dst, Immediate src) {
+  mov(SafepointRegisterSlot(dst), src);
+}
+
+
+void MacroAssembler::LoadFromSafepointRegisterSlot(Register dst, Register src) {
+  mov(dst, SafepointRegisterSlot(src));
+}
+
+
+Operand MacroAssembler::SafepointRegisterSlot(Register reg) {
+  return Operand(esp, SafepointRegisterStackIndex(reg.code()) * kPointerSize);
+}
+
+
 int MacroAssembler::SafepointRegisterStackIndex(int reg_code) {
   // The registers are pushed starting with the lowest encoding,
   // which means that lowest encodings are furthest away from
index 16361ad2390ffeea3a19c4f1789f0a2e10f8ab60..62bb0f36343c93019e5dd5ed87076addd6fab91d 100644 (file)
@@ -143,7 +143,11 @@ class MacroAssembler: public Assembler {
   // Push and pop the registers that can hold pointers.
   void PushSafepointRegisters() { pushad(); }
   void PopSafepointRegisters() { popad(); }
-  static int SafepointRegisterStackIndex(int reg_code);
+  // Store the value in register/immediate src in the safepoint
+  // register stack slot for register dst.
+  void StoreToSafepointRegisterSlot(Register dst, Register src);
+  void StoreToSafepointRegisterSlot(Register dst, Immediate src);
+  void LoadFromSafepointRegisterSlot(Register dst, Register src);
 
   // ---------------------------------------------------------------------------
   // JavaScript invokes
@@ -667,6 +671,15 @@ class MacroAssembler: public Assembler {
   MUST_USE_RESULT MaybeObject* PopHandleScopeHelper(Register saved,
                                                     Register scratch,
                                                     bool gc_allowed);
+
+
+  // Compute memory operands for safepoint stack slots.
+  Operand SafepointRegisterSlot(Register reg);
+  static int SafepointRegisterStackIndex(int reg_code);
+
+  // Needs access to SafepointRegisterStackIndex for optimized frame
+  // traversal.
+  friend class OptimizedFrame;
 };
 
 
index 17170dab961f0fc4870a98d11e38e7280850bdac..ea41a202d58c392821be0d992617a0fe14595e81 100644 (file)
@@ -200,11 +200,6 @@ const int Register::kAllocationIndexByRegisterCode[kNumRegisters] = {
 };
 
 
-const int Register::kRspIndexForPushAllByRegisterCode[kNumRegisters] = {
-  10, 9, 8, 7, -1, -1, 6, 5, 4, 3, -1, 2, 1, -1, 0, -1
-};
-
-
 // -----------------------------------------------------------------------------
 // Implementation of Operand
 
index fff449c155ef63b07a17574cdc6ae5c40ca37cda..553fbe4220b910394c0f1789e2f555612101b262 100644 (file)
@@ -108,12 +108,6 @@ struct Register {
     return result;
   }
 
-  static int ToRspIndexForPushAll(Register reg) {
-    // TODO(ager): Refactor this so we can use the right constants for
-    // this computation. Move it to the macro assembler as on ARM.
-    return kRspIndexForPushAllByRegisterCode[reg.code()] + 5;
-  }
-
   static const char* AllocationIndexToString(int index) {
     ASSERT(index >= 0 && index < kNumAllocatableRegisters);
     const char* const names[] = {
@@ -163,7 +157,6 @@ struct Register {
  private:
   static const int kRegisterCodeByAllocationIndex[kNumAllocatableRegisters];
   static const int kAllocationIndexByRegisterCode[kNumRegisters];
-  static const int kRspIndexForPushAllByRegisterCode[kNumRegisters];
 };
 
 const Register rax = { 0 };
index d6c7640bb48dcebdc6ecafa2384625f19efba1e4..e695eb8eab50b4c0af25fc070068ce97885ffc56 100644 (file)
@@ -2620,8 +2620,7 @@ void LCodeGen::DoDeferredStringCharCodeAt(LStringCharCodeAt* instr) {
     __ AbortIfNotSmi(rax);
   }
   __ SmiToInteger32(rax, rax);
-  __ movq(Operand(rsp, Register::ToRspIndexForPushAll(result) * kPointerSize),
-          rax);
+  __ StoreToSafepointRegisterSlot(result, rax);
   __ PopSafepointRegisters();
 }
 
index 9ebaaa94cc66212a9f06e9bd44df9eb21f9ff2c5..48e42c85ca51e27b489eb8ffe47c3df936fdc957 100644 (file)
@@ -1446,15 +1446,17 @@ void MacroAssembler::Pushad() {
   // r15 is kSmiConstantRegister
   STATIC_ASSERT(11 == kNumSafepointSavedRegisters);
   // Use lea for symmetry with Popad.
-  lea(rsp, Operand(rsp,
-      -(kNumSafepointRegisters-kNumSafepointSavedRegisters) * kPointerSize));
+  int sp_delta =
+      (kNumSafepointRegisters - kNumSafepointSavedRegisters) * kPointerSize;
+  lea(rsp, Operand(rsp, -sp_delta));
 }
 
 
 void MacroAssembler::Popad() {
   // Popad must not change the flags, so use lea instead of addq.
-  lea(rsp, Operand(rsp,
-      (kNumSafepointRegisters-kNumSafepointSavedRegisters) * kPointerSize));
+  int sp_delta =
+      (kNumSafepointRegisters - kNumSafepointSavedRegisters) * kPointerSize;
+  lea(rsp, Operand(rsp, sp_delta));
   pop(r14);
   pop(r12);
   pop(r11);
@@ -1496,6 +1498,16 @@ int MacroAssembler::kSafepointPushRegisterIndices[Register::kNumRegisters] = {
 };
 
 
+void MacroAssembler::StoreToSafepointRegisterSlot(Register dst, Register src) {
+  movq(SafepointRegisterSlot(dst), src);
+}
+
+
+Operand MacroAssembler::SafepointRegisterSlot(Register reg) {
+  return Operand(rsp, SafepointRegisterStackIndex(reg.code()) * kPointerSize);
+}
+
+
 void MacroAssembler::PushTryHandler(CodeLocation try_location,
                                     HandlerType type) {
   // Adjust this code if not the case.
index 845de57cda4e849d44c5cfb49c015b9c1ce23dbd..4c5c60c8f0009b8db26c8daa07c49203df7204fd 100644 (file)
@@ -171,10 +171,9 @@ class MacroAssembler: public Assembler {
   // Push and pop the registers that can hold pointers.
   void PushSafepointRegisters() { Pushad(); }
   void PopSafepointRegisters() { Popad(); }
-  static int SafepointRegisterStackIndex(int reg_code) {
-    return kNumSafepointRegisters - 1 -
-        kSafepointPushRegisterIndices[reg_code];
-  }
+  // Store the value in register src in the safepoint register stack
+  // slot for register dst.
+  void StoreToSafepointRegisterSlot(Register dst, Register src);
 
 
   // ---------------------------------------------------------------------------
@@ -1035,6 +1034,17 @@ class MacroAssembler: public Assembler {
   Object* PopHandleScopeHelper(Register saved,
                                Register scratch,
                                bool gc_allowed);
+
+
+  // Compute memory operands for safepoint stack slots.
+  Operand SafepointRegisterSlot(Register reg);
+  static int SafepointRegisterStackIndex(int reg_code) {
+    return kNumSafepointRegisters - kSafepointPushRegisterIndices[reg_code] - 1;
+  }
+
+  // Needs access to SafepointRegisterStackIndex for optimized frame
+  // traversal.
+  friend class OptimizedFrame;
 };