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

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

Issue 3141047: Cleanup the way the debugger stores live registers when entering at a break... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 4 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 | Annotate | Revision Log
« no previous file with comments | « src/arm/code-stubs-arm.cc ('k') | src/arm/frames-arm.h » ('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 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
123 ASSERT(IsDebugBreakSlot()); 123 ASSERT(IsDebugBreakSlot());
124 rinfo()->PatchCode(original_rinfo()->pc(), 124 rinfo()->PatchCode(original_rinfo()->pc(),
125 Assembler::kDebugBreakSlotInstructions); 125 Assembler::kDebugBreakSlotInstructions);
126 } 126 }
127 127
128 128
129 #define __ ACCESS_MASM(masm) 129 #define __ ACCESS_MASM(masm)
130 130
131 131
132 static void Generate_DebugBreakCallHelper(MacroAssembler* masm, 132 static void Generate_DebugBreakCallHelper(MacroAssembler* masm,
133 RegList pointer_regs) { 133 RegList object_regs,
134 // Save the content of all general purpose registers in memory. This copy in 134 RegList non_object_regs) {
135 // memory is later pushed onto the JS expression stack for the fake JS frame
136 // generated and also to the C frame generated on top of that. In the JS
137 // frame ONLY the registers containing pointers will be pushed on the
138 // expression stack. This causes the GC to update these pointers so that
139 // they will have the correct value when returning from the debugger.
140 __ SaveRegistersToMemory(kJSCallerSaved);
141
142 __ EnterInternalFrame(); 135 __ EnterInternalFrame();
143 136
144 // Store the registers containing object pointers on the expression stack to 137 // Store the registers containing live values on the expression stack to
145 // make sure that these are correctly updated during GC. 138 // make sure that these are correctly updated during GC. Non object values
146 // Use sp as base to push. 139 // are stored as a smi causing it to be untouched by GC.
147 __ CopyRegistersFromMemoryToStack(sp, pointer_regs); 140 ASSERT((object_regs & ~kJSCallerSaved) == 0);
141 ASSERT((non_object_regs & ~kJSCallerSaved) == 0);
142 ASSERT((object_regs & non_object_regs) == 0);
143 if ((object_regs | non_object_regs) != 0) {
144 for (int i = 0; i < kNumJSCallerSaved; i++) {
145 int r = JSCallerSavedCode(i);
146 Register reg = { r };
147 if ((non_object_regs & (1 << r)) != 0) {
148 if (FLAG_debug_code) {
149 __ tst(reg, Operand(0xc0000000));
150 __ Assert(eq, "Unable to encode value as smi");
151 }
152 __ mov(reg, Operand(reg, LSL, kSmiTagSize));
153 }
154 }
155 __ stm(db_w, sp, object_regs | non_object_regs);
156 }
148 157
149 #ifdef DEBUG 158 #ifdef DEBUG
150 __ RecordComment("// Calling from debug break to runtime - come in - over"); 159 __ RecordComment("// Calling from debug break to runtime - come in - over");
151 #endif 160 #endif
152 __ mov(r0, Operand(0)); // no arguments 161 __ mov(r0, Operand(0)); // no arguments
153 __ mov(r1, Operand(ExternalReference::debug_break())); 162 __ mov(r1, Operand(ExternalReference::debug_break()));
154 163
155 CEntryStub ceb(1, ExitFrame::MODE_DEBUG); 164 CEntryStub ceb(1);
156 __ CallStub(&ceb); 165 __ CallStub(&ceb);
157 166
158 // Restore the register values containing object pointers from the expression 167 // Restore the register values from the expression stack.
159 // stack in the reverse order as they where pushed. 168 if ((object_regs | non_object_regs) != 0) {
160 // Use sp as base to pop. 169 __ ldm(ia_w, sp, object_regs | non_object_regs);
161 __ CopyRegistersFromStackToMemory(sp, r3, pointer_regs); 170 for (int i = 0; i < kNumJSCallerSaved; i++) {
171 int r = JSCallerSavedCode(i);
172 Register reg = { r };
173 if ((non_object_regs & (1 << r)) != 0) {
174 __ mov(reg, Operand(reg, LSR, kSmiTagSize));
175 }
176 if (FLAG_debug_code &&
177 (((object_regs |non_object_regs) & (1 << r)) == 0)) {
178 __ mov(reg, Operand(kDebugZapValue));
179 }
180 }
181 }
162 182
163 __ LeaveInternalFrame(); 183 __ LeaveInternalFrame();
164 184
165 // Finally restore all registers.
166 __ RestoreRegistersFromMemory(kJSCallerSaved);
167
168 // Now that the break point has been handled, resume normal execution by 185 // Now that the break point has been handled, resume normal execution by
169 // jumping to the target address intended by the caller and that was 186 // jumping to the target address intended by the caller and that was
170 // overwritten by the address of DebugBreakXXX. 187 // overwritten by the address of DebugBreakXXX.
171 __ mov(ip, Operand(ExternalReference(Debug_Address::AfterBreakTarget()))); 188 __ mov(ip, Operand(ExternalReference(Debug_Address::AfterBreakTarget())));
172 __ ldr(ip, MemOperand(ip)); 189 __ ldr(ip, MemOperand(ip));
173 __ Jump(ip); 190 __ Jump(ip);
174 } 191 }
175 192
176 193
177 void Debug::GenerateLoadICDebugBreak(MacroAssembler* masm) { 194 void Debug::GenerateLoadICDebugBreak(MacroAssembler* masm) {
178 // Calling convention for IC load (from ic-arm.cc). 195 // Calling convention for IC load (from ic-arm.cc).
179 // ----------- S t a t e ------------- 196 // ----------- S t a t e -------------
180 // -- r2 : name 197 // -- r2 : name
181 // -- lr : return address 198 // -- lr : return address
182 // -- r0 : receiver 199 // -- r0 : receiver
183 // -- [sp] : receiver 200 // -- [sp] : receiver
184 // ----------------------------------- 201 // -----------------------------------
185 // Registers r0 and r2 contain objects that need to be pushed on the 202 // Registers r0 and r2 contain objects that need to be pushed on the
186 // expression stack of the fake JS frame. 203 // expression stack of the fake JS frame.
187 Generate_DebugBreakCallHelper(masm, r0.bit() | r2.bit()); 204 Generate_DebugBreakCallHelper(masm, r0.bit() | r2.bit(), 0);
188 } 205 }
189 206
190 207
191 void Debug::GenerateStoreICDebugBreak(MacroAssembler* masm) { 208 void Debug::GenerateStoreICDebugBreak(MacroAssembler* masm) {
192 // Calling convention for IC store (from ic-arm.cc). 209 // Calling convention for IC store (from ic-arm.cc).
193 // ----------- S t a t e ------------- 210 // ----------- S t a t e -------------
194 // -- r0 : value 211 // -- r0 : value
195 // -- r1 : receiver 212 // -- r1 : receiver
196 // -- r2 : name 213 // -- r2 : name
197 // -- lr : return address 214 // -- lr : return address
198 // ----------------------------------- 215 // -----------------------------------
199 // Registers r0, r1, and r2 contain objects that need to be pushed on the 216 // Registers r0, r1, and r2 contain objects that need to be pushed on the
200 // expression stack of the fake JS frame. 217 // expression stack of the fake JS frame.
201 Generate_DebugBreakCallHelper(masm, r0.bit() | r1.bit() | r2.bit()); 218 Generate_DebugBreakCallHelper(masm, r0.bit() | r1.bit() | r2.bit(), 0);
202 } 219 }
203 220
204 221
205 void Debug::GenerateKeyedLoadICDebugBreak(MacroAssembler* masm) { 222 void Debug::GenerateKeyedLoadICDebugBreak(MacroAssembler* masm) {
206 // ---------- S t a t e -------------- 223 // ---------- S t a t e --------------
207 // -- lr : return address 224 // -- lr : return address
208 // -- r0 : key 225 // -- r0 : key
209 // -- sp[0] : key 226 // -- r1 : receiver
210 // -- sp[4] : receiver 227 Generate_DebugBreakCallHelper(masm, r0.bit() | r1.bit(), 0);
211 Generate_DebugBreakCallHelper(masm, r0.bit());
212 } 228 }
213 229
214 230
215 void Debug::GenerateKeyedStoreICDebugBreak(MacroAssembler* masm) { 231 void Debug::GenerateKeyedStoreICDebugBreak(MacroAssembler* masm) {
216 // ---------- S t a t e -------------- 232 // ---------- S t a t e --------------
217 // -- r0 : value 233 // -- r0 : value
218 // -- r1 : key 234 // -- r1 : key
219 // -- r2 : receiver 235 // -- r2 : receiver
220 // -- lr : return address 236 // -- lr : return address
221 Generate_DebugBreakCallHelper(masm, r0.bit() | r1.bit() | r2.bit()); 237 Generate_DebugBreakCallHelper(masm, r0.bit() | r1.bit() | r2.bit(), 0);
222 } 238 }
223 239
224 240
225 void Debug::GenerateCallICDebugBreak(MacroAssembler* masm) { 241 void Debug::GenerateCallICDebugBreak(MacroAssembler* masm) {
226 // Calling convention for IC call (from ic-arm.cc) 242 // Calling convention for IC call (from ic-arm.cc)
227 // ----------- S t a t e ------------- 243 // ----------- S t a t e -------------
228 // -- r2: name 244 // -- r2 : name
229 // ----------------------------------- 245 // -----------------------------------
230 Generate_DebugBreakCallHelper(masm, r2.bit()); 246 Generate_DebugBreakCallHelper(masm, r2.bit(), 0);
231 } 247 }
232 248
233 249
234 void Debug::GenerateConstructCallDebugBreak(MacroAssembler* masm) { 250 void Debug::GenerateConstructCallDebugBreak(MacroAssembler* masm) {
235 // In places other than IC call sites it is expected that r0 is TOS which 251 // Calling convention for construct call (from builtins-arm.cc)
236 // is an object - this is not generally the case so this should be used with 252 // -- r0 : number of arguments (not smi)
237 // care. 253 // -- r1 : constructor function
238 Generate_DebugBreakCallHelper(masm, r0.bit()); 254 Generate_DebugBreakCallHelper(masm, r1.bit(), r0.bit());
239 } 255 }
240 256
241 257
242 void Debug::GenerateReturnDebugBreak(MacroAssembler* masm) { 258 void Debug::GenerateReturnDebugBreak(MacroAssembler* masm) {
243 // In places other than IC call sites it is expected that r0 is TOS which 259 // In places other than IC call sites it is expected that r0 is TOS which
244 // is an object - this is not generally the case so this should be used with 260 // is an object - this is not generally the case so this should be used with
245 // care. 261 // care.
246 Generate_DebugBreakCallHelper(masm, r0.bit()); 262 Generate_DebugBreakCallHelper(masm, r0.bit(), 0);
247 } 263 }
248 264
249 265
250 void Debug::GenerateStubNoRegistersDebugBreak(MacroAssembler* masm) { 266 void Debug::GenerateStubNoRegistersDebugBreak(MacroAssembler* masm) {
251 // ----------- S t a t e ------------- 267 // ----------- S t a t e -------------
252 // No registers used on entry. 268 // No registers used on entry.
253 // ----------------------------------- 269 // -----------------------------------
254 Generate_DebugBreakCallHelper(masm, 0); 270 Generate_DebugBreakCallHelper(masm, 0, 0);
255 } 271 }
256 272
257 273
258 void Debug::GenerateSlot(MacroAssembler* masm) { 274 void Debug::GenerateSlot(MacroAssembler* masm) {
259 // Generate enough nop's to make space for a call instruction. Avoid emitting 275 // Generate enough nop's to make space for a call instruction. Avoid emitting
260 // the constant pool in the debug break slot code. 276 // the constant pool in the debug break slot code.
261 Assembler::BlockConstPoolScope block_const_pool(masm); 277 Assembler::BlockConstPoolScope block_const_pool(masm);
262 Label check_codesize; 278 Label check_codesize;
263 __ bind(&check_codesize); 279 __ bind(&check_codesize);
264 __ RecordDebugBreakSlot(); 280 __ RecordDebugBreakSlot();
265 for (int i = 0; i < Assembler::kDebugBreakSlotInstructions; i++) { 281 for (int i = 0; i < Assembler::kDebugBreakSlotInstructions; i++) {
266 __ nop(2); 282 __ nop(2);
267 } 283 }
268 ASSERT_EQ(Assembler::kDebugBreakSlotInstructions, 284 ASSERT_EQ(Assembler::kDebugBreakSlotInstructions,
269 masm->InstructionsGeneratedSince(&check_codesize)); 285 masm->InstructionsGeneratedSince(&check_codesize));
270 } 286 }
271 287
272 288
273 void Debug::GenerateSlotDebugBreak(MacroAssembler* masm) { 289 void Debug::GenerateSlotDebugBreak(MacroAssembler* masm) {
274 // In the places where a debug break slot is inserted no registers can contain 290 // In the places where a debug break slot is inserted no registers can contain
275 // object pointers. 291 // object pointers.
276 Generate_DebugBreakCallHelper(masm, 0); 292 Generate_DebugBreakCallHelper(masm, 0, 0);
277 } 293 }
278 294
279 295
280 void Debug::GeneratePlainReturnLiveEdit(MacroAssembler* masm) { 296 void Debug::GeneratePlainReturnLiveEdit(MacroAssembler* masm) {
281 masm->Abort("LiveEdit frame dropping is not supported on arm"); 297 masm->Abort("LiveEdit frame dropping is not supported on arm");
282 } 298 }
283 299
284 300
285 void Debug::GenerateFrameDropperLiveEdit(MacroAssembler* masm) { 301 void Debug::GenerateFrameDropperLiveEdit(MacroAssembler* masm) {
286 masm->Abort("LiveEdit frame dropping is not supported on arm"); 302 masm->Abort("LiveEdit frame dropping is not supported on arm");
287 } 303 }
288 304
289 const bool Debug::kFrameDropperSupported = false; 305 const bool Debug::kFrameDropperSupported = false;
290 306
291 #undef __ 307 #undef __
292 308
293 309
294 310
295 #endif // ENABLE_DEBUGGER_SUPPORT 311 #endif // ENABLE_DEBUGGER_SUPPORT
296 312
297 } } // namespace v8::internal 313 } } // namespace v8::internal
298 314
299 #endif // V8_TARGET_ARCH_ARM 315 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/code-stubs-arm.cc ('k') | src/arm/frames-arm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698