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

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

Issue 7032003: Submit debug-mips.cc. (Closed) Base URL: http://github.com/v8/v8.git@bleeding_edge
Patch Set: Created 9 years, 7 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 | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2011 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
11 // with the distribution. 11 // with the distribution.
(...skipping 21 matching lines...) Expand all
33 33
34 #include "codegen.h" 34 #include "codegen.h"
35 #include "debug.h" 35 #include "debug.h"
36 36
37 namespace v8 { 37 namespace v8 {
38 namespace internal { 38 namespace internal {
39 39
40 #ifdef ENABLE_DEBUGGER_SUPPORT 40 #ifdef ENABLE_DEBUGGER_SUPPORT
41 41
42 bool BreakLocationIterator::IsDebugBreakAtReturn() { 42 bool BreakLocationIterator::IsDebugBreakAtReturn() {
43 UNIMPLEMENTED_MIPS(); 43 return Debug::IsDebugBreakAtReturn(rinfo());
44 return false;
45 } 44 }
46 45
47 46
48 void BreakLocationIterator::SetDebugBreakAtReturn() { 47 void BreakLocationIterator::SetDebugBreakAtReturn() {
49 UNIMPLEMENTED_MIPS(); 48 // Mips return sequence:
49 // mov sp, fp
50 // lw fp, sp(0)
51 // lw ra, sp(4)
52 // addiu sp, sp, 8
53 // addiu sp, sp, N
54 // jr ra
55 // nop (in branch delay slot)
56
57 // Make sure this constant matches the number if instrucntions we emit.
58 ASSERT(Assembler::kJSReturnSequenceInstructions == 7);
59 CodePatcher patcher(rinfo()->pc(), Assembler::kJSReturnSequenceInstructions);
60 // li and Call pseudo-instructions emit two instructions each.
61 patcher.masm()->li(v8::internal::t9,
62 Operand(reinterpret_cast<int32_t>(
63 Isolate::Current()->debug()->debug_break_return()->entry())));
64 patcher.masm()->Call(v8::internal::t9);
65 patcher.masm()->nop();
66 patcher.masm()->nop();
67 patcher.masm()->nop();
68
69 // TODO(mips): Open issue about using breakpoint instruction instead of nops.
70 // patcher.masm()->bkpt(0);
50 } 71 }
51 72
52 73
53 // Restore the JS frame exit code. 74 // Restore the JS frame exit code.
54 void BreakLocationIterator::ClearDebugBreakAtReturn() { 75 void BreakLocationIterator::ClearDebugBreakAtReturn() {
55 UNIMPLEMENTED_MIPS(); 76 rinfo()->PatchCode(original_rinfo()->pc(),
77 Assembler::kJSReturnSequenceInstructions);
56 } 78 }
57 79
58 80
59 // A debug break in the exit code is identified by the JS frame exit code 81 // A debug break in the exit code is identified by the JS frame exit code
60 // having been patched with li/call psuedo-instrunction (liu/ori/jalr) 82 // having been patched with li/call psuedo-instrunction (liu/ori/jalr).
61 bool Debug::IsDebugBreakAtReturn(RelocInfo* rinfo) { 83 bool Debug::IsDebugBreakAtReturn(RelocInfo* rinfo) {
62 UNIMPLEMENTED_MIPS(); 84 ASSERT(RelocInfo::IsJSReturn(rinfo->rmode()));
63 return false; 85 return rinfo->IsPatchedReturnSequence();
64 } 86 }
65 87
66 88
67 bool BreakLocationIterator::IsDebugBreakAtSlot() { 89 bool BreakLocationIterator::IsDebugBreakAtSlot() {
68 UNIMPLEMENTED_MIPS(); 90 ASSERT(IsDebugBreakSlot());
69 return false; 91 // Check whether the debug break slot instructions have been patched.
92 return rinfo()->IsPatchedDebugBreakSlotSequence();
70 } 93 }
71 94
72 95
73 void BreakLocationIterator::SetDebugBreakAtSlot() { 96 void BreakLocationIterator::SetDebugBreakAtSlot() {
74 UNIMPLEMENTED_MIPS(); 97 ASSERT(IsDebugBreakSlot());
98 // Patch the code changing the debug break slot code from:
99 // nop(DEBUG_BREAK_NOP) - nop(1) is sll(zero_reg, zero_reg, 1)
100 // nop(DEBUG_BREAK_NOP)
101 // nop(DEBUG_BREAK_NOP)
102 // nop(DEBUG_BREAK_NOP)
103 // to a call to the debug break slot code.
104 // li t9, address (lui t9 / ori t9 instruction pair)
105 // call t9 (jalr t9 / nop instruction pair)
106 CodePatcher patcher(rinfo()->pc(), Assembler::kDebugBreakSlotInstructions);
107 patcher.masm()->li(v8::internal::t9, Operand(reinterpret_cast<int32_t>(
108 Isolate::Current()->debug()->debug_break_return()->entry())));
109 patcher.masm()->Call(v8::internal::t9);
75 } 110 }
76 111
77 112
78 void BreakLocationIterator::ClearDebugBreakAtSlot() { 113 void BreakLocationIterator::ClearDebugBreakAtSlot() {
79 UNIMPLEMENTED_MIPS(); 114 ASSERT(IsDebugBreakSlot());
115 rinfo()->PatchCode(original_rinfo()->pc(),
116 Assembler::kDebugBreakSlotInstructions);
80 } 117 }
81 118
82 119
83 #define __ ACCESS_MASM(masm) 120 #define __ ACCESS_MASM(masm)
84 121
85 122
123
124 static void Generate_DebugBreakCallHelper(MacroAssembler* masm,
125 RegList object_regs,
126 RegList non_object_regs) {
127 __ EnterInternalFrame();
128
129 // Store the registers containing live values on the expression stack to
130 // make sure that these are correctly updated during GC. Non object values
131 // are stored as a smi causing it to be untouched by GC.
132 ASSERT((object_regs & ~kJSCallerSaved) == 0);
133 ASSERT((non_object_regs & ~kJSCallerSaved) == 0);
134 ASSERT((object_regs & non_object_regs) == 0);
135 if ((object_regs | non_object_regs) != 0) {
136 for (int i = 0; i < kNumJSCallerSaved; i++) {
137 int r = JSCallerSavedCode(i);
138 Register reg = { r };
139 if ((non_object_regs & (1 << r)) != 0) {
140 if (FLAG_debug_code) {
141 __ And(at, reg, 0xc0000000);
142 __ Assert(eq, "Unable to encode value as smi", at, Operand(zero_reg));
143 }
144 __ sll(reg, reg, kSmiTagSize);
145 }
146 }
147 __ MultiPush(object_regs | non_object_regs);
148 }
149
150 #ifdef DEBUG
151 __ RecordComment("// Calling from debug break to runtime - come in - over");
152 #endif
153 __ mov(a0, zero_reg); // No arguments.
154 __ li(a1, Operand(ExternalReference::debug_break(masm->isolate())));
155
156 CEntryStub ceb(1);
157 __ CallStub(&ceb);
158
159 // Restore the register values from the expression stack.
160 if ((object_regs | non_object_regs) != 0) {
161 __ MultiPop(object_regs | non_object_regs);
162 for (int i = 0; i < kNumJSCallerSaved; i++) {
163 int r = JSCallerSavedCode(i);
164 Register reg = { r };
165 if ((non_object_regs & (1 << r)) != 0) {
166 __ srl(reg, reg, kSmiTagSize);
167 }
168 if (FLAG_debug_code &&
169 (((object_regs |non_object_regs) & (1 << r)) == 0)) {
170 __ li(reg, kDebugZapValue);
171 }
172 }
173 }
174
175 __ LeaveInternalFrame();
176
177 // Now that the break point has been handled, resume normal execution by
178 // jumping to the target address intended by the caller and that was
179 // overwritten by the address of DebugBreakXXX.
180 __ li(t9, Operand(
181 ExternalReference(Debug_Address::AfterBreakTarget(), masm->isolate())));
182 __ lw(t9, MemOperand(t9));
183 __ Jump(t9);
184 }
185
186
86 void Debug::GenerateLoadICDebugBreak(MacroAssembler* masm) { 187 void Debug::GenerateLoadICDebugBreak(MacroAssembler* masm) {
87 UNIMPLEMENTED_MIPS(); 188 // Calling convention for IC load (from ic-mips.cc).
189 // ----------- S t a t e -------------
190 // -- a2 : name
191 // -- ra : return address
192 // -- a0 : receiver
193 // -- [sp] : receiver
194 // -----------------------------------
195 // Registers a0 and a2 contain objects that need to be pushed on the
196 // expression stack of the fake JS frame.
197 Generate_DebugBreakCallHelper(masm, a0.bit() | a2.bit(), 0);
88 } 198 }
89 199
90 200
91 void Debug::GenerateStoreICDebugBreak(MacroAssembler* masm) { 201 void Debug::GenerateStoreICDebugBreak(MacroAssembler* masm) {
92 UNIMPLEMENTED_MIPS(); 202 // Calling convention for IC store (from ic-mips.cc).
203 // ----------- S t a t e -------------
204 // -- a0 : value
205 // -- a1 : receiver
206 // -- a2 : name
207 // -- ra : return address
208 // -----------------------------------
209 // Registers a0, a1, and a2 contain objects that need to be pushed on the
210 // expression stack of the fake JS frame.
211 Generate_DebugBreakCallHelper(masm, a0.bit() | a1.bit() | a2.bit(), 0);
93 } 212 }
94 213
95 214
96 void Debug::GenerateKeyedLoadICDebugBreak(MacroAssembler* masm) { 215 void Debug::GenerateKeyedLoadICDebugBreak(MacroAssembler* masm) {
97 UNIMPLEMENTED_MIPS(); 216 // ---------- S t a t e --------------
217 // -- ra : return address
218 // -- a0 : key
219 // -- a1 : receiver
220 Generate_DebugBreakCallHelper(masm, a0.bit() | a1.bit(), 0);
98 } 221 }
99 222
100 223
101 void Debug::GenerateKeyedStoreICDebugBreak(MacroAssembler* masm) { 224 void Debug::GenerateKeyedStoreICDebugBreak(MacroAssembler* masm) {
102 UNIMPLEMENTED_MIPS(); 225 // ---------- S t a t e --------------
226 // -- a0 : value
227 // -- a1 : key
228 // -- a2 : receiver
229 // -- ra : return address
230 Generate_DebugBreakCallHelper(masm, a0.bit() | a1.bit() | a2.bit(), 0);
103 } 231 }
104 232
105 233
106 void Debug::GenerateCallICDebugBreak(MacroAssembler* masm) { 234 void Debug::GenerateCallICDebugBreak(MacroAssembler* masm) {
107 UNIMPLEMENTED_MIPS(); 235 // Calling convention for IC call (from ic-mips.cc).
236 // ----------- S t a t e -------------
237 // -- a2: name
238 // -----------------------------------
239 Generate_DebugBreakCallHelper(masm, a2.bit(), 0);
108 } 240 }
109 241
110 242
111 void Debug::GenerateConstructCallDebugBreak(MacroAssembler* masm) { 243 void Debug::GenerateConstructCallDebugBreak(MacroAssembler* masm) {
112 UNIMPLEMENTED_MIPS(); 244 // Calling convention for construct call (from builtins-mips.cc).
245 // -- a0 : number of arguments (not smi)
246 // -- a1 : constructor function
247 Generate_DebugBreakCallHelper(masm, a1.bit(), a0.bit());
113 } 248 }
114 249
115 250
116 void Debug::GenerateReturnDebugBreak(MacroAssembler* masm) { 251 void Debug::GenerateReturnDebugBreak(MacroAssembler* masm) {
117 UNIMPLEMENTED_MIPS(); 252 // In places other than IC call sites it is expected that v0 is TOS which
253 // is an object - this is not generally the case so this should be used with
254 // care.
255 Generate_DebugBreakCallHelper(masm, v0.bit(), 0);
118 } 256 }
119 257
120 258
121 void Debug::GenerateStubNoRegistersDebugBreak(MacroAssembler* masm) { 259 void Debug::GenerateStubNoRegistersDebugBreak(MacroAssembler* masm) {
122 UNIMPLEMENTED_MIPS(); 260 // ----------- S t a t e -------------
261 // No registers used on entry.
262 // -----------------------------------
263 Generate_DebugBreakCallHelper(masm, 0, 0);
123 } 264 }
124 265
125 266
126 void Debug::GenerateSlot(MacroAssembler* masm) { 267 void Debug::GenerateSlot(MacroAssembler* masm) {
127 UNIMPLEMENTED_MIPS(); 268 // Generate enough nop's to make space for a call instruction. Avoid emitting
269 // the trampoline pool in the debug break slot code.
270 Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm);
271 Label check_codesize;
272 __ bind(&check_codesize);
273 __ RecordDebugBreakSlot();
274 for (int i = 0; i < Assembler::kDebugBreakSlotInstructions; i++) {
275 __ nop(MacroAssembler::DEBUG_BREAK_NOP);
276 }
277 ASSERT_EQ(Assembler::kDebugBreakSlotInstructions,
278 masm->InstructionsGeneratedSince(&check_codesize));
128 } 279 }
129 280
130 281
131 void Debug::GenerateSlotDebugBreak(MacroAssembler* masm) { 282 void Debug::GenerateSlotDebugBreak(MacroAssembler* masm) {
132 UNIMPLEMENTED_MIPS(); 283 // In the places where a debug break slot is inserted no registers can contain
284 // object pointers.
285 Generate_DebugBreakCallHelper(masm, 0, 0);
133 } 286 }
134 287
135 288
136 void Debug::GeneratePlainReturnLiveEdit(MacroAssembler* masm) { 289 void Debug::GeneratePlainReturnLiveEdit(MacroAssembler* masm) {
137 UNIMPLEMENTED_MIPS(); 290 masm->Abort("LiveEdit frame dropping is not supported on mips");
138 } 291 }
139 292
140 293
141 void Debug::GenerateFrameDropperLiveEdit(MacroAssembler* masm) { 294 void Debug::GenerateFrameDropperLiveEdit(MacroAssembler* masm) {
142 UNIMPLEMENTED_MIPS(); 295 masm->Abort("LiveEdit frame dropping is not supported on mips");
143 } 296 }
144 297
145 298
146 const bool Debug::kFrameDropperSupported = false; 299 const bool Debug::kFrameDropperSupported = false;
147 300
148 #undef __ 301 #undef __
149 302
150 303
151 #endif // ENABLE_DEBUGGER_SUPPORT 304 #endif // ENABLE_DEBUGGER_SUPPORT
152 305
153 } } // namespace v8::internal 306 } } // namespace v8::internal
154 307
155 #endif // V8_TARGET_ARCH_MIPS 308 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698