| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #if V8_TARGET_ARCH_ARM | 7 #if V8_TARGET_ARCH_ARM |
| 8 | 8 |
| 9 #include "src/codegen.h" | 9 #include "src/codegen.h" |
| 10 #include "src/debug.h" | 10 #include "src/debug.h" |
| (...skipping 29 matching lines...) Expand all Loading... |
| 40 // Restore the JS frame exit code. | 40 // Restore the JS frame exit code. |
| 41 void BreakLocationIterator::ClearDebugBreakAtReturn() { | 41 void BreakLocationIterator::ClearDebugBreakAtReturn() { |
| 42 rinfo()->PatchCode(original_rinfo()->pc(), | 42 rinfo()->PatchCode(original_rinfo()->pc(), |
| 43 Assembler::kJSReturnSequenceInstructions); | 43 Assembler::kJSReturnSequenceInstructions); |
| 44 } | 44 } |
| 45 | 45 |
| 46 | 46 |
| 47 // A debug break in the frame exit code is identified by the JS frame exit code | 47 // A debug break in the frame exit code is identified by the JS frame exit code |
| 48 // having been patched with a call instruction. | 48 // having been patched with a call instruction. |
| 49 bool Debug::IsDebugBreakAtReturn(RelocInfo* rinfo) { | 49 bool Debug::IsDebugBreakAtReturn(RelocInfo* rinfo) { |
| 50 ASSERT(RelocInfo::IsJSReturn(rinfo->rmode())); | 50 DCHECK(RelocInfo::IsJSReturn(rinfo->rmode())); |
| 51 return rinfo->IsPatchedReturnSequence(); | 51 return rinfo->IsPatchedReturnSequence(); |
| 52 } | 52 } |
| 53 | 53 |
| 54 | 54 |
| 55 bool BreakLocationIterator::IsDebugBreakAtSlot() { | 55 bool BreakLocationIterator::IsDebugBreakAtSlot() { |
| 56 ASSERT(IsDebugBreakSlot()); | 56 DCHECK(IsDebugBreakSlot()); |
| 57 // Check whether the debug break slot instructions have been patched. | 57 // Check whether the debug break slot instructions have been patched. |
| 58 return rinfo()->IsPatchedDebugBreakSlotSequence(); | 58 return rinfo()->IsPatchedDebugBreakSlotSequence(); |
| 59 } | 59 } |
| 60 | 60 |
| 61 | 61 |
| 62 void BreakLocationIterator::SetDebugBreakAtSlot() { | 62 void BreakLocationIterator::SetDebugBreakAtSlot() { |
| 63 ASSERT(IsDebugBreakSlot()); | 63 DCHECK(IsDebugBreakSlot()); |
| 64 // Patch the code changing the debug break slot code from | 64 // Patch the code changing the debug break slot code from |
| 65 // mov r2, r2 | 65 // mov r2, r2 |
| 66 // mov r2, r2 | 66 // mov r2, r2 |
| 67 // mov r2, r2 | 67 // mov r2, r2 |
| 68 // to a call to the debug break slot code. | 68 // to a call to the debug break slot code. |
| 69 // ldr ip, [pc, #0] | 69 // ldr ip, [pc, #0] |
| 70 // blx ip | 70 // blx ip |
| 71 // <debug break slot code entry point address> | 71 // <debug break slot code entry point address> |
| 72 CodePatcher patcher(rinfo()->pc(), Assembler::kDebugBreakSlotInstructions); | 72 CodePatcher patcher(rinfo()->pc(), Assembler::kDebugBreakSlotInstructions); |
| 73 patcher.masm()->ldr(v8::internal::ip, MemOperand(v8::internal::pc, 0)); | 73 patcher.masm()->ldr(v8::internal::ip, MemOperand(v8::internal::pc, 0)); |
| 74 patcher.masm()->blx(v8::internal::ip); | 74 patcher.masm()->blx(v8::internal::ip); |
| 75 patcher.Emit( | 75 patcher.Emit( |
| 76 debug_info_->GetIsolate()->builtins()->Slot_DebugBreak()->entry()); | 76 debug_info_->GetIsolate()->builtins()->Slot_DebugBreak()->entry()); |
| 77 } | 77 } |
| 78 | 78 |
| 79 | 79 |
| 80 void BreakLocationIterator::ClearDebugBreakAtSlot() { | 80 void BreakLocationIterator::ClearDebugBreakAtSlot() { |
| 81 ASSERT(IsDebugBreakSlot()); | 81 DCHECK(IsDebugBreakSlot()); |
| 82 rinfo()->PatchCode(original_rinfo()->pc(), | 82 rinfo()->PatchCode(original_rinfo()->pc(), |
| 83 Assembler::kDebugBreakSlotInstructions); | 83 Assembler::kDebugBreakSlotInstructions); |
| 84 } | 84 } |
| 85 | 85 |
| 86 | 86 |
| 87 #define __ ACCESS_MASM(masm) | 87 #define __ ACCESS_MASM(masm) |
| 88 | 88 |
| 89 | 89 |
| 90 static void Generate_DebugBreakCallHelper(MacroAssembler* masm, | 90 static void Generate_DebugBreakCallHelper(MacroAssembler* masm, |
| 91 RegList object_regs, | 91 RegList object_regs, |
| 92 RegList non_object_regs) { | 92 RegList non_object_regs) { |
| 93 { | 93 { |
| 94 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); | 94 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); |
| 95 | 95 |
| 96 // Load padding words on stack. | 96 // Load padding words on stack. |
| 97 __ mov(ip, Operand(Smi::FromInt(LiveEdit::kFramePaddingValue))); | 97 __ mov(ip, Operand(Smi::FromInt(LiveEdit::kFramePaddingValue))); |
| 98 for (int i = 0; i < LiveEdit::kFramePaddingInitialSize; i++) { | 98 for (int i = 0; i < LiveEdit::kFramePaddingInitialSize; i++) { |
| 99 __ push(ip); | 99 __ push(ip); |
| 100 } | 100 } |
| 101 __ mov(ip, Operand(Smi::FromInt(LiveEdit::kFramePaddingInitialSize))); | 101 __ mov(ip, Operand(Smi::FromInt(LiveEdit::kFramePaddingInitialSize))); |
| 102 __ push(ip); | 102 __ push(ip); |
| 103 | 103 |
| 104 // Store the registers containing live values on the expression stack to | 104 // Store the registers containing live values on the expression stack to |
| 105 // make sure that these are correctly updated during GC. Non object values | 105 // make sure that these are correctly updated during GC. Non object values |
| 106 // are stored as a smi causing it to be untouched by GC. | 106 // are stored as a smi causing it to be untouched by GC. |
| 107 ASSERT((object_regs & ~kJSCallerSaved) == 0); | 107 DCHECK((object_regs & ~kJSCallerSaved) == 0); |
| 108 ASSERT((non_object_regs & ~kJSCallerSaved) == 0); | 108 DCHECK((non_object_regs & ~kJSCallerSaved) == 0); |
| 109 ASSERT((object_regs & non_object_regs) == 0); | 109 DCHECK((object_regs & non_object_regs) == 0); |
| 110 if ((object_regs | non_object_regs) != 0) { | 110 if ((object_regs | non_object_regs) != 0) { |
| 111 for (int i = 0; i < kNumJSCallerSaved; i++) { | 111 for (int i = 0; i < kNumJSCallerSaved; i++) { |
| 112 int r = JSCallerSavedCode(i); | 112 int r = JSCallerSavedCode(i); |
| 113 Register reg = { r }; | 113 Register reg = { r }; |
| 114 if ((non_object_regs & (1 << r)) != 0) { | 114 if ((non_object_regs & (1 << r)) != 0) { |
| 115 if (FLAG_debug_code) { | 115 if (FLAG_debug_code) { |
| 116 __ tst(reg, Operand(0xc0000000)); | 116 __ tst(reg, Operand(0xc0000000)); |
| 117 __ Assert(eq, kUnableToEncodeValueAsSmi); | 117 __ Assert(eq, kUnableToEncodeValueAsSmi); |
| 118 } | 118 } |
| 119 __ SmiTag(reg); | 119 __ SmiTag(reg); |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 260 void DebugCodegen::GenerateSlot(MacroAssembler* masm) { | 260 void DebugCodegen::GenerateSlot(MacroAssembler* masm) { |
| 261 // Generate enough nop's to make space for a call instruction. Avoid emitting | 261 // Generate enough nop's to make space for a call instruction. Avoid emitting |
| 262 // the constant pool in the debug break slot code. | 262 // the constant pool in the debug break slot code. |
| 263 Assembler::BlockConstPoolScope block_const_pool(masm); | 263 Assembler::BlockConstPoolScope block_const_pool(masm); |
| 264 Label check_codesize; | 264 Label check_codesize; |
| 265 __ bind(&check_codesize); | 265 __ bind(&check_codesize); |
| 266 __ RecordDebugBreakSlot(); | 266 __ RecordDebugBreakSlot(); |
| 267 for (int i = 0; i < Assembler::kDebugBreakSlotInstructions; i++) { | 267 for (int i = 0; i < Assembler::kDebugBreakSlotInstructions; i++) { |
| 268 __ nop(MacroAssembler::DEBUG_BREAK_NOP); | 268 __ nop(MacroAssembler::DEBUG_BREAK_NOP); |
| 269 } | 269 } |
| 270 ASSERT_EQ(Assembler::kDebugBreakSlotInstructions, | 270 DCHECK_EQ(Assembler::kDebugBreakSlotInstructions, |
| 271 masm->InstructionsGeneratedSince(&check_codesize)); | 271 masm->InstructionsGeneratedSince(&check_codesize)); |
| 272 } | 272 } |
| 273 | 273 |
| 274 | 274 |
| 275 void DebugCodegen::GenerateSlotDebugBreak(MacroAssembler* masm) { | 275 void DebugCodegen::GenerateSlotDebugBreak(MacroAssembler* masm) { |
| 276 // In the places where a debug break slot is inserted no registers can contain | 276 // In the places where a debug break slot is inserted no registers can contain |
| 277 // object pointers. | 277 // object pointers. |
| 278 Generate_DebugBreakCallHelper(masm, 0, 0); | 278 Generate_DebugBreakCallHelper(masm, 0, 0); |
| 279 } | 279 } |
| 280 | 280 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 315 } | 315 } |
| 316 | 316 |
| 317 | 317 |
| 318 const bool LiveEdit::kFrameDropperSupported = true; | 318 const bool LiveEdit::kFrameDropperSupported = true; |
| 319 | 319 |
| 320 #undef __ | 320 #undef __ |
| 321 | 321 |
| 322 } } // namespace v8::internal | 322 } } // namespace v8::internal |
| 323 | 323 |
| 324 #endif // V8_TARGET_ARCH_ARM | 324 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |