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

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

Issue 1682853003: [debugger] introduce abstract interface for break location. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: revert stray edit Created 4 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
« no previous file with comments | « src/debug/debug.h ('k') | src/debug/ia32/debug-ia32.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/debug/debug.h" 5 #include "src/debug/debug.h"
6 6
7 #include "src/api.h" 7 #include "src/api.h"
8 #include "src/arguments.h" 8 #include "src/arguments.h"
9 #include "src/bootstrapper.h" 9 #include "src/bootstrapper.h"
10 #include "src/code-stubs.h" 10 #include "src/code-stubs.h"
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 51
52 static v8::Local<v8::Context> GetDebugEventContext(Isolate* isolate) { 52 static v8::Local<v8::Context> GetDebugEventContext(Isolate* isolate) {
53 Handle<Context> context = isolate->debug()->debugger_entry()->GetContext(); 53 Handle<Context> context = isolate->debug()->debugger_entry()->GetContext();
54 // Isolate::context() may have been NULL when "script collected" event 54 // Isolate::context() may have been NULL when "script collected" event
55 // occured. 55 // occured.
56 if (context.is_null()) return v8::Local<v8::Context>(); 56 if (context.is_null()) return v8::Local<v8::Context>();
57 Handle<Context> native_context(context->native_context()); 57 Handle<Context> native_context(context->native_context());
58 return v8::Utils::ToLocal(native_context); 58 return v8::Utils::ToLocal(native_context);
59 } 59 }
60 60
61 BreakLocation::BreakLocation(Handle<DebugInfo> debug_info, RelocInfo* rinfo, 61 BreakLocation::BreakLocation(Handle<DebugInfo> debug_info, DebugBreakType type,
62 int position, int statement_position) 62 int code_offset, int position,
63 int statement_position)
63 : debug_info_(debug_info), 64 : debug_info_(debug_info),
64 code_offset_(static_cast<int>(rinfo->pc() - debug_info->code()->entry())), 65 code_offset_(code_offset),
65 rmode_(rinfo->rmode()), 66 type_(type),
66 data_(rinfo->data()),
67 position_(position), 67 position_(position),
68 statement_position_(statement_position) {} 68 statement_position_(statement_position) {}
69 69
70 BreakLocation::Iterator* BreakLocation::GetIterator(
71 Handle<DebugInfo> debug_info, BreakLocatorType type) {
72 if (debug_info->shared()->HasBytecodeArray()) {
73 UNIMPLEMENTED();
74 return nullptr;
75 }
76 return new CodeIterator(debug_info, type);
77 }
78
70 BreakLocation::Iterator::Iterator(Handle<DebugInfo> debug_info, 79 BreakLocation::Iterator::Iterator(Handle<DebugInfo> debug_info,
71 BreakLocatorType type) 80 BreakLocatorType type)
72 : debug_info_(debug_info), 81 : debug_info_(debug_info),
73 reloc_iterator_(debug_info->code(), GetModeMask(type)),
74 break_index_(-1), 82 break_index_(-1),
75 position_(1), 83 position_(1),
76 statement_position_(1) { 84 statement_position_(1) {
85 }
86
87 BreakLocation::CodeIterator::CodeIterator(Handle<DebugInfo> debug_info,
88 BreakLocatorType type)
89 : Iterator(debug_info, type),
90 reloc_iterator_(debug_info->abstract_code()->GetCode(),
91 GetModeMask(type)) {
77 if (!Done()) Next(); 92 if (!Done()) Next();
78 } 93 }
79 94
80 95 int BreakLocation::CodeIterator::GetModeMask(BreakLocatorType type) {
81 int BreakLocation::Iterator::GetModeMask(BreakLocatorType type) {
82 int mask = 0; 96 int mask = 0;
83 mask |= RelocInfo::ModeMask(RelocInfo::POSITION); 97 mask |= RelocInfo::ModeMask(RelocInfo::POSITION);
84 mask |= RelocInfo::ModeMask(RelocInfo::STATEMENT_POSITION); 98 mask |= RelocInfo::ModeMask(RelocInfo::STATEMENT_POSITION);
85 mask |= RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT_AT_RETURN); 99 mask |= RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT_AT_RETURN);
86 mask |= RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT_AT_CALL); 100 mask |= RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT_AT_CALL);
87 if (type == ALL_BREAK_LOCATIONS) { 101 if (type == ALL_BREAK_LOCATIONS) {
88 mask |= RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT_AT_POSITION); 102 mask |= RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT_AT_POSITION);
89 mask |= RelocInfo::ModeMask(RelocInfo::DEBUGGER_STATEMENT); 103 mask |= RelocInfo::ModeMask(RelocInfo::DEBUGGER_STATEMENT);
90 } 104 }
91 return mask; 105 return mask;
92 } 106 }
93 107
94 108 void BreakLocation::CodeIterator::Next() {
95 void BreakLocation::Iterator::Next() {
96 DisallowHeapAllocation no_gc; 109 DisallowHeapAllocation no_gc;
97 DCHECK(!Done()); 110 DCHECK(!Done());
98 111
99 // Iterate through reloc info for code and original code stopping at each 112 // Iterate through reloc info for code and original code stopping at each
100 // breakable code target. 113 // breakable code target.
101 bool first = break_index_ == -1; 114 bool first = break_index_ == -1;
102 while (!Done()) { 115 while (!Done()) {
103 if (!first) reloc_iterator_.next(); 116 if (!first) reloc_iterator_.next();
104 first = false; 117 first = false;
105 if (Done()) return; 118 if (Done()) return;
(...skipping 26 matching lines...) Expand all
132 position_ = 0; 145 position_ = 0;
133 } 146 }
134 statement_position_ = position_; 147 statement_position_ = position_;
135 } 148 }
136 149
137 break; 150 break;
138 } 151 }
139 break_index_++; 152 break_index_++;
140 } 153 }
141 154
155 BreakLocation BreakLocation::CodeIterator::GetBreakLocation() {
156 DebugBreakType type;
157 if (RelocInfo::IsDebugBreakSlotAtReturn(rmode())) {
158 type = DEBUG_BREAK_SLOT_AT_RETURN;
159 } else if (RelocInfo::IsDebugBreakSlotAtCall(rmode())) {
160 type = DEBUG_BREAK_SLOT_AT_CALL;
161 } else if (RelocInfo::IsDebuggerStatement(rmode())) {
162 type = DEBUGGER_STATEMENT;
163 } else if (RelocInfo::IsDebugBreakSlot(rmode())) {
164 type = DEBUG_BREAK_SLOT;
165 } else {
166 type = NOT_DEBUG_BREAK;
167 }
168 return BreakLocation(debug_info_, type, code_offset(), position(),
169 statement_position());
170 }
142 171
143 // Find the break point at the supplied address, or the closest one before 172 // Find the break point at the supplied address, or the closest one before
144 // the address. 173 // the address.
145 BreakLocation BreakLocation::FromCodeOffset(Handle<DebugInfo> debug_info, 174 BreakLocation BreakLocation::FromCodeOffset(Handle<DebugInfo> debug_info,
146 int offset) { 175 int offset) {
147 Iterator it(debug_info, ALL_BREAK_LOCATIONS); 176 base::SmartPointer<Iterator> it(GetIterator(debug_info));
148 it.SkipTo(BreakIndexFromCodeOffset(debug_info, offset)); 177 it->SkipTo(BreakIndexFromCodeOffset(debug_info, offset));
149 return it.GetBreakLocation(); 178 return it->GetBreakLocation();
150 } 179 }
151 180
152 // Move GetFirstFrameSummary Definition to here as FromFrame use it. 181 // Move GetFirstFrameSummary Definition to here as FromFrame use it.
153 FrameSummary GetFirstFrameSummary(JavaScriptFrame* frame) { 182 FrameSummary GetFirstFrameSummary(JavaScriptFrame* frame) {
154 List<FrameSummary> frames(FLAG_max_inlining_levels + 1); 183 List<FrameSummary> frames(FLAG_max_inlining_levels + 1);
155 frame->Summarize(&frames); 184 frame->Summarize(&frames);
156 return frames.first(); 185 return frames.first();
157 } 186 }
158 187
159 BreakLocation BreakLocation::FromFrame(Handle<DebugInfo> debug_info, 188 BreakLocation BreakLocation::FromFrame(Handle<DebugInfo> debug_info,
160 JavaScriptFrame* frame) { 189 JavaScriptFrame* frame) {
161 // Code offset to the instruction after the current one, possibly a break 190 // Code offset to the instruction after the current one, possibly a break
162 // location as well. So the "- 1" to exclude it from the search. 191 // location as well. So the "- 1" to exclude it from the search.
163 // Get code offset from the unoptimized code. 192 // Get code offset from the unoptimized code.
164 FrameSummary summary = GetFirstFrameSummary(frame); 193 FrameSummary summary = GetFirstFrameSummary(frame);
165 return FromCodeOffset(debug_info, summary.code_offset() - 1); 194 return FromCodeOffset(debug_info, summary.code_offset() - 1);
166 } 195 }
167 196
168 // Find the break point at the supplied address, or the closest one before 197 // Find the break point at the supplied address, or the closest one before
169 // the address. 198 // the address.
170 void BreakLocation::FromCodeOffsetSameStatement( 199 void BreakLocation::FromCodeOffsetSameStatement(
171 Handle<DebugInfo> debug_info, int offset, List<BreakLocation>* result_out) { 200 Handle<DebugInfo> debug_info, int offset, List<BreakLocation>* result_out) {
172 int break_index = BreakIndexFromCodeOffset(debug_info, offset); 201 int break_index = BreakIndexFromCodeOffset(debug_info, offset);
173 Iterator it(debug_info, ALL_BREAK_LOCATIONS); 202 base::SmartPointer<Iterator> it(GetIterator(debug_info));
174 it.SkipTo(break_index); 203 it->SkipTo(break_index);
175 int statement_position = it.statement_position(); 204 int statement_position = it->statement_position();
176 while (!it.Done() && it.statement_position() == statement_position) { 205 while (!it->Done() && it->statement_position() == statement_position) {
177 result_out->Add(it.GetBreakLocation()); 206 result_out->Add(it->GetBreakLocation());
178 it.Next(); 207 it->Next();
179 } 208 }
180 } 209 }
181 210
182 211
183 void BreakLocation::AllForStatementPosition(Handle<DebugInfo> debug_info, 212 void BreakLocation::AllForStatementPosition(Handle<DebugInfo> debug_info,
184 int statement_position, 213 int statement_position,
185 List<BreakLocation>* result_out) { 214 List<BreakLocation>* result_out) {
186 for (Iterator it(debug_info, ALL_BREAK_LOCATIONS); !it.Done(); it.Next()) { 215 for (base::SmartPointer<Iterator> it(GetIterator(debug_info)); !it->Done();
187 if (it.statement_position() == statement_position) { 216 it->Next()) {
188 result_out->Add(it.GetBreakLocation()); 217 if (it->statement_position() == statement_position) {
218 result_out->Add(it->GetBreakLocation());
189 } 219 }
190 } 220 }
191 } 221 }
192 222
193 int BreakLocation::BreakIndexFromCodeOffset(Handle<DebugInfo> debug_info, 223 int BreakLocation::BreakIndexFromCodeOffset(Handle<DebugInfo> debug_info,
194 int offset) { 224 int offset) {
195 // Run through all break points to locate the one closest to the address. 225 // Run through all break points to locate the one closest to the address.
196 int closest_break = 0; 226 int closest_break = 0;
197 int distance = kMaxInt; 227 int distance = kMaxInt;
198 Code* code = debug_info->code(); 228 DCHECK(0 <= offset && offset < debug_info->abstract_code()->Size());
199 DCHECK(0 <= offset && offset < code->instruction_size()); 229 for (base::SmartPointer<Iterator> it(GetIterator(debug_info)); !it->Done();
200 Address pc = code->instruction_start() + offset; 230 it->Next()) {
201 for (Iterator it(debug_info, ALL_BREAK_LOCATIONS); !it.Done(); it.Next()) {
202 // Check if this break point is closer that what was previously found. 231 // Check if this break point is closer that what was previously found.
203 if (it.pc() <= pc && pc - it.pc() < distance) { 232 if (it->code_offset() <= offset && offset - it->code_offset() < distance) {
204 closest_break = it.break_index(); 233 closest_break = it->break_index();
205 distance = static_cast<int>(pc - it.pc()); 234 distance = offset - it->code_offset();
206 // Check whether we can't get any closer. 235 // Check whether we can't get any closer.
207 if (distance == 0) break; 236 if (distance == 0) break;
208 } 237 }
209 } 238 }
210 return closest_break; 239 return closest_break;
211 } 240 }
212 241
213 242
214 BreakLocation BreakLocation::FromPosition(Handle<DebugInfo> debug_info, 243 BreakLocation BreakLocation::FromPosition(Handle<DebugInfo> debug_info,
215 int position, 244 int position,
216 BreakPositionAlignment alignment) { 245 BreakPositionAlignment alignment) {
217 // Run through all break points to locate the one closest to the source 246 // Run through all break points to locate the one closest to the source
218 // position. 247 // position.
219 int closest_break = 0;
220 int distance = kMaxInt; 248 int distance = kMaxInt;
221 249 base::SmartPointer<Iterator> it(GetIterator(debug_info));
222 for (Iterator it(debug_info, ALL_BREAK_LOCATIONS); !it.Done(); it.Next()) { 250 BreakLocation closest_break = it->GetBreakLocation();
251 while (!it->Done()) {
223 int next_position; 252 int next_position;
224 if (alignment == STATEMENT_ALIGNED) { 253 if (alignment == STATEMENT_ALIGNED) {
225 next_position = it.statement_position(); 254 next_position = it->statement_position();
226 } else { 255 } else {
227 DCHECK(alignment == BREAK_POSITION_ALIGNED); 256 DCHECK(alignment == BREAK_POSITION_ALIGNED);
228 next_position = it.position(); 257 next_position = it->position();
229 } 258 }
230 if (position <= next_position && next_position - position < distance) { 259 if (position <= next_position && next_position - position < distance) {
231 closest_break = it.break_index(); 260 closest_break = it->GetBreakLocation();
232 distance = next_position - position; 261 distance = next_position - position;
233 // Check whether we can't get any closer. 262 // Check whether we can't get any closer.
234 if (distance == 0) break; 263 if (distance == 0) break;
235 } 264 }
265 it->Next();
236 } 266 }
237 267 return closest_break;
238 Iterator it(debug_info, ALL_BREAK_LOCATIONS);
239 it.SkipTo(closest_break);
240 return it.GetBreakLocation();
241 } 268 }
242 269
243 270
244 void BreakLocation::SetBreakPoint(Handle<Object> break_point_object) { 271 void BreakLocation::SetBreakPoint(Handle<Object> break_point_object) {
245 // If there is not already a real break point here patch code with debug 272 // If there is not already a real break point here patch code with debug
246 // break. 273 // break.
247 if (!HasBreakPoint()) SetDebugBreak(); 274 if (!HasBreakPoint()) SetDebugBreak();
248 DCHECK(IsDebugBreak() || IsDebuggerStatement()); 275 DCHECK(IsDebugBreak() || IsDebuggerStatement());
249 // Set the break point information. 276 // Set the break point information.
250 DebugInfo::SetBreakPoint(debug_info_, code_offset_, position_, 277 DebugInfo::SetBreakPoint(debug_info_, code_offset_, position_,
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
298 // Debugger statement always calls debugger. No need to modify it. 325 // Debugger statement always calls debugger. No need to modify it.
299 if (IsDebuggerStatement()) return; 326 if (IsDebuggerStatement()) return;
300 327
301 // If there is already a break point here just return. This might happen if 328 // If there is already a break point here just return. This might happen if
302 // the same code is flooded with break points twice. Flooding the same 329 // the same code is flooded with break points twice. Flooding the same
303 // function twice might happen when stepping in a function with an exception 330 // function twice might happen when stepping in a function with an exception
304 // handler as the handler and the function is the same. 331 // handler as the handler and the function is the same.
305 if (IsDebugBreak()) return; 332 if (IsDebugBreak()) return;
306 333
307 DCHECK(IsDebugBreakSlot()); 334 DCHECK(IsDebugBreakSlot());
308 Isolate* isolate = debug_info_->GetIsolate(); 335 if (abstract_code()->IsCode()) {
309 Builtins* builtins = isolate->builtins(); 336 Code* code = abstract_code()->GetCode();
310 Handle<Code> target = 337 DCHECK(code->kind() == Code::FUNCTION);
311 IsReturn() ? builtins->Return_DebugBreak() : builtins->Slot_DebugBreak(); 338 Builtins* builtins = isolate()->builtins();
312 DebugCodegen::PatchDebugBreakSlot(isolate, pc(), target); 339 Handle<Code> target = IsReturn() ? builtins->Return_DebugBreak()
313 DCHECK(IsDebugBreak()); 340 : builtins->Slot_DebugBreak();
341 Address pc = code->instruction_start() + code_offset();
342 DebugCodegen::PatchDebugBreakSlot(isolate(), pc, target);
343 DCHECK(IsDebugBreak());
344 } else {
345 UNIMPLEMENTED();
346 }
314 } 347 }
315 348
316 349
317 void BreakLocation::ClearDebugBreak() { 350 void BreakLocation::ClearDebugBreak() {
318 // Debugger statement always calls debugger. No need to modify it. 351 // Debugger statement always calls debugger. No need to modify it.
319 if (IsDebuggerStatement()) return; 352 if (IsDebuggerStatement()) return;
320 353
321 DCHECK(IsDebugBreakSlot()); 354 DCHECK(IsDebugBreakSlot());
322 DebugCodegen::ClearDebugBreakSlot(debug_info_->GetIsolate(), pc()); 355 if (abstract_code()->IsCode()) {
323 DCHECK(!IsDebugBreak()); 356 Code* code = abstract_code()->GetCode();
357 DCHECK(code->kind() == Code::FUNCTION);
358 Address pc = code->instruction_start() + code_offset();
359 DebugCodegen::ClearDebugBreakSlot(isolate(), pc);
360 DCHECK(!IsDebugBreak());
361 } else {
362 UNIMPLEMENTED();
363 }
324 } 364 }
325 365
326 366
327 bool BreakLocation::IsDebugBreak() const { 367 bool BreakLocation::IsDebugBreak() const {
328 if (IsDebuggerStatement()) return false; 368 if (IsDebuggerStatement()) return false;
329 DCHECK(IsDebugBreakSlot()); 369 DCHECK(IsDebugBreakSlot());
330 return rinfo().IsPatchedDebugBreakSlotSequence(); 370 if (abstract_code()->IsCode()) {
371 Code* code = abstract_code()->GetCode();
372 DCHECK(code->kind() == Code::FUNCTION);
373 Address pc = code->instruction_start() + code_offset();
374 return DebugCodegen::DebugBreakSlotIsPatched(pc);
375 } else {
376 UNIMPLEMENTED();
377 return false;
378 }
331 } 379 }
332 380
333 381
334 Handle<Object> BreakLocation::BreakPointObjects() const { 382 Handle<Object> BreakLocation::BreakPointObjects() const {
335 return debug_info_->GetBreakPointObjects(code_offset_); 383 return debug_info_->GetBreakPointObjects(code_offset_);
336 } 384 }
337 385
338
339 void DebugFeatureTracker::Track(DebugFeatureTracker::Feature feature) { 386 void DebugFeatureTracker::Track(DebugFeatureTracker::Feature feature) {
340 uint32_t mask = 1 << feature; 387 uint32_t mask = 1 << feature;
341 // Only count one sample per feature and isolate. 388 // Only count one sample per feature and isolate.
342 if (bitfield_ & mask) return; 389 if (bitfield_ & mask) return;
343 isolate_->counters()->debug_feature_usage()->AddSample(feature); 390 isolate_->counters()->debug_feature_usage()->AddSample(feature);
344 bitfield_ |= mask; 391 bitfield_ |= mask;
345 } 392 }
346 393
347 394
348 // Threading support. 395 // Threading support.
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
493 return; 540 return;
494 case StepOut: 541 case StepOut:
495 // Step out has not reached the target frame yet. 542 // Step out has not reached the target frame yet.
496 if (current_fp < target_fp) return; 543 if (current_fp < target_fp) return;
497 break; 544 break;
498 case StepNext: 545 case StepNext:
499 // Step next should not break in a deeper frame. 546 // Step next should not break in a deeper frame.
500 if (current_fp < target_fp) return; 547 if (current_fp < target_fp) return;
501 // Fall through. 548 // Fall through.
502 case StepIn: { 549 case StepIn: {
503 int offset = 550 FrameSummary summary = GetFirstFrameSummary(frame);
504 static_cast<int>(frame->pc() - location.code()->instruction_start()); 551 int offset = summary.code_offset();
505 step_break = location.IsReturn() || (current_fp != last_fp) || 552 step_break = location.IsReturn() || (current_fp != last_fp) ||
506 (thread_local_.last_statement_position_ != 553 (thread_local_.last_statement_position_ !=
507 location.code()->SourceStatementPosition(offset)); 554 location.abstract_code()->SourceStatementPosition(offset));
508 break; 555 break;
509 } 556 }
510 case StepFrame: 557 case StepFrame:
511 step_break = current_fp != last_fp; 558 step_break = current_fp != last_fp;
512 break; 559 break;
513 } 560 }
514 561
515 // Clear all current stepping setup. 562 // Clear all current stepping setup.
516 ClearStepping(); 563 ClearStepping();
517 564
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
737 } 784 }
738 } 785 }
739 786
740 787
741 // Clear out all the debug break code. This is ONLY supposed to be used when 788 // Clear out all the debug break code. This is ONLY supposed to be used when
742 // shutting down the debugger as it will leave the break point information in 789 // shutting down the debugger as it will leave the break point information in
743 // DebugInfo even though the code is patched back to the non break point state. 790 // DebugInfo even though the code is patched back to the non break point state.
744 void Debug::ClearAllBreakPoints() { 791 void Debug::ClearAllBreakPoints() {
745 for (DebugInfoListNode* node = debug_info_list_; node != NULL; 792 for (DebugInfoListNode* node = debug_info_list_; node != NULL;
746 node = node->next()) { 793 node = node->next()) {
747 for (BreakLocation::Iterator it(node->debug_info(), ALL_BREAK_LOCATIONS); 794 for (base::SmartPointer<BreakLocation::Iterator> it(
748 !it.Done(); it.Next()) { 795 BreakLocation::GetIterator(node->debug_info()));
749 it.GetBreakLocation().ClearDebugBreak(); 796 !it->Done(); it->Next()) {
797 it->GetBreakLocation().ClearDebugBreak();
750 } 798 }
751 } 799 }
752 // Remove all debug info. 800 // Remove all debug info.
753 while (debug_info_list_ != NULL) { 801 while (debug_info_list_ != NULL) {
754 RemoveDebugInfoAndClearFromShared(debug_info_list_->debug_info()); 802 RemoveDebugInfoAndClearFromShared(debug_info_list_->debug_info());
755 } 803 }
756 } 804 }
757 805
758 806
759 void Debug::FloodWithOneShot(Handle<JSFunction> function, 807 void Debug::FloodWithOneShot(Handle<JSFunction> function,
(...skipping 10 matching lines...) Expand all
770 } 818 }
771 // Make sure the function is compiled and has set up the debug info. 819 // Make sure the function is compiled and has set up the debug info.
772 Handle<SharedFunctionInfo> shared(function->shared()); 820 Handle<SharedFunctionInfo> shared(function->shared());
773 if (!EnsureDebugInfo(shared, function)) { 821 if (!EnsureDebugInfo(shared, function)) {
774 // Return if we failed to retrieve the debug info. 822 // Return if we failed to retrieve the debug info.
775 return; 823 return;
776 } 824 }
777 825
778 // Flood the function with break points. 826 // Flood the function with break points.
779 Handle<DebugInfo> debug_info(shared->GetDebugInfo()); 827 Handle<DebugInfo> debug_info(shared->GetDebugInfo());
780 for (BreakLocation::Iterator it(debug_info, type); !it.Done(); it.Next()) { 828 for (base::SmartPointer<BreakLocation::Iterator> it(
781 it.GetBreakLocation().SetOneShot(); 829 BreakLocation::GetIterator(debug_info, type));
830 !it->Done(); it->Next()) {
831 it->GetBreakLocation().SetOneShot();
782 } 832 }
783 } 833 }
784 834
785 835
786 void Debug::ChangeBreakOnException(ExceptionBreakType type, bool enable) { 836 void Debug::ChangeBreakOnException(ExceptionBreakType type, bool enable) {
787 if (type == BreakUncaughtException) { 837 if (type == BreakUncaughtException) {
788 break_on_uncaught_exception_ = enable; 838 break_on_uncaught_exception_ = enable;
789 } else { 839 } else {
790 break_on_exception_ = enable; 840 break_on_exception_ = enable;
791 } 841 }
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
891 941
892 // PC points to the instruction after the current one, possibly a break 942 // PC points to the instruction after the current one, possibly a break
893 // location as well. So the "- 1" to exclude it from the search. 943 // location as well. So the "- 1" to exclude it from the search.
894 BreakLocation location = 944 BreakLocation location =
895 BreakLocation::FromCodeOffset(debug_info, summary.code_offset() - 1); 945 BreakLocation::FromCodeOffset(debug_info, summary.code_offset() - 1);
896 946
897 // At a return statement we will step out either way. 947 // At a return statement we will step out either way.
898 if (location.IsReturn()) step_action = StepOut; 948 if (location.IsReturn()) step_action = StepOut;
899 949
900 thread_local_.last_statement_position_ = 950 thread_local_.last_statement_position_ =
901 debug_info->code()->SourceStatementPosition(summary.code_offset()); 951 debug_info->abstract_code()->SourceStatementPosition(
952 summary.code_offset());
902 thread_local_.last_fp_ = frame->UnpaddedFP(); 953 thread_local_.last_fp_ = frame->UnpaddedFP();
903 954
904 switch (step_action) { 955 switch (step_action) {
905 case StepNone: 956 case StepNone:
906 UNREACHABLE(); 957 UNREACHABLE();
907 break; 958 break;
908 case StepOut: 959 case StepOut:
909 // Advance to caller frame. 960 // Advance to caller frame.
910 frames_it.Advance(); 961 frames_it.Advance();
911 // Skip native and extension functions on the stack. 962 // Skip native and extension functions on the stack.
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
998 1049
999 // Clears all the one-shot break points that are currently set. Normally this 1050 // Clears all the one-shot break points that are currently set. Normally this
1000 // function is called each time a break point is hit as one shot break points 1051 // function is called each time a break point is hit as one shot break points
1001 // are used to support stepping. 1052 // are used to support stepping.
1002 void Debug::ClearOneShot() { 1053 void Debug::ClearOneShot() {
1003 // The current implementation just runs through all the breakpoints. When the 1054 // The current implementation just runs through all the breakpoints. When the
1004 // last break point for a function is removed that function is automatically 1055 // last break point for a function is removed that function is automatically
1005 // removed from the list. 1056 // removed from the list.
1006 for (DebugInfoListNode* node = debug_info_list_; node != NULL; 1057 for (DebugInfoListNode* node = debug_info_list_; node != NULL;
1007 node = node->next()) { 1058 node = node->next()) {
1008 for (BreakLocation::Iterator it(node->debug_info(), ALL_BREAK_LOCATIONS); 1059 for (base::SmartPointer<BreakLocation::Iterator> it(
1009 !it.Done(); it.Next()) { 1060 BreakLocation::GetIterator(node->debug_info()));
1010 it.GetBreakLocation().ClearOneShot(); 1061 !it->Done(); it->Next()) {
1062 it->GetBreakLocation().ClearOneShot();
1011 } 1063 }
1012 } 1064 }
1013 } 1065 }
1014 1066
1015 1067
1016 void Debug::EnableStepIn() { 1068 void Debug::EnableStepIn() {
1017 STATIC_ASSERT(StepFrame > StepIn); 1069 STATIC_ASSERT(StepFrame > StepIn);
1018 thread_local_.step_in_enabled_ = (last_step_action() >= StepIn); 1070 thread_local_.step_in_enabled_ = (last_step_action() >= StepIn);
1019 } 1071 }
1020 1072
(...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after
1431 1483
1432 bool Debug::IsBreakAtReturn(JavaScriptFrame* frame) { 1484 bool Debug::IsBreakAtReturn(JavaScriptFrame* frame) {
1433 HandleScope scope(isolate_); 1485 HandleScope scope(isolate_);
1434 1486
1435 // Get the executing function in which the debug break occurred. 1487 // Get the executing function in which the debug break occurred.
1436 Handle<JSFunction> function(JSFunction::cast(frame->function())); 1488 Handle<JSFunction> function(JSFunction::cast(frame->function()));
1437 Handle<SharedFunctionInfo> shared(function->shared()); 1489 Handle<SharedFunctionInfo> shared(function->shared());
1438 1490
1439 // With no debug info there are no break points, so we can't be at a return. 1491 // With no debug info there are no break points, so we can't be at a return.
1440 if (!shared->HasDebugInfo()) return false; 1492 if (!shared->HasDebugInfo()) return false;
1493
1494 DCHECK(!frame->is_optimized());
1495 FrameSummary summary = GetFirstFrameSummary(frame);
1496
1441 Handle<DebugInfo> debug_info(shared->GetDebugInfo()); 1497 Handle<DebugInfo> debug_info(shared->GetDebugInfo());
1442 Handle<Code> code(debug_info->code()); 1498 BreakLocation location =
1443 #ifdef DEBUG 1499 BreakLocation::FromCodeOffset(debug_info, summary.code_offset());
1444 // Get the code which is actually executing. 1500 return location.IsReturn();
1445 Handle<Code> frame_code(frame->LookupCode());
1446 DCHECK(frame_code.is_identical_to(code));
1447 #endif
1448
1449 // Find the reloc info matching the start of the debug break slot.
1450 Address slot_pc = frame->pc() - Assembler::kDebugBreakSlotLength;
1451 int mask = RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT_AT_RETURN);
1452 for (RelocIterator it(*code, mask); !it.done(); it.next()) {
1453 if (it.rinfo()->pc() == slot_pc) return true;
1454 }
1455 return false;
1456 } 1501 }
1457 1502
1458 1503
1459 void Debug::FramesHaveBeenDropped(StackFrame::Id new_break_frame_id, 1504 void Debug::FramesHaveBeenDropped(StackFrame::Id new_break_frame_id,
1460 LiveEdit::FrameDropMode mode) { 1505 LiveEdit::FrameDropMode mode) {
1461 if (mode != LiveEdit::CURRENTLY_SET_MODE) { 1506 if (mode != LiveEdit::CURRENTLY_SET_MODE) {
1462 thread_local_.frame_drop_mode_ = mode; 1507 thread_local_.frame_drop_mode_ = mode;
1463 } 1508 }
1464 thread_local_.break_frame_id_ = new_break_frame_id; 1509 thread_local_.break_frame_id_ = new_break_frame_id;
1465 } 1510 }
(...skipping 994 matching lines...) Expand 10 before | Expand all | Expand 10 after
2460 } 2505 }
2461 2506
2462 2507
2463 void LockingCommandMessageQueue::Clear() { 2508 void LockingCommandMessageQueue::Clear() {
2464 base::LockGuard<base::Mutex> lock_guard(&mutex_); 2509 base::LockGuard<base::Mutex> lock_guard(&mutex_);
2465 queue_.Clear(); 2510 queue_.Clear();
2466 } 2511 }
2467 2512
2468 } // namespace internal 2513 } // namespace internal
2469 } // namespace v8 2514 } // namespace v8
OLDNEW
« no previous file with comments | « src/debug/debug.h ('k') | src/debug/ia32/debug-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698