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

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

Issue 1682853004: [interpreter, debugger] implement bytecode break location iterator. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: fix build 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/interpreter/bytecode-array-builder.h » ('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"
11 #include "src/codegen.h" 11 #include "src/codegen.h"
12 #include "src/compilation-cache.h" 12 #include "src/compilation-cache.h"
13 #include "src/compiler.h" 13 #include "src/compiler.h"
14 #include "src/deoptimizer.h" 14 #include "src/deoptimizer.h"
15 #include "src/execution.h" 15 #include "src/execution.h"
16 #include "src/frames-inl.h" 16 #include "src/frames-inl.h"
17 #include "src/full-codegen/full-codegen.h" 17 #include "src/full-codegen/full-codegen.h"
18 #include "src/global-handles.h" 18 #include "src/global-handles.h"
19 #include "src/interpreter/bytecodes.h"
19 #include "src/isolate-inl.h" 20 #include "src/isolate-inl.h"
20 #include "src/list.h" 21 #include "src/list.h"
21 #include "src/log.h" 22 #include "src/log.h"
22 #include "src/messages.h" 23 #include "src/messages.h"
23 #include "src/snapshot/natives.h" 24 #include "src/snapshot/natives.h"
24 25
25 #include "include/v8-debug.h" 26 #include "include/v8-debug.h"
26 27
27 namespace v8 { 28 namespace v8 {
28 namespace internal { 29 namespace internal {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
62 int code_offset, int position, 63 int code_offset, int position,
63 int statement_position) 64 int statement_position)
64 : debug_info_(debug_info), 65 : debug_info_(debug_info),
65 code_offset_(code_offset), 66 code_offset_(code_offset),
66 type_(type), 67 type_(type),
67 position_(position), 68 position_(position),
68 statement_position_(statement_position) {} 69 statement_position_(statement_position) {}
69 70
70 BreakLocation::Iterator* BreakLocation::GetIterator( 71 BreakLocation::Iterator* BreakLocation::GetIterator(
71 Handle<DebugInfo> debug_info, BreakLocatorType type) { 72 Handle<DebugInfo> debug_info, BreakLocatorType type) {
72 if (debug_info->shared()->HasBytecodeArray()) { 73 if (debug_info->abstract_code()->IsBytecodeArray()) {
73 UNIMPLEMENTED(); 74 return new BytecodeArrayIterator(debug_info, type);
74 return nullptr; 75 } else {
76 return new CodeIterator(debug_info, type);
75 } 77 }
76 return new CodeIterator(debug_info, type);
77 } 78 }
78 79
79 BreakLocation::Iterator::Iterator(Handle<DebugInfo> debug_info, 80 BreakLocation::Iterator::Iterator(Handle<DebugInfo> debug_info)
80 BreakLocatorType type)
81 : debug_info_(debug_info), 81 : debug_info_(debug_info),
82 break_index_(-1), 82 break_index_(-1),
83 position_(1), 83 position_(1),
84 statement_position_(1) { 84 statement_position_(1) {}
85 }
86 85
87 BreakLocation::CodeIterator::CodeIterator(Handle<DebugInfo> debug_info, 86 BreakLocation::CodeIterator::CodeIterator(Handle<DebugInfo> debug_info,
88 BreakLocatorType type) 87 BreakLocatorType type)
89 : Iterator(debug_info, type), 88 : Iterator(debug_info),
90 reloc_iterator_(debug_info->abstract_code()->GetCode(), 89 reloc_iterator_(debug_info->abstract_code()->GetCode(),
91 GetModeMask(type)) { 90 GetModeMask(type)) {
92 if (!Done()) Next(); 91 if (!Done()) Next();
93 } 92 }
94 93
95 int BreakLocation::CodeIterator::GetModeMask(BreakLocatorType type) { 94 int BreakLocation::CodeIterator::GetModeMask(BreakLocatorType type) {
96 int mask = 0; 95 int mask = 0;
97 mask |= RelocInfo::ModeMask(RelocInfo::POSITION); 96 mask |= RelocInfo::ModeMask(RelocInfo::POSITION);
98 mask |= RelocInfo::ModeMask(RelocInfo::STATEMENT_POSITION); 97 mask |= RelocInfo::ModeMask(RelocInfo::STATEMENT_POSITION);
99 mask |= RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT_AT_RETURN); 98 mask |= RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT_AT_RETURN);
100 mask |= RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT_AT_CALL); 99 mask |= RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT_AT_CALL);
101 if (type == ALL_BREAK_LOCATIONS) { 100 if (type == ALL_BREAK_LOCATIONS) {
102 mask |= RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT_AT_POSITION); 101 mask |= RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT_AT_POSITION);
103 mask |= RelocInfo::ModeMask(RelocInfo::DEBUGGER_STATEMENT); 102 mask |= RelocInfo::ModeMask(RelocInfo::DEBUGGER_STATEMENT);
104 } 103 }
105 return mask; 104 return mask;
106 } 105 }
107 106
108 void BreakLocation::CodeIterator::Next() { 107 void BreakLocation::CodeIterator::Next() {
109 DisallowHeapAllocation no_gc; 108 DisallowHeapAllocation no_gc;
110 DCHECK(!Done()); 109 DCHECK(!Done());
111 110
112 // Iterate through reloc info for code and original code stopping at each 111 // Iterate through reloc info stopping at each breakable code target.
113 // breakable code target.
114 bool first = break_index_ == -1; 112 bool first = break_index_ == -1;
115 while (!Done()) { 113 while (!Done()) {
116 if (!first) reloc_iterator_.next(); 114 if (!first) reloc_iterator_.next();
117 first = false; 115 first = false;
118 if (Done()) return; 116 if (Done()) return;
119 117
120 // Whenever a statement position or (plain) position is passed update the 118 // Whenever a statement position or (plain) position is passed update the
121 // current value of these. 119 // current value of these.
122 if (RelocInfo::IsPosition(rmode())) { 120 if (RelocInfo::IsPosition(rmode())) {
123 if (RelocInfo::IsStatementPosition(rmode())) { 121 if (RelocInfo::IsStatementPosition(rmode())) {
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
162 type = DEBUGGER_STATEMENT; 160 type = DEBUGGER_STATEMENT;
163 } else if (RelocInfo::IsDebugBreakSlot(rmode())) { 161 } else if (RelocInfo::IsDebugBreakSlot(rmode())) {
164 type = DEBUG_BREAK_SLOT; 162 type = DEBUG_BREAK_SLOT;
165 } else { 163 } else {
166 type = NOT_DEBUG_BREAK; 164 type = NOT_DEBUG_BREAK;
167 } 165 }
168 return BreakLocation(debug_info_, type, code_offset(), position(), 166 return BreakLocation(debug_info_, type, code_offset(), position(),
169 statement_position()); 167 statement_position());
170 } 168 }
171 169
170 BreakLocation::BytecodeArrayIterator::BytecodeArrayIterator(
171 Handle<DebugInfo> debug_info, BreakLocatorType type)
172 : Iterator(debug_info),
173 source_position_iterator_(
174 debug_info->abstract_code()->GetBytecodeArray()),
175 break_locator_type_(type),
176 start_position_(debug_info->shared()->start_position()) {
177 if (!Done()) Next();
178 }
179
180 void BreakLocation::BytecodeArrayIterator::Next() {
181 DisallowHeapAllocation no_gc;
182 DCHECK(!Done());
183 bool first = break_index_ == -1;
184 while (!Done()) {
185 if (!first) source_position_iterator_.Advance();
186 first = false;
187 if (Done()) return;
188 position_ = source_position_iterator_.source_position() - start_position_;
189 if (source_position_iterator_.is_statement()) {
190 statement_position_ = position_;
191 }
192 DCHECK(position_ >= 0);
193 DCHECK(statement_position_ >= 0);
194 break_index_++;
195
196 if (break_locator_type_ == ALL_BREAK_LOCATIONS) break;
197
198 DCHECK_EQ(CALLS_AND_RETURNS, break_locator_type_);
199 enum DebugBreakType type = GetDebugBreakType();
200 if (type == DEBUG_BREAK_SLOT_AT_CALL ||
201 type == DEBUG_BREAK_SLOT_AT_RETURN) {
202 break;
203 }
204 }
205 }
206
207 BreakLocation::DebugBreakType
208 BreakLocation::BytecodeArrayIterator::GetDebugBreakType() {
209 BytecodeArray* bytecode_array =
210 debug_info_->abstract_code()->GetBytecodeArray();
211 interpreter::Bytecode bytecode =
212 static_cast<interpreter::Bytecode>(bytecode_array->get(code_offset()));
213
214 if (bytecode == interpreter::Bytecode::kDebugger) {
215 return DEBUGGER_STATEMENT;
216 } else if (bytecode == interpreter::Bytecode::kReturn) {
217 return DEBUG_BREAK_SLOT_AT_RETURN;
218 } else if (interpreter::Bytecodes::IsCallOrNew(bytecode)) {
219 return DEBUG_BREAK_SLOT_AT_CALL;
220 } else if (source_position_iterator_.is_statement()) {
221 return DEBUG_BREAK_SLOT;
222 } else {
223 return NOT_DEBUG_BREAK;
224 }
225 }
226
227 BreakLocation BreakLocation::BytecodeArrayIterator::GetBreakLocation() {
228 return BreakLocation(debug_info_, GetDebugBreakType(), code_offset(),
229 position(), statement_position());
230 }
231
172 // Find the break point at the supplied address, or the closest one before 232 // Find the break point at the supplied address, or the closest one before
173 // the address. 233 // the address.
174 BreakLocation BreakLocation::FromCodeOffset(Handle<DebugInfo> debug_info, 234 BreakLocation BreakLocation::FromCodeOffset(Handle<DebugInfo> debug_info,
175 int offset) { 235 int offset) {
176 base::SmartPointer<Iterator> it(GetIterator(debug_info)); 236 base::SmartPointer<Iterator> it(GetIterator(debug_info));
177 it->SkipTo(BreakIndexFromCodeOffset(debug_info, offset)); 237 it->SkipTo(BreakIndexFromCodeOffset(debug_info, offset));
178 return it->GetBreakLocation(); 238 return it->GetBreakLocation();
179 } 239 }
180 240
181 // Move GetFirstFrameSummary Definition to here as FromFrame use it. 241 // Move GetFirstFrameSummary Definition to here as FromFrame use it.
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
335 if (abstract_code()->IsCode()) { 395 if (abstract_code()->IsCode()) {
336 Code* code = abstract_code()->GetCode(); 396 Code* code = abstract_code()->GetCode();
337 DCHECK(code->kind() == Code::FUNCTION); 397 DCHECK(code->kind() == Code::FUNCTION);
338 Builtins* builtins = isolate()->builtins(); 398 Builtins* builtins = isolate()->builtins();
339 Handle<Code> target = IsReturn() ? builtins->Return_DebugBreak() 399 Handle<Code> target = IsReturn() ? builtins->Return_DebugBreak()
340 : builtins->Slot_DebugBreak(); 400 : builtins->Slot_DebugBreak();
341 Address pc = code->instruction_start() + code_offset(); 401 Address pc = code->instruction_start() + code_offset();
342 DebugCodegen::PatchDebugBreakSlot(isolate(), pc, target); 402 DebugCodegen::PatchDebugBreakSlot(isolate(), pc, target);
343 DCHECK(IsDebugBreak()); 403 DCHECK(IsDebugBreak());
344 } else { 404 } else {
345 UNIMPLEMENTED(); 405 // TODO(yangguo): implement this once we have a way to record break points.
346 } 406 }
347 } 407 }
348 408
349 409
350 void BreakLocation::ClearDebugBreak() { 410 void BreakLocation::ClearDebugBreak() {
351 // Debugger statement always calls debugger. No need to modify it. 411 // Debugger statement always calls debugger. No need to modify it.
352 if (IsDebuggerStatement()) return; 412 if (IsDebuggerStatement()) return;
353 413
354 DCHECK(IsDebugBreakSlot()); 414 DCHECK(IsDebugBreakSlot());
355 if (abstract_code()->IsCode()) { 415 if (abstract_code()->IsCode()) {
356 Code* code = abstract_code()->GetCode(); 416 Code* code = abstract_code()->GetCode();
357 DCHECK(code->kind() == Code::FUNCTION); 417 DCHECK(code->kind() == Code::FUNCTION);
358 Address pc = code->instruction_start() + code_offset(); 418 Address pc = code->instruction_start() + code_offset();
359 DebugCodegen::ClearDebugBreakSlot(isolate(), pc); 419 DebugCodegen::ClearDebugBreakSlot(isolate(), pc);
360 DCHECK(!IsDebugBreak()); 420 DCHECK(!IsDebugBreak());
361 } else { 421 } else {
362 UNIMPLEMENTED(); 422 // TODO(yangguo): implement this once we have a way to record break points.
363 } 423 }
364 } 424 }
365 425
366 426
367 bool BreakLocation::IsDebugBreak() const { 427 bool BreakLocation::IsDebugBreak() const {
368 if (IsDebuggerStatement()) return false; 428 if (IsDebuggerStatement()) return false;
369 DCHECK(IsDebugBreakSlot()); 429 DCHECK(IsDebugBreakSlot());
370 if (abstract_code()->IsCode()) { 430 if (abstract_code()->IsCode()) {
371 Code* code = abstract_code()->GetCode(); 431 Code* code = abstract_code()->GetCode();
372 DCHECK(code->kind() == Code::FUNCTION); 432 DCHECK(code->kind() == Code::FUNCTION);
373 Address pc = code->instruction_start() + code_offset(); 433 Address pc = code->instruction_start() + code_offset();
374 return DebugCodegen::DebugBreakSlotIsPatched(pc); 434 return DebugCodegen::DebugBreakSlotIsPatched(pc);
375 } else { 435 } else {
376 UNIMPLEMENTED(); 436 // TODO(yangguo): implement this once we have a way to record break points.
377 return false; 437 return false;
378 } 438 }
379 } 439 }
380 440
381 441
382 Handle<Object> BreakLocation::BreakPointObjects() const { 442 Handle<Object> BreakLocation::BreakPointObjects() const {
383 return debug_info_->GetBreakPointObjects(code_offset_); 443 return debug_info_->GetBreakPointObjects(code_offset_);
384 } 444 }
385 445
386 void DebugFeatureTracker::Track(DebugFeatureTracker::Feature feature) { 446 void DebugFeatureTracker::Track(DebugFeatureTracker::Feature feature) {
(...skipping 769 matching lines...) Expand 10 before | Expand all | Expand 10 after
1156 public: 1216 public:
1157 explicit RedirectActiveFunctions(SharedFunctionInfo* shared) 1217 explicit RedirectActiveFunctions(SharedFunctionInfo* shared)
1158 : shared_(shared) { 1218 : shared_(shared) {
1159 DCHECK(shared->HasDebugCode()); 1219 DCHECK(shared->HasDebugCode());
1160 } 1220 }
1161 1221
1162 void VisitThread(Isolate* isolate, ThreadLocalTop* top) { 1222 void VisitThread(Isolate* isolate, ThreadLocalTop* top) {
1163 for (JavaScriptFrameIterator it(isolate, top); !it.done(); it.Advance()) { 1223 for (JavaScriptFrameIterator it(isolate, top); !it.done(); it.Advance()) {
1164 JavaScriptFrame* frame = it.frame(); 1224 JavaScriptFrame* frame = it.frame();
1165 JSFunction* function = frame->function(); 1225 JSFunction* function = frame->function();
1226 if (frame->is_interpreted()) {
1227 // TODO(yangguo): replace dispatch table for activated frames.
1228 continue;
1229 }
1166 if (frame->is_optimized()) continue; 1230 if (frame->is_optimized()) continue;
1167 if (!function->Inlines(shared_)) continue; 1231 if (!function->Inlines(shared_)) continue;
1168 1232
1169 Code* frame_code = frame->LookupCode(); 1233 Code* frame_code = frame->LookupCode();
1170 DCHECK(frame_code->kind() == Code::FUNCTION); 1234 DCHECK(frame_code->kind() == Code::FUNCTION);
1171 if (frame_code->has_debug_break_slots()) continue; 1235 if (frame_code->has_debug_break_slots()) continue;
1172 1236
1173 Code* new_code = function->shared()->code(); 1237 Code* new_code = function->shared()->code();
1174 Address old_pc = frame->pc(); 1238 Address old_pc = frame->pc();
1175 Address new_pc = ComputeNewPcForRedirect(new_code, frame_code, old_pc); 1239 Address new_pc = ComputeNewPcForRedirect(new_code, frame_code, old_pc);
(...skipping 1329 matching lines...) Expand 10 before | Expand all | Expand 10 after
2505 } 2569 }
2506 2570
2507 2571
2508 void LockingCommandMessageQueue::Clear() { 2572 void LockingCommandMessageQueue::Clear() {
2509 base::LockGuard<base::Mutex> lock_guard(&mutex_); 2573 base::LockGuard<base::Mutex> lock_guard(&mutex_);
2510 queue_.Clear(); 2574 queue_.Clear();
2511 } 2575 }
2512 2576
2513 } // namespace internal 2577 } // namespace internal
2514 } // namespace v8 2578 } // namespace v8
OLDNEW
« no previous file with comments | « src/debug/debug.h ('k') | src/interpreter/bytecode-array-builder.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698