Reviewers: Erik Corry,
Description:
Change the ARM fixup code to handle the use of the following
instruction sequence for jumps:
mov(ip, Operand(target, rmode), LeaveCC, cond);
bx(ip, cond)
Changed a JS call in the compare stub to a tail call to avoid GC
problems where the pushed return address is not updated on GC.
Please review this at http://codereview.chromium.org/549022
SVN Base: http://v8.googlecode.com/svn/branches/bleeding_edge/
Affected files:
M src/arm/assembler-arm-inl.h
M src/arm/codegen-arm.cc
Index: src/arm/assembler-arm-inl.h
===================================================================
--- src/arm/assembler-arm-inl.h (revision 3577)
+++ src/arm/assembler-arm-inl.h (working copy)
@@ -229,14 +229,23 @@
Address Assembler::target_address_address_at(Address pc) {
- Instr instr = Memory::int32_at(pc);
- // Verify that the instruction at pc is a ldr<cond> <Rd>, [pc +/-
offset_12].
+ Address target_pc = pc;
+ Instr instr = Memory::int32_at(target_pc);
+ // If we have a bx instruction, the instruction before the bx is
+ // what we need to patch.
+ static const int32_t kBxInstMask = 0x0ffffff0;
+ static const int32_t kBxInstPattern = 0x012fff10;
+ if ((instr & kBxInstMask) == kBxInstPattern) {
+ target_pc -= kInstrSize;
+ instr = Memory::int32_at(target_pc);
+ }
+ // Verify that the instruction to patch is a ldr<cond> <Rd>, [pc +/-
offset_12].
ASSERT((instr & 0x0f7f0000) == 0x051f0000);
int offset = instr & 0xfff; // offset_12 is unsigned
if ((instr & (1 << 23)) == 0) offset = -offset; // U bit defines offset
sign
// Verify that the constant pool comes after the instruction referencing
it.
ASSERT(offset >= -4);
- return pc + offset + 8;
+ return target_pc + offset + 8;
}
Index: src/arm/codegen-arm.cc
===================================================================
--- src/arm/codegen-arm.cc (revision 3578)
+++ src/arm/codegen-arm.cc (working copy)
@@ -5098,12 +5098,10 @@
}
__ bind(&slow);
- __ push(lr);
__ push(r1);
__ push(r0);
// Figure out which native to call and setup the arguments.
Builtins::JavaScript native;
- int arg_count = 1; // Not counting receiver.
if (cc_ == eq) {
native = strict_ ? Builtins::STRICT_EQUALS : Builtins::EQUALS;
} else {
@@ -5115,16 +5113,13 @@
ASSERT(cc_ == gt || cc_ == ge); // remaining cases
ncr = LESS;
}
- arg_count++;
__ mov(r0, Operand(Smi::FromInt(ncr)));
__ push(r0);
}
// Call the native; it returns -1 (less), 0 (equal), or 1 (greater)
// tagged as a small integer.
- __ InvokeBuiltin(native, CALL_JS);
- __ cmp(r0, Operand(0));
- __ pop(pc);
+ __ InvokeBuiltin(native, JUMP_JS);
}
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev