Fix an occasional crash in Assembler::ldr() for arm.

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
This commit is contained in:
dimich@chromium.org 2010-06-01 08:01:50 +00:00
parent 019b8c4511
commit 610ad370a3

View File

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