| OLD | NEW |
| (Empty) |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "mojo/dart/embedder/dart_debugger.h" | |
| 6 #include "dart/runtime/include/dart_api.h" | |
| 7 #include "dart/runtime/include/dart_native_api.h" | |
| 8 #include "dart/runtime/include/dart_tools_api.h" | |
| 9 | |
| 10 | |
| 11 namespace mojo { | |
| 12 namespace dart { | |
| 13 | |
| 14 void DartDebuggerIsolate::MessageLoop() { | |
| 15 MonitorLocker ml(&monitor_); | |
| 16 // Request notification on isolate messages. This allows us to | |
| 17 // respond to vm service messages while at breakpoint. | |
| 18 Dart_SetMessageNotifyCallback(DartDebugger::NotifyIsolate); | |
| 19 while (true) { | |
| 20 // Handle all available vm service messages, up to a resume | |
| 21 // request. | |
| 22 bool resume = false; | |
| 23 while (!resume && Dart_HasServiceMessages()) { | |
| 24 monitor_.Exit(); | |
| 25 resume = Dart_HandleServiceMessages(); | |
| 26 monitor_.Enter(); | |
| 27 } | |
| 28 if (resume) { | |
| 29 break; | |
| 30 } | |
| 31 ml.Wait(); | |
| 32 } | |
| 33 Dart_SetMessageNotifyCallback(nullptr); | |
| 34 } | |
| 35 | |
| 36 void DartDebugger::BptResolvedHandler(Dart_IsolateId isolate_id, | |
| 37 intptr_t bp_id, | |
| 38 const Dart_CodeLocation& location) { | |
| 39 // Nothing to do here. Service event is dispatched to let Observatory know | |
| 40 // that a breakpoint was resolved. | |
| 41 } | |
| 42 | |
| 43 void DartDebugger::PausedEventHandler(Dart_IsolateId isolate_id, | |
| 44 intptr_t bp_id, | |
| 45 const Dart_CodeLocation& loc) { | |
| 46 Dart_EnterScope(); | |
| 47 intptr_t isolate_index = FindIsolateIndexById(isolate_id); | |
| 48 CHECK(isolate_index != -1); | |
| 49 (*isolates_)[isolate_index]->MessageLoop(); | |
| 50 Dart_ExitScope(); | |
| 51 } | |
| 52 | |
| 53 void DartDebugger::ExceptionThrownHandler(Dart_IsolateId isolate_id, | |
| 54 Dart_Handle exception, | |
| 55 Dart_StackTrace stack_trace) { | |
| 56 Dart_EnterScope(); | |
| 57 intptr_t isolate_index = FindIsolateIndexById(isolate_id); | |
| 58 CHECK(isolate_index != -1); | |
| 59 (*isolates_)[isolate_index]->MessageLoop(); | |
| 60 Dart_ExitScope(); | |
| 61 } | |
| 62 | |
| 63 void DartDebugger::IsolateEventHandler(Dart_IsolateId isolate_id, | |
| 64 Dart_IsolateEvent kind) { | |
| 65 Dart_EnterScope(); | |
| 66 if (kind == Dart_IsolateEvent::kCreated) { | |
| 67 AddIsolate(isolate_id); | |
| 68 } else { | |
| 69 intptr_t isolate_index = FindIsolateIndexById(isolate_id); | |
| 70 CHECK(isolate_index != -1); | |
| 71 if (kind == Dart_IsolateEvent::kInterrupted) { | |
| 72 (*isolates_)[isolate_index]->MessageLoop(); | |
| 73 } else { | |
| 74 CHECK(kind == Dart_IsolateEvent::kShutdown); | |
| 75 RemoveIsolate(isolate_id); | |
| 76 } | |
| 77 } | |
| 78 Dart_ExitScope(); | |
| 79 } | |
| 80 | |
| 81 void DartDebugger::NotifyIsolate(Dart_Isolate isolate) { | |
| 82 base::AutoLock al(*lock_); | |
| 83 Dart_IsolateId isolate_id = Dart_GetIsolateId(isolate); | |
| 84 intptr_t isolate_index = FindIsolateIndexByIdLocked(isolate_id); | |
| 85 if (isolate_index >= 0) { | |
| 86 (*isolates_)[isolate_index]->Notify(); | |
| 87 } | |
| 88 } | |
| 89 | |
| 90 void DartDebugger::InitDebugger() { | |
| 91 Dart_SetIsolateEventHandler(IsolateEventHandler); | |
| 92 Dart_SetPausedEventHandler(PausedEventHandler); | |
| 93 Dart_SetBreakpointResolvedHandler(BptResolvedHandler); | |
| 94 Dart_SetExceptionThrownHandler(ExceptionThrownHandler); | |
| 95 lock_ = new base::Lock(); | |
| 96 isolates_ = new std::vector<std::unique_ptr<DartDebuggerIsolate>>(); | |
| 97 } | |
| 98 | |
| 99 intptr_t DartDebugger::FindIsolateIndexById(Dart_IsolateId id) { | |
| 100 base::AutoLock al(*lock_); | |
| 101 return FindIsolateIndexByIdLocked(id); | |
| 102 } | |
| 103 | |
| 104 intptr_t DartDebugger::FindIsolateIndexByIdLocked( | |
| 105 Dart_IsolateId id) { | |
| 106 lock_->AssertAcquired(); | |
| 107 for (size_t i = 0; i < isolates_->size(); i++) { | |
| 108 if ((*isolates_)[i]->id() == id) { | |
| 109 return i; | |
| 110 } | |
| 111 } | |
| 112 return -1; | |
| 113 } | |
| 114 | |
| 115 void DartDebugger::AddIsolate(Dart_IsolateId id) { | |
| 116 base::AutoLock al(*lock_); | |
| 117 CHECK(FindIsolateIndexByIdLocked(id) == -1); | |
| 118 std::unique_ptr<DartDebuggerIsolate> debugger_isolate = | |
| 119 std::unique_ptr<DartDebuggerIsolate>(new DartDebuggerIsolate(id)); | |
| 120 isolates_->push_back(std::move(debugger_isolate)); | |
| 121 } | |
| 122 | |
| 123 void DartDebugger::RemoveIsolate(Dart_IsolateId id) { | |
| 124 base::AutoLock al(*lock_); | |
| 125 for (size_t i = 0; i < isolates_->size(); i++) { | |
| 126 if (id == (*isolates_)[i]->id()) { | |
| 127 isolates_->erase(isolates_->begin() + i); | |
| 128 return; | |
| 129 } | |
| 130 } | |
| 131 NOTREACHED(); | |
| 132 } | |
| 133 | |
| 134 base::Lock* DartDebugger::lock_ = nullptr; | |
| 135 std::vector<std::unique_ptr<DartDebuggerIsolate>>* DartDebugger::isolates_ = | |
| 136 nullptr; | |
| 137 | |
| 138 } // namespace dart | |
| 139 } // namespace mojo | |
| OLD | NEW |