ARM: Implement PatchStackCheckCodeAt and RevertStackCheckCode.

This patch also adds platform independent CPU instruction cache flushing.

BUG=none
TEST=none

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@6759 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent dd68fcc7
......@@ -124,14 +124,62 @@ void Deoptimizer::DeoptimizeFunction(JSFunction* function) {
void Deoptimizer::PatchStackCheckCodeAt(Address pc_after,
Code* check_code,
Code* replacement_code) {
UNIMPLEMENTED();
const int kInstrSize = Assembler::kInstrSize;
// The call of the stack guard check has the following form:
// e1 5d 00 0c cmp sp, <limit>
// 2a 00 00 01 bcs ok
// e5 9f c? ?? ldr ip, [pc, <stack guard address>]
// e1 2f ff 3c blx ip
ASSERT(Memory::int32_at(pc_after - kInstrSize) ==
(al | B24 | B21 | 15*B16 | 15*B12 | 15*B8 | BLX | ip.code()));
ASSERT(Assembler::IsLdrPcImmediateOffset(
Assembler::instr_at(pc_after - 2 * kInstrSize)));
// We patch the code to the following form:
// e1 5d 00 0c cmp sp, <limit>
// e1 a0 00 00 mov r0, r0 (NOP)
// e5 9f c? ?? ldr ip, [pc, <on-stack replacement address>]
// e1 2f ff 3c blx ip
// and overwrite the constant containing the
// address of the stack check stub.
// Replace conditional jump with NOP.
CodePatcher patcher(pc_after - 3 * kInstrSize, 1);
patcher.masm()->nop();
// Replace the stack check address in the constant pool
// with the entry address of the replacement code.
uint32_t stack_check_address_offset = Memory::uint16_at(pc_after -
2 * kInstrSize) & 0xfff;
Address stack_check_address_pointer = pc_after + stack_check_address_offset;
ASSERT(Memory::uint32_at(stack_check_address_pointer) ==
reinterpret_cast<uint32_t>(check_code->entry()));
Memory::uint32_at(stack_check_address_pointer) =
reinterpret_cast<uint32_t>(replacement_code->entry());
}
void Deoptimizer::RevertStackCheckCodeAt(Address pc_after,
Code* check_code,
Code* replacement_code) {
UNIMPLEMENTED();
const int kInstrSize = Assembler::kInstrSize;
ASSERT(Memory::uint32_at(pc_after - kInstrSize) == 0xe12fff3c);
ASSERT(Memory::uint8_at(pc_after - kInstrSize - 1) == 0xe5);
ASSERT(Memory::uint8_at(pc_after - kInstrSize - 2) == 0x9f);
// Replace NOP wi th conditional jump.
CodePatcher patcher(pc_after - 3 * kInstrSize, 1);
patcher.masm()->b(+4, cs);
// Replace the stack check address in the constant pool
// with the entry address of the replacement code.
uint32_t stack_check_address_offset = Memory::uint16_at(pc_after -
2 * kInstrSize) & 0xfff;
Address stack_check_address_pointer = pc_after + stack_check_address_offset;
ASSERT(Memory::uint32_at(stack_check_address_pointer) ==
reinterpret_cast<uint32_t>(replacement_code->entry()));
Memory::uint32_at(stack_check_address_pointer) =
reinterpret_cast<uint32_t>(check_code->entry());
}
......
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