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

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

Issue 6577036: [Isolates] Merge from bleeding_edge to isolates, revisions 6100-6300. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/isolates/
Patch Set: '' Created 9 years, 10 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/x64/codegen-x64.cc ('k') | src/x64/deoptimizer-x64.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 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 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.
12 // * Neither the name of Google Inc. nor the names of its 12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived 13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission. 14 // from this software without specific prior written permission.
15 // 15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28
29 #include "v8.h" 28 #include "v8.h"
30 29
31 #if defined(V8_TARGET_ARCH_X64) 30 #if defined(V8_TARGET_ARCH_X64)
32 31
33 #include "codegen-inl.h" 32 #include "codegen-inl.h"
34 #include "debug.h" 33 #include "debug.h"
35 34
36 35
37 namespace v8 { 36 namespace v8 {
38 namespace internal { 37 namespace internal {
39 38
40 #ifdef ENABLE_DEBUGGER_SUPPORT 39 #ifdef ENABLE_DEBUGGER_SUPPORT
41 40
41 bool BreakLocationIterator::IsDebugBreakAtReturn() {
42 return Debug::IsDebugBreakAtReturn(rinfo());
43 }
44
45
46 // Patch the JS frame exit code with a debug break call. See
47 // CodeGenerator::VisitReturnStatement and VirtualFrame::Exit in codegen-x64.cc
48 // for the precise return instructions sequence.
49 void BreakLocationIterator::SetDebugBreakAtReturn() {
50 ASSERT(Assembler::kJSReturnSequenceLength >=
51 Assembler::kCallInstructionLength);
52 rinfo()->PatchCodeWithCall(
53 Isolate::Current()->debug()->debug_break_return()->entry(),
54 Assembler::kJSReturnSequenceLength - Assembler::kCallInstructionLength);
55 }
56
57
58 // Restore the JS frame exit code.
59 void BreakLocationIterator::ClearDebugBreakAtReturn() {
60 rinfo()->PatchCode(original_rinfo()->pc(),
61 Assembler::kJSReturnSequenceLength);
62 }
63
64
65 // A debug break in the frame exit code is identified by the JS frame exit code
66 // having been patched with a call instruction.
42 bool Debug::IsDebugBreakAtReturn(v8::internal::RelocInfo* rinfo) { 67 bool Debug::IsDebugBreakAtReturn(v8::internal::RelocInfo* rinfo) {
43 ASSERT(RelocInfo::IsJSReturn(rinfo->rmode())); 68 ASSERT(RelocInfo::IsJSReturn(rinfo->rmode()));
44 return rinfo->IsPatchedReturnSequence(); 69 return rinfo->IsPatchedReturnSequence();
45 } 70 }
46 71
72
73 bool BreakLocationIterator::IsDebugBreakAtSlot() {
74 ASSERT(IsDebugBreakSlot());
75 // Check whether the debug break slot instructions have been patched.
76 return !Assembler::IsNop(rinfo()->pc());
77 }
78
79
80 void BreakLocationIterator::SetDebugBreakAtSlot() {
81 ASSERT(IsDebugBreakSlot());
82 rinfo()->PatchCodeWithCall(
83 Isolate::Current()->debug()->debug_break_slot()->entry(),
84 Assembler::kDebugBreakSlotLength - Assembler::kCallInstructionLength);
85 }
86
87
88 void BreakLocationIterator::ClearDebugBreakAtSlot() {
89 ASSERT(IsDebugBreakSlot());
90 rinfo()->PatchCode(original_rinfo()->pc(), Assembler::kDebugBreakSlotLength);
91 }
92
93
47 #define __ ACCESS_MASM(masm) 94 #define __ ACCESS_MASM(masm)
48 95
96
49 static void Generate_DebugBreakCallHelper(MacroAssembler* masm, 97 static void Generate_DebugBreakCallHelper(MacroAssembler* masm,
50 RegList object_regs, 98 RegList object_regs,
51 RegList non_object_regs, 99 RegList non_object_regs,
52 bool convert_call_to_jmp) { 100 bool convert_call_to_jmp) {
53 // Enter an internal frame. 101 // Enter an internal frame.
54 __ EnterInternalFrame(); 102 __ EnterInternalFrame();
55 103
56 // Store the registers containing live values on the expression stack to 104 // Store the registers containing live values on the expression stack to
57 // make sure that these are correctly updated during GC. Non object values 105 // make sure that these are correctly updated during GC. Non object values
58 // are stored as as two smi causing it to be untouched by GC. 106 // are stored as as two smis causing it to be untouched by GC.
59 ASSERT((object_regs & ~kJSCallerSaved) == 0); 107 ASSERT((object_regs & ~kJSCallerSaved) == 0);
60 ASSERT((non_object_regs & ~kJSCallerSaved) == 0); 108 ASSERT((non_object_regs & ~kJSCallerSaved) == 0);
61 ASSERT((object_regs & non_object_regs) == 0); 109 ASSERT((object_regs & non_object_regs) == 0);
62 for (int i = 0; i < kNumJSCallerSaved; i++) { 110 for (int i = 0; i < kNumJSCallerSaved; i++) {
63 int r = JSCallerSavedCode(i); 111 int r = JSCallerSavedCode(i);
64 Register reg = { r }; 112 Register reg = { r };
65 ASSERT(!reg.is(kScratchRegister)); 113 ASSERT(!reg.is(kScratchRegister));
66 if ((object_regs & (1 << r)) != 0) { 114 if ((object_regs & (1 << r)) != 0) {
67 __ push(reg); 115 __ push(reg);
68 } 116 }
69 // Store the 64-bit value as two smis. 117 // Store the 64-bit value as two smis.
70 if ((non_object_regs & (1 << r)) != 0) { 118 if ((non_object_regs & (1 << r)) != 0) {
71 __ movq(kScratchRegister, reg); 119 __ movq(kScratchRegister, reg);
72 __ Integer32ToSmi(reg, reg); 120 __ Integer32ToSmi(reg, reg);
73 __ push(reg); 121 __ push(reg);
74 __ sar(kScratchRegister, Immediate(32)); 122 __ sar(kScratchRegister, Immediate(32));
75 __ Integer32ToSmi(kScratchRegister, kScratchRegister); 123 __ Integer32ToSmi(kScratchRegister, kScratchRegister);
76 __ push(kScratchRegister); 124 __ push(kScratchRegister);
77 } 125 }
78 } 126 }
79 127
80 #ifdef DEBUG 128 #ifdef DEBUG
81 __ RecordComment("// Calling from debug break to runtime - come in - over"); 129 __ RecordComment("// Calling from debug break to runtime - come in - over");
82 #endif 130 #endif
83 __ xor_(rax, rax); // No arguments (argc == 0). 131 __ Set(rax, 0); // No arguments (argc == 0).
84 __ movq(rbx, ExternalReference::debug_break()); 132 __ movq(rbx, ExternalReference::debug_break());
85 133
86 CEntryStub ceb(1); 134 CEntryStub ceb(1);
87 __ CallStub(&ceb); 135 __ CallStub(&ceb);
88 136
89 // Restore the register values from the expression stack. 137 // Restore the register values from the expression stack.
90 for (int i = kNumJSCallerSaved - 1; i >= 0; i--) { 138 for (int i = kNumJSCallerSaved - 1; i >= 0; i--) {
91 int r = JSCallerSavedCode(i); 139 int r = JSCallerSavedCode(i);
92 Register reg = { r }; 140 Register reg = { r };
93 if (FLAG_debug_code) { 141 if (FLAG_debug_code) {
(...skipping 25 matching lines...) Expand all
119 // Now that the break point has been handled, resume normal execution by 167 // Now that the break point has been handled, resume normal execution by
120 // jumping to the target address intended by the caller and that was 168 // jumping to the target address intended by the caller and that was
121 // overwritten by the address of DebugBreakXXX. 169 // overwritten by the address of DebugBreakXXX.
122 ExternalReference after_break_target = 170 ExternalReference after_break_target =
123 ExternalReference(Debug_Address::AfterBreakTarget()); 171 ExternalReference(Debug_Address::AfterBreakTarget());
124 __ movq(kScratchRegister, after_break_target); 172 __ movq(kScratchRegister, after_break_target);
125 __ jmp(Operand(kScratchRegister, 0)); 173 __ jmp(Operand(kScratchRegister, 0));
126 } 174 }
127 175
128 176
129 void Debug::GenerateCallICDebugBreak(MacroAssembler* masm) { 177 void Debug::GenerateLoadICDebugBreak(MacroAssembler* masm) {
130 // Register state for IC call call (from ic-x64.cc) 178 // Register state for IC load call (from ic-x64.cc).
131 // ----------- S t a t e ------------- 179 // ----------- S t a t e -------------
132 // -- rcx: function name 180 // -- rax : receiver
181 // -- rcx : name
133 // ----------------------------------- 182 // -----------------------------------
134 Generate_DebugBreakCallHelper(masm, rcx.bit(), 0, false); 183 Generate_DebugBreakCallHelper(masm, rax.bit() | rcx.bit(), 0, false);
135 } 184 }
136 185
137 186
138 void Debug::GenerateConstructCallDebugBreak(MacroAssembler* masm) { 187 void Debug::GenerateStoreICDebugBreak(MacroAssembler* masm) {
139 // Register state just before return from JS function (from codegen-x64.cc). 188 // Register state for IC store call (from ic-x64.cc).
140 // rax is the actual number of arguments not encoded as a smi, see comment
141 // above IC call.
142 // ----------- S t a t e ------------- 189 // ----------- S t a t e -------------
143 // -- rax: number of arguments 190 // -- rax : value
191 // -- rcx : name
192 // -- rdx : receiver
144 // ----------------------------------- 193 // -----------------------------------
145 // The number of arguments in rax is not smi encoded. 194 Generate_DebugBreakCallHelper(
146 Generate_DebugBreakCallHelper(masm, rdi.bit(), rax.bit(), false); 195 masm, rax.bit() | rcx.bit() | rdx.bit(), 0, false);
147 } 196 }
148 197
149 198
150 void Debug::GenerateKeyedLoadICDebugBreak(MacroAssembler* masm) { 199 void Debug::GenerateKeyedLoadICDebugBreak(MacroAssembler* masm) {
151 // Register state for keyed IC load call (from ic-x64.cc). 200 // Register state for keyed IC load call (from ic-x64.cc).
152 // ----------- S t a t e ------------- 201 // ----------- S t a t e -------------
153 // -- rax : key 202 // -- rax : key
154 // -- rdx : receiver 203 // -- rdx : receiver
155 // ----------------------------------- 204 // -----------------------------------
156 Generate_DebugBreakCallHelper(masm, rax.bit() | rdx.bit(), 0, false); 205 Generate_DebugBreakCallHelper(masm, rax.bit() | rdx.bit(), 0, false);
157 } 206 }
158 207
159 208
160 void Debug::GenerateKeyedStoreICDebugBreak(MacroAssembler* masm) { 209 void Debug::GenerateKeyedStoreICDebugBreak(MacroAssembler* masm) {
161 // Register state for keyed IC load call (from ic-x64.cc). 210 // Register state for keyed IC load call (from ic-x64.cc).
162 // ----------- S t a t e ------------- 211 // ----------- S t a t e -------------
163 // -- rax : value 212 // -- rax : value
164 // -- rcx : key 213 // -- rcx : key
165 // -- rdx : receiver 214 // -- rdx : receiver
166 // ----------------------------------- 215 // -----------------------------------
167 Generate_DebugBreakCallHelper( 216 Generate_DebugBreakCallHelper(
168 masm, rax.bit() | rcx.bit() | rdx.bit(), 0, false); 217 masm, rax.bit() | rcx.bit() | rdx.bit(), 0, false);
169 } 218 }
170 219
171 220
172 void Debug::GenerateLoadICDebugBreak(MacroAssembler* masm) { 221 void Debug::GenerateCallICDebugBreak(MacroAssembler* masm) {
173 // Register state for IC load call (from ic-x64.cc). 222 // Register state for IC call call (from ic-x64.cc)
174 // ----------- S t a t e ------------- 223 // ----------- S t a t e -------------
175 // -- rax : receiver 224 // -- rcx: function name
176 // -- rcx : name
177 // ----------------------------------- 225 // -----------------------------------
178 Generate_DebugBreakCallHelper(masm, rax.bit() | rcx.bit(), 0, false); 226 Generate_DebugBreakCallHelper(masm, rcx.bit(), 0, false);
227 }
228
229
230 void Debug::GenerateConstructCallDebugBreak(MacroAssembler* masm) {
231 // Register state just before return from JS function (from codegen-x64.cc).
232 // rax is the actual number of arguments not encoded as a smi, see comment
233 // above IC call.
234 // ----------- S t a t e -------------
235 // -- rax: number of arguments
236 // -----------------------------------
237 // The number of arguments in rax is not smi encoded.
238 Generate_DebugBreakCallHelper(masm, rdi.bit(), rax.bit(), false);
179 } 239 }
180 240
181 241
182 void Debug::GenerateReturnDebugBreak(MacroAssembler* masm) { 242 void Debug::GenerateReturnDebugBreak(MacroAssembler* masm) {
183 // Register state just before return from JS function (from codegen-x64.cc). 243 // Register state just before return from JS function (from codegen-x64.cc).
184 // ----------- S t a t e ------------- 244 // ----------- S t a t e -------------
185 // -- rax: return value 245 // -- rax: return value
186 // ----------------------------------- 246 // -----------------------------------
187 Generate_DebugBreakCallHelper(masm, rax.bit(), 0, true); 247 Generate_DebugBreakCallHelper(masm, rax.bit(), 0, true);
188 } 248 }
189 249
190 250
191 void Debug::GenerateStoreICDebugBreak(MacroAssembler* masm) {
192 // Register state for IC store call (from ic-x64.cc).
193 // ----------- S t a t e -------------
194 // -- rax : value
195 // -- rcx : name
196 // -- rdx : receiver
197 // -----------------------------------
198 Generate_DebugBreakCallHelper(
199 masm, rax.bit() | rcx.bit() | rdx.bit(), 0, false);
200 }
201
202
203 void Debug::GenerateStubNoRegistersDebugBreak(MacroAssembler* masm) { 251 void Debug::GenerateStubNoRegistersDebugBreak(MacroAssembler* masm) {
204 // Register state for stub CallFunction (from CallFunctionStub in ic-x64.cc). 252 // Register state for stub CallFunction (from CallFunctionStub in ic-x64.cc).
205 // ----------- S t a t e ------------- 253 // ----------- S t a t e -------------
206 // No registers used on entry. 254 // No registers used on entry.
207 // ----------------------------------- 255 // -----------------------------------
208 Generate_DebugBreakCallHelper(masm, 0, 0, false); 256 Generate_DebugBreakCallHelper(masm, 0, 0, false);
209 } 257 }
210 258
211 259
212 void Debug::GenerateSlot(MacroAssembler* masm) { 260 void Debug::GenerateSlot(MacroAssembler* masm) {
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
255 __ lea(rdx, FieldOperand(rdx, Code::kHeaderSize)); 303 __ lea(rdx, FieldOperand(rdx, Code::kHeaderSize));
256 304
257 // Re-run JSFunction, rdi is function, rsi is context. 305 // Re-run JSFunction, rdi is function, rsi is context.
258 __ jmp(rdx); 306 __ jmp(rdx);
259 } 307 }
260 308
261 const bool Debug::kFrameDropperSupported = true; 309 const bool Debug::kFrameDropperSupported = true;
262 310
263 #undef __ 311 #undef __
264 312
265
266
267
268 void BreakLocationIterator::ClearDebugBreakAtReturn() {
269 rinfo()->PatchCode(original_rinfo()->pc(),
270 Assembler::kJSReturnSequenceLength);
271 }
272
273
274 bool BreakLocationIterator::IsDebugBreakAtReturn() {
275 return Debug::IsDebugBreakAtReturn(rinfo());
276 }
277
278
279 void BreakLocationIterator::SetDebugBreakAtReturn() {
280 ASSERT(Assembler::kJSReturnSequenceLength >=
281 Assembler::kCallInstructionLength);
282 rinfo()->PatchCodeWithCall(
283 Isolate::Current()->debug()->debug_break_return()->entry(),
284 Assembler::kJSReturnSequenceLength - Assembler::kCallInstructionLength);
285 }
286
287
288 bool BreakLocationIterator::IsDebugBreakAtSlot() {
289 ASSERT(IsDebugBreakSlot());
290 // Check whether the debug break slot instructions have been patched.
291 return !Assembler::IsNop(rinfo()->pc());
292 }
293
294
295 void BreakLocationIterator::SetDebugBreakAtSlot() {
296 ASSERT(IsDebugBreakSlot());
297 rinfo()->PatchCodeWithCall(
298 Isolate::Current()->debug()->debug_break_slot()->entry(),
299 Assembler::kDebugBreakSlotLength - Assembler::kCallInstructionLength);
300 }
301
302
303 void BreakLocationIterator::ClearDebugBreakAtSlot() {
304 ASSERT(IsDebugBreakSlot());
305 rinfo()->PatchCode(original_rinfo()->pc(), Assembler::kDebugBreakSlotLength);
306 }
307
308
309 #endif // ENABLE_DEBUGGER_SUPPORT 313 #endif // ENABLE_DEBUGGER_SUPPORT
310 314
311 } } // namespace v8::internal 315 } } // namespace v8::internal
312 316
313 #endif // V8_TARGET_ARCH_X64 317 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/codegen-x64.cc ('k') | src/x64/deoptimizer-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698