| 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 = | 313 const Error& error = Error::Handle(zone(), |
| 314 Error::Handle(isolate_, isolate_->object_store()->sticky_error()); | 314 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(isolate_, isolate_->object_store()->sticky_error()); | 368 Error::Handle(zone(), 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 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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) { |
| 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(isolate_); | 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 937 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1425 const Context& ctx = activation->GetSavedCurrentContext(); | 1425 const Context& ctx = activation->GetSavedCurrentContext(); |
| 1426 OS::PrintErr("\tUsing saved context: %s\n", ctx.ToCString()); | 1426 OS::PrintErr("\tUsing saved context: %s\n", ctx.ToCString()); |
| 1427 } | 1427 } |
| 1428 if (FLAG_trace_debugger_stacktrace) { | 1428 if (FLAG_trace_debugger_stacktrace) { |
| 1429 OS::PrintErr("\tLine number: %" Pd "\n", activation->LineNumber()); | 1429 OS::PrintErr("\tLine number: %" Pd "\n", activation->LineNumber()); |
| 1430 } | 1430 } |
| 1431 return activation; | 1431 return activation; |
| 1432 } | 1432 } |
| 1433 | 1433 |
| 1434 | 1434 |
| 1435 RawArray* Debugger::DeoptimizeToArray(Isolate* isolate, | 1435 RawArray* Debugger::DeoptimizeToArray(Thread* thread, |
| 1436 StackFrame* frame, | 1436 StackFrame* frame, |
| 1437 const Code& code) { | 1437 const Code& code) { |
| 1438 ASSERT(code.is_optimized()); | 1438 ASSERT(code.is_optimized()); |
| 1439 | 1439 Isolate* isolate = thread->isolate(); |
| 1440 // Create the DeoptContext for this deoptimization. | 1440 // Create the DeoptContext for this deoptimization. |
| 1441 DeoptContext* deopt_context = | 1441 DeoptContext* deopt_context = |
| 1442 new DeoptContext(frame, code, | 1442 new DeoptContext(frame, code, |
| 1443 DeoptContext::kDestIsAllocated, | 1443 DeoptContext::kDestIsAllocated, |
| 1444 NULL, | 1444 NULL, |
| 1445 NULL, | 1445 NULL, |
| 1446 true); | 1446 true); |
| 1447 isolate->set_deopt_context(deopt_context); | 1447 isolate->set_deopt_context(deopt_context); |
| 1448 | 1448 |
| 1449 deopt_context->FillDestFrame(); | 1449 deopt_context->FillDestFrame(); |
| 1450 deopt_context->MaterializeDeferredObjects(); | 1450 deopt_context->MaterializeDeferredObjects(); |
| 1451 const Array& dest_frame = Array::Handle(isolate, | 1451 const Array& dest_frame = Array::Handle(thread->zone(), |
| 1452 deopt_context->DestFrameAsArray()); | 1452 deopt_context->DestFrameAsArray()); |
| 1453 | 1453 |
| 1454 isolate->set_deopt_context(NULL); | 1454 isolate->set_deopt_context(NULL); |
| 1455 delete deopt_context; | 1455 delete deopt_context; |
| 1456 | 1456 |
| 1457 return dest_frame.raw(); | 1457 return dest_frame.raw(); |
| 1458 } | 1458 } |
| 1459 | 1459 |
| 1460 | 1460 |
| 1461 DebuggerStackTrace* Debugger::CollectStackTrace() { | 1461 DebuggerStackTrace* Debugger::CollectStackTrace() { |
| 1462 Isolate* isolate = Isolate::Current(); | 1462 Thread* thread = Thread::Current(); |
| 1463 Zone* zone = thread->zone(); |
| 1464 Isolate* isolate = thread->isolate(); |
| 1463 DebuggerStackTrace* stack_trace = new DebuggerStackTrace(8); | 1465 DebuggerStackTrace* stack_trace = new DebuggerStackTrace(8); |
| 1464 StackFrameIterator iterator(false); | 1466 StackFrameIterator iterator(false); |
| 1465 Code& code = Code::Handle(isolate); | 1467 Code& code = Code::Handle(zone); |
| 1466 Code& inlined_code = Code::Handle(isolate); | 1468 Code& inlined_code = Code::Handle(zone); |
| 1467 Array& deopt_frame = Array::Handle(isolate); | 1469 Array& deopt_frame = Array::Handle(zone); |
| 1468 | 1470 |
| 1469 for (StackFrame* frame = iterator.NextFrame(); | 1471 for (StackFrame* frame = iterator.NextFrame(); |
| 1470 frame != NULL; | 1472 frame != NULL; |
| 1471 frame = iterator.NextFrame()) { | 1473 frame = iterator.NextFrame()) { |
| 1472 ASSERT(frame->IsValid()); | 1474 ASSERT(frame->IsValid()); |
| 1473 if (FLAG_trace_debugger_stacktrace) { | 1475 if (FLAG_trace_debugger_stacktrace) { |
| 1474 OS::PrintErr("CollectStackTrace: visiting frame:\n\t%s\n", | 1476 OS::PrintErr("CollectStackTrace: visiting frame:\n\t%s\n", |
| 1475 frame->ToCString()); | 1477 frame->ToCString()); |
| 1476 } | 1478 } |
| 1477 if (frame->IsDartFrame()) { | 1479 if (frame->IsDartFrame()) { |
| 1478 code = frame->LookupDartCode(); | 1480 code = frame->LookupDartCode(); |
| 1479 if (code.is_optimized() && !Compiler::always_optimize()) { | 1481 if (code.is_optimized() && !Compiler::always_optimize()) { |
| 1480 deopt_frame = DeoptimizeToArray(isolate, frame, code); | 1482 deopt_frame = DeoptimizeToArray(thread, frame, code); |
| 1481 for (InlinedFunctionsIterator it(code, frame->pc()); | 1483 for (InlinedFunctionsIterator it(code, frame->pc()); |
| 1482 !it.Done(); | 1484 !it.Done(); |
| 1483 it.Advance()) { | 1485 it.Advance()) { |
| 1484 inlined_code = it.code(); | 1486 inlined_code = it.code(); |
| 1485 if (FLAG_trace_debugger_stacktrace) { | 1487 if (FLAG_trace_debugger_stacktrace) { |
| 1486 const Function& function = | 1488 const Function& function = |
| 1487 Function::Handle(isolate, inlined_code.function()); | 1489 Function::Handle(zone, inlined_code.function()); |
| 1488 ASSERT(!function.IsNull()); | 1490 ASSERT(!function.IsNull()); |
| 1489 OS::PrintErr("CollectStackTrace: visiting inlined function: %s\n", | 1491 OS::PrintErr("CollectStackTrace: visiting inlined function: %s\n", |
| 1490 function.ToFullyQualifiedCString()); | 1492 function.ToFullyQualifiedCString()); |
| 1491 } | 1493 } |
| 1492 intptr_t deopt_frame_offset = it.GetDeoptFpOffset(); | 1494 intptr_t deopt_frame_offset = it.GetDeoptFpOffset(); |
| 1493 stack_trace->AddActivation(CollectDartFrame(isolate, | 1495 stack_trace->AddActivation(CollectDartFrame(isolate, |
| 1494 it.pc(), | 1496 it.pc(), |
| 1495 frame, | 1497 frame, |
| 1496 inlined_code, | 1498 inlined_code, |
| 1497 deopt_frame, | 1499 deopt_frame, |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1510 return stack_trace; | 1512 return stack_trace; |
| 1511 } | 1513 } |
| 1512 | 1514 |
| 1513 | 1515 |
| 1514 ActivationFrame* Debugger::TopDartFrame() const { | 1516 ActivationFrame* Debugger::TopDartFrame() const { |
| 1515 StackFrameIterator iterator(false); | 1517 StackFrameIterator iterator(false); |
| 1516 StackFrame* frame = iterator.NextFrame(); | 1518 StackFrame* frame = iterator.NextFrame(); |
| 1517 while ((frame != NULL) && !frame->IsDartFrame()) { | 1519 while ((frame != NULL) && !frame->IsDartFrame()) { |
| 1518 frame = iterator.NextFrame(); | 1520 frame = iterator.NextFrame(); |
| 1519 } | 1521 } |
| 1520 Code& code = Code::Handle(isolate_, frame->LookupDartCode()); | 1522 Code& code = Code::Handle(zone(), frame->LookupDartCode()); |
| 1521 ActivationFrame* activation = | 1523 ActivationFrame* activation = |
| 1522 new ActivationFrame(frame->pc(), frame->fp(), frame->sp(), code, | 1524 new ActivationFrame(frame->pc(), frame->fp(), frame->sp(), code, |
| 1523 Object::null_array(), 0); | 1525 Object::null_array(), 0); |
| 1524 return activation; | 1526 return activation; |
| 1525 } | 1527 } |
| 1526 | 1528 |
| 1527 | 1529 |
| 1528 DebuggerStackTrace* Debugger::StackTrace() { | 1530 DebuggerStackTrace* Debugger::StackTrace() { |
| 1529 return (stack_trace_ != NULL) ? stack_trace_ : CollectStackTrace(); | 1531 return (stack_trace_ != NULL) ? stack_trace_ : CollectStackTrace(); |
| 1530 } | 1532 } |
| (...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1857 if (loc->AnyEnabled()) { | 1859 if (loc->AnyEnabled()) { |
| 1858 code_bpt->Enable(); | 1860 code_bpt->Enable(); |
| 1859 } | 1861 } |
| 1860 } | 1862 } |
| 1861 | 1863 |
| 1862 | 1864 |
| 1863 void Debugger::FindCompiledFunctions(const Script& script, | 1865 void Debugger::FindCompiledFunctions(const Script& script, |
| 1864 intptr_t start_pos, | 1866 intptr_t start_pos, |
| 1865 intptr_t end_pos, | 1867 intptr_t end_pos, |
| 1866 GrowableObjectArray* function_list) { | 1868 GrowableObjectArray* function_list) { |
| 1867 Class& cls = Class::Handle(isolate_); | 1869 Zone* zn = zone(); |
| 1868 Array& functions = Array::Handle(isolate_); | 1870 Class& cls = Class::Handle(zn); |
| 1869 GrowableObjectArray& closures = GrowableObjectArray::Handle(isolate_); | 1871 Array& functions = Array::Handle(zn); |
| 1870 Function& function = Function::Handle(isolate_); | 1872 GrowableObjectArray& closures = GrowableObjectArray::Handle(zn); |
| 1873 Function& function = Function::Handle(zn); |
| 1871 | 1874 |
| 1872 const ClassTable& class_table = *isolate_->class_table(); | 1875 const ClassTable& class_table = *isolate_->class_table(); |
| 1873 const intptr_t num_classes = class_table.NumCids(); | 1876 const intptr_t num_classes = class_table.NumCids(); |
| 1874 for (intptr_t i = 1; i < num_classes; i++) { | 1877 for (intptr_t i = 1; i < num_classes; i++) { |
| 1875 if (class_table.HasValidClassAt(i)) { | 1878 if (class_table.HasValidClassAt(i)) { |
| 1876 cls = class_table.At(i); | 1879 cls = class_table.At(i); |
| 1877 // If the class is not finalized, e.g. if it hasn't been parsed | 1880 // If the class is not finalized, e.g. if it hasn't been parsed |
| 1878 // yet entirely, we can ignore it. If it contains a function with | 1881 // yet entirely, we can ignore it. If it contains a function with |
| 1879 // an unresolved breakpoint, we will detect it if and when the | 1882 // an unresolved breakpoint, we will detect it if and when the |
| 1880 // function gets compiled. | 1883 // function gets compiled. |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1940 if ((func->token_pos() > best_fit->token_pos()) && | 1943 if ((func->token_pos() > best_fit->token_pos()) && |
| 1941 ((func->end_token_pos() <= best_fit->end_token_pos()))) { | 1944 ((func->end_token_pos() <= best_fit->end_token_pos()))) { |
| 1942 *best_fit = func->raw(); | 1945 *best_fit = func->raw(); |
| 1943 } | 1946 } |
| 1944 } | 1947 } |
| 1945 } | 1948 } |
| 1946 | 1949 |
| 1947 | 1950 |
| 1948 RawFunction* Debugger::FindBestFit(const Script& script, | 1951 RawFunction* Debugger::FindBestFit(const Script& script, |
| 1949 intptr_t token_pos) { | 1952 intptr_t token_pos) { |
| 1950 Class& cls = Class::Handle(isolate_); | 1953 Zone* zn = zone(); |
| 1951 Array& functions = Array::Handle(isolate_); | 1954 Class& cls = Class::Handle(zn); |
| 1952 GrowableObjectArray& closures = GrowableObjectArray::Handle(isolate_); | 1955 Array& functions = Array::Handle(zn); |
| 1953 Function& function = Function::Handle(isolate_); | 1956 GrowableObjectArray& closures = GrowableObjectArray::Handle(zn); |
| 1954 Function& best_fit = Function::Handle(isolate_); | 1957 Function& function = Function::Handle(zn); |
| 1955 Error& error = Error::Handle(isolate_); | 1958 Function& best_fit = Function::Handle(zn); |
| 1959 Error& error = Error::Handle(zn); |
| 1956 | 1960 |
| 1957 const ClassTable& class_table = *isolate_->class_table(); | 1961 const ClassTable& class_table = *isolate_->class_table(); |
| 1958 const intptr_t num_classes = class_table.NumCids(); | 1962 const intptr_t num_classes = class_table.NumCids(); |
| 1959 for (intptr_t i = 1; i < num_classes; i++) { | 1963 for (intptr_t i = 1; i < num_classes; i++) { |
| 1960 if (class_table.HasValidClassAt(i)) { | 1964 if (class_table.HasValidClassAt(i)) { |
| 1961 cls = class_table.At(i); | 1965 cls = class_table.At(i); |
| 1962 // Note: if this class has been parsed and finalized already, | 1966 // Note: if this class has been parsed and finalized already, |
| 1963 // we need to check the functions of this class even if | 1967 // we need to check the functions of this class even if |
| 1964 // it is defined in a differenct 'script'. There could | 1968 // it is defined in a differenct 'script'. There could |
| 1965 // be mixin functions from the given script in this class. | 1969 // be mixin functions from the given script in this class. |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2004 } | 2008 } |
| 2005 return best_fit.raw(); | 2009 return best_fit.raw(); |
| 2006 } | 2010 } |
| 2007 | 2011 |
| 2008 | 2012 |
| 2009 BreakpointLocation* Debugger::SetBreakpoint(const Script& script, | 2013 BreakpointLocation* Debugger::SetBreakpoint(const Script& script, |
| 2010 intptr_t token_pos, | 2014 intptr_t token_pos, |
| 2011 intptr_t last_token_pos, | 2015 intptr_t last_token_pos, |
| 2012 intptr_t requested_line, | 2016 intptr_t requested_line, |
| 2013 intptr_t requested_column) { | 2017 intptr_t requested_column) { |
| 2014 Function& func = Function::Handle(isolate_); | 2018 Function& func = Function::Handle(zone()); |
| 2015 func = FindBestFit(script, token_pos); | 2019 func = FindBestFit(script, token_pos); |
| 2016 if (func.IsNull()) { | 2020 if (func.IsNull()) { |
| 2017 return NULL; | 2021 return NULL; |
| 2018 } | 2022 } |
| 2019 // There may be more than one function object for a given function | 2023 // There may be more than one function object for a given function |
| 2020 // in source code. There may be implicit closure functions, and | 2024 // in source code. There may be implicit closure functions, and |
| 2021 // there may be copies of mixin functions. Collect all compiled | 2025 // there may be copies of mixin functions. Collect all compiled |
| 2022 // functions whose source code range matches exactly the best fit | 2026 // functions whose source code range matches exactly the best fit |
| 2023 // function we found. | 2027 // function we found. |
| 2024 GrowableObjectArray& functions = | 2028 GrowableObjectArray& functions = |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2196 return loc->AddRepeated(this); | 2200 return loc->AddRepeated(this); |
| 2197 } | 2201 } |
| 2198 return NULL; | 2202 return NULL; |
| 2199 } | 2203 } |
| 2200 | 2204 |
| 2201 | 2205 |
| 2202 BreakpointLocation* Debugger::BreakpointLocationAtLineCol( | 2206 BreakpointLocation* Debugger::BreakpointLocationAtLineCol( |
| 2203 const String& script_url, | 2207 const String& script_url, |
| 2204 intptr_t line_number, | 2208 intptr_t line_number, |
| 2205 intptr_t column_number) { | 2209 intptr_t column_number) { |
| 2206 Library& lib = Library::Handle(isolate_); | 2210 Library& lib = Library::Handle(zone()); |
| 2207 Script& script = Script::Handle(isolate_); | 2211 Script& script = Script::Handle(zone()); |
| 2208 const GrowableObjectArray& libs = | 2212 const GrowableObjectArray& libs = |
| 2209 GrowableObjectArray::Handle(isolate_->object_store()->libraries()); | 2213 GrowableObjectArray::Handle(isolate_->object_store()->libraries()); |
| 2210 const GrowableObjectArray& scripts = | 2214 const GrowableObjectArray& scripts = |
| 2211 GrowableObjectArray::Handle(isolate_, GrowableObjectArray::New()); | 2215 GrowableObjectArray::Handle(zone(), GrowableObjectArray::New()); |
| 2212 for (intptr_t i = 0; i < libs.Length(); i++) { | 2216 for (intptr_t i = 0; i < libs.Length(); i++) { |
| 2213 lib ^= libs.At(i); | 2217 lib ^= libs.At(i); |
| 2214 script = lib.LookupScript(script_url); | 2218 script = lib.LookupScript(script_url); |
| 2215 if (!script.IsNull()) { | 2219 if (!script.IsNull()) { |
| 2216 scripts.Add(script); | 2220 scripts.Add(script); |
| 2217 } | 2221 } |
| 2218 } | 2222 } |
| 2219 if (scripts.Length() == 0) { | 2223 if (scripts.Length() == 0) { |
| 2220 // No script found with given url. Create a latent breakpoint which | 2224 // No script found with given url. Create a latent breakpoint which |
| 2221 // will be set if the url is loaded later. | 2225 // will be set if the url is loaded later. |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2391 } | 2395 } |
| 2392 return Array::MakeArray(field_list); | 2396 return Array::MakeArray(field_list); |
| 2393 } | 2397 } |
| 2394 | 2398 |
| 2395 | 2399 |
| 2396 void Debugger::CollectLibraryFields(const GrowableObjectArray& field_list, | 2400 void Debugger::CollectLibraryFields(const GrowableObjectArray& field_list, |
| 2397 const Library& lib, | 2401 const Library& lib, |
| 2398 const String& prefix, | 2402 const String& prefix, |
| 2399 bool include_private_fields) { | 2403 bool include_private_fields) { |
| 2400 DictionaryIterator it(lib); | 2404 DictionaryIterator it(lib); |
| 2401 Object& entry = Object::Handle(isolate_); | 2405 Object& entry = Object::Handle(isolate_->current_zone()); |
| 2402 Field& field = Field::Handle(isolate_); | 2406 Field& field = Field::Handle(zone()); |
| 2403 String& field_name = String::Handle(isolate_); | 2407 String& field_name = String::Handle(zone()); |
| 2404 PassiveObject& field_value = PassiveObject::Handle(isolate_); | 2408 PassiveObject& field_value = PassiveObject::Handle(isolate_->current_zone()); |
| 2405 while (it.HasNext()) { | 2409 while (it.HasNext()) { |
| 2406 entry = it.GetNext(); | 2410 entry = it.GetNext(); |
| 2407 if (entry.IsField()) { | 2411 if (entry.IsField()) { |
| 2408 field ^= entry.raw(); | 2412 field ^= entry.raw(); |
| 2409 ASSERT(field.is_static()); | 2413 ASSERT(field.is_static()); |
| 2410 field_name = field.name(); | 2414 field_name = field.name(); |
| 2411 if ((field_name.CharAt(0) == '_') && !include_private_fields) { | 2415 if ((field_name.CharAt(0) == '_') && !include_private_fields) { |
| 2412 // Skip library-private field. | 2416 // Skip library-private field. |
| 2413 continue; | 2417 continue; |
| 2414 } | 2418 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 2427 field_list.Add(field_name); | 2431 field_list.Add(field_name); |
| 2428 field_list.Add(field_value); | 2432 field_list.Add(field_value); |
| 2429 } | 2433 } |
| 2430 } | 2434 } |
| 2431 } | 2435 } |
| 2432 | 2436 |
| 2433 | 2437 |
| 2434 RawArray* Debugger::GetLibraryFields(const Library& lib) { | 2438 RawArray* Debugger::GetLibraryFields(const Library& lib) { |
| 2435 const GrowableObjectArray& field_list = | 2439 const GrowableObjectArray& field_list = |
| 2436 GrowableObjectArray::Handle(GrowableObjectArray::New(8)); | 2440 GrowableObjectArray::Handle(GrowableObjectArray::New(8)); |
| 2437 CollectLibraryFields(field_list, lib, String::Handle(isolate_), true); | 2441 CollectLibraryFields(field_list, lib, String::Handle(zone()), true); |
| 2438 return Array::MakeArray(field_list); | 2442 return Array::MakeArray(field_list); |
| 2439 } | 2443 } |
| 2440 | 2444 |
| 2441 | 2445 |
| 2442 RawArray* Debugger::GetGlobalFields(const Library& lib) { | 2446 RawArray* Debugger::GetGlobalFields(const Library& lib) { |
| 2443 const GrowableObjectArray& field_list = | 2447 const GrowableObjectArray& field_list = |
| 2444 GrowableObjectArray::Handle(GrowableObjectArray::New(8)); | 2448 GrowableObjectArray::Handle(GrowableObjectArray::New(8)); |
| 2445 String& prefix_name = String::Handle(isolate_); | 2449 String& prefix_name = String::Handle(zone()); |
| 2446 CollectLibraryFields(field_list, lib, prefix_name, true); | 2450 CollectLibraryFields(field_list, lib, prefix_name, true); |
| 2447 Library& imported = Library::Handle(isolate_); | 2451 Library& imported = Library::Handle(zone()); |
| 2448 intptr_t num_imports = lib.num_imports(); | 2452 intptr_t num_imports = lib.num_imports(); |
| 2449 for (intptr_t i = 0; i < num_imports; i++) { | 2453 for (intptr_t i = 0; i < num_imports; i++) { |
| 2450 imported = lib.ImportLibraryAt(i); | 2454 imported = lib.ImportLibraryAt(i); |
| 2451 ASSERT(!imported.IsNull()); | 2455 ASSERT(!imported.IsNull()); |
| 2452 CollectLibraryFields(field_list, imported, prefix_name, false); | 2456 CollectLibraryFields(field_list, imported, prefix_name, false); |
| 2453 } | 2457 } |
| 2454 LibraryPrefix& prefix = LibraryPrefix::Handle(isolate_); | 2458 LibraryPrefix& prefix = LibraryPrefix::Handle(zone()); |
| 2455 LibraryPrefixIterator it(lib); | 2459 LibraryPrefixIterator it(lib); |
| 2456 while (it.HasNext()) { | 2460 while (it.HasNext()) { |
| 2457 prefix = it.GetNext(); | 2461 prefix = it.GetNext(); |
| 2458 prefix_name = prefix.name(); | 2462 prefix_name = prefix.name(); |
| 2459 ASSERT(!prefix_name.IsNull()); | 2463 ASSERT(!prefix_name.IsNull()); |
| 2460 prefix_name = String::Concat(prefix_name, Symbols::Dot()); | 2464 prefix_name = String::Concat(prefix_name, Symbols::Dot()); |
| 2461 for (int32_t i = 0; i < prefix.num_imports(); i++) { | 2465 for (int32_t i = 0; i < prefix.num_imports(); i++) { |
| 2462 imported = prefix.GetLibrary(i); | 2466 imported = prefix.GetLibrary(i); |
| 2463 CollectLibraryFields(field_list, imported, prefix_name, false); | 2467 CollectLibraryFields(field_list, imported, prefix_name, false); |
| 2464 } | 2468 } |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2653 } | 2657 } |
| 2654 | 2658 |
| 2655 ASSERT(stack_trace_ == NULL); | 2659 ASSERT(stack_trace_ == NULL); |
| 2656 stack_trace_ = CollectStackTrace(); | 2660 stack_trace_ = CollectStackTrace(); |
| 2657 SignalPausedEvent(frame, NULL); | 2661 SignalPausedEvent(frame, NULL); |
| 2658 HandleSteppingRequest(stack_trace_); | 2662 HandleSteppingRequest(stack_trace_); |
| 2659 stack_trace_ = NULL; | 2663 stack_trace_ = NULL; |
| 2660 | 2664 |
| 2661 // If any error occurred while in the debug message loop, return it here. | 2665 // If any error occurred while in the debug message loop, return it here. |
| 2662 const Error& error = | 2666 const Error& error = |
| 2663 Error::Handle(isolate_, isolate_->object_store()->sticky_error()); | 2667 Error::Handle(zone(), isolate_->object_store()->sticky_error()); |
| 2664 isolate_->object_store()->clear_sticky_error(); | 2668 isolate_->object_store()->clear_sticky_error(); |
| 2665 return error.raw(); | 2669 return error.raw(); |
| 2666 } | 2670 } |
| 2667 | 2671 |
| 2668 | 2672 |
| 2669 RawError* Debugger::SignalBpReached() { | 2673 RawError* Debugger::SignalBpReached() { |
| 2670 // We ignore this breakpoint when the VM is executing code invoked | 2674 // We ignore this breakpoint when the VM is executing code invoked |
| 2671 // by the debugger to evaluate variables values, or when we see a nested | 2675 // by the debugger to evaluate variables values, or when we see a nested |
| 2672 // breakpoint or exception event. | 2676 // breakpoint or exception event. |
| 2673 if (ignore_breakpoints_ || IsPaused() || !HasEventHandler()) { | 2677 if (ignore_breakpoints_ || IsPaused() || !HasEventHandler()) { |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2742 stack_trace_ = stack_trace; | 2746 stack_trace_ = stack_trace; |
| 2743 SignalPausedEvent(top_frame, bpt_hit); | 2747 SignalPausedEvent(top_frame, bpt_hit); |
| 2744 HandleSteppingRequest(stack_trace_); | 2748 HandleSteppingRequest(stack_trace_); |
| 2745 stack_trace_ = NULL; | 2749 stack_trace_ = NULL; |
| 2746 if (cbpt->IsInternal()) { | 2750 if (cbpt->IsInternal()) { |
| 2747 RemoveInternalBreakpoints(); | 2751 RemoveInternalBreakpoints(); |
| 2748 } | 2752 } |
| 2749 | 2753 |
| 2750 // If any error occurred while in the debug message loop, return it here. | 2754 // If any error occurred while in the debug message loop, return it here. |
| 2751 const Error& error = | 2755 const Error& error = |
| 2752 Error::Handle(isolate_, isolate_->object_store()->sticky_error()); | 2756 Error::Handle(zone(), isolate_->object_store()->sticky_error()); |
| 2753 isolate_->object_store()->clear_sticky_error(); | 2757 isolate_->object_store()->clear_sticky_error(); |
| 2754 return error.raw(); | 2758 return error.raw(); |
| 2755 } | 2759 } |
| 2756 | 2760 |
| 2757 | 2761 |
| 2758 void Debugger::BreakHere(const String& msg) { | 2762 void Debugger::BreakHere(const String& msg) { |
| 2759 // We ignore this breakpoint when the VM is executing code invoked | 2763 // We ignore this breakpoint when the VM is executing code invoked |
| 2760 // by the debugger to evaluate variables values, or when we see a nested | 2764 // by the debugger to evaluate variables values, or when we see a nested |
| 2761 // breakpoint or exception event. | 2765 // breakpoint or exception event. |
| 2762 if (ignore_breakpoints_ || IsPaused() || !HasEventHandler()) { | 2766 if (ignore_breakpoints_ || IsPaused() || !HasEventHandler()) { |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2799 if (!ServiceIsolate::IsServiceIsolateDescendant(isolate_)) { | 2803 if (!ServiceIsolate::IsServiceIsolateDescendant(isolate_)) { |
| 2800 SignalIsolateEvent(DebuggerEvent::kIsolateCreated); | 2804 SignalIsolateEvent(DebuggerEvent::kIsolateCreated); |
| 2801 } | 2805 } |
| 2802 } | 2806 } |
| 2803 | 2807 |
| 2804 | 2808 |
| 2805 // Return innermost closure contained in 'function' that contains | 2809 // Return innermost closure contained in 'function' that contains |
| 2806 // the given token position. | 2810 // the given token position. |
| 2807 RawFunction* Debugger::FindInnermostClosure(const Function& function, | 2811 RawFunction* Debugger::FindInnermostClosure(const Function& function, |
| 2808 intptr_t token_pos) { | 2812 intptr_t token_pos) { |
| 2809 const Class& owner = Class::Handle(isolate_, function.Owner()); | 2813 const Class& owner = Class::Handle(zone(), function.Owner()); |
| 2810 if (owner.closures() == GrowableObjectArray::null()) { | 2814 if (owner.closures() == GrowableObjectArray::null()) { |
| 2811 return Function::null(); | 2815 return Function::null(); |
| 2812 } | 2816 } |
| 2813 // Note that we need to check that the closure is in the same | 2817 // Note that we need to check that the closure is in the same |
| 2814 // script as the outer function. We could have closures originating | 2818 // script as the outer function. We could have closures originating |
| 2815 // in mixin classes whose source code is contained in a different | 2819 // in mixin classes whose source code is contained in a different |
| 2816 // script. | 2820 // script. |
| 2817 const Script& outer_origin = Script::Handle(isolate_, function.script()); | 2821 const Script& outer_origin = Script::Handle(zone(), function.script()); |
| 2818 const GrowableObjectArray& closures = | 2822 const GrowableObjectArray& closures = |
| 2819 GrowableObjectArray::Handle(isolate_, owner.closures()); | 2823 GrowableObjectArray::Handle(zone(), owner.closures()); |
| 2820 const intptr_t num_closures = closures.Length(); | 2824 const intptr_t num_closures = closures.Length(); |
| 2821 Function& closure = Function::Handle(isolate_); | 2825 Function& closure = Function::Handle(zone()); |
| 2822 Function& best_fit = Function::Handle(isolate_); | 2826 Function& best_fit = Function::Handle(zone()); |
| 2823 for (intptr_t i = 0; i < num_closures; i++) { | 2827 for (intptr_t i = 0; i < num_closures; i++) { |
| 2824 closure ^= closures.At(i); | 2828 closure ^= closures.At(i); |
| 2825 if ((function.token_pos() < closure.token_pos()) && | 2829 if ((function.token_pos() < closure.token_pos()) && |
| 2826 (closure.end_token_pos() < function.end_token_pos()) && | 2830 (closure.end_token_pos() < function.end_token_pos()) && |
| 2827 (closure.token_pos() <= token_pos) && | 2831 (closure.token_pos() <= token_pos) && |
| 2828 (token_pos <= closure.end_token_pos()) && | 2832 (token_pos <= closure.end_token_pos()) && |
| 2829 (closure.script() == outer_origin.raw())) { | 2833 (closure.script() == outer_origin.raw())) { |
| 2830 SelectBestFit(&best_fit, &closure); | 2834 SelectBestFit(&best_fit, &closure); |
| 2831 } | 2835 } |
| 2832 } | 2836 } |
| 2833 return best_fit.raw(); | 2837 return best_fit.raw(); |
| 2834 } | 2838 } |
| 2835 | 2839 |
| 2836 | 2840 |
| 2837 void Debugger::NotifyCompilation(const Function& func) { | 2841 void Debugger::NotifyCompilation(const Function& func) { |
| 2838 if (breakpoint_locations_ == NULL) { | 2842 if (breakpoint_locations_ == NULL) { |
| 2839 // Return with minimal overhead if there are no breakpoints. | 2843 // Return with minimal overhead if there are no breakpoints. |
| 2840 return; | 2844 return; |
| 2841 } | 2845 } |
| 2842 if (!func.is_debuggable()) { | 2846 if (!func.is_debuggable()) { |
| 2843 // Nothing to do if the function is not debuggable. If there is | 2847 // Nothing to do if the function is not debuggable. If there is |
| 2844 // a pending breakpoint in an inner function (that is debuggable), | 2848 // a pending breakpoint in an inner function (that is debuggable), |
| 2845 // we'll resolve the breakpoint when the inner function is compiled. | 2849 // we'll resolve the breakpoint when the inner function is compiled. |
| 2846 return; | 2850 return; |
| 2847 } | 2851 } |
| 2848 // Iterate over all source breakpoints to check whether breakpoints | 2852 // Iterate over all source breakpoints to check whether breakpoints |
| 2849 // need to be set in the newly compiled function. | 2853 // need to be set in the newly compiled function. |
| 2850 Script& script = Script::Handle(isolate_); | 2854 Script& script = Script::Handle(zone()); |
| 2851 for (BreakpointLocation* loc = breakpoint_locations_; | 2855 for (BreakpointLocation* loc = breakpoint_locations_; |
| 2852 loc != NULL; | 2856 loc != NULL; |
| 2853 loc = loc->next()) { | 2857 loc = loc->next()) { |
| 2854 script = loc->script(); | 2858 script = loc->script(); |
| 2855 if (FunctionContains(func, script, loc->token_pos())) { | 2859 if (FunctionContains(func, script, loc->token_pos())) { |
| 2856 Function& inner_function = Function::Handle(isolate_); | 2860 Function& inner_function = Function::Handle(zone()); |
| 2857 inner_function = FindInnermostClosure(func, loc->token_pos()); | 2861 inner_function = FindInnermostClosure(func, loc->token_pos()); |
| 2858 if (!inner_function.IsNull()) { | 2862 if (!inner_function.IsNull()) { |
| 2859 // The local function of a function we just compiled cannot | 2863 // The local function of a function we just compiled cannot |
| 2860 // be compiled already. | 2864 // be compiled already. |
| 2861 ASSERT(!inner_function.HasCode()); | 2865 ASSERT(!inner_function.HasCode()); |
| 2862 if (FLAG_verbose_debug) { | 2866 if (FLAG_verbose_debug) { |
| 2863 OS::Print("Pending BP remains unresolved in inner function '%s'\n", | 2867 OS::Print("Pending BP remains unresolved in inner function '%s'\n", |
| 2864 inner_function.ToFullyQualifiedCString()); | 2868 inner_function.ToFullyQualifiedCString()); |
| 2865 } | 2869 } |
| 2866 continue; | 2870 continue; |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2927 } | 2931 } |
| 2928 } | 2932 } |
| 2929 } | 2933 } |
| 2930 | 2934 |
| 2931 | 2935 |
| 2932 void Debugger::NotifyDoneLoading() { | 2936 void Debugger::NotifyDoneLoading() { |
| 2933 if (latent_locations_ == NULL) { | 2937 if (latent_locations_ == NULL) { |
| 2934 // Common, fast path. | 2938 // Common, fast path. |
| 2935 return; | 2939 return; |
| 2936 } | 2940 } |
| 2937 Library& lib = Library::Handle(isolate_); | 2941 Zone* zn = zone(); |
| 2938 Script& script = Script::Handle(isolate_); | 2942 Library& lib = Library::Handle(zn); |
| 2939 String& url = String::Handle(isolate_); | 2943 Script& script = Script::Handle(zn); |
| 2944 String& url = String::Handle(zn); |
| 2940 BreakpointLocation* loc = latent_locations_; | 2945 BreakpointLocation* loc = latent_locations_; |
| 2941 BreakpointLocation* prev_loc = NULL; | 2946 BreakpointLocation* prev_loc = NULL; |
| 2942 const GrowableObjectArray& libs = | 2947 const GrowableObjectArray& libs = |
| 2943 GrowableObjectArray::Handle(isolate_->object_store()->libraries()); | 2948 GrowableObjectArray::Handle(isolate_->object_store()->libraries()); |
| 2944 while (loc != NULL) { | 2949 while (loc != NULL) { |
| 2945 url = loc->url(); | 2950 url = loc->url(); |
| 2946 bool found_match = false; | 2951 bool found_match = false; |
| 2947 for (intptr_t i = 0; i < libs.Length(); i++) { | 2952 for (intptr_t i = 0; i < libs.Length(); i++) { |
| 2948 lib ^= libs.At(i); | 2953 lib ^= libs.At(i); |
| 2949 script = lib.LookupScript(url); | 2954 script = lib.LookupScript(url); |
| (...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3202 loc = loc->next(); | 3207 loc = loc->next(); |
| 3203 } | 3208 } |
| 3204 return NULL; | 3209 return NULL; |
| 3205 } | 3210 } |
| 3206 | 3211 |
| 3207 | 3212 |
| 3208 BreakpointLocation* Debugger::GetLatentBreakpoint(const String& url, | 3213 BreakpointLocation* Debugger::GetLatentBreakpoint(const String& url, |
| 3209 intptr_t line, | 3214 intptr_t line, |
| 3210 intptr_t column) { | 3215 intptr_t column) { |
| 3211 BreakpointLocation* bpt = latent_locations_; | 3216 BreakpointLocation* bpt = latent_locations_; |
| 3212 String& bpt_url = String::Handle(isolate_); | 3217 String& bpt_url = String::Handle(zone()); |
| 3213 while (bpt != NULL) { | 3218 while (bpt != NULL) { |
| 3214 bpt_url = bpt->url(); | 3219 bpt_url = bpt->url(); |
| 3215 if (bpt_url.Equals(url) && | 3220 if (bpt_url.Equals(url) && |
| 3216 (bpt->requested_line_number() == line) && | 3221 (bpt->requested_line_number() == line) && |
| 3217 (bpt->requested_column_number() == column)) { | 3222 (bpt->requested_column_number() == column)) { |
| 3218 return bpt; | 3223 return bpt; |
| 3219 } | 3224 } |
| 3220 bpt = bpt->next(); | 3225 bpt = bpt->next(); |
| 3221 } | 3226 } |
| 3222 // No breakpoint for this location requested. Allocate new one. | 3227 // No breakpoint for this location requested. Allocate new one. |
| (...skipping 11 matching lines...) Expand all Loading... |
| 3234 } | 3239 } |
| 3235 | 3240 |
| 3236 | 3241 |
| 3237 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { | 3242 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { |
| 3238 ASSERT(bpt->next() == NULL); | 3243 ASSERT(bpt->next() == NULL); |
| 3239 bpt->set_next(code_breakpoints_); | 3244 bpt->set_next(code_breakpoints_); |
| 3240 code_breakpoints_ = bpt; | 3245 code_breakpoints_ = bpt; |
| 3241 } | 3246 } |
| 3242 | 3247 |
| 3243 } // namespace dart | 3248 } // namespace dart |
| OLD | NEW |