| Index: src/arm/debug-arm.cc
|
| ===================================================================
|
| --- src/arm/debug-arm.cc (revision 4816)
|
| +++ src/arm/debug-arm.cc (working copy)
|
| @@ -57,7 +57,7 @@
|
| // #endif
|
| // <debug break return code entry point address>
|
| // bktp 0
|
| - CodePatcher patcher(rinfo()->pc(), 4);
|
| + CodePatcher patcher(rinfo()->pc(), Assembler::kJSReturnSequenceInstructions);
|
| #ifdef USE_BLX
|
| patcher.masm()->ldr(v8::internal::ip, MemOperand(v8::internal::pc, 0));
|
| patcher.masm()->blx(v8::internal::ip);
|
| @@ -73,17 +73,59 @@
|
| // Restore the JS frame exit code.
|
| void BreakLocationIterator::ClearDebugBreakAtReturn() {
|
| rinfo()->PatchCode(original_rinfo()->pc(),
|
| - Assembler::kJSReturnSequenceLength);
|
| + Assembler::kJSReturnSequenceInstructions);
|
| }
|
|
|
|
|
| -// A debug break in the exit code is identified by a call.
|
| +// A debug break in the frame exit code is identified by the JS frame exit code
|
| +// having been patched with a call instruction.
|
| bool Debug::IsDebugBreakAtReturn(RelocInfo* rinfo) {
|
| ASSERT(RelocInfo::IsJSReturn(rinfo->rmode()));
|
| return rinfo->IsPatchedReturnSequence();
|
| }
|
|
|
|
|
| +bool BreakLocationIterator::IsDebugBreakAtSlot() {
|
| + ASSERT(IsDebugBreakSlot());
|
| + // Check whether the debug break slot instructions have been patched.
|
| + return rinfo()->IsPatchedDebugBreakSlotSequence();
|
| +}
|
| +
|
| +
|
| +void BreakLocationIterator::SetDebugBreakAtSlot() {
|
| + ASSERT(IsDebugBreakSlot());
|
| + // Patch the code changing the debug break slot code from
|
| + // mov r2, r2
|
| + // mov r2, r2
|
| + // mov r2, r2
|
| + // to a call to the debug break slot code.
|
| + // #if USE_BLX
|
| + // ldr ip, [pc, #0]
|
| + // blx ip
|
| + // #else
|
| + // mov lr, pc
|
| + // ldr pc, [pc, #-4]
|
| + // #endif
|
| + // <debug break slot code entry point address>
|
| + CodePatcher patcher(rinfo()->pc(), Assembler::kDebugBreakSlotInstructions);
|
| +#ifdef USE_BLX
|
| + patcher.masm()->ldr(v8::internal::ip, MemOperand(v8::internal::pc, 0));
|
| + patcher.masm()->blx(v8::internal::ip);
|
| +#else
|
| + patcher.masm()->mov(v8::internal::lr, v8::internal::pc);
|
| + patcher.masm()->ldr(v8::internal::pc, MemOperand(v8::internal::pc, -4));
|
| +#endif
|
| + patcher.Emit(Debug::debug_break_return()->entry());
|
| +}
|
| +
|
| +
|
| +void BreakLocationIterator::ClearDebugBreakAtSlot() {
|
| + ASSERT(IsDebugBreakSlot());
|
| + rinfo()->PatchCode(original_rinfo()->pc(),
|
| + Assembler::kDebugBreakSlotInstructions);
|
| +}
|
| +
|
| +
|
| #define __ ACCESS_MASM(masm)
|
|
|
|
|
| @@ -220,10 +262,31 @@
|
| }
|
|
|
|
|
| +void Debug::GenerateSlot(MacroAssembler* masm) {
|
| + // Generate enough nop's to make space for a call instruction.
|
| + Label check_codesize;
|
| + __ bind(&check_codesize);
|
| + __ RecordDebugBreakSlot();
|
| + for (int i = 0; i < Assembler::kDebugBreakSlotInstructions; i++) {
|
| + __ nop(2);
|
| + }
|
| + ASSERT_EQ(Assembler::kDebugBreakSlotInstructions,
|
| + masm->InstructionsGeneratedSince(&check_codesize));
|
| +}
|
| +
|
| +
|
| +void Debug::GenerateSlotDebugBreak(MacroAssembler* masm) {
|
| + // In the places where a debug break slot is inserted no registers can contain
|
| + // object pointers.
|
| + Generate_DebugBreakCallHelper(masm, 0);
|
| +}
|
| +
|
| +
|
| void Debug::GeneratePlainReturnLiveEdit(MacroAssembler* masm) {
|
| masm->Abort("LiveEdit frame dropping is not supported on arm");
|
| }
|
|
|
| +
|
| void Debug::GenerateFrameDropperLiveEdit(MacroAssembler* masm) {
|
| masm->Abort("LiveEdit frame dropping is not supported on arm");
|
| }
|
|
|