| 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 |