| Index: src/arm/deoptimizer-arm.cc
|
| diff --git a/src/arm/deoptimizer-arm.cc b/src/arm/deoptimizer-arm.cc
|
| index caec55affb5d7a60874f368e055d003dbc3e1c4d..9af7a8d190706092f6d2e6e49ac1483343d5bb77 100644
|
| --- a/src/arm/deoptimizer-arm.cc
|
| +++ b/src/arm/deoptimizer-arm.cc
|
| @@ -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 with 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());
|
| }
|
|
|
|
|
|
|