Fix cctest/test-cpu-profiler/FunctionApplySample fakiness on ARM simulator
authoryurys@chromium.org <yurys@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 16 Jul 2013 09:34:09 +0000 (09:34 +0000)
committeryurys@chromium.org <yurys@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 16 Jul 2013 09:34:09 +0000 (09:34 +0000)
For STM and LDM instuctions with writeback update base register only after all registers have been saved/loaded. This guarantees that invariant sp <= fp is always true when iterating stack in the Sampler.

BUG=v8:2782
R=yangguo@chromium.org

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

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

src/arm/simulator-arm.cc
src/arm/simulator-arm.h

index 00af777..c47f2ab 100644 (file)
@@ -1534,11 +1534,11 @@ static int count_bits(int bit_vector) {
 }
 
 
-void Simulator::ProcessPUW(Instruction* instr,
-                           int num_regs,
-                           int reg_size,
-                           intptr_t* start_address,
-                           intptr_t* end_address) {
+int32_t Simulator::ProcessPU(Instruction* instr,
+                             int num_regs,
+                             int reg_size,
+                             intptr_t* start_address,
+                             intptr_t* end_address) {
   int rn = instr->RnValue();
   int32_t rn_val = get_register(rn);
   switch (instr->PUField()) {
@@ -1569,9 +1569,7 @@ void Simulator::ProcessPUW(Instruction* instr,
       break;
     }
   }
-  if (instr->HasW()) {
-    set_register(rn, rn_val);
-  }
+  return rn_val;
 }
 
 
@@ -1582,7 +1580,8 @@ void Simulator::HandleRList(Instruction* instr, bool load) {
 
   intptr_t start_address = 0;
   intptr_t end_address = 0;
-  ProcessPUW(instr, num_regs, kPointerSize, &start_address, &end_address);
+  int32_t rn_val =
+      ProcessPU(instr, num_regs, kPointerSize, &start_address, &end_address);
 
   intptr_t* address = reinterpret_cast<intptr_t*>(start_address);
   // Catch null pointers a little earlier.
@@ -1601,6 +1600,9 @@ void Simulator::HandleRList(Instruction* instr, bool load) {
     rlist >>= 1;
   }
   ASSERT(end_address == ((intptr_t)address) - 4);
+  if (instr->HasW()) {
+    set_register(instr->RnValue(), rn_val);
+  }
 }
 
 
@@ -1623,7 +1625,8 @@ void Simulator::HandleVList(Instruction* instr) {
 
   intptr_t start_address = 0;
   intptr_t end_address = 0;
-  ProcessPUW(instr, num_regs, operand_size, &start_address, &end_address);
+  int32_t rn_val =
+      ProcessPU(instr, num_regs, operand_size, &start_address, &end_address);
 
   intptr_t* address = reinterpret_cast<intptr_t*>(start_address);
   for (int reg = vd; reg < vd + num_regs; reg++) {
@@ -1656,6 +1659,9 @@ void Simulator::HandleVList(Instruction* instr) {
     }
   }
   ASSERT(reinterpret_cast<intptr_t>(address) - operand_size == end_address);
+  if (instr->HasW()) {
+    set_register(instr->RnValue(), rn_val);
+  }
 }
 
 
index 2a458f9..7fca743 100644 (file)
@@ -291,11 +291,11 @@ class Simulator {
   // Helper functions to decode common "addressing" modes
   int32_t GetShiftRm(Instruction* instr, bool* carry_out);
   int32_t GetImm(Instruction* instr, bool* carry_out);
-  void ProcessPUW(Instruction* instr,
-                  int num_regs,
-                  int operand_size,
-                  intptr_t* start_address,
-                  intptr_t* end_address);
+  int32_t ProcessPU(Instruction* instr,
+                    int num_regs,
+                    int operand_size,
+                    intptr_t* start_address,
+                    intptr_t* end_address);
   void HandleRList(Instruction* instr, bool load);
   void HandleVList(Instruction* inst);
   void SoftwareInterrupt(Instruction* instr);