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

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

Issue 1618343002: [interpreter, debugger] abstraction for source position calculation. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: remove bogus assertion 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/debug-frames.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
62 BreakLocation::BreakLocation(Handle<DebugInfo> debug_info, RelocInfo* rinfo, 61 BreakLocation::BreakLocation(Handle<DebugInfo> debug_info, RelocInfo* rinfo,
63 int position, int statement_position) 62 int position, int statement_position)
64 : debug_info_(debug_info), 63 : debug_info_(debug_info),
65 pc_offset_(static_cast<int>(rinfo->pc() - debug_info->code()->entry())), 64 code_offset_(static_cast<int>(rinfo->pc() - debug_info->code()->entry())),
66 rmode_(rinfo->rmode()), 65 rmode_(rinfo->rmode()),
67 data_(rinfo->data()), 66 data_(rinfo->data()),
68 position_(position), 67 position_(position),
69 statement_position_(statement_position) {} 68 statement_position_(statement_position) {}
70 69
71
72 BreakLocation::Iterator::Iterator(Handle<DebugInfo> debug_info, 70 BreakLocation::Iterator::Iterator(Handle<DebugInfo> debug_info,
73 BreakLocatorType type) 71 BreakLocatorType type)
74 : debug_info_(debug_info), 72 : debug_info_(debug_info),
75 reloc_iterator_(debug_info->code(), GetModeMask(type)), 73 reloc_iterator_(debug_info->code(), GetModeMask(type)),
76 break_index_(-1), 74 break_index_(-1),
77 position_(1), 75 position_(1),
78 statement_position_(1) { 76 statement_position_(1) {
79 if (!Done()) Next(); 77 if (!Done()) Next();
80 } 78 }
81 79
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
137 } 135 }
138 136
139 break; 137 break;
140 } 138 }
141 break_index_++; 139 break_index_++;
142 } 140 }
143 141
144 142
145 // Find the break point at the supplied address, or the closest one before 143 // Find the break point at the supplied address, or the closest one before
146 // the address. 144 // the address.
147 BreakLocation BreakLocation::FromAddress(Handle<DebugInfo> debug_info, 145 BreakLocation BreakLocation::FromCodeOffset(Handle<DebugInfo> debug_info,
148 Address pc) { 146 int offset) {
149 Iterator it(debug_info, ALL_BREAK_LOCATIONS); 147 Iterator it(debug_info, ALL_BREAK_LOCATIONS);
150 it.SkipTo(BreakIndexFromAddress(debug_info, pc)); 148 it.SkipTo(BreakIndexFromCodeOffset(debug_info, offset));
151 return it.GetBreakLocation(); 149 return it.GetBreakLocation();
152 } 150 }
153 151
152 BreakLocation BreakLocation::FromFrame(Handle<DebugInfo> debug_info,
153 JavaScriptFrame* frame) {
154 // Code offset to the instruction after the current one, possibly a break
155 // location as well. So the "- 1" to exclude it from the search.
156 Code* code = frame->LookupCode();
157 int code_offset = static_cast<int>(frame->pc() - code->instruction_start());
158 return FromCodeOffset(debug_info, code_offset - 1);
159 }
154 160
155 // Find the break point at the supplied address, or the closest one before 161 // Find the break point at the supplied address, or the closest one before
156 // the address. 162 // the address.
157 void BreakLocation::FromAddressSameStatement(Handle<DebugInfo> debug_info, 163 void BreakLocation::FromCodeOffsetSameStatement(
158 Address pc, 164 Handle<DebugInfo> debug_info, int offset, List<BreakLocation>* result_out) {
159 List<BreakLocation>* result_out) { 165 int break_index = BreakIndexFromCodeOffset(debug_info, offset);
160 int break_index = BreakIndexFromAddress(debug_info, pc);
161 Iterator it(debug_info, ALL_BREAK_LOCATIONS); 166 Iterator it(debug_info, ALL_BREAK_LOCATIONS);
162 it.SkipTo(break_index); 167 it.SkipTo(break_index);
163 int statement_position = it.statement_position(); 168 int statement_position = it.statement_position();
164 while (!it.Done() && it.statement_position() == statement_position) { 169 while (!it.Done() && it.statement_position() == statement_position) {
165 result_out->Add(it.GetBreakLocation()); 170 result_out->Add(it.GetBreakLocation());
166 it.Next(); 171 it.Next();
167 } 172 }
168 } 173 }
169 174
170 175
171 // Find all break locations with the given statement position.
172 void BreakLocation::AllForStatementPosition(Handle<DebugInfo> debug_info, 176 void BreakLocation::AllForStatementPosition(Handle<DebugInfo> debug_info,
173 int statement_position, 177 int statement_position,
174 List<BreakLocation>* result_out) { 178 List<BreakLocation>* result_out) {
175 for (Iterator it(debug_info, ALL_BREAK_LOCATIONS); !it.Done(); it.Next()) { 179 for (Iterator it(debug_info, ALL_BREAK_LOCATIONS); !it.Done(); it.Next()) {
176 if (it.statement_position() == statement_position) { 180 if (it.statement_position() == statement_position) {
177 result_out->Add(it.GetBreakLocation()); 181 result_out->Add(it.GetBreakLocation());
178 } 182 }
179 } 183 }
180 } 184 }
181 185
182 186 int BreakLocation::BreakIndexFromCodeOffset(Handle<DebugInfo> debug_info,
183 int BreakLocation::BreakIndexFromAddress(Handle<DebugInfo> debug_info, 187 int offset) {
184 Address pc) {
185 // Run through all break points to locate the one closest to the address. 188 // Run through all break points to locate the one closest to the address.
186 int closest_break = 0; 189 int closest_break = 0;
187 int distance = kMaxInt; 190 int distance = kMaxInt;
191 Code* code = debug_info->code();
192 DCHECK(0 <= offset && offset < code->instruction_size());
193 Address pc = code->instruction_start() + offset;
188 for (Iterator it(debug_info, ALL_BREAK_LOCATIONS); !it.Done(); it.Next()) { 194 for (Iterator it(debug_info, ALL_BREAK_LOCATIONS); !it.Done(); it.Next()) {
189 // Check if this break point is closer that what was previously found. 195 // Check if this break point is closer that what was previously found.
190 if (it.pc() <= pc && pc - it.pc() < distance) { 196 if (it.pc() <= pc && pc - it.pc() < distance) {
191 closest_break = it.break_index(); 197 closest_break = it.break_index();
192 distance = static_cast<int>(pc - it.pc()); 198 distance = static_cast<int>(pc - it.pc());
193 // Check whether we can't get any closer. 199 // Check whether we can't get any closer.
194 if (distance == 0) break; 200 if (distance == 0) break;
195 } 201 }
196 } 202 }
197 return closest_break; 203 return closest_break;
(...skipping 29 matching lines...) Expand all
227 return it.GetBreakLocation(); 233 return it.GetBreakLocation();
228 } 234 }
229 235
230 236
231 void BreakLocation::SetBreakPoint(Handle<Object> break_point_object) { 237 void BreakLocation::SetBreakPoint(Handle<Object> break_point_object) {
232 // If there is not already a real break point here patch code with debug 238 // If there is not already a real break point here patch code with debug
233 // break. 239 // break.
234 if (!HasBreakPoint()) SetDebugBreak(); 240 if (!HasBreakPoint()) SetDebugBreak();
235 DCHECK(IsDebugBreak() || IsDebuggerStatement()); 241 DCHECK(IsDebugBreak() || IsDebuggerStatement());
236 // Set the break point information. 242 // Set the break point information.
237 DebugInfo::SetBreakPoint(debug_info_, pc_offset_, position_, 243 DebugInfo::SetBreakPoint(debug_info_, code_offset_, position_,
238 statement_position_, break_point_object); 244 statement_position_, break_point_object);
239 } 245 }
240 246
241 247
242 void BreakLocation::ClearBreakPoint(Handle<Object> break_point_object) { 248 void BreakLocation::ClearBreakPoint(Handle<Object> break_point_object) {
243 // Clear the break point information. 249 // Clear the break point information.
244 DebugInfo::ClearBreakPoint(debug_info_, pc_offset_, break_point_object); 250 DebugInfo::ClearBreakPoint(debug_info_, code_offset_, break_point_object);
245 // If there are no more break points here remove the debug break. 251 // If there are no more break points here remove the debug break.
246 if (!HasBreakPoint()) { 252 if (!HasBreakPoint()) {
247 ClearDebugBreak(); 253 ClearDebugBreak();
248 DCHECK(!IsDebugBreak()); 254 DCHECK(!IsDebugBreak());
249 } 255 }
250 } 256 }
251 257
252 258
253 void BreakLocation::SetOneShot() { 259 void BreakLocation::SetOneShot() {
254 // Debugger statement always calls debugger. No need to modify it. 260 // Debugger statement always calls debugger. No need to modify it.
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
312 318
313 319
314 bool BreakLocation::IsDebugBreak() const { 320 bool BreakLocation::IsDebugBreak() const {
315 if (IsDebuggerStatement()) return false; 321 if (IsDebuggerStatement()) return false;
316 DCHECK(IsDebugBreakSlot()); 322 DCHECK(IsDebugBreakSlot());
317 return rinfo().IsPatchedDebugBreakSlotSequence(); 323 return rinfo().IsPatchedDebugBreakSlotSequence();
318 } 324 }
319 325
320 326
321 Handle<Object> BreakLocation::BreakPointObjects() const { 327 Handle<Object> BreakLocation::BreakPointObjects() const {
322 return debug_info_->GetBreakPointObjects(pc_offset_); 328 return debug_info_->GetBreakPointObjects(code_offset_);
323 } 329 }
324 330
325 331
326 void DebugFeatureTracker::Track(DebugFeatureTracker::Feature feature) { 332 void DebugFeatureTracker::Track(DebugFeatureTracker::Feature feature) {
327 uint32_t mask = 1 << feature; 333 uint32_t mask = 1 << feature;
328 // Only count one sample per feature and isolate. 334 // Only count one sample per feature and isolate.
329 if (bitfield_ & mask) return; 335 if (bitfield_ & mask) return;
330 isolate_->counters()->debug_feature_usage()->AddSample(feature); 336 isolate_->counters()->debug_feature_usage()->AddSample(feature);
331 bitfield_ |= mask; 337 bitfield_ |= mask;
332 } 338 }
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
479 case StepNone: 485 case StepNone:
480 return; 486 return;
481 case StepOut: 487 case StepOut:
482 // Step out has not reached the target frame yet. 488 // Step out has not reached the target frame yet.
483 if (current_fp < target_fp) return; 489 if (current_fp < target_fp) return;
484 break; 490 break;
485 case StepNext: 491 case StepNext:
486 // Step next should not break in a deeper frame. 492 // Step next should not break in a deeper frame.
487 if (current_fp < target_fp) return; 493 if (current_fp < target_fp) return;
488 // Fall through. 494 // Fall through.
489 case StepIn: 495 case StepIn: {
496 int offset =
497 static_cast<int>(frame->pc() - location.code()->instruction_start());
490 step_break = location.IsReturn() || (current_fp != last_fp) || 498 step_break = location.IsReturn() || (current_fp != last_fp) ||
491 (thread_local_.last_statement_position_ != 499 (thread_local_.last_statement_position_ !=
492 location.code()->SourceStatementPosition(frame->pc())); 500 location.code()->SourceStatementPosition(offset));
493 break; 501 break;
502 }
494 case StepFrame: 503 case StepFrame:
495 step_break = current_fp != last_fp; 504 step_break = current_fp != last_fp;
496 break; 505 break;
497 } 506 }
498 507
499 // Clear all current stepping setup. 508 // Clear all current stepping setup.
500 ClearStepping(); 509 ClearStepping();
501 510
502 if (step_break) { 511 if (step_break) {
503 // Notify the debug event listeners. 512 // Notify the debug event listeners.
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
698 DebugInfoListNode* node = debug_info_list_; 707 DebugInfoListNode* node = debug_info_list_;
699 while (node != NULL) { 708 while (node != NULL) {
700 Handle<Object> result = 709 Handle<Object> result =
701 DebugInfo::FindBreakPointInfo(node->debug_info(), break_point_object); 710 DebugInfo::FindBreakPointInfo(node->debug_info(), break_point_object);
702 if (!result->IsUndefined()) { 711 if (!result->IsUndefined()) {
703 // Get information in the break point. 712 // Get information in the break point.
704 Handle<BreakPointInfo> break_point_info = 713 Handle<BreakPointInfo> break_point_info =
705 Handle<BreakPointInfo>::cast(result); 714 Handle<BreakPointInfo>::cast(result);
706 Handle<DebugInfo> debug_info = node->debug_info(); 715 Handle<DebugInfo> debug_info = node->debug_info();
707 716
708 // Find the break point and clear it. 717 BreakLocation location = BreakLocation::FromCodeOffset(
709 Address pc = 718 debug_info, break_point_info->code_offset());
710 debug_info->code()->entry() + break_point_info->code_position();
711
712 BreakLocation location = BreakLocation::FromAddress(debug_info, pc);
713 location.ClearBreakPoint(break_point_object); 719 location.ClearBreakPoint(break_point_object);
714 720
715 // If there are no more break points left remove the debug info for this 721 // If there are no more break points left remove the debug info for this
716 // function. 722 // function.
717 if (debug_info->GetBreakPointCount() == 0) { 723 if (debug_info->GetBreakPointCount() == 0) {
718 RemoveDebugInfoAndClearFromShared(debug_info); 724 RemoveDebugInfoAndClearFromShared(debug_info);
719 } 725 }
720 726
721 return; 727 return;
722 } 728 }
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
873 FrameSummary summary = GetFirstFrameSummary(frame); 879 FrameSummary summary = GetFirstFrameSummary(frame);
874 Handle<JSFunction> function(summary.function()); 880 Handle<JSFunction> function(summary.function());
875 Handle<SharedFunctionInfo> shared(function->shared()); 881 Handle<SharedFunctionInfo> shared(function->shared());
876 if (!EnsureDebugInfo(shared, function)) { 882 if (!EnsureDebugInfo(shared, function)) {
877 // Return if ensuring debug info failed. 883 // Return if ensuring debug info failed.
878 return; 884 return;
879 } 885 }
880 886
881 Handle<DebugInfo> debug_info(shared->GetDebugInfo()); 887 Handle<DebugInfo> debug_info(shared->GetDebugInfo());
882 // Refresh frame summary if the code has been recompiled for debugging. 888 // Refresh frame summary if the code has been recompiled for debugging.
883 if (shared->code() != *summary.code()) summary = GetFirstFrameSummary(frame); 889 if (AbstractCode::cast(shared->code()) != *summary.abstract_code()) {
890 summary = GetFirstFrameSummary(frame);
891 }
884 892
885 // PC points to the instruction after the current one, possibly a break 893 // PC points to the instruction after the current one, possibly a break
886 // location as well. So the "- 1" to exclude it from the search. 894 // location as well. So the "- 1" to exclude it from the search.
887 BreakLocation location = BreakLocation::FromFrame(debug_info, &summary); 895 BreakLocation location =
896 BreakLocation::FromCodeOffset(debug_info, summary.code_offset() - 1);
888 897
889 // At a return statement we will step out either way. 898 // At a return statement we will step out either way.
890 if (location.IsReturn()) step_action = StepOut; 899 if (location.IsReturn()) step_action = StepOut;
891 900
892 thread_local_.last_statement_position_ = 901 thread_local_.last_statement_position_ =
893 debug_info->code()->SourceStatementPosition(summary.pc()); 902 debug_info->code()->SourceStatementPosition(summary.code_offset());
894 thread_local_.last_fp_ = frame->UnpaddedFP(); 903 thread_local_.last_fp_ = frame->UnpaddedFP();
895 904
896 switch (step_action) { 905 switch (step_action) {
897 case StepNone: 906 case StepNone:
898 UNREACHABLE(); 907 UNREACHABLE();
899 break; 908 break;
900 case StepOut: 909 case StepOut:
901 // Advance to caller frame. 910 // Advance to caller frame.
902 frames_it.Advance(); 911 frames_it.Advance();
903 // Skip native and extension functions on the stack. 912 // Skip native and extension functions on the stack.
(...skipping 591 matching lines...) Expand 10 before | Expand all | Expand 10 after
1495 List<int>* results_out) { 1504 List<int>* results_out) {
1496 FrameSummary summary = GetFirstFrameSummary(frame); 1505 FrameSummary summary = GetFirstFrameSummary(frame);
1497 1506
1498 Handle<JSFunction> fun = Handle<JSFunction>(summary.function()); 1507 Handle<JSFunction> fun = Handle<JSFunction>(summary.function());
1499 Handle<SharedFunctionInfo> shared = Handle<SharedFunctionInfo>(fun->shared()); 1508 Handle<SharedFunctionInfo> shared = Handle<SharedFunctionInfo>(fun->shared());
1500 1509
1501 if (!EnsureDebugInfo(shared, fun)) return; 1510 if (!EnsureDebugInfo(shared, fun)) return;
1502 1511
1503 Handle<DebugInfo> debug_info(shared->GetDebugInfo()); 1512 Handle<DebugInfo> debug_info(shared->GetDebugInfo());
1504 // Refresh frame summary if the code has been recompiled for debugging. 1513 // Refresh frame summary if the code has been recompiled for debugging.
1505 if (shared->code() != *summary.code()) summary = GetFirstFrameSummary(frame); 1514 if (AbstractCode::cast(shared->code()) != *summary.abstract_code()) {
1515 summary = GetFirstFrameSummary(frame);
1516 }
1506 1517
1507 // Find range of break points starting from the break point where execution 1518 // Find range of break points starting from the break point where execution
1508 // has stopped. 1519 // has stopped. The code offset points to the instruction after the current
1509 Address call_pc = summary.pc() - 1; 1520 // possibly a break location, too. Subtract one to exclude it from the search.
1521 int call_offset = summary.code_offset() - 1;
1510 List<BreakLocation> locations; 1522 List<BreakLocation> locations;
1511 BreakLocation::FromAddressSameStatement(debug_info, call_pc, &locations); 1523 BreakLocation::FromCodeOffsetSameStatement(debug_info, call_offset,
1524 &locations);
1512 1525
1513 for (BreakLocation location : locations) { 1526 for (BreakLocation location : locations) {
1514 if (location.pc() <= summary.pc()) { 1527 if (location.code_offset() <= summary.code_offset()) {
1515 // The break point is near our pc. Could be a step-in possibility, 1528 // The break point is near our pc. Could be a step-in possibility,
1516 // that is currently taken by active debugger call. 1529 // that is currently taken by active debugger call.
1517 if (break_frame_id() == StackFrame::NO_ID) { 1530 if (break_frame_id() == StackFrame::NO_ID) {
1518 continue; // We are not stepping. 1531 continue; // We are not stepping.
1519 } else { 1532 } else {
1520 JavaScriptFrameIterator frame_it(isolate_, break_frame_id()); 1533 JavaScriptFrameIterator frame_it(isolate_, break_frame_id());
1521 // If our frame is a top frame and we are stepping, we can do step-in 1534 // If our frame is a top frame and we are stepping, we can do step-in
1522 // at this place. 1535 // at this place.
1523 if (frame_it.frame()->id() != frame_id) continue; 1536 if (frame_it.frame()->id() != frame_id) continue;
1524 } 1537 }
(...skipping 923 matching lines...) Expand 10 before | Expand all | Expand 10 after
2448 } 2461 }
2449 2462
2450 2463
2451 void LockingCommandMessageQueue::Clear() { 2464 void LockingCommandMessageQueue::Clear() {
2452 base::LockGuard<base::Mutex> lock_guard(&mutex_); 2465 base::LockGuard<base::Mutex> lock_guard(&mutex_);
2453 queue_.Clear(); 2466 queue_.Clear();
2454 } 2467 }
2455 2468
2456 } // namespace internal 2469 } // namespace internal
2457 } // namespace v8 2470 } // namespace v8
OLDNEW
« no previous file with comments | « src/debug/debug.h ('k') | src/debug/debug-frames.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698