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 | 5 |
6 | 6 |
7 #include "src/v8.h" | 7 #include "src/v8.h" |
8 | 8 |
9 #if V8_TARGET_ARCH_MIPS64 | 9 #if V8_TARGET_ARCH_MIPS64 |
10 | 10 |
(...skipping 12 matching lines...) Expand all Loading... |
23 // Mips return sequence: | 23 // Mips return sequence: |
24 // mov sp, fp | 24 // mov sp, fp |
25 // lw fp, sp(0) | 25 // lw fp, sp(0) |
26 // lw ra, sp(4) | 26 // lw ra, sp(4) |
27 // addiu sp, sp, 8 | 27 // addiu sp, sp, 8 |
28 // addiu sp, sp, N | 28 // addiu sp, sp, N |
29 // jr ra | 29 // jr ra |
30 // nop (in branch delay slot) | 30 // nop (in branch delay slot) |
31 | 31 |
32 // Make sure this constant matches the number if instructions we emit. | 32 // Make sure this constant matches the number if instructions we emit. |
33 ASSERT(Assembler::kJSReturnSequenceInstructions == 7); | 33 DCHECK(Assembler::kJSReturnSequenceInstructions == 7); |
34 CodePatcher patcher(rinfo()->pc(), Assembler::kJSReturnSequenceInstructions); | 34 CodePatcher patcher(rinfo()->pc(), Assembler::kJSReturnSequenceInstructions); |
35 // li and Call pseudo-instructions emit 6 + 2 instructions. | 35 // li and Call pseudo-instructions emit 6 + 2 instructions. |
36 patcher.masm()->li(v8::internal::t9, Operand(reinterpret_cast<int64_t>( | 36 patcher.masm()->li(v8::internal::t9, Operand(reinterpret_cast<int64_t>( |
37 debug_info_->GetIsolate()->builtins()->Return_DebugBreak()->entry())), | 37 debug_info_->GetIsolate()->builtins()->Return_DebugBreak()->entry())), |
38 ADDRESS_LOAD); | 38 ADDRESS_LOAD); |
39 patcher.masm()->Call(v8::internal::t9); | 39 patcher.masm()->Call(v8::internal::t9); |
40 // Place nop to match return sequence size. | 40 // Place nop to match return sequence size. |
41 patcher.masm()->nop(); | 41 patcher.masm()->nop(); |
42 // TODO(mips): Open issue about using breakpoint instruction instead of nops. | 42 // TODO(mips): Open issue about using breakpoint instruction instead of nops. |
43 // patcher.masm()->bkpt(0); | 43 // patcher.masm()->bkpt(0); |
44 } | 44 } |
45 | 45 |
46 | 46 |
47 // Restore the JS frame exit code. | 47 // Restore the JS frame exit code. |
48 void BreakLocationIterator::ClearDebugBreakAtReturn() { | 48 void BreakLocationIterator::ClearDebugBreakAtReturn() { |
49 rinfo()->PatchCode(original_rinfo()->pc(), | 49 rinfo()->PatchCode(original_rinfo()->pc(), |
50 Assembler::kJSReturnSequenceInstructions); | 50 Assembler::kJSReturnSequenceInstructions); |
51 } | 51 } |
52 | 52 |
53 | 53 |
54 // A debug break in the exit code is identified by the JS frame exit code | 54 // A debug break in the exit code is identified by the JS frame exit code |
55 // having been patched with li/call psuedo-instrunction (liu/ori/jalr). | 55 // having been patched with li/call psuedo-instrunction (liu/ori/jalr). |
56 bool Debug::IsDebugBreakAtReturn(RelocInfo* rinfo) { | 56 bool Debug::IsDebugBreakAtReturn(RelocInfo* rinfo) { |
57 ASSERT(RelocInfo::IsJSReturn(rinfo->rmode())); | 57 DCHECK(RelocInfo::IsJSReturn(rinfo->rmode())); |
58 return rinfo->IsPatchedReturnSequence(); | 58 return rinfo->IsPatchedReturnSequence(); |
59 } | 59 } |
60 | 60 |
61 | 61 |
62 bool BreakLocationIterator::IsDebugBreakAtSlot() { | 62 bool BreakLocationIterator::IsDebugBreakAtSlot() { |
63 ASSERT(IsDebugBreakSlot()); | 63 DCHECK(IsDebugBreakSlot()); |
64 // Check whether the debug break slot instructions have been patched. | 64 // Check whether the debug break slot instructions have been patched. |
65 return rinfo()->IsPatchedDebugBreakSlotSequence(); | 65 return rinfo()->IsPatchedDebugBreakSlotSequence(); |
66 } | 66 } |
67 | 67 |
68 | 68 |
69 void BreakLocationIterator::SetDebugBreakAtSlot() { | 69 void BreakLocationIterator::SetDebugBreakAtSlot() { |
70 ASSERT(IsDebugBreakSlot()); | 70 DCHECK(IsDebugBreakSlot()); |
71 // Patch the code changing the debug break slot code from: | 71 // Patch the code changing the debug break slot code from: |
72 // nop(DEBUG_BREAK_NOP) - nop(1) is sll(zero_reg, zero_reg, 1) | 72 // nop(DEBUG_BREAK_NOP) - nop(1) is sll(zero_reg, zero_reg, 1) |
73 // nop(DEBUG_BREAK_NOP) | 73 // nop(DEBUG_BREAK_NOP) |
74 // nop(DEBUG_BREAK_NOP) | 74 // nop(DEBUG_BREAK_NOP) |
75 // nop(DEBUG_BREAK_NOP) | 75 // nop(DEBUG_BREAK_NOP) |
76 // nop(DEBUG_BREAK_NOP) | 76 // nop(DEBUG_BREAK_NOP) |
77 // nop(DEBUG_BREAK_NOP) | 77 // nop(DEBUG_BREAK_NOP) |
78 // to a call to the debug break slot code. | 78 // to a call to the debug break slot code. |
79 // li t9, address (4-instruction sequence on mips64) | 79 // li t9, address (4-instruction sequence on mips64) |
80 // call t9 (jalr t9 / nop instruction pair) | 80 // call t9 (jalr t9 / nop instruction pair) |
81 CodePatcher patcher(rinfo()->pc(), Assembler::kDebugBreakSlotInstructions); | 81 CodePatcher patcher(rinfo()->pc(), Assembler::kDebugBreakSlotInstructions); |
82 patcher.masm()->li(v8::internal::t9, | 82 patcher.masm()->li(v8::internal::t9, |
83 Operand(reinterpret_cast<int64_t>( | 83 Operand(reinterpret_cast<int64_t>( |
84 debug_info_->GetIsolate()->builtins()->Slot_DebugBreak()->entry())), | 84 debug_info_->GetIsolate()->builtins()->Slot_DebugBreak()->entry())), |
85 ADDRESS_LOAD); | 85 ADDRESS_LOAD); |
86 patcher.masm()->Call(v8::internal::t9); | 86 patcher.masm()->Call(v8::internal::t9); |
87 } | 87 } |
88 | 88 |
89 | 89 |
90 void BreakLocationIterator::ClearDebugBreakAtSlot() { | 90 void BreakLocationIterator::ClearDebugBreakAtSlot() { |
91 ASSERT(IsDebugBreakSlot()); | 91 DCHECK(IsDebugBreakSlot()); |
92 rinfo()->PatchCode(original_rinfo()->pc(), | 92 rinfo()->PatchCode(original_rinfo()->pc(), |
93 Assembler::kDebugBreakSlotInstructions); | 93 Assembler::kDebugBreakSlotInstructions); |
94 } | 94 } |
95 | 95 |
96 | 96 |
97 #define __ ACCESS_MASM(masm) | 97 #define __ ACCESS_MASM(masm) |
98 | 98 |
99 | 99 |
100 | 100 |
101 static void Generate_DebugBreakCallHelper(MacroAssembler* masm, | 101 static void Generate_DebugBreakCallHelper(MacroAssembler* masm, |
(...skipping 12 matching lines...) Expand all Loading... |
114 __ li(at, Operand(Smi::FromInt(LiveEdit::kFramePaddingInitialSize))); | 114 __ li(at, Operand(Smi::FromInt(LiveEdit::kFramePaddingInitialSize))); |
115 __ push(at); | 115 __ push(at); |
116 | 116 |
117 | 117 |
118 // TODO(plind): This needs to be revised to store pairs of smi's per | 118 // TODO(plind): This needs to be revised to store pairs of smi's per |
119 // the other 64-bit arch's. | 119 // the other 64-bit arch's. |
120 | 120 |
121 // Store the registers containing live values on the expression stack to | 121 // Store the registers containing live values on the expression stack to |
122 // make sure that these are correctly updated during GC. Non object values | 122 // make sure that these are correctly updated during GC. Non object values |
123 // are stored as a smi causing it to be untouched by GC. | 123 // are stored as a smi causing it to be untouched by GC. |
124 ASSERT((object_regs & ~kJSCallerSaved) == 0); | 124 DCHECK((object_regs & ~kJSCallerSaved) == 0); |
125 ASSERT((non_object_regs & ~kJSCallerSaved) == 0); | 125 DCHECK((non_object_regs & ~kJSCallerSaved) == 0); |
126 ASSERT((object_regs & non_object_regs) == 0); | 126 DCHECK((object_regs & non_object_regs) == 0); |
127 for (int i = 0; i < kNumJSCallerSaved; i++) { | 127 for (int i = 0; i < kNumJSCallerSaved; i++) { |
128 int r = JSCallerSavedCode(i); | 128 int r = JSCallerSavedCode(i); |
129 Register reg = { r }; | 129 Register reg = { r }; |
130 if ((object_regs & (1 << r)) != 0) { | 130 if ((object_regs & (1 << r)) != 0) { |
131 __ push(reg); | 131 __ push(reg); |
132 } | 132 } |
133 if ((non_object_regs & (1 << r)) != 0) { | 133 if ((non_object_regs & (1 << r)) != 0) { |
134 __ PushRegisterAsTwoSmis(reg); | 134 __ PushRegisterAsTwoSmis(reg); |
135 } | 135 } |
136 } | 136 } |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
272 void DebugCodegen::GenerateSlot(MacroAssembler* masm) { | 272 void DebugCodegen::GenerateSlot(MacroAssembler* masm) { |
273 // Generate enough nop's to make space for a call instruction. Avoid emitting | 273 // Generate enough nop's to make space for a call instruction. Avoid emitting |
274 // the trampoline pool in the debug break slot code. | 274 // the trampoline pool in the debug break slot code. |
275 Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm); | 275 Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm); |
276 Label check_codesize; | 276 Label check_codesize; |
277 __ bind(&check_codesize); | 277 __ bind(&check_codesize); |
278 __ RecordDebugBreakSlot(); | 278 __ RecordDebugBreakSlot(); |
279 for (int i = 0; i < Assembler::kDebugBreakSlotInstructions; i++) { | 279 for (int i = 0; i < Assembler::kDebugBreakSlotInstructions; i++) { |
280 __ nop(MacroAssembler::DEBUG_BREAK_NOP); | 280 __ nop(MacroAssembler::DEBUG_BREAK_NOP); |
281 } | 281 } |
282 ASSERT_EQ(Assembler::kDebugBreakSlotInstructions, | 282 DCHECK_EQ(Assembler::kDebugBreakSlotInstructions, |
283 masm->InstructionsGeneratedSince(&check_codesize)); | 283 masm->InstructionsGeneratedSince(&check_codesize)); |
284 } | 284 } |
285 | 285 |
286 | 286 |
287 void DebugCodegen::GenerateSlotDebugBreak(MacroAssembler* masm) { | 287 void DebugCodegen::GenerateSlotDebugBreak(MacroAssembler* masm) { |
288 // In the places where a debug break slot is inserted no registers can contain | 288 // In the places where a debug break slot is inserted no registers can contain |
289 // object pointers. | 289 // object pointers. |
290 Generate_DebugBreakCallHelper(masm, 0, 0); | 290 Generate_DebugBreakCallHelper(masm, 0, 0); |
291 } | 291 } |
292 | 292 |
(...skipping 28 matching lines...) Expand all Loading... |
321 } | 321 } |
322 | 322 |
323 | 323 |
324 const bool LiveEdit::kFrameDropperSupported = true; | 324 const bool LiveEdit::kFrameDropperSupported = true; |
325 | 325 |
326 #undef __ | 326 #undef __ |
327 | 327 |
328 } } // namespace v8::internal | 328 } } // namespace v8::internal |
329 | 329 |
330 #endif // V8_TARGET_ARCH_MIPS64 | 330 #endif // V8_TARGET_ARCH_MIPS64 |
OLD | NEW |