Chromium Code Reviews| Index: src/arm/deoptimizer-arm.cc |
| diff --git a/src/arm/deoptimizer-arm.cc b/src/arm/deoptimizer-arm.cc |
| index e05001f3c38fe228bd7ee7e6ff9b926c39a3af20..44f207a64ce4432ffc2dbdc8eea9d954d76b36da 100644 |
| --- a/src/arm/deoptimizer-arm.cc |
| +++ b/src/arm/deoptimizer-arm.cc |
| @@ -124,14 +124,57 @@ void Deoptimizer::DeoptimizeFunction(JSFunction* function) { |
| void Deoptimizer::PatchStackCheckCodeAt(Address pc_after, |
| Code* check_code, |
| Code* replacement_code) { |
| - UNIMPLEMENTED(); |
| + // The call of the stack guard check has the following form: |
| + // e1 5d 00 0c cmp sp, <limit> |
| + // 2a ?? ?? ?? bcs ok |
|
Søren Thygesen Gjesse
2011/02/04 13:54:27
?? ?? ?? -> 00 00 01, the restoring puts in 1 here
Karl Klose
2011/02/04 18:06:49
Done.
|
| + // e5 9f c? ?? ldr ip, [pc, <stack guard address>] |
| + // e1 2f ff 3c blx ip |
| + ASSERT(Memory::uint32_at(pc_after - 4) == 0xe12fff3c); |
|
Søren Thygesen Gjesse
2011/02/04 13:54:27
0xe12fff3c -> al | B24 | B21 | 15*B16 | 15*B12 | 1
Søren Thygesen Gjesse
2011/02/04 13:54:27
4 -> kInstrSize
Karl Klose
2011/02/04 18:06:49
Done.
Karl Klose
2011/02/04 18:06:49
Done.
|
| + ASSERT(Memory::uint8_at(pc_after - 5) == 0xe5); |
|
Søren Thygesen Gjesse
2011/02/04 13:54:27
Use Assembler::IsLdrPcImmediateOffset() to check t
Karl Klose
2011/02/04 18:06:49
Done.
|
| + ASSERT(Memory::uint8_at(pc_after - 6) == 0x9f); |
| + |
| + // 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. |
| + Memory::uint32_at(pc_after - 12) = 0xe1a00000; |
|
Søren Thygesen Gjesse
2011/02/04 13:54:27
I think you should be able to use the code patcher
Karl Klose
2011/02/04 18:06:49
Done.
|
| + |
| + // 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 - 8) & |
| + 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(); |
| + ASSERT(Memory::uint32_at(pc_after - 4) == 0xe12fff3c); |
| + ASSERT(Memory::uint8_at(pc_after - 5) == 0xe5); |
| + ASSERT(Memory::uint8_at(pc_after - 6) == 0x9f); |
| + |
| + // Replace NOP with conditional jump. |
| + Memory::uint32_at(pc_after - 12) = 0x2a000001; |
|
Søren Thygesen Gjesse
2011/02/04 13:54:27
Use CodePatcher if possible, or at least:
0x2a000
Karl Klose
2011/02/04 18:06:49
I used the CodePatcher.
|
| + |
| + // 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 - 8) & |
| + 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()); |
| } |