Index: src/arm/full-codegen-arm.cc |
diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc |
index 195fc8c5be7f6ae4bf5282ea6479755378ff5d9c..5a4ceec32dda7b4fc5c607870424a19f028874cc 100644 |
--- a/src/arm/full-codegen-arm.cc |
+++ b/src/arm/full-codegen-arm.cc |
@@ -4895,96 +4895,86 @@ FullCodeGenerator::NestedStatement* FullCodeGenerator::TryFinally::Exit( |
static const int32_t kBranchBeforeInterrupt = 0x5a000004; |
-// The back edge bookkeeping code matches the pattern: |
-// |
-// <decrement profiling counter> |
-// 2a 00 00 01 bpl ok |
-// e5 9f c? ?? ldr ip, [pc, <interrupt stub address>] |
-// e1 2f ff 3c blx ip |
-// ok-label |
-// |
-// We patch the code to the following form: |
-// |
-// <decrement profiling counter> |
-// e1 a0 00 00 mov r0, r0 (NOP) |
-// e5 9f c? ?? ldr ip, [pc, <on-stack replacement address>] |
-// e1 2f ff 3c blx ip |
-// ok-label |
void BackEdgeTable::PatchAt(Code* unoptimized_code, |
- Address pc_after, |
+ Address pc, |
+ BackEdgeState target_state, |
Code* replacement_code) { |
static const int kInstrSize = Assembler::kInstrSize; |
- // Turn the jump into nops. |
- CodePatcher patcher(pc_after - 3 * kInstrSize, 1); |
- patcher.masm()->nop(); |
+ Address branch_address = pc - 3 * kInstrSize; |
+ CodePatcher patcher(branch_address, 1); |
+ |
+ switch (target_state) { |
+ case INTERRUPT: |
+ // <decrement profiling counter> |
+ // 2a 00 00 01 bpl ok |
+ // e5 9f c? ?? ldr ip, [pc, <interrupt stub address>] |
+ // e1 2f ff 3c blx ip |
+ // ok-label |
+ patcher.masm()->b(4 * kInstrSize, pl); // Jump offset is 4 instructions. |
+ ASSERT_EQ(kBranchBeforeInterrupt, Memory::int32_at(branch_address)); |
+ break; |
+ case ON_STACK_REPLACEMENT: |
+ case OSR_AFTER_STACK_CHECK: |
+ // <decrement profiling counter> |
+ // e1 a0 00 00 mov r0, r0 (NOP) |
+ // e5 9f c? ?? ldr ip, [pc, <on-stack replacement address>] |
+ // e1 2f ff 3c blx ip |
+ // ok-label |
+ patcher.masm()->nop(); |
+ break; |
+ } |
+ |
+ Address pc_immediate_load_address = pc - 2 * kInstrSize; |
// Replace the call address. |
- uint32_t interrupt_address_offset = Memory::uint16_at(pc_after - |
- 2 * kInstrSize) & 0xfff; |
- Address interrupt_address_pointer = pc_after + interrupt_address_offset; |
+ uint32_t interrupt_address_offset = |
+ Memory::uint16_at(pc_immediate_load_address) & 0xfff; |
+ Address interrupt_address_pointer = pc + interrupt_address_offset; |
Memory::uint32_at(interrupt_address_pointer) = |
reinterpret_cast<uint32_t>(replacement_code->entry()); |
unoptimized_code->GetHeap()->incremental_marking()->RecordCodeTargetPatch( |
- unoptimized_code, pc_after - 2 * kInstrSize, replacement_code); |
+ unoptimized_code, pc_immediate_load_address, replacement_code); |
} |
-void BackEdgeTable::RevertAt(Code* unoptimized_code, |
- Address pc_after, |
- Code* interrupt_code) { |
- static const int kInstrSize = Assembler::kInstrSize; |
- // Restore the original jump. |
- CodePatcher patcher(pc_after - 3 * kInstrSize, 1); |
- patcher.masm()->b(4 * kInstrSize, pl); // ok-label is 4 instructions later. |
- ASSERT_EQ(kBranchBeforeInterrupt, |
- Memory::int32_at(pc_after - 3 * kInstrSize)); |
- // Restore the original call address. |
- uint32_t interrupt_address_offset = Memory::uint16_at(pc_after - |
- 2 * kInstrSize) & 0xfff; |
- Address interrupt_address_pointer = pc_after + interrupt_address_offset; |
- Memory::uint32_at(interrupt_address_pointer) = |
- reinterpret_cast<uint32_t>(interrupt_code->entry()); |
- |
- interrupt_code->GetHeap()->incremental_marking()->RecordCodeTargetPatch( |
- unoptimized_code, pc_after - 2 * kInstrSize, interrupt_code); |
-} |
- |
- |
-#ifdef DEBUG |
BackEdgeTable::BackEdgeState BackEdgeTable::GetBackEdgeState( |
Isolate* isolate, |
Code* unoptimized_code, |
- Address pc_after) { |
+ Address pc) { |
static const int kInstrSize = Assembler::kInstrSize; |
- ASSERT(Memory::int32_at(pc_after - kInstrSize) == kBlxIp); |
+ ASSERT(Memory::int32_at(pc - kInstrSize) == kBlxIp); |
+ Address branch_address = pc - 3 * kInstrSize; |
+ Address pc_immediate_load_address = pc - 2 * kInstrSize; |
uint32_t interrupt_address_offset = |
- Memory::uint16_at(pc_after - 2 * kInstrSize) & 0xfff; |
- Address interrupt_address_pointer = pc_after + interrupt_address_offset; |
+ Memory::uint16_at(pc_immediate_load_address) & 0xfff; |
+ Address interrupt_address_pointer = pc + interrupt_address_offset; |
- if (Assembler::IsNop(Assembler::instr_at(pc_after - 3 * kInstrSize))) { |
- ASSERT(Assembler::IsLdrPcImmediateOffset( |
- Assembler::instr_at(pc_after - 2 * kInstrSize))); |
- Code* osr_builtin = |
- isolate->builtins()->builtin(Builtins::kOnStackReplacement); |
- ASSERT(reinterpret_cast<uint32_t>(osr_builtin->entry()) == |
- Memory::uint32_at(interrupt_address_pointer)); |
- return ON_STACK_REPLACEMENT; |
- } else { |
- // Get the interrupt stub code object to match against from cache. |
- Code* interrupt_builtin = |
- isolate->builtins()->builtin(Builtins::kInterruptCheck); |
+ if (Memory::int32_at(branch_address) == kBranchBeforeInterrupt) { |
+ ASSERT(Memory::uint32_at(interrupt_address_pointer) == |
+ reinterpret_cast<uint32_t>( |
+ isolate->builtins()->InterruptCheck()->entry())); |
ASSERT(Assembler::IsLdrPcImmediateOffset( |
- Assembler::instr_at(pc_after - 2 * kInstrSize))); |
- ASSERT_EQ(kBranchBeforeInterrupt, |
- Memory::int32_at(pc_after - 3 * kInstrSize)); |
- ASSERT(reinterpret_cast<uint32_t>(interrupt_builtin->entry()) == |
- Memory::uint32_at(interrupt_address_pointer)); |
+ Assembler::instr_at(pc_immediate_load_address))); |
return INTERRUPT; |
} |
+ |
+ ASSERT(Assembler::IsNop(Assembler::instr_at(branch_address))); |
+ ASSERT(Assembler::IsLdrPcImmediateOffset( |
+ Assembler::instr_at(pc_immediate_load_address))); |
+ |
+ if (Memory::uint32_at(interrupt_address_pointer) == |
+ reinterpret_cast<uint32_t>( |
+ isolate->builtins()->OnStackReplacement()->entry())) { |
+ return ON_STACK_REPLACEMENT; |
+ } |
+ |
+ ASSERT(Memory::uint32_at(interrupt_address_pointer) == |
+ reinterpret_cast<uint32_t>( |
+ isolate->builtins()->OsrAfterStackCheck()->entry())); |
+ return OSR_AFTER_STACK_CHECK; |
} |
-#endif // DEBUG |
} } // namespace v8::internal |