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

Side by Side Diff: runtime/vm/debugger.cc

Issue 9271008: Implement deletion of breakpoints (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: '' Created 8 years, 11 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 | « runtime/vm/debugger.h ('k') | runtime/vm/debugger_api_impl.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 (c) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/debugger.h" 5 #include "vm/debugger.h"
6 6
7 #include "vm/code_index_table.h" 7 #include "vm/code_index_table.h"
8 #include "vm/code_patcher.h" 8 #include "vm/code_patcher.h"
9 #include "vm/compiler.h" 9 #include "vm/compiler.h"
10 #include "vm/flags.h" 10 #include "vm/flags.h"
11 #include "vm/globals.h" 11 #include "vm/globals.h"
12 #include "vm/object.h" 12 #include "vm/object.h"
13 #include "vm/object_store.h" 13 #include "vm/object_store.h"
14 #include "vm/os.h" 14 #include "vm/os.h"
15 #include "vm/stack_frame.h" 15 #include "vm/stack_frame.h"
16 #include "vm/stub_code.h" 16 #include "vm/stub_code.h"
17 #include "vm/visitor.h" 17 #include "vm/visitor.h"
18 18
19 19
20 namespace dart { 20 namespace dart {
21 21
22 static const bool verbose = false; 22 static const bool verbose = false;
23 23
24 Breakpoint::Breakpoint(const Function& func, intptr_t pc_desc_index) 24 Breakpoint::Breakpoint(const Function& func, intptr_t pc_desc_index)
25 : function_(func.raw()), 25 : function_(func.raw()),
26 pc_desc_index_(pc_desc_index), 26 pc_desc_index_(pc_desc_index),
27 pc_(0), 27 pc_(0),
28 saved_bytes_(0),
28 line_number_(-1), 29 line_number_(-1),
29 next_(NULL) { 30 next_(NULL) {
30 Code& code = Code::Handle(func.code()); 31 Code& code = Code::Handle(func.code());
31 ASSERT(!code.IsNull()); // Function must be compiled. 32 ASSERT(!code.IsNull()); // Function must be compiled.
32 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); 33 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors());
33 ASSERT(pc_desc_index < desc.Length()); 34 ASSERT(pc_desc_index < desc.Length());
34 this->token_index_ = desc.TokenIndex(pc_desc_index); 35 this->token_index_ = desc.TokenIndex(pc_desc_index);
35 ASSERT(this->token_index_ > 0); 36 ASSERT(this->token_index_ > 0);
36 this->pc_ = desc.PC(pc_desc_index); 37 this->pc_ = desc.PC(pc_desc_index);
37 ASSERT(this->pc_ != 0); 38 ASSERT(this->pc_ != 0);
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
223 } 224 }
224 225
225 226
226 Debugger::Debugger() 227 Debugger::Debugger()
227 : initialized_(false), 228 : initialized_(false),
228 bp_handler_(NULL), 229 bp_handler_(NULL),
229 breakpoints_(NULL) { 230 breakpoints_(NULL) {
230 } 231 }
231 232
232 233
234 Debugger::~Debugger() {
235 ASSERT(breakpoints_ == NULL);
236 }
237
238
239 void Debugger::Shutdown() {
240 while (breakpoints_ != NULL) {
241 Breakpoint* bpt = breakpoints_;
242 breakpoints_ = breakpoints_->next();
243 UnsetBreakpoint(bpt);
244 delete bpt;
245 }
246 }
247
248
233 bool Debugger::IsActive() { 249 bool Debugger::IsActive() {
234 // TODO(hausner): The code generator uses this function to prevent 250 // TODO(hausner): The code generator uses this function to prevent
235 // generation of optimized code when Dart code is being debugged. 251 // generation of optimized code when Dart code is being debugged.
236 // This is probably not conservative enough (we could set the first 252 // This is probably not conservative enough (we could set the first
237 // breakpoint after optimized code has already been produced). 253 // breakpoint after optimized code has already been produced).
238 // Long-term, we need to be able to de-optimize code. 254 // Long-term, we need to be able to de-optimize code.
239 return breakpoints_ != NULL; 255 return breakpoints_ != NULL;
240 } 256 }
241 257
242 258
(...skipping 24 matching lines...) Expand all
267 if (!cls.IsNull()) { 283 if (!cls.IsNull()) {
268 function = cls.LookupStaticFunction(function_name); 284 function = cls.LookupStaticFunction(function_name);
269 if (function.IsNull()) { 285 if (function.IsNull()) {
270 function = cls.LookupDynamicFunction(function_name); 286 function = cls.LookupDynamicFunction(function_name);
271 } 287 }
272 } 288 }
273 return function.raw(); 289 return function.raw();
274 } 290 }
275 291
276 292
277 // TODO(hausner): Need to check whether a breakpoint for the 293 // TODO(hausner): Distinguish between newly created breakpoints and
278 // location already exists and either return the existing breakpoint 294 // returning a breakpoint that already exists?
279 // or return an error.
280 Breakpoint* Debugger::SetBreakpoint(const Function& target_function, 295 Breakpoint* Debugger::SetBreakpoint(const Function& target_function,
281 intptr_t token_index) { 296 intptr_t token_index) {
282 if ((token_index < target_function.token_index()) || 297 if ((token_index < target_function.token_index()) ||
283 (target_function.end_token_index() <= token_index)) { 298 (target_function.end_token_index() <= token_index)) {
284 // The given token position is not within the target function. 299 // The given token position is not within the target function.
285 return NULL; 300 return NULL;
286 } 301 }
287 if (!target_function.HasCode()) { 302 if (!target_function.HasCode()) {
288 Compiler::CompileFunction(target_function); 303 Compiler::CompileFunction(target_function);
289 } 304 }
290 Code& code = Code::Handle(target_function.code()); 305 Code& code = Code::Handle(target_function.code());
291 ASSERT(!code.IsNull()); 306 ASSERT(!code.IsNull());
292 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); 307 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors());
293 for (int i = 0; i < desc.Length(); i++) { 308 for (int i = 0; i < desc.Length(); i++) {
294 if (desc.TokenIndex(i) < token_index) { 309 if (desc.TokenIndex(i) < token_index) {
295 continue; 310 continue;
296 } 311 }
297 PcDescriptors::Kind kind = desc.DescriptorKind(i); 312 PcDescriptors::Kind kind = desc.DescriptorKind(i);
298 Breakpoint* bpt = NULL; 313 Breakpoint* bpt = NULL;
299 if (kind == PcDescriptors::kIcCall) { 314 if (kind == PcDescriptors::kIcCall) {
315 bpt = GetBreakpoint(desc.PC(i));
316 if (bpt != NULL) {
317 // There is an existing breakpoint at this token position.
318 break;
319 }
320 bpt = new Breakpoint(target_function, i);
321 String& func_name = String::Handle();
322 int num_args, num_named_args;
323 CodePatcher::GetInstanceCallAt(desc.PC(i),
324 &func_name, &num_args, &num_named_args, &bpt->saved_bytes_);
300 CodePatcher::PatchInstanceCallAt( 325 CodePatcher::PatchInstanceCallAt(
301 desc.PC(i), StubCode::BreakpointDynamicEntryPoint()); 326 desc.PC(i), StubCode::BreakpointDynamicEntryPoint());
302 bpt = new Breakpoint(target_function, i); 327 RegisterBreakpoint(bpt);
303 } else if (kind == PcDescriptors::kOther) { 328 } else if (kind == PcDescriptors::kOther) {
304 if ((desc.TokenIndex(i) > 0) && CodePatcher::IsDartCall(desc.PC(i))) { 329 if ((desc.TokenIndex(i) > 0) && CodePatcher::IsDartCall(desc.PC(i))) {
330 bpt = GetBreakpoint(desc.PC(i));
331 if (bpt != NULL) {
332 // There is an existing breakpoint at this token position.
333 break;
334 }
335 bpt = new Breakpoint(target_function, i);
336 Function& func = Function::Handle();
337 CodePatcher::GetStaticCallAt(desc.PC(i), &func, &bpt->saved_bytes_);
305 CodePatcher::PatchStaticCallAt( 338 CodePatcher::PatchStaticCallAt(
306 desc.PC(i), StubCode::BreakpointStaticEntryPoint()); 339 desc.PC(i), StubCode::BreakpointStaticEntryPoint());
307 bpt = new Breakpoint(target_function, i); 340 RegisterBreakpoint(bpt);
308 } 341 }
309 } 342 }
310 if (bpt != NULL) { 343 if (bpt != NULL) {
311 if (verbose) { 344 if (verbose) {
312 OS::Print("Setting breakpoint at '%s' line %d (PC %p)\n", 345 OS::Print("Setting breakpoint at '%s' line %d (PC %p)\n",
313 String::Handle(bpt->SourceUrl()).ToCString(), 346 String::Handle(bpt->SourceUrl()).ToCString(),
314 bpt->LineNumber(), 347 bpt->LineNumber(),
315 bpt->pc()); 348 bpt->pc());
316 } 349 }
317 AddBreakpoint(bpt);
318 return bpt; 350 return bpt;
319 } 351 }
320 } 352 }
321 return NULL; 353 return NULL;
322 } 354 }
323 355
324 356
357 void Debugger::UnsetBreakpoint(Breakpoint* bpt) {
358 const Function& func = Function::Handle(bpt->function());
359 const Code& code = Code::Handle(func.code());
360 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors());
361 intptr_t desc_index = bpt->pc_desc_index();
362 ASSERT(desc_index < desc.Length());
363 ASSERT(bpt->pc() == desc.PC(desc_index));
364 PcDescriptors::Kind kind = desc.DescriptorKind(desc_index);
365 if (kind == PcDescriptors::kIcCall) {
366 CodePatcher::PatchInstanceCallAt(desc.PC(desc_index), bpt->saved_bytes_);
367 } else {
368 CodePatcher::PatchStaticCallAt(desc.PC(desc_index), bpt->saved_bytes_);
369 }
370 }
371
372
325 Breakpoint* Debugger::SetBreakpointAtEntry(const Function& target_function) { 373 Breakpoint* Debugger::SetBreakpointAtEntry(const Function& target_function) {
326 ASSERT(!target_function.IsNull()); 374 ASSERT(!target_function.IsNull());
327 return SetBreakpoint(target_function, target_function.token_index()); 375 return SetBreakpoint(target_function, target_function.token_index());
328 } 376 }
329 377
330 378
331 Breakpoint* Debugger::SetBreakpointAtLine(const String& script_url, 379 Breakpoint* Debugger::SetBreakpointAtLine(const String& script_url,
332 intptr_t line_number) { 380 intptr_t line_number) {
333 Library& lib = Library::Handle(); 381 Library& lib = Library::Handle();
334 Script& script = Script::Handle(); 382 Script& script = Script::Handle();
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
438 while (bpt != NULL) { 486 while (bpt != NULL) {
439 if (bpt->pc() == breakpoint_address) { 487 if (bpt->pc() == breakpoint_address) {
440 return bpt; 488 return bpt;
441 } 489 }
442 bpt = bpt->next(); 490 bpt = bpt->next();
443 } 491 }
444 return NULL; 492 return NULL;
445 } 493 }
446 494
447 495
448 void Debugger::AddBreakpoint(Breakpoint* bpt) { 496 void Debugger::RemoveBreakpoint(Breakpoint* bpt) {
497 ASSERT(breakpoints_ != NULL);
498 Breakpoint* prev_bpt = NULL;
499 Breakpoint* curr_bpt = breakpoints_;
500 while (curr_bpt != NULL) {
501 if (bpt == curr_bpt) {
502 if (prev_bpt == NULL) {
503 breakpoints_ = breakpoints_->next();
504 } else {
505 prev_bpt->set_next(curr_bpt->next());
506 }
507 UnsetBreakpoint(bpt);
508 delete bpt;
509 return;
510 }
511 prev_bpt = curr_bpt;
512 curr_bpt = curr_bpt->next();
513 }
514 // bpt is not a registered breakpoint, nothing to do.
515 }
516
517
518 Breakpoint* Debugger::GetBreakpointByFunction(const Function& func,
519 intptr_t token_index) {
520 Breakpoint* bpt = this->breakpoints_;
521 while (bpt != NULL) {
522 if ((bpt->function() == func.raw()) &&
523 (bpt->token_index() == token_index)) {
524 return bpt;
525 }
526 bpt = bpt->next();
527 }
528 return NULL;
529 }
530
531
532 void Debugger::RegisterBreakpoint(Breakpoint* bpt) {
449 ASSERT(bpt->next() == NULL); 533 ASSERT(bpt->next() == NULL);
450 bpt->set_next(this->breakpoints_); 534 bpt->set_next(this->breakpoints_);
451 this->breakpoints_ = bpt; 535 this->breakpoints_ = bpt;
452 } 536 }
453 537
454 538
455 } // namespace dart 539 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/debugger.h ('k') | runtime/vm/debugger_api_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698