OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 "include/dart_api.h" | 7 #include "include/dart_api.h" |
8 | 8 |
9 #include "vm/code_generator.h" | 9 #include "vm/code_generator.h" |
10 #include "vm/code_patcher.h" | 10 #include "vm/code_patcher.h" |
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
303 | 303 |
304 if (FLAG_steal_breakpoints && event->IsPauseEvent()) { | 304 if (FLAG_steal_breakpoints && event->IsPauseEvent()) { |
305 // We allow the embedder's default breakpoint handler to be overridden. | 305 // We allow the embedder's default breakpoint handler to be overridden. |
306 isolate_->PauseEventHandler(); | 306 isolate_->PauseEventHandler(); |
307 } else if (event_handler_ != NULL) { | 307 } else if (event_handler_ != NULL) { |
308 (*event_handler_)(event); | 308 (*event_handler_)(event); |
309 } | 309 } |
310 | 310 |
311 if (ServiceNeedsDebuggerEvent(event->type()) && event->IsPauseEvent()) { | 311 if (ServiceNeedsDebuggerEvent(event->type()) && event->IsPauseEvent()) { |
312 // If we were paused, notify the service that we have resumed. | 312 // If we were paused, notify the service that we have resumed. |
313 const Error& error = Error::Handle(zone(), | 313 const Error& error = |
314 isolate_->object_store()->sticky_error()); | 314 Error::Handle(isolate_->object_store()->sticky_error()); |
315 ASSERT(error.IsNull() || error.IsUnwindError()); | 315 ASSERT(error.IsNull() || error.IsUnwindError()); |
316 | 316 |
317 // Only send a resume event when the isolate is not unwinding. | 317 // Only send a resume event when the isolate is not unwinding. |
318 if (!error.IsUnwindError()) { | 318 if (!error.IsUnwindError()) { |
319 ServiceEvent service_event(event->isolate(), ServiceEvent::kResume); | 319 ServiceEvent service_event(event->isolate(), ServiceEvent::kResume); |
320 service_event.set_top_frame(event->top_frame()); | 320 service_event.set_top_frame(event->top_frame()); |
321 Service::HandleEvent(&service_event); | 321 Service::HandleEvent(&service_event); |
322 } | 322 } |
323 } | 323 } |
324 } | 324 } |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
358 "\tisolate: %s\n", isolate_->name()); | 358 "\tisolate: %s\n", isolate_->name()); |
359 } | 359 } |
360 const String& msg = | 360 const String& msg = |
361 String::Handle(String::New("isolate terminated by embedder")); | 361 String::Handle(String::New("isolate terminated by embedder")); |
362 return UnwindError::New(msg); | 362 return UnwindError::New(msg); |
363 } | 363 } |
364 } | 364 } |
365 | 365 |
366 // If any error occurred while in the debug message loop, return it here. | 366 // If any error occurred while in the debug message loop, return it here. |
367 const Error& error = | 367 const Error& error = |
368 Error::Handle(zone(), isolate_->object_store()->sticky_error()); | 368 Error::Handle(isolate_->object_store()->sticky_error()); |
369 ASSERT(error.IsNull() || error.IsUnwindError()); | 369 ASSERT(error.IsNull() || error.IsUnwindError()); |
370 isolate_->object_store()->clear_sticky_error(); | 370 isolate_->object_store()->clear_sticky_error(); |
371 return error.raw(); | 371 return error.raw(); |
372 } | 372 } |
373 | 373 |
374 | 374 |
375 // The vm service handles breakpoint notifications in a different way | 375 // The vm service handles breakpoint notifications in a different way |
376 // than the regular debugger breakpoint notifications. | 376 // than the regular debugger breakpoint notifications. |
377 static void SendServiceBreakpointEvent(ServiceEvent::EventKind kind, | 377 static void SendServiceBreakpointEvent(ServiceEvent::EventKind kind, |
378 Breakpoint* bpt) { | 378 Breakpoint* bpt) { |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
461 intptr_t token_pos) { | 461 intptr_t token_pos) { |
462 if ((func.token_pos() <= token_pos) && (token_pos <= func.end_token_pos())) { | 462 if ((func.token_pos() <= token_pos) && (token_pos <= func.end_token_pos())) { |
463 // Check script equality second because it allocates | 463 // Check script equality second because it allocates |
464 // handles as a side effect. | 464 // handles as a side effect. |
465 return func.script() == script.raw(); | 465 return func.script() == script.raw(); |
466 } | 466 } |
467 return false; | 467 return false; |
468 } | 468 } |
469 | 469 |
470 | 470 |
471 bool Debugger::HasBreakpoint(const Function& func) { | 471 bool Debugger::HasBreakpoint(const Function& func, Zone* zone) { |
472 if (!func.HasCode()) { | 472 if (!func.HasCode()) { |
473 // If the function is not compiled yet, just check whether there | 473 // If the function is not compiled yet, just check whether there |
474 // is a user-defined breakpoint that falls into the token | 474 // is a user-defined breakpoint that falls into the token |
475 // range of the function. This may be a false positive: the breakpoint | 475 // range of the function. This may be a false positive: the breakpoint |
476 // might be inside a local closure. | 476 // might be inside a local closure. |
477 Script& script = Script::Handle(zone()); | 477 Script& script = Script::Handle(zone); |
478 BreakpointLocation* sbpt = breakpoint_locations_; | 478 BreakpointLocation* sbpt = breakpoint_locations_; |
479 while (sbpt != NULL) { | 479 while (sbpt != NULL) { |
480 script = sbpt->script(); | 480 script = sbpt->script(); |
481 if (FunctionContains(func, script, sbpt->token_pos())) { | 481 if (FunctionContains(func, script, sbpt->token_pos())) { |
482 return true; | 482 return true; |
483 } | 483 } |
484 sbpt = sbpt->next_; | 484 sbpt = sbpt->next_; |
485 } | 485 } |
486 return false; | 486 return false; |
487 } | 487 } |
(...skipping 1025 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1513 return stack_trace; | 1513 return stack_trace; |
1514 } | 1514 } |
1515 | 1515 |
1516 | 1516 |
1517 ActivationFrame* Debugger::TopDartFrame() const { | 1517 ActivationFrame* Debugger::TopDartFrame() const { |
1518 StackFrameIterator iterator(false); | 1518 StackFrameIterator iterator(false); |
1519 StackFrame* frame = iterator.NextFrame(); | 1519 StackFrame* frame = iterator.NextFrame(); |
1520 while ((frame != NULL) && !frame->IsDartFrame()) { | 1520 while ((frame != NULL) && !frame->IsDartFrame()) { |
1521 frame = iterator.NextFrame(); | 1521 frame = iterator.NextFrame(); |
1522 } | 1522 } |
1523 Code& code = Code::Handle(zone(), frame->LookupDartCode()); | 1523 Code& code = Code::Handle(frame->LookupDartCode()); |
1524 ActivationFrame* activation = | 1524 ActivationFrame* activation = |
1525 new ActivationFrame(frame->pc(), frame->fp(), frame->sp(), code, | 1525 new ActivationFrame(frame->pc(), frame->fp(), frame->sp(), code, |
1526 Object::null_array(), 0); | 1526 Object::null_array(), 0); |
1527 return activation; | 1527 return activation; |
1528 } | 1528 } |
1529 | 1529 |
1530 | 1530 |
1531 DebuggerStackTrace* Debugger::StackTrace() { | 1531 DebuggerStackTrace* Debugger::StackTrace() { |
1532 return (stack_trace_ != NULL) ? stack_trace_ : CollectStackTrace(); | 1532 return (stack_trace_ != NULL) ? stack_trace_ : CollectStackTrace(); |
1533 } | 1533 } |
(...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1860 if (loc->AnyEnabled()) { | 1860 if (loc->AnyEnabled()) { |
1861 code_bpt->Enable(); | 1861 code_bpt->Enable(); |
1862 } | 1862 } |
1863 } | 1863 } |
1864 | 1864 |
1865 | 1865 |
1866 void Debugger::FindCompiledFunctions(const Script& script, | 1866 void Debugger::FindCompiledFunctions(const Script& script, |
1867 intptr_t start_pos, | 1867 intptr_t start_pos, |
1868 intptr_t end_pos, | 1868 intptr_t end_pos, |
1869 GrowableObjectArray* function_list) { | 1869 GrowableObjectArray* function_list) { |
1870 Zone* zn = zone(); | 1870 Zone* zone = Thread::Current()->zone(); |
1871 Class& cls = Class::Handle(zn); | 1871 Class& cls = Class::Handle(zone); |
1872 Array& functions = Array::Handle(zn); | 1872 Array& functions = Array::Handle(zone); |
1873 GrowableObjectArray& closures = GrowableObjectArray::Handle(zn); | 1873 GrowableObjectArray& closures = GrowableObjectArray::Handle(zone); |
1874 Function& function = Function::Handle(zn); | 1874 Function& function = Function::Handle(zone); |
1875 | 1875 |
1876 const ClassTable& class_table = *isolate_->class_table(); | 1876 const ClassTable& class_table = *isolate_->class_table(); |
1877 const intptr_t num_classes = class_table.NumCids(); | 1877 const intptr_t num_classes = class_table.NumCids(); |
1878 for (intptr_t i = 1; i < num_classes; i++) { | 1878 for (intptr_t i = 1; i < num_classes; i++) { |
1879 if (class_table.HasValidClassAt(i)) { | 1879 if (class_table.HasValidClassAt(i)) { |
1880 cls = class_table.At(i); | 1880 cls = class_table.At(i); |
1881 // If the class is not finalized, e.g. if it hasn't been parsed | 1881 // If the class is not finalized, e.g. if it hasn't been parsed |
1882 // yet entirely, we can ignore it. If it contains a function with | 1882 // yet entirely, we can ignore it. If it contains a function with |
1883 // an unresolved breakpoint, we will detect it if and when the | 1883 // an unresolved breakpoint, we will detect it if and when the |
1884 // function gets compiled. | 1884 // function gets compiled. |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1944 if ((func->token_pos() > best_fit->token_pos()) && | 1944 if ((func->token_pos() > best_fit->token_pos()) && |
1945 ((func->end_token_pos() <= best_fit->end_token_pos()))) { | 1945 ((func->end_token_pos() <= best_fit->end_token_pos()))) { |
1946 *best_fit = func->raw(); | 1946 *best_fit = func->raw(); |
1947 } | 1947 } |
1948 } | 1948 } |
1949 } | 1949 } |
1950 | 1950 |
1951 | 1951 |
1952 RawFunction* Debugger::FindBestFit(const Script& script, | 1952 RawFunction* Debugger::FindBestFit(const Script& script, |
1953 intptr_t token_pos) { | 1953 intptr_t token_pos) { |
1954 Zone* zn = zone(); | 1954 Zone* zone = Thread::Current()->zone(); |
1955 Class& cls = Class::Handle(zn); | 1955 Class& cls = Class::Handle(zone); |
1956 Array& functions = Array::Handle(zn); | 1956 Array& functions = Array::Handle(zone); |
1957 GrowableObjectArray& closures = GrowableObjectArray::Handle(zn); | 1957 GrowableObjectArray& closures = GrowableObjectArray::Handle(zone); |
1958 Function& function = Function::Handle(zn); | 1958 Function& function = Function::Handle(zone); |
1959 Function& best_fit = Function::Handle(zn); | 1959 Function& best_fit = Function::Handle(zone); |
1960 Error& error = Error::Handle(zn); | 1960 Error& error = Error::Handle(zone); |
1961 | 1961 |
1962 const ClassTable& class_table = *isolate_->class_table(); | 1962 const ClassTable& class_table = *isolate_->class_table(); |
1963 const intptr_t num_classes = class_table.NumCids(); | 1963 const intptr_t num_classes = class_table.NumCids(); |
1964 for (intptr_t i = 1; i < num_classes; i++) { | 1964 for (intptr_t i = 1; i < num_classes; i++) { |
1965 if (class_table.HasValidClassAt(i)) { | 1965 if (class_table.HasValidClassAt(i)) { |
1966 cls = class_table.At(i); | 1966 cls = class_table.At(i); |
1967 // Note: if this class has been parsed and finalized already, | 1967 // Note: if this class has been parsed and finalized already, |
1968 // we need to check the functions of this class even if | 1968 // we need to check the functions of this class even if |
1969 // it is defined in a differenct 'script'. There could | 1969 // it is defined in a differenct 'script'. There could |
1970 // be mixin functions from the given script in this class. | 1970 // be mixin functions from the given script in this class. |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2009 } | 2009 } |
2010 return best_fit.raw(); | 2010 return best_fit.raw(); |
2011 } | 2011 } |
2012 | 2012 |
2013 | 2013 |
2014 BreakpointLocation* Debugger::SetBreakpoint(const Script& script, | 2014 BreakpointLocation* Debugger::SetBreakpoint(const Script& script, |
2015 intptr_t token_pos, | 2015 intptr_t token_pos, |
2016 intptr_t last_token_pos, | 2016 intptr_t last_token_pos, |
2017 intptr_t requested_line, | 2017 intptr_t requested_line, |
2018 intptr_t requested_column) { | 2018 intptr_t requested_column) { |
2019 Function& func = Function::Handle(zone()); | 2019 Function& func = Function::Handle(); |
2020 func = FindBestFit(script, token_pos); | 2020 func = FindBestFit(script, token_pos); |
2021 if (func.IsNull()) { | 2021 if (func.IsNull()) { |
2022 return NULL; | 2022 return NULL; |
2023 } | 2023 } |
2024 // There may be more than one function object for a given function | 2024 // There may be more than one function object for a given function |
2025 // in source code. There may be implicit closure functions, and | 2025 // in source code. There may be implicit closure functions, and |
2026 // there may be copies of mixin functions. Collect all compiled | 2026 // there may be copies of mixin functions. Collect all compiled |
2027 // functions whose source code range matches exactly the best fit | 2027 // functions whose source code range matches exactly the best fit |
2028 // function we found. | 2028 // function we found. |
2029 GrowableObjectArray& functions = | 2029 GrowableObjectArray& functions = |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2201 return loc->AddRepeated(this); | 2201 return loc->AddRepeated(this); |
2202 } | 2202 } |
2203 return NULL; | 2203 return NULL; |
2204 } | 2204 } |
2205 | 2205 |
2206 | 2206 |
2207 BreakpointLocation* Debugger::BreakpointLocationAtLineCol( | 2207 BreakpointLocation* Debugger::BreakpointLocationAtLineCol( |
2208 const String& script_url, | 2208 const String& script_url, |
2209 intptr_t line_number, | 2209 intptr_t line_number, |
2210 intptr_t column_number) { | 2210 intptr_t column_number) { |
2211 Library& lib = Library::Handle(zone()); | 2211 Zone* zone = Thread::Current()->zone(); |
2212 Script& script = Script::Handle(zone()); | 2212 Library& lib = Library::Handle(zone); |
| 2213 Script& script = Script::Handle(zone); |
2213 const GrowableObjectArray& libs = | 2214 const GrowableObjectArray& libs = |
2214 GrowableObjectArray::Handle(isolate_->object_store()->libraries()); | 2215 GrowableObjectArray::Handle(isolate_->object_store()->libraries()); |
2215 const GrowableObjectArray& scripts = | 2216 const GrowableObjectArray& scripts = |
2216 GrowableObjectArray::Handle(zone(), GrowableObjectArray::New()); | 2217 GrowableObjectArray::Handle(zone, GrowableObjectArray::New()); |
2217 for (intptr_t i = 0; i < libs.Length(); i++) { | 2218 for (intptr_t i = 0; i < libs.Length(); i++) { |
2218 lib ^= libs.At(i); | 2219 lib ^= libs.At(i); |
2219 script = lib.LookupScript(script_url); | 2220 script = lib.LookupScript(script_url); |
2220 if (!script.IsNull()) { | 2221 if (!script.IsNull()) { |
2221 scripts.Add(script); | 2222 scripts.Add(script); |
2222 } | 2223 } |
2223 } | 2224 } |
2224 if (scripts.Length() == 0) { | 2225 if (scripts.Length() == 0) { |
2225 // No script found with given url. Create a latent breakpoint which | 2226 // No script found with given url. Create a latent breakpoint which |
2226 // will be set if the url is loaded later. | 2227 // will be set if the url is loaded later. |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2396 } | 2397 } |
2397 return Array::MakeArray(field_list); | 2398 return Array::MakeArray(field_list); |
2398 } | 2399 } |
2399 | 2400 |
2400 | 2401 |
2401 void Debugger::CollectLibraryFields(const GrowableObjectArray& field_list, | 2402 void Debugger::CollectLibraryFields(const GrowableObjectArray& field_list, |
2402 const Library& lib, | 2403 const Library& lib, |
2403 const String& prefix, | 2404 const String& prefix, |
2404 bool include_private_fields) { | 2405 bool include_private_fields) { |
2405 DictionaryIterator it(lib); | 2406 DictionaryIterator it(lib); |
2406 Object& entry = Object::Handle(zone()); | 2407 Zone* zone = Thread::Current()->zone(); |
2407 Field& field = Field::Handle(zone()); | 2408 Object& entry = Object::Handle(zone); |
2408 String& field_name = String::Handle(zone()); | 2409 Field& field = Field::Handle(zone); |
2409 PassiveObject& field_value = PassiveObject::Handle(zone()); | 2410 String& field_name = String::Handle(zone); |
| 2411 PassiveObject& field_value = PassiveObject::Handle(zone); |
2410 while (it.HasNext()) { | 2412 while (it.HasNext()) { |
2411 entry = it.GetNext(); | 2413 entry = it.GetNext(); |
2412 if (entry.IsField()) { | 2414 if (entry.IsField()) { |
2413 field ^= entry.raw(); | 2415 field ^= entry.raw(); |
2414 ASSERT(field.is_static()); | 2416 ASSERT(field.is_static()); |
2415 field_name = field.name(); | 2417 field_name = field.name(); |
2416 if ((field_name.CharAt(0) == '_') && !include_private_fields) { | 2418 if ((field_name.CharAt(0) == '_') && !include_private_fields) { |
2417 // Skip library-private field. | 2419 // Skip library-private field. |
2418 continue; | 2420 continue; |
2419 } | 2421 } |
(...skipping 10 matching lines...) Expand all Loading... |
2430 field_name = String::Concat(prefix, field_name); | 2432 field_name = String::Concat(prefix, field_name); |
2431 } | 2433 } |
2432 field_list.Add(field_name); | 2434 field_list.Add(field_name); |
2433 field_list.Add(field_value); | 2435 field_list.Add(field_value); |
2434 } | 2436 } |
2435 } | 2437 } |
2436 } | 2438 } |
2437 | 2439 |
2438 | 2440 |
2439 RawArray* Debugger::GetLibraryFields(const Library& lib) { | 2441 RawArray* Debugger::GetLibraryFields(const Library& lib) { |
| 2442 Zone* zone = Thread::Current()->zone(); |
2440 const GrowableObjectArray& field_list = | 2443 const GrowableObjectArray& field_list = |
2441 GrowableObjectArray::Handle(GrowableObjectArray::New(8)); | 2444 GrowableObjectArray::Handle(GrowableObjectArray::New(8)); |
2442 CollectLibraryFields(field_list, lib, String::Handle(zone()), true); | 2445 CollectLibraryFields(field_list, lib, String::Handle(zone), true); |
2443 return Array::MakeArray(field_list); | 2446 return Array::MakeArray(field_list); |
2444 } | 2447 } |
2445 | 2448 |
2446 | 2449 |
2447 RawArray* Debugger::GetGlobalFields(const Library& lib) { | 2450 RawArray* Debugger::GetGlobalFields(const Library& lib) { |
| 2451 Zone* zone = Thread::Current()->zone(); |
2448 const GrowableObjectArray& field_list = | 2452 const GrowableObjectArray& field_list = |
2449 GrowableObjectArray::Handle(GrowableObjectArray::New(8)); | 2453 GrowableObjectArray::Handle(zone, GrowableObjectArray::New(8)); |
2450 String& prefix_name = String::Handle(zone()); | 2454 String& prefix_name = String::Handle(zone); |
2451 CollectLibraryFields(field_list, lib, prefix_name, true); | 2455 CollectLibraryFields(field_list, lib, prefix_name, true); |
2452 Library& imported = Library::Handle(zone()); | 2456 Library& imported = Library::Handle(zone); |
2453 intptr_t num_imports = lib.num_imports(); | 2457 intptr_t num_imports = lib.num_imports(); |
2454 for (intptr_t i = 0; i < num_imports; i++) { | 2458 for (intptr_t i = 0; i < num_imports; i++) { |
2455 imported = lib.ImportLibraryAt(i); | 2459 imported = lib.ImportLibraryAt(i); |
2456 ASSERT(!imported.IsNull()); | 2460 ASSERT(!imported.IsNull()); |
2457 CollectLibraryFields(field_list, imported, prefix_name, false); | 2461 CollectLibraryFields(field_list, imported, prefix_name, false); |
2458 } | 2462 } |
2459 LibraryPrefix& prefix = LibraryPrefix::Handle(zone()); | 2463 LibraryPrefix& prefix = LibraryPrefix::Handle(zone); |
2460 LibraryPrefixIterator it(lib); | 2464 LibraryPrefixIterator it(lib); |
2461 while (it.HasNext()) { | 2465 while (it.HasNext()) { |
2462 prefix = it.GetNext(); | 2466 prefix = it.GetNext(); |
2463 prefix_name = prefix.name(); | 2467 prefix_name = prefix.name(); |
2464 ASSERT(!prefix_name.IsNull()); | 2468 ASSERT(!prefix_name.IsNull()); |
2465 prefix_name = String::Concat(prefix_name, Symbols::Dot()); | 2469 prefix_name = String::Concat(prefix_name, Symbols::Dot()); |
2466 for (int32_t i = 0; i < prefix.num_imports(); i++) { | 2470 for (int32_t i = 0; i < prefix.num_imports(); i++) { |
2467 imported = prefix.GetLibrary(i); | 2471 imported = prefix.GetLibrary(i); |
2468 CollectLibraryFields(field_list, imported, prefix_name, false); | 2472 CollectLibraryFields(field_list, imported, prefix_name, false); |
2469 } | 2473 } |
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2658 } | 2662 } |
2659 | 2663 |
2660 ASSERT(stack_trace_ == NULL); | 2664 ASSERT(stack_trace_ == NULL); |
2661 stack_trace_ = CollectStackTrace(); | 2665 stack_trace_ = CollectStackTrace(); |
2662 SignalPausedEvent(frame, NULL); | 2666 SignalPausedEvent(frame, NULL); |
2663 HandleSteppingRequest(stack_trace_); | 2667 HandleSteppingRequest(stack_trace_); |
2664 stack_trace_ = NULL; | 2668 stack_trace_ = NULL; |
2665 | 2669 |
2666 // If any error occurred while in the debug message loop, return it here. | 2670 // If any error occurred while in the debug message loop, return it here. |
2667 const Error& error = | 2671 const Error& error = |
2668 Error::Handle(zone(), isolate_->object_store()->sticky_error()); | 2672 Error::Handle(isolate_->object_store()->sticky_error()); |
2669 isolate_->object_store()->clear_sticky_error(); | 2673 isolate_->object_store()->clear_sticky_error(); |
2670 return error.raw(); | 2674 return error.raw(); |
2671 } | 2675 } |
2672 | 2676 |
2673 | 2677 |
2674 RawError* Debugger::SignalBpReached() { | 2678 RawError* Debugger::SignalBpReached() { |
2675 // We ignore this breakpoint when the VM is executing code invoked | 2679 // We ignore this breakpoint when the VM is executing code invoked |
2676 // by the debugger to evaluate variables values, or when we see a nested | 2680 // by the debugger to evaluate variables values, or when we see a nested |
2677 // breakpoint or exception event. | 2681 // breakpoint or exception event. |
2678 if (ignore_breakpoints_ || IsPaused() || !HasEventHandler()) { | 2682 if (ignore_breakpoints_ || IsPaused() || !HasEventHandler()) { |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2747 stack_trace_ = stack_trace; | 2751 stack_trace_ = stack_trace; |
2748 SignalPausedEvent(top_frame, bpt_hit); | 2752 SignalPausedEvent(top_frame, bpt_hit); |
2749 HandleSteppingRequest(stack_trace_); | 2753 HandleSteppingRequest(stack_trace_); |
2750 stack_trace_ = NULL; | 2754 stack_trace_ = NULL; |
2751 if (cbpt->IsInternal()) { | 2755 if (cbpt->IsInternal()) { |
2752 RemoveInternalBreakpoints(); | 2756 RemoveInternalBreakpoints(); |
2753 } | 2757 } |
2754 | 2758 |
2755 // If any error occurred while in the debug message loop, return it here. | 2759 // If any error occurred while in the debug message loop, return it here. |
2756 const Error& error = | 2760 const Error& error = |
2757 Error::Handle(zone(), isolate_->object_store()->sticky_error()); | 2761 Error::Handle(isolate_->object_store()->sticky_error()); |
2758 isolate_->object_store()->clear_sticky_error(); | 2762 isolate_->object_store()->clear_sticky_error(); |
2759 return error.raw(); | 2763 return error.raw(); |
2760 } | 2764 } |
2761 | 2765 |
2762 | 2766 |
2763 void Debugger::BreakHere(const String& msg) { | 2767 void Debugger::BreakHere(const String& msg) { |
2764 // We ignore this breakpoint when the VM is executing code invoked | 2768 // We ignore this breakpoint when the VM is executing code invoked |
2765 // by the debugger to evaluate variables values, or when we see a nested | 2769 // by the debugger to evaluate variables values, or when we see a nested |
2766 // breakpoint or exception event. | 2770 // breakpoint or exception event. |
2767 if (ignore_breakpoints_ || IsPaused() || !HasEventHandler()) { | 2771 if (ignore_breakpoints_ || IsPaused() || !HasEventHandler()) { |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2804 if (!ServiceIsolate::IsServiceIsolateDescendant(isolate_)) { | 2808 if (!ServiceIsolate::IsServiceIsolateDescendant(isolate_)) { |
2805 SignalIsolateEvent(DebuggerEvent::kIsolateCreated); | 2809 SignalIsolateEvent(DebuggerEvent::kIsolateCreated); |
2806 } | 2810 } |
2807 } | 2811 } |
2808 | 2812 |
2809 | 2813 |
2810 // Return innermost closure contained in 'function' that contains | 2814 // Return innermost closure contained in 'function' that contains |
2811 // the given token position. | 2815 // the given token position. |
2812 RawFunction* Debugger::FindInnermostClosure(const Function& function, | 2816 RawFunction* Debugger::FindInnermostClosure(const Function& function, |
2813 intptr_t token_pos) { | 2817 intptr_t token_pos) { |
2814 const Class& owner = Class::Handle(zone(), function.Owner()); | 2818 const Class& owner = Class::Handle(function.Owner()); |
2815 if (owner.closures() == GrowableObjectArray::null()) { | 2819 if (owner.closures() == GrowableObjectArray::null()) { |
2816 return Function::null(); | 2820 return Function::null(); |
2817 } | 2821 } |
2818 // Note that we need to check that the closure is in the same | 2822 // Note that we need to check that the closure is in the same |
2819 // script as the outer function. We could have closures originating | 2823 // script as the outer function. We could have closures originating |
2820 // in mixin classes whose source code is contained in a different | 2824 // in mixin classes whose source code is contained in a different |
2821 // script. | 2825 // script. |
2822 const Script& outer_origin = Script::Handle(zone(), function.script()); | 2826 Zone* zone = Thread::Current()->zone(); |
| 2827 const Script& outer_origin = Script::Handle(zone, function.script()); |
2823 const GrowableObjectArray& closures = | 2828 const GrowableObjectArray& closures = |
2824 GrowableObjectArray::Handle(zone(), owner.closures()); | 2829 GrowableObjectArray::Handle(zone, owner.closures()); |
2825 const intptr_t num_closures = closures.Length(); | 2830 const intptr_t num_closures = closures.Length(); |
2826 Function& closure = Function::Handle(zone()); | 2831 Function& closure = Function::Handle(zone); |
2827 Function& best_fit = Function::Handle(zone()); | 2832 Function& best_fit = Function::Handle(zone); |
2828 for (intptr_t i = 0; i < num_closures; i++) { | 2833 for (intptr_t i = 0; i < num_closures; i++) { |
2829 closure ^= closures.At(i); | 2834 closure ^= closures.At(i); |
2830 if ((function.token_pos() < closure.token_pos()) && | 2835 if ((function.token_pos() < closure.token_pos()) && |
2831 (closure.end_token_pos() < function.end_token_pos()) && | 2836 (closure.end_token_pos() < function.end_token_pos()) && |
2832 (closure.token_pos() <= token_pos) && | 2837 (closure.token_pos() <= token_pos) && |
2833 (token_pos <= closure.end_token_pos()) && | 2838 (token_pos <= closure.end_token_pos()) && |
2834 (closure.script() == outer_origin.raw())) { | 2839 (closure.script() == outer_origin.raw())) { |
2835 SelectBestFit(&best_fit, &closure); | 2840 SelectBestFit(&best_fit, &closure); |
2836 } | 2841 } |
2837 } | 2842 } |
2838 return best_fit.raw(); | 2843 return best_fit.raw(); |
2839 } | 2844 } |
2840 | 2845 |
2841 | 2846 |
2842 void Debugger::NotifyCompilation(const Function& func) { | 2847 void Debugger::NotifyCompilation(const Function& func) { |
2843 if (breakpoint_locations_ == NULL) { | 2848 if (breakpoint_locations_ == NULL) { |
2844 // Return with minimal overhead if there are no breakpoints. | 2849 // Return with minimal overhead if there are no breakpoints. |
2845 return; | 2850 return; |
2846 } | 2851 } |
2847 if (!func.is_debuggable()) { | 2852 if (!func.is_debuggable()) { |
2848 // Nothing to do if the function is not debuggable. If there is | 2853 // Nothing to do if the function is not debuggable. If there is |
2849 // a pending breakpoint in an inner function (that is debuggable), | 2854 // a pending breakpoint in an inner function (that is debuggable), |
2850 // we'll resolve the breakpoint when the inner function is compiled. | 2855 // we'll resolve the breakpoint when the inner function is compiled. |
2851 return; | 2856 return; |
2852 } | 2857 } |
2853 // Iterate over all source breakpoints to check whether breakpoints | 2858 // Iterate over all source breakpoints to check whether breakpoints |
2854 // need to be set in the newly compiled function. | 2859 // need to be set in the newly compiled function. |
2855 Script& script = Script::Handle(zone()); | 2860 Zone* zone = Thread::Current()->zone(); |
| 2861 Script& script = Script::Handle(zone); |
2856 for (BreakpointLocation* loc = breakpoint_locations_; | 2862 for (BreakpointLocation* loc = breakpoint_locations_; |
2857 loc != NULL; | 2863 loc != NULL; |
2858 loc = loc->next()) { | 2864 loc = loc->next()) { |
2859 script = loc->script(); | 2865 script = loc->script(); |
2860 if (FunctionContains(func, script, loc->token_pos())) { | 2866 if (FunctionContains(func, script, loc->token_pos())) { |
2861 Function& inner_function = Function::Handle(zone()); | 2867 Function& inner_function = Function::Handle(zone); |
2862 inner_function = FindInnermostClosure(func, loc->token_pos()); | 2868 inner_function = FindInnermostClosure(func, loc->token_pos()); |
2863 if (!inner_function.IsNull()) { | 2869 if (!inner_function.IsNull()) { |
2864 // The local function of a function we just compiled cannot | 2870 // The local function of a function we just compiled cannot |
2865 // be compiled already. | 2871 // be compiled already. |
2866 ASSERT(!inner_function.HasCode()); | 2872 ASSERT(!inner_function.HasCode()); |
2867 if (FLAG_verbose_debug) { | 2873 if (FLAG_verbose_debug) { |
2868 OS::Print("Pending BP remains unresolved in inner function '%s'\n", | 2874 OS::Print("Pending BP remains unresolved in inner function '%s'\n", |
2869 inner_function.ToFullyQualifiedCString()); | 2875 inner_function.ToFullyQualifiedCString()); |
2870 } | 2876 } |
2871 continue; | 2877 continue; |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2932 } | 2938 } |
2933 } | 2939 } |
2934 } | 2940 } |
2935 | 2941 |
2936 | 2942 |
2937 void Debugger::NotifyDoneLoading() { | 2943 void Debugger::NotifyDoneLoading() { |
2938 if (latent_locations_ == NULL) { | 2944 if (latent_locations_ == NULL) { |
2939 // Common, fast path. | 2945 // Common, fast path. |
2940 return; | 2946 return; |
2941 } | 2947 } |
2942 Zone* zn = zone(); | 2948 Zone* zone = Thread::Current()->zone(); |
2943 Library& lib = Library::Handle(zn); | 2949 Library& lib = Library::Handle(zone); |
2944 Script& script = Script::Handle(zn); | 2950 Script& script = Script::Handle(zone); |
2945 String& url = String::Handle(zn); | 2951 String& url = String::Handle(zone); |
2946 BreakpointLocation* loc = latent_locations_; | 2952 BreakpointLocation* loc = latent_locations_; |
2947 BreakpointLocation* prev_loc = NULL; | 2953 BreakpointLocation* prev_loc = NULL; |
2948 const GrowableObjectArray& libs = | 2954 const GrowableObjectArray& libs = |
2949 GrowableObjectArray::Handle(isolate_->object_store()->libraries()); | 2955 GrowableObjectArray::Handle(isolate_->object_store()->libraries()); |
2950 while (loc != NULL) { | 2956 while (loc != NULL) { |
2951 url = loc->url(); | 2957 url = loc->url(); |
2952 bool found_match = false; | 2958 bool found_match = false; |
2953 for (intptr_t i = 0; i < libs.Length(); i++) { | 2959 for (intptr_t i = 0; i < libs.Length(); i++) { |
2954 lib ^= libs.At(i); | 2960 lib ^= libs.At(i); |
2955 script = lib.LookupScript(url); | 2961 script = lib.LookupScript(url); |
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3208 loc = loc->next(); | 3214 loc = loc->next(); |
3209 } | 3215 } |
3210 return NULL; | 3216 return NULL; |
3211 } | 3217 } |
3212 | 3218 |
3213 | 3219 |
3214 BreakpointLocation* Debugger::GetLatentBreakpoint(const String& url, | 3220 BreakpointLocation* Debugger::GetLatentBreakpoint(const String& url, |
3215 intptr_t line, | 3221 intptr_t line, |
3216 intptr_t column) { | 3222 intptr_t column) { |
3217 BreakpointLocation* bpt = latent_locations_; | 3223 BreakpointLocation* bpt = latent_locations_; |
3218 String& bpt_url = String::Handle(zone()); | 3224 String& bpt_url = String::Handle(); |
3219 while (bpt != NULL) { | 3225 while (bpt != NULL) { |
3220 bpt_url = bpt->url(); | 3226 bpt_url = bpt->url(); |
3221 if (bpt_url.Equals(url) && | 3227 if (bpt_url.Equals(url) && |
3222 (bpt->requested_line_number() == line) && | 3228 (bpt->requested_line_number() == line) && |
3223 (bpt->requested_column_number() == column)) { | 3229 (bpt->requested_column_number() == column)) { |
3224 return bpt; | 3230 return bpt; |
3225 } | 3231 } |
3226 bpt = bpt->next(); | 3232 bpt = bpt->next(); |
3227 } | 3233 } |
3228 // No breakpoint for this location requested. Allocate new one. | 3234 // No breakpoint for this location requested. Allocate new one. |
(...skipping 11 matching lines...) Expand all Loading... |
3240 } | 3246 } |
3241 | 3247 |
3242 | 3248 |
3243 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { | 3249 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { |
3244 ASSERT(bpt->next() == NULL); | 3250 ASSERT(bpt->next() == NULL); |
3245 bpt->set_next(code_breakpoints_); | 3251 bpt->set_next(code_breakpoints_); |
3246 code_breakpoints_ = bpt; | 3252 code_breakpoints_ = bpt; |
3247 } | 3253 } |
3248 | 3254 |
3249 } // namespace dart | 3255 } // namespace dart |
OLD | NEW |