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 |