Commit 61a1c089 authored by ager@chromium.org's avatar ager@chromium.org

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.
Review URL: http://codereview.chromium.org/549022

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3582 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent c891a7a6
...@@ -229,14 +229,24 @@ void Assembler::emit(Instr x) { ...@@ -229,14 +229,24 @@ void Assembler::emit(Instr x) {
Address Assembler::target_address_address_at(Address pc) { Address Assembler::target_address_address_at(Address pc) {
Instr instr = Memory::int32_at(pc); Address target_pc = pc;
// Verify that the instruction at pc is a ldr<cond> <Rd>, [pc +/- offset_12]. 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); ASSERT((instr & 0x0f7f0000) == 0x051f0000);
int offset = instr & 0xfff; // offset_12 is unsigned int offset = instr & 0xfff; // offset_12 is unsigned
if ((instr & (1 << 23)) == 0) offset = -offset; // U bit defines offset sign if ((instr & (1 << 23)) == 0) offset = -offset; // U bit defines offset sign
// Verify that the constant pool comes after the instruction referencing it. // Verify that the constant pool comes after the instruction referencing it.
ASSERT(offset >= -4); ASSERT(offset >= -4);
return pc + offset + 8; return target_pc + offset + 8;
} }
......
...@@ -5090,12 +5090,10 @@ void CompareStub::Generate(MacroAssembler* masm) { ...@@ -5090,12 +5090,10 @@ void CompareStub::Generate(MacroAssembler* masm) {
} }
__ bind(&slow); __ bind(&slow);
__ push(lr);
__ push(r1); __ push(r1);
__ push(r0); __ push(r0);
// Figure out which native to call and setup the arguments. // Figure out which native to call and setup the arguments.
Builtins::JavaScript native; Builtins::JavaScript native;
int arg_count = 1; // Not counting receiver.
if (cc_ == eq) { if (cc_ == eq) {
native = strict_ ? Builtins::STRICT_EQUALS : Builtins::EQUALS; native = strict_ ? Builtins::STRICT_EQUALS : Builtins::EQUALS;
} else { } else {
...@@ -5107,16 +5105,13 @@ void CompareStub::Generate(MacroAssembler* masm) { ...@@ -5107,16 +5105,13 @@ void CompareStub::Generate(MacroAssembler* masm) {
ASSERT(cc_ == gt || cc_ == ge); // remaining cases ASSERT(cc_ == gt || cc_ == ge); // remaining cases
ncr = LESS; ncr = LESS;
} }
arg_count++;
__ mov(r0, Operand(Smi::FromInt(ncr))); __ mov(r0, Operand(Smi::FromInt(ncr)));
__ push(r0); __ push(r0);
} }
// Call the native; it returns -1 (less), 0 (equal), or 1 (greater) // Call the native; it returns -1 (less), 0 (equal), or 1 (greater)
// tagged as a small integer. // tagged as a small integer.
__ InvokeBuiltin(native, CALL_JS); __ InvokeBuiltin(native, JUMP_JS);
__ cmp(r0, Operand(0));
__ pop(pc);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment