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

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

Issue 1233823002: X87: Debugger: use debug break slot to break on call. (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/x87/assembler-x87.h ('k') | src/x87/full-codegen-x87.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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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_X87 7 #if V8_TARGET_ARCH_X87
8 8
9 #include "src/codegen.h" 9 #include "src/codegen.h"
10 #include "src/debug.h" 10 #include "src/debug.h"
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
63 Isolate* isolate = debug_info_->GetIsolate(); 63 Isolate* isolate = debug_info_->GetIsolate();
64 PatchCodeWithCall( 64 PatchCodeWithCall(
65 pc(), isolate->builtins()->Slot_DebugBreak()->entry(), 65 pc(), isolate->builtins()->Slot_DebugBreak()->entry(),
66 Assembler::kDebugBreakSlotLength - Assembler::kCallInstructionLength); 66 Assembler::kDebugBreakSlotLength - Assembler::kCallInstructionLength);
67 } 67 }
68 68
69 69
70 #define __ ACCESS_MASM(masm) 70 #define __ ACCESS_MASM(masm)
71 71
72 static void Generate_DebugBreakCallHelper(MacroAssembler* masm, 72 static void Generate_DebugBreakCallHelper(MacroAssembler* masm,
73 RegList object_regs, 73 RegList object_regs) {
74 RegList non_object_regs,
75 bool convert_call_to_jmp) {
76 // Enter an internal frame. 74 // Enter an internal frame.
77 { 75 {
78 FrameScope scope(masm, StackFrame::INTERNAL); 76 FrameScope scope(masm, StackFrame::INTERNAL);
79 77
80 // Load padding words on stack. 78 // Load padding words on stack.
81 for (int i = 0; i < LiveEdit::kFramePaddingInitialSize; i++) { 79 for (int i = 0; i < LiveEdit::kFramePaddingInitialSize; i++) {
82 __ push(Immediate(Smi::FromInt(LiveEdit::kFramePaddingValue))); 80 __ push(Immediate(Smi::FromInt(LiveEdit::kFramePaddingValue)));
83 } 81 }
84 __ push(Immediate(Smi::FromInt(LiveEdit::kFramePaddingInitialSize))); 82 __ push(Immediate(Smi::FromInt(LiveEdit::kFramePaddingInitialSize)));
85 83
86 // Store the registers containing live values on the expression stack to 84 // Store the registers containing live values on the expression stack to
87 // make sure that these are correctly updated during GC. Non object values 85 // 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. 86 // are stored as a smi causing it to be untouched by GC.
89 DCHECK((object_regs & ~kJSCallerSaved) == 0); 87 DCHECK((object_regs & ~kJSCallerSaved) == 0);
90 DCHECK((non_object_regs & ~kJSCallerSaved) == 0);
91 DCHECK((object_regs & non_object_regs) == 0);
92 for (int i = 0; i < kNumJSCallerSaved; i++) { 88 for (int i = 0; i < kNumJSCallerSaved; i++) {
93 int r = JSCallerSavedCode(i); 89 int r = JSCallerSavedCode(i);
94 Register reg = { r }; 90 Register reg = { r };
95 if ((object_regs & (1 << r)) != 0) { 91 if ((object_regs & (1 << r)) != 0) {
96 __ push(reg); 92 __ push(reg);
97 } 93 }
98 if ((non_object_regs & (1 << r)) != 0) {
99 if (FLAG_debug_code) {
100 __ test(reg, Immediate(0xc0000000));
101 __ Assert(zero, kUnableToEncodeValueAsSmi);
102 }
103 __ SmiTag(reg);
104 __ push(reg);
105 }
106 } 94 }
107 95
108 #ifdef DEBUG 96 #ifdef DEBUG
109 __ RecordComment("// Calling from debug break to runtime - come in - over"); 97 __ RecordComment("// Calling from debug break to runtime - come in - over");
110 #endif 98 #endif
111 __ Move(eax, Immediate(0)); // No arguments. 99 __ Move(eax, Immediate(0)); // No arguments.
112 __ mov(ebx, Immediate(ExternalReference::debug_break(masm->isolate()))); 100 __ mov(ebx, Immediate(ExternalReference::debug_break(masm->isolate())));
113 101
114 CEntryStub ceb(masm->isolate(), 1); 102 CEntryStub ceb(masm->isolate(), 1);
115 __ CallStub(&ceb); 103 __ CallStub(&ceb);
116 104
117 // Automatically find register that could be used after register restore. 105 // Automatically find register that could be used after register restore.
118 // We need one register for padding skip instructions. 106 // We need one register for padding skip instructions.
119 Register unused_reg = { -1 }; 107 Register unused_reg = { -1 };
120 108
121 // Restore the register values containing object pointers from the 109 // Restore the register values containing object pointers from the
122 // expression stack. 110 // expression stack.
123 for (int i = kNumJSCallerSaved; --i >= 0;) { 111 for (int i = kNumJSCallerSaved; --i >= 0;) {
124 int r = JSCallerSavedCode(i); 112 int r = JSCallerSavedCode(i);
125 Register reg = { r }; 113 Register reg = { r };
126 if (FLAG_debug_code) { 114 if (FLAG_debug_code) {
127 __ Move(reg, Immediate(kDebugZapValue)); 115 __ Move(reg, Immediate(kDebugZapValue));
128 } 116 }
129 bool taken = reg.code() == esi.code(); 117 bool taken = reg.code() == esi.code();
130 if ((object_regs & (1 << r)) != 0) { 118 if ((object_regs & (1 << r)) != 0) {
131 __ pop(reg); 119 __ pop(reg);
132 taken = true; 120 taken = true;
133 } 121 }
134 if ((non_object_regs & (1 << r)) != 0) {
135 __ pop(reg);
136 __ SmiUntag(reg);
137 taken = true;
138 }
139 if (!taken) { 122 if (!taken) {
140 unused_reg = reg; 123 unused_reg = reg;
141 } 124 }
142 } 125 }
143 126
144 DCHECK(unused_reg.code() != -1); 127 DCHECK(unused_reg.code() != -1);
145 128
146 // Read current padding counter and skip corresponding number of words. 129 // Read current padding counter and skip corresponding number of words.
147 __ pop(unused_reg); 130 __ pop(unused_reg);
148 // We divide stored value by 2 (untagging) and multiply it by word's size. 131 // We divide stored value by 2 (untagging) and multiply it by word's size.
149 STATIC_ASSERT(kSmiTagSize == 1 && kSmiShiftSize == 0); 132 STATIC_ASSERT(kSmiTagSize == 1 && kSmiShiftSize == 0);
150 __ lea(esp, Operand(esp, unused_reg, times_half_pointer_size, 0)); 133 __ lea(esp, Operand(esp, unused_reg, times_half_pointer_size, 0));
151 134
152 // Get rid of the internal frame. 135 // Get rid of the internal frame.
153 } 136 }
154 137
155 // If this call did not replace a call but patched other code then there will 138 // This call did not replace a call , so there will be an unwanted
156 // be an unwanted return address left on the stack. Here we get rid of that. 139 // return address left on the stack. Here we get rid of that.
157 if (convert_call_to_jmp) { 140 __ add(esp, Immediate(kPointerSize));
158 __ add(esp, Immediate(kPointerSize));
159 }
160 141
161 // Now that the break point has been handled, resume normal execution by 142 // Now that the break point has been handled, resume normal execution by
162 // jumping to the target address intended by the caller and that was 143 // jumping to the target address intended by the caller and that was
163 // overwritten by the address of DebugBreakXXX. 144 // overwritten by the address of DebugBreakXXX.
164 ExternalReference after_break_target = 145 ExternalReference after_break_target =
165 ExternalReference::debug_after_break_target_address(masm->isolate()); 146 ExternalReference::debug_after_break_target_address(masm->isolate());
166 __ jmp(Operand::StaticVariable(after_break_target)); 147 __ jmp(Operand::StaticVariable(after_break_target));
167 } 148 }
168 149
169 150
170 void DebugCodegen::GenerateCallICStubDebugBreak(MacroAssembler* masm) {
171 // Register state for CallICStub
172 // ----------- S t a t e -------------
173 // -- edx : type feedback slot (smi)
174 // -- edi : function
175 // -----------------------------------
176 Generate_DebugBreakCallHelper(masm, edx.bit() | edi.bit(),
177 0, false);
178 }
179
180
181 void DebugCodegen::GenerateReturnDebugBreak(MacroAssembler* masm) { 151 void DebugCodegen::GenerateReturnDebugBreak(MacroAssembler* masm) {
182 // Register state just before return from JS function (from codegen-x87.cc). 152 // Register state just before return from JS function (from codegen-x87.cc).
183 // ----------- S t a t e ------------- 153 // ----------- S t a t e -------------
184 // -- eax: return value 154 // -- eax: return value
185 // ----------------------------------- 155 // -----------------------------------
186 Generate_DebugBreakCallHelper(masm, eax.bit(), 0, true); 156 Generate_DebugBreakCallHelper(masm, eax.bit());
187 } 157 }
188 158
189 159
190 void DebugCodegen::GenerateCallFunctionStubDebugBreak(MacroAssembler* masm) {
191 // Register state for CallFunctionStub (from code-stubs-x87.cc).
192 // ----------- S t a t e -------------
193 // -- edi: function
194 // -----------------------------------
195 Generate_DebugBreakCallHelper(masm, edi.bit(), 0, false);
196 }
197
198
199 void DebugCodegen::GenerateCallConstructStubDebugBreak(MacroAssembler* masm) {
200 // Register state for CallConstructStub (from code-stubs-x87.cc).
201 // eax is the actual number of arguments not encoded as a smi see comment
202 // above IC call.
203 // ----------- S t a t e -------------
204 // -- eax: number of arguments (not smi)
205 // -- edi: constructor function
206 // -----------------------------------
207 // The number of arguments in eax is not smi encoded.
208 Generate_DebugBreakCallHelper(masm, edi.bit(), eax.bit(), false);
209 }
210
211
212 void DebugCodegen::GenerateCallConstructStubRecordDebugBreak(
213 MacroAssembler* masm) {
214 // Register state for CallConstructStub (from code-stubs-x87.cc).
215 // eax is the actual number of arguments not encoded as a smi see comment
216 // above IC call.
217 // ----------- S t a t e -------------
218 // -- eax: number of arguments (not smi)
219 // -- ebx: feedback array
220 // -- edx: feedback slot (smi)
221 // -- edi: constructor function
222 // -----------------------------------
223 // The number of arguments in eax is not smi encoded.
224 Generate_DebugBreakCallHelper(masm, ebx.bit() | edx.bit() | edi.bit(),
225 eax.bit(), false);
226 }
227
228
229 void DebugCodegen::GenerateSlot(MacroAssembler* masm) { 160 void DebugCodegen::GenerateSlot(MacroAssembler* masm) {
230 // Generate enough nop's to make space for a call instruction. 161 // Generate enough nop's to make space for a call instruction.
231 Label check_codesize; 162 Label check_codesize;
232 __ bind(&check_codesize); 163 __ bind(&check_codesize);
233 __ RecordDebugBreakSlot();
234 __ Nop(Assembler::kDebugBreakSlotLength); 164 __ Nop(Assembler::kDebugBreakSlotLength);
235 DCHECK_EQ(Assembler::kDebugBreakSlotLength, 165 DCHECK_EQ(Assembler::kDebugBreakSlotLength,
236 masm->SizeOfCodeGeneratedSince(&check_codesize)); 166 masm->SizeOfCodeGeneratedSince(&check_codesize));
237 } 167 }
238 168
239 169
240 void DebugCodegen::GenerateSlotDebugBreak(MacroAssembler* masm) { 170 void DebugCodegen::GenerateSlotDebugBreak(MacroAssembler* masm) {
241 Generate_DebugBreakCallHelper(masm, 0, 0, true); 171 Generate_DebugBreakCallHelper(masm, 0);
242 } 172 }
243 173
244 174
245 void DebugCodegen::GeneratePlainReturnLiveEdit(MacroAssembler* masm) { 175 void DebugCodegen::GeneratePlainReturnLiveEdit(MacroAssembler* masm) {
246 masm->ret(0); 176 masm->ret(0);
247 } 177 }
248 178
249 179
250 void DebugCodegen::GenerateFrameDropperLiveEdit(MacroAssembler* masm) { 180 void DebugCodegen::GenerateFrameDropperLiveEdit(MacroAssembler* masm) {
251 ExternalReference restarter_frame_function_slot = 181 ExternalReference restarter_frame_function_slot =
(...skipping 21 matching lines...) Expand all
273 203
274 204
275 const bool LiveEdit::kFrameDropperSupported = true; 205 const bool LiveEdit::kFrameDropperSupported = true;
276 206
277 #undef __ 207 #undef __
278 208
279 } // namespace internal 209 } // namespace internal
280 } // namespace v8 210 } // namespace v8
281 211
282 #endif // V8_TARGET_ARCH_X87 212 #endif // V8_TARGET_ARCH_X87
OLDNEW
« no previous file with comments | « src/x87/assembler-x87.h ('k') | src/x87/full-codegen-x87.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698