Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(172)

Side by Side Diff: src/ppc/debug-ppc.cc

Issue 1238503003: PPC: Debugger: use debug break slots to break at function exit. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/ppc/assembler-ppc-inl.h ('k') | src/ppc/full-codegen-ppc.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 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_PPC 7 #if V8_TARGET_ARCH_PPC
8 8
9 #include "src/codegen.h" 9 #include "src/codegen.h"
10 #include "src/debug.h" 10 #include "src/debug.h"
11 11
12 namespace v8 { 12 namespace v8 {
13 namespace internal { 13 namespace internal {
14 14
15 void BreakLocation::SetDebugBreakAtReturn() { 15 #define __ ACCESS_MASM(masm)
16 // Patch the code changing the return from JS function sequence from 16
17 // 17
18 // LeaveFrame 18 void EmitDebugBreakSlot(MacroAssembler* masm) {
19 // blr 19 Label check_size;
20 // 20 __ bind(&check_size);
21 // to a call to the debug break return code. 21 for (int i = 0; i < Assembler::kDebugBreakSlotInstructions; i++) {
22 // this uses a FIXED_SEQUENCE to load an address constant 22 __ nop(MacroAssembler::DEBUG_BREAK_NOP);
23 // 23 }
24 // mov r0, <address> 24 DCHECK_EQ(Assembler::kDebugBreakSlotInstructions,
25 // mtlr r0 25 masm->InstructionsGeneratedSince(&check_size));
26 // blrl
27 // bkpt
28 //
29 CodePatcher patcher(pc(), Assembler::kJSReturnSequenceInstructions);
30 Assembler::BlockTrampolinePoolScope block_trampoline_pool(patcher.masm());
31 patcher.masm()->mov(
32 v8::internal::r0,
33 Operand(reinterpret_cast<intptr_t>(debug_info_->GetIsolate()
34 ->builtins()
35 ->Return_DebugBreak()
36 ->entry())));
37 patcher.masm()->mtctr(v8::internal::r0);
38 patcher.masm()->bctrl();
39 patcher.masm()->bkpt(0);
40 } 26 }
41 27
42 28
43 void BreakLocation::SetDebugBreakAtSlot() { 29 void DebugCodegen::GenerateSlot(MacroAssembler* masm, RelocInfo::Mode mode,
44 DCHECK(IsDebugBreakSlot()); 30 int call_argc) {
31 // Generate enough nop's to make space for a call instruction. Avoid emitting
32 // the trampoline pool in the debug break slot code.
33 Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm);
34 masm->RecordDebugBreakSlot(mode, call_argc);
35 EmitDebugBreakSlot(masm);
36 }
37
38
39 void DebugCodegen::ClearDebugBreakSlot(Address pc) {
40 CodePatcher patcher(pc, Assembler::kDebugBreakSlotInstructions);
41 EmitDebugBreakSlot(patcher.masm());
42 }
43
44
45 void DebugCodegen::PatchDebugBreakSlot(Address pc, Handle<Code> code) {
46 DCHECK_EQ(Code::BUILTIN, code->kind());
47 CodePatcher patcher(pc, Assembler::kDebugBreakSlotInstructions);
45 // Patch the code changing the debug break slot code from 48 // Patch the code changing the debug break slot code from
46 // 49 //
47 // ori r3, r3, 0 50 // ori r3, r3, 0
48 // ori r3, r3, 0 51 // ori r3, r3, 0
49 // ori r3, r3, 0 52 // ori r3, r3, 0
50 // ori r3, r3, 0 53 // ori r3, r3, 0
51 // ori r3, r3, 0 54 // ori r3, r3, 0
52 // 55 //
53 // to a call to the debug break code, using a FIXED_SEQUENCE. 56 // to a call to the debug break code, using a FIXED_SEQUENCE.
54 // 57 //
55 // mov r0, <address> 58 // mov r0, <address>
56 // mtlr r0 59 // mtlr r0
57 // blrl 60 // blrl
58 // 61 //
59 CodePatcher patcher(pc(), Assembler::kDebugBreakSlotInstructions);
60 Assembler::BlockTrampolinePoolScope block_trampoline_pool(patcher.masm()); 62 Assembler::BlockTrampolinePoolScope block_trampoline_pool(patcher.masm());
61 patcher.masm()->mov( 63 patcher.masm()->mov(v8::internal::r0,
62 v8::internal::r0, 64 Operand(reinterpret_cast<intptr_t>(code->entry())));
63 Operand(reinterpret_cast<intptr_t>(
64 debug_info_->GetIsolate()->builtins()->Slot_DebugBreak()->entry())));
65 patcher.masm()->mtctr(v8::internal::r0); 65 patcher.masm()->mtctr(v8::internal::r0);
66 patcher.masm()->bctrl(); 66 patcher.masm()->bctrl();
67 } 67 }
68 68
69 69
70 #define __ ACCESS_MASM(masm) 70 void DebugCodegen::GenerateDebugBreakStub(MacroAssembler* masm,
71 71 DebugBreakCallHelperMode mode) {
72 72 __ RecordComment("Debug break");
73 static void Generate_DebugBreakCallHelper(MacroAssembler* masm,
74 RegList object_regs) {
75 { 73 {
76 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); 74 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
77 75
78 // Load padding words on stack. 76 // Load padding words on stack.
79 __ LoadSmiLiteral(ip, Smi::FromInt(LiveEdit::kFramePaddingValue)); 77 __ LoadSmiLiteral(ip, Smi::FromInt(LiveEdit::kFramePaddingValue));
80 for (int i = 0; i < LiveEdit::kFramePaddingInitialSize; i++) { 78 for (int i = 0; i < LiveEdit::kFramePaddingInitialSize; i++) {
81 __ push(ip); 79 __ push(ip);
82 } 80 }
83 __ LoadSmiLiteral(ip, Smi::FromInt(LiveEdit::kFramePaddingInitialSize)); 81 __ LoadSmiLiteral(ip, Smi::FromInt(LiveEdit::kFramePaddingInitialSize));
84 __ push(ip); 82 __ push(ip);
85 83
86 // Store the registers containing live values on the expression stack to 84 if (mode == SAVE_RESULT_REGISTER) __ push(r3);
87 // make sure that these are correctly updated during GC. Non object values
88 // are stored as a smi causing it to be untouched by GC.
89 DCHECK((object_regs & ~kJSCallerSaved) == 0);
90 if (object_regs != 0) {
91 __ MultiPush(object_regs);
92 }
93 85
94 #ifdef DEBUG
95 __ RecordComment("// Calling from debug break to runtime - come in - over");
96 #endif
97 __ mov(r3, Operand::Zero()); // no arguments 86 __ mov(r3, Operand::Zero()); // no arguments
98 __ mov(r4, Operand(ExternalReference::debug_break(masm->isolate()))); 87 __ mov(r4, Operand(ExternalReference::debug_break(masm->isolate())));
99 88
100 CEntryStub ceb(masm->isolate(), 1); 89 CEntryStub ceb(masm->isolate(), 1);
101 __ CallStub(&ceb); 90 __ CallStub(&ceb);
102 91
103 // Restore the register values from the expression stack. 92 if (FLAG_debug_code) {
104 if (object_regs != 0) { 93 for (int i = 0; i < kNumJSCallerSaved; i++) {
105 __ MultiPop(object_regs); 94 Register reg = {JSCallerSavedCode(i)};
106 }
107
108 for (int i = 0; i < kNumJSCallerSaved; i++) {
109 int r = JSCallerSavedCode(i);
110 Register reg = {r};
111 if (FLAG_debug_code && ((object_regs & (1 << r)) == 0)) {
112 __ mov(reg, Operand(kDebugZapValue)); 95 __ mov(reg, Operand(kDebugZapValue));
113 } 96 }
114 } 97 }
115 98
99 if (mode == SAVE_RESULT_REGISTER) __ pop(r3);
100
116 // Don't bother removing padding bytes pushed on the stack 101 // Don't bother removing padding bytes pushed on the stack
117 // as the frame is going to be restored right away. 102 // as the frame is going to be restored right away.
118 103
119 // Leave the internal frame. 104 // Leave the internal frame.
120 } 105 }
121 106
122 // Now that the break point has been handled, resume normal execution by 107 // Now that the break point has been handled, resume normal execution by
123 // jumping to the target address intended by the caller and that was 108 // jumping to the target address intended by the caller and that was
124 // overwritten by the address of DebugBreakXXX. 109 // overwritten by the address of DebugBreakXXX.
125 ExternalReference after_break_target = 110 ExternalReference after_break_target =
126 ExternalReference::debug_after_break_target_address(masm->isolate()); 111 ExternalReference::debug_after_break_target_address(masm->isolate());
127 __ mov(ip, Operand(after_break_target)); 112 __ mov(ip, Operand(after_break_target));
128 __ LoadP(ip, MemOperand(ip)); 113 __ LoadP(ip, MemOperand(ip));
129 __ JumpToJSEntry(ip); 114 __ JumpToJSEntry(ip);
130 } 115 }
131 116
132 117
133 void DebugCodegen::GenerateReturnDebugBreak(MacroAssembler* masm) {
134 // In places other than IC call sites it is expected that r3 is TOS which
135 // is an object - this is not generally the case so this should be used with
136 // care.
137 Generate_DebugBreakCallHelper(masm, r3.bit());
138 }
139
140
141 void DebugCodegen::GenerateSlot(MacroAssembler* masm,
142 DebugCodegen::SlotLocation location,
143 int call_argc) {
144 // Generate enough nop's to make space for a call instruction. Avoid emitting
145 // the trampoline pool in the debug break slot code.
146 Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm);
147 Label check_codesize;
148 __ bind(&check_codesize);
149 RecordRelocInfo(masm, location, call_argc);
150 for (int i = 0; i < Assembler::kDebugBreakSlotInstructions; i++) {
151 __ nop(MacroAssembler::DEBUG_BREAK_NOP);
152 }
153 DCHECK_EQ(Assembler::kDebugBreakSlotInstructions,
154 masm->InstructionsGeneratedSince(&check_codesize));
155 }
156
157
158 void DebugCodegen::GenerateSlotDebugBreak(MacroAssembler* masm) {
159 // In the places where a debug break slot is inserted no registers can contain
160 // object pointers.
161 Generate_DebugBreakCallHelper(masm, 0);
162 }
163
164
165 void DebugCodegen::GeneratePlainReturnLiveEdit(MacroAssembler* masm) { 118 void DebugCodegen::GeneratePlainReturnLiveEdit(MacroAssembler* masm) {
166 __ Ret(); 119 __ Ret();
167 } 120 }
168 121
169 122
170 void DebugCodegen::GenerateFrameDropperLiveEdit(MacroAssembler* masm) { 123 void DebugCodegen::GenerateFrameDropperLiveEdit(MacroAssembler* masm) {
171 ExternalReference restarter_frame_function_slot = 124 ExternalReference restarter_frame_function_slot =
172 ExternalReference::debug_restarter_frame_function_pointer_address( 125 ExternalReference::debug_restarter_frame_function_pointer_address(
173 masm->isolate()); 126 masm->isolate());
174 __ mov(ip, Operand(restarter_frame_function_slot)); 127 __ mov(ip, Operand(restarter_frame_function_slot));
(...skipping 20 matching lines...) Expand all
195 } 148 }
196 149
197 150
198 const bool LiveEdit::kFrameDropperSupported = true; 151 const bool LiveEdit::kFrameDropperSupported = true;
199 152
200 #undef __ 153 #undef __
201 } // namespace internal 154 } // namespace internal
202 } // namespace v8 155 } // namespace v8
203 156
204 #endif // V8_TARGET_ARCH_PPC 157 #endif // V8_TARGET_ARCH_PPC
OLDNEW
« no previous file with comments | « src/ppc/assembler-ppc-inl.h ('k') | src/ppc/full-codegen-ppc.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698