Fix an occasional crash in Assembler::ldr() for arm.
authordimich@chromium.org <dimich@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 1 Jun 2010 08:01:50 +0000 (08:01 +0000)
committerdimich@chromium.org <dimich@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 1 Jun 2010 08:01:50 +0000 (08:01 +0000)
A peephole optimization can be attempted on a buffer that contains only a single command. The crash happens when running debug on Snow Leopard with --simulator=arm.

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

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

src/arm/assembler-arm.cc

index 6dd381febb26bacfc14bc3095594682b35e507f7..846464ab5a1f7786961b3d329cc5b5f46b58240e 100644 (file)
@@ -1213,31 +1213,32 @@ void Assembler::ldr(Register dst, const MemOperand& src, Condition cond) {
   // Both instructions can be eliminated if ry = rx.
   // If ry != rx, a register copy from ry to rx is inserted
   // after eliminating the push and the pop instructions.
-  Instr push_instr = instr_at(pc_ - 2 * kInstrSize);
-  Instr pop_instr = instr_at(pc_ - 1 * kInstrSize);
-
-  if (can_peephole_optimize(2) &&
-      IsPush(push_instr) &&
-      IsPop(pop_instr)) {
-    if ((pop_instr & kRdMask) != (push_instr & kRdMask)) {
-      // For consecutive push and pop on different registers,
-      // we delete both the push & pop and insert a register move.
-      // push ry, pop rx --> mov rx, ry
-      Register reg_pushed, reg_popped;
-      reg_pushed = GetRd(push_instr);
-      reg_popped = GetRd(pop_instr);
-      pc_ -= 2 * kInstrSize;
-      // Insert a mov instruction, which is better than a pair of push & pop
-      mov(reg_popped, reg_pushed);
-      if (FLAG_print_peephole_optimization) {
-        PrintF("%x push/pop (diff reg) replaced by a reg move\n", pc_offset());
-      }
-    } else {
-      // For consecutive push and pop on the same register,
-      // both the push and the pop can be deleted.
-      pc_ -= 2 * kInstrSize;
-      if (FLAG_print_peephole_optimization) {
-        PrintF("%x push/pop (same reg) eliminated\n", pc_offset());
+  if (can_peephole_optimize(2)) {
+    Instr push_instr = instr_at(pc_ - 2 * kInstrSize);
+    Instr pop_instr = instr_at(pc_ - 1 * kInstrSize);
+
+    if (IsPush(push_instr) && IsPop(pop_instr)) {
+      if ((pop_instr & kRdMask) != (push_instr & kRdMask)) {
+        // For consecutive push and pop on different registers,
+        // we delete both the push & pop and insert a register move.
+        // push ry, pop rx --> mov rx, ry
+        Register reg_pushed, reg_popped;
+        reg_pushed = GetRd(push_instr);
+        reg_popped = GetRd(pop_instr);
+        pc_ -= 2 * kInstrSize;
+        // Insert a mov instruction, which is better than a pair of push & pop
+        mov(reg_popped, reg_pushed);
+        if (FLAG_print_peephole_optimization) {
+          PrintF("%x push/pop (diff reg) replaced by a reg move\n",
+                 pc_offset());
+        }
+      } else {
+        // For consecutive push and pop on the same register,
+        // both the push and the pop can be deleted.
+        pc_ -= 2 * kInstrSize;
+        if (FLAG_print_peephole_optimization) {
+          PrintF("%x push/pop (same reg) eliminated\n", pc_offset());
+        }
       }
     }
   }