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 |