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

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

Issue 1222093007: Debugger: use debug break slot to break on call. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: rebased and addressed comments 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/arm64/assembler-arm64.h ('k') | src/arm64/full-codegen-arm64.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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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_ARM64 7 #if V8_TARGET_ARCH_ARM64
8 8
9 #include "src/codegen.h" 9 #include "src/codegen.h"
10 #include "src/debug.h" 10 #include "src/debug.h"
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
87 // code. By using blr, event hough control will not return after the branch, 87 // code. By using blr, event hough control will not return after the branch,
88 // this call site will be registered in the frame (lr being saved as the pc 88 // this call site will be registered in the frame (lr being saved as the pc
89 // of the next instruction to execute for this frame). The debugger can now 89 // of the next instruction to execute for this frame). The debugger can now
90 // iterate on the frames to find call to debug break slot code. 90 // iterate on the frames to find call to debug break slot code.
91 patcher.blr(ip0); 91 patcher.blr(ip0);
92 patcher.dc64(reinterpret_cast<int64_t>(entry)); 92 patcher.dc64(reinterpret_cast<int64_t>(entry));
93 } 93 }
94 94
95 95
96 static void Generate_DebugBreakCallHelper(MacroAssembler* masm, 96 static void Generate_DebugBreakCallHelper(MacroAssembler* masm,
97 RegList object_regs, 97 RegList object_regs) {
98 RegList non_object_regs, 98 Register scratch = x10;
99 Register scratch) {
100 { 99 {
101 FrameScope scope(masm, StackFrame::INTERNAL); 100 FrameScope scope(masm, StackFrame::INTERNAL);
102 101
103 // Load padding words on stack. 102 // Load padding words on stack.
104 __ Mov(scratch, Smi::FromInt(LiveEdit::kFramePaddingValue)); 103 __ Mov(scratch, Smi::FromInt(LiveEdit::kFramePaddingValue));
105 __ PushMultipleTimes(scratch, LiveEdit::kFramePaddingInitialSize); 104 __ PushMultipleTimes(scratch, LiveEdit::kFramePaddingInitialSize);
106 __ Mov(scratch, Smi::FromInt(LiveEdit::kFramePaddingInitialSize)); 105 __ Mov(scratch, Smi::FromInt(LiveEdit::kFramePaddingInitialSize));
107 __ Push(scratch); 106 __ Push(scratch);
108 107
109 // Any live values (object_regs and non_object_regs) in caller-saved 108 // Any live values (object_regs and non_object_regs) in caller-saved
110 // registers (or lr) need to be stored on the stack so that their values are 109 // registers (or lr) need to be stored on the stack so that their values are
111 // safely preserved for a call into C code. 110 // safely preserved for a call into C code.
112 // 111 //
113 // Also: 112 // Also:
114 // * object_regs may be modified during the C code by the garbage 113 // * object_regs may be modified during the C code by the garbage
115 // collector. Every object register must be a valid tagged pointer or 114 // collector. Every object register must be a valid tagged pointer or
116 // SMI. 115 // SMI.
117 // 116 //
118 // * non_object_regs will be converted to SMIs so that the garbage 117 // * non_object_regs will be converted to SMIs so that the garbage
119 // collector doesn't try to interpret them as pointers. 118 // collector doesn't try to interpret them as pointers.
120 // 119 //
121 // TODO(jbramley): Why can't this handle callee-saved registers? 120 // TODO(jbramley): Why can't this handle callee-saved registers?
122 DCHECK((~kCallerSaved.list() & object_regs) == 0); 121 DCHECK((~kCallerSaved.list() & object_regs) == 0);
123 DCHECK((~kCallerSaved.list() & non_object_regs) == 0);
124 DCHECK((object_regs & non_object_regs) == 0);
125 DCHECK((scratch.Bit() & object_regs) == 0); 122 DCHECK((scratch.Bit() & object_regs) == 0);
126 DCHECK((scratch.Bit() & non_object_regs) == 0); 123 DCHECK((masm->TmpList()->list() & object_regs) == 0);
127 DCHECK((masm->TmpList()->list() & (object_regs | non_object_regs)) == 0);
128 STATIC_ASSERT(kSmiValueSize == 32); 124 STATIC_ASSERT(kSmiValueSize == 32);
129 125
130 CPURegList non_object_list =
131 CPURegList(CPURegister::kRegister, kXRegSizeInBits, non_object_regs);
132 while (!non_object_list.IsEmpty()) {
133 // Store each non-object register as two SMIs.
134 Register reg = Register(non_object_list.PopLowestIndex());
135 __ Lsr(scratch, reg, 32);
136 __ SmiTagAndPush(scratch, reg);
137
138 // Stack:
139 // jssp[12]: reg[63:32]
140 // jssp[8]: 0x00000000 (SMI tag & padding)
141 // jssp[4]: reg[31:0]
142 // jssp[0]: 0x00000000 (SMI tag & padding)
143 STATIC_ASSERT(kSmiTag == 0);
144 STATIC_ASSERT(static_cast<unsigned>(kSmiShift) == kWRegSizeInBits);
145 }
146
147 if (object_regs != 0) { 126 if (object_regs != 0) {
148 __ PushXRegList(object_regs); 127 __ PushXRegList(object_regs);
149 } 128 }
150 129
151 #ifdef DEBUG 130 #ifdef DEBUG
152 __ RecordComment("// Calling from debug break to runtime - come in - over"); 131 __ RecordComment("// Calling from debug break to runtime - come in - over");
153 #endif 132 #endif
154 __ Mov(x0, 0); // No arguments. 133 __ Mov(x0, 0); // No arguments.
155 __ Mov(x1, ExternalReference::debug_break(masm->isolate())); 134 __ Mov(x1, ExternalReference::debug_break(masm->isolate()));
156 135
157 CEntryStub stub(masm->isolate(), 1); 136 CEntryStub stub(masm->isolate(), 1);
158 __ CallStub(&stub); 137 __ CallStub(&stub);
159 138
160 // Restore the register values from the expression stack. 139 // Restore the register values from the expression stack.
161 if (object_regs != 0) { 140 if (object_regs != 0) {
162 __ PopXRegList(object_regs); 141 __ PopXRegList(object_regs);
163 } 142 }
164 143
165 non_object_list =
166 CPURegList(CPURegister::kRegister, kXRegSizeInBits, non_object_regs);
167 while (!non_object_list.IsEmpty()) {
168 // Load each non-object register from two SMIs.
169 // Stack:
170 // jssp[12]: reg[63:32]
171 // jssp[8]: 0x00000000 (SMI tag & padding)
172 // jssp[4]: reg[31:0]
173 // jssp[0]: 0x00000000 (SMI tag & padding)
174 Register reg = Register(non_object_list.PopHighestIndex());
175 __ Pop(scratch, reg);
176 __ Bfxil(reg, scratch, 32, 32);
177 }
178
179 // Don't bother removing padding bytes pushed on the stack 144 // Don't bother removing padding bytes pushed on the stack
180 // as the frame is going to be restored right away. 145 // as the frame is going to be restored right away.
181 146
182 // Leave the internal frame. 147 // Leave the internal frame.
183 } 148 }
184 149
185 // Now that the break point has been handled, resume normal execution by 150 // Now that the break point has been handled, resume normal execution by
186 // jumping to the target address intended by the caller and that was 151 // jumping to the target address intended by the caller and that was
187 // overwritten by the address of DebugBreakXXX. 152 // overwritten by the address of DebugBreakXXX.
188 ExternalReference after_break_target = 153 ExternalReference after_break_target =
189 ExternalReference::debug_after_break_target_address(masm->isolate()); 154 ExternalReference::debug_after_break_target_address(masm->isolate());
190 __ Mov(scratch, after_break_target); 155 __ Mov(scratch, after_break_target);
191 __ Ldr(scratch, MemOperand(scratch)); 156 __ Ldr(scratch, MemOperand(scratch));
192 __ Br(scratch); 157 __ Br(scratch);
193 } 158 }
194 159
195 160
196 void DebugCodegen::GenerateCallICStubDebugBreak(MacroAssembler* masm) {
197 // Register state for CallICStub
198 // ----------- S t a t e -------------
199 // -- x1 : function
200 // -- x3 : slot in feedback array
201 // -----------------------------------
202 Generate_DebugBreakCallHelper(masm, x1.Bit() | x3.Bit(), 0, x10);
203 }
204
205
206 void DebugCodegen::GenerateReturnDebugBreak(MacroAssembler* masm) { 161 void DebugCodegen::GenerateReturnDebugBreak(MacroAssembler* masm) {
207 // In places other than IC call sites it is expected that r0 is TOS which 162 // In places other than IC call sites it is expected that r0 is TOS which
208 // is an object - this is not generally the case so this should be used with 163 // is an object - this is not generally the case so this should be used with
209 // care. 164 // care.
210 Generate_DebugBreakCallHelper(masm, x0.Bit(), 0, x10); 165 Generate_DebugBreakCallHelper(masm, x0.Bit());
211 } 166 }
212 167
213 168
214 void DebugCodegen::GenerateCallFunctionStubDebugBreak(MacroAssembler* masm) {
215 // Register state for CallFunctionStub (from code-stubs-arm64.cc).
216 // ----------- S t a t e -------------
217 // -- x1 : function
218 // -----------------------------------
219 Generate_DebugBreakCallHelper(masm, x1.Bit(), 0, x10);
220 }
221
222
223 void DebugCodegen::GenerateCallConstructStubDebugBreak(MacroAssembler* masm) {
224 // Calling convention for CallConstructStub (from code-stubs-arm64.cc).
225 // ----------- S t a t e -------------
226 // -- x0 : number of arguments (not smi)
227 // -- x1 : constructor function
228 // -----------------------------------
229 Generate_DebugBreakCallHelper(masm, x1.Bit(), x0.Bit(), x10);
230 }
231
232
233 void DebugCodegen::GenerateCallConstructStubRecordDebugBreak(
234 MacroAssembler* masm) {
235 // Calling convention for CallConstructStub (from code-stubs-arm64.cc).
236 // ----------- S t a t e -------------
237 // -- x0 : number of arguments (not smi)
238 // -- x1 : constructor function
239 // -- x2 : feedback array
240 // -- x3 : feedback slot (smi)
241 // -----------------------------------
242 Generate_DebugBreakCallHelper(
243 masm, x1.Bit() | x2.Bit() | x3.Bit(), x0.Bit(), x10);
244 }
245
246
247 void DebugCodegen::GenerateSlot(MacroAssembler* masm) { 169 void DebugCodegen::GenerateSlot(MacroAssembler* masm) {
248 // Generate enough nop's to make space for a call instruction. Avoid emitting 170 // Generate enough nop's to make space for a call instruction. Avoid emitting
249 // the constant pool in the debug break slot code. 171 // the constant pool in the debug break slot code.
250 InstructionAccurateScope scope(masm, Assembler::kDebugBreakSlotInstructions); 172 InstructionAccurateScope scope(masm, Assembler::kDebugBreakSlotInstructions);
251 173
252 __ RecordDebugBreakSlot();
253 for (int i = 0; i < Assembler::kDebugBreakSlotInstructions; i++) { 174 for (int i = 0; i < Assembler::kDebugBreakSlotInstructions; i++) {
254 __ nop(Assembler::DEBUG_BREAK_NOP); 175 __ nop(Assembler::DEBUG_BREAK_NOP);
255 } 176 }
256 } 177 }
257 178
258 179
259 void DebugCodegen::GenerateSlotDebugBreak(MacroAssembler* masm) { 180 void DebugCodegen::GenerateSlotDebugBreak(MacroAssembler* masm) {
260 // In the places where a debug break slot is inserted no registers can contain 181 // In the places where a debug break slot is inserted no registers can contain
261 // object pointers. 182 // object pointers.
262 Generate_DebugBreakCallHelper(masm, 0, 0, x10); 183 Generate_DebugBreakCallHelper(masm, 0);
263 } 184 }
264 185
265 186
266 void DebugCodegen::GeneratePlainReturnLiveEdit(MacroAssembler* masm) { 187 void DebugCodegen::GeneratePlainReturnLiveEdit(MacroAssembler* masm) {
267 __ Ret(); 188 __ Ret();
268 } 189 }
269 190
270 191
271 void DebugCodegen::GenerateFrameDropperLiveEdit(MacroAssembler* masm) { 192 void DebugCodegen::GenerateFrameDropperLiveEdit(MacroAssembler* masm) {
272 ExternalReference restarter_frame_function_slot = 193 ExternalReference restarter_frame_function_slot =
(...skipping 23 matching lines...) Expand all
296 __ Br(scratch); 217 __ Br(scratch);
297 } 218 }
298 219
299 220
300 const bool LiveEdit::kFrameDropperSupported = true; 221 const bool LiveEdit::kFrameDropperSupported = true;
301 222
302 } // namespace internal 223 } // namespace internal
303 } // namespace v8 224 } // namespace v8
304 225
305 #endif // V8_TARGET_ARCH_ARM64 226 #endif // V8_TARGET_ARCH_ARM64
OLDNEW
« no previous file with comments | « src/arm64/assembler-arm64.h ('k') | src/arm64/full-codegen-arm64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698