OLD | NEW |
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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/service_isolate.h" | 5 #include "vm/service_isolate.h" |
6 | 6 |
7 #include "vm/compiler.h" | 7 #include "vm/compiler.h" |
8 #include "vm/dart_api_impl.h" | 8 #include "vm/dart_api_impl.h" |
9 #include "vm/dart_entry.h" | 9 #include "vm/dart_entry.h" |
10 #include "vm/isolate.h" | 10 #include "vm/isolate.h" |
11 #include "vm/lockers.h" | 11 #include "vm/lockers.h" |
12 #include "vm/message.h" | 12 #include "vm/message.h" |
13 #include "vm/message_handler.h" | 13 #include "vm/message_handler.h" |
| 14 #include "vm/native_arguments.h" |
14 #include "vm/native_entry.h" | 15 #include "vm/native_entry.h" |
15 #include "vm/native_arguments.h" | |
16 #include "vm/object.h" | 16 #include "vm/object.h" |
17 #include "vm/object_store.h" | 17 #include "vm/object_store.h" |
18 #include "vm/port.h" | 18 #include "vm/port.h" |
19 #include "vm/service.h" | 19 #include "vm/service.h" |
20 #include "vm/symbols.h" | 20 #include "vm/symbols.h" |
21 #include "vm/thread_pool.h" | 21 #include "vm/thread_pool.h" |
22 #include "vm/timeline.h" | 22 #include "vm/timeline.h" |
23 | 23 |
24 namespace dart { | 24 namespace dart { |
25 | 25 |
26 #define Z (T->zone()) | 26 #define Z (T->zone()) |
27 | 27 |
28 | |
29 DEFINE_FLAG(bool, trace_service, false, "Trace VM service requests."); | 28 DEFINE_FLAG(bool, trace_service, false, "Trace VM service requests."); |
30 DEFINE_FLAG(bool, | 29 DEFINE_FLAG(bool, |
31 trace_service_pause_events, | 30 trace_service_pause_events, |
32 false, | 31 false, |
33 "Trace VM service isolate pause events."); | 32 "Trace VM service isolate pause events."); |
34 DEFINE_FLAG(bool, | 33 DEFINE_FLAG(bool, |
35 trace_service_verbose, | 34 trace_service_verbose, |
36 false, | 35 false, |
37 "Provide extra service tracing information."); | 36 "Provide extra service tracing information."); |
38 | 37 |
39 static uint8_t* malloc_allocator(uint8_t* ptr, | 38 static uint8_t* malloc_allocator(uint8_t* ptr, |
40 intptr_t old_size, | 39 intptr_t old_size, |
41 intptr_t new_size) { | 40 intptr_t new_size) { |
42 void* new_ptr = realloc(reinterpret_cast<void*>(ptr), new_size); | 41 void* new_ptr = realloc(reinterpret_cast<void*>(ptr), new_size); |
43 return reinterpret_cast<uint8_t*>(new_ptr); | 42 return reinterpret_cast<uint8_t*>(new_ptr); |
44 } | 43 } |
45 | 44 |
46 static void malloc_deallocator(uint8_t* ptr) { | 45 static void malloc_deallocator(uint8_t* ptr) { |
47 free(reinterpret_cast<void*>(ptr)); | 46 free(reinterpret_cast<void*>(ptr)); |
48 } | 47 } |
49 | 48 |
50 | |
51 // These must be kept in sync with service/constants.dart | 49 // These must be kept in sync with service/constants.dart |
52 #define VM_SERVICE_ISOLATE_EXIT_MESSAGE_ID 0 | 50 #define VM_SERVICE_ISOLATE_EXIT_MESSAGE_ID 0 |
53 #define VM_SERVICE_ISOLATE_STARTUP_MESSAGE_ID 1 | 51 #define VM_SERVICE_ISOLATE_STARTUP_MESSAGE_ID 1 |
54 #define VM_SERVICE_ISOLATE_SHUTDOWN_MESSAGE_ID 2 | 52 #define VM_SERVICE_ISOLATE_SHUTDOWN_MESSAGE_ID 2 |
55 | 53 |
56 #define VM_SERVICE_WEB_SERVER_CONTROL_MESSAGE_ID 3 | 54 #define VM_SERVICE_WEB_SERVER_CONTROL_MESSAGE_ID 3 |
57 #define VM_SERVICE_SERVER_INFO_MESSAGE_ID 4 | 55 #define VM_SERVICE_SERVER_INFO_MESSAGE_ID 4 |
58 | 56 |
59 static RawArray* MakeServiceControlMessage(Dart_Port port_id, | 57 static RawArray* MakeServiceControlMessage(Dart_Port port_id, |
60 intptr_t code, | 58 intptr_t code, |
61 const String& name) { | 59 const String& name) { |
62 const Array& list = Array::Handle(Array::New(4)); | 60 const Array& list = Array::Handle(Array::New(4)); |
63 ASSERT(!list.IsNull()); | 61 ASSERT(!list.IsNull()); |
64 const Integer& code_int = Integer::Handle(Integer::New(code)); | 62 const Integer& code_int = Integer::Handle(Integer::New(code)); |
65 const Integer& port_int = Integer::Handle(Integer::New(port_id)); | 63 const Integer& port_int = Integer::Handle(Integer::New(port_id)); |
66 const SendPort& send_port = SendPort::Handle(SendPort::New(port_id)); | 64 const SendPort& send_port = SendPort::Handle(SendPort::New(port_id)); |
67 list.SetAt(0, code_int); | 65 list.SetAt(0, code_int); |
68 list.SetAt(1, port_int); | 66 list.SetAt(1, port_int); |
69 list.SetAt(2, send_port); | 67 list.SetAt(2, send_port); |
70 list.SetAt(3, name); | 68 list.SetAt(3, name); |
71 return list.raw(); | 69 return list.raw(); |
72 } | 70 } |
73 | 71 |
74 | |
75 static RawArray* MakeServerControlMessage(const SendPort& sp, | 72 static RawArray* MakeServerControlMessage(const SendPort& sp, |
76 intptr_t code, | 73 intptr_t code, |
77 bool enable = false) { | 74 bool enable = false) { |
78 const Array& list = Array::Handle(Array::New(3)); | 75 const Array& list = Array::Handle(Array::New(3)); |
79 ASSERT(!list.IsNull()); | 76 ASSERT(!list.IsNull()); |
80 list.SetAt(0, Integer::Handle(Integer::New(code))); | 77 list.SetAt(0, Integer::Handle(Integer::New(code))); |
81 list.SetAt(1, sp); | 78 list.SetAt(1, sp); |
82 list.SetAt(2, Bool::Get(enable)); | 79 list.SetAt(2, Bool::Get(enable)); |
83 return list.raw(); | 80 return list.raw(); |
84 } | 81 } |
85 | 82 |
86 | |
87 static RawArray* MakeServiceExitMessage() { | 83 static RawArray* MakeServiceExitMessage() { |
88 const Array& list = Array::Handle(Array::New(1)); | 84 const Array& list = Array::Handle(Array::New(1)); |
89 ASSERT(!list.IsNull()); | 85 ASSERT(!list.IsNull()); |
90 const intptr_t code = VM_SERVICE_ISOLATE_EXIT_MESSAGE_ID; | 86 const intptr_t code = VM_SERVICE_ISOLATE_EXIT_MESSAGE_ID; |
91 const Integer& code_int = Integer::Handle(Integer::New(code)); | 87 const Integer& code_int = Integer::Handle(Integer::New(code)); |
92 list.SetAt(0, code_int); | 88 list.SetAt(0, code_int); |
93 return list.raw(); | 89 return list.raw(); |
94 } | 90 } |
95 | 91 |
96 | |
97 const char* ServiceIsolate::kName = "vm-service"; | 92 const char* ServiceIsolate::kName = "vm-service"; |
98 Isolate* ServiceIsolate::isolate_ = NULL; | 93 Isolate* ServiceIsolate::isolate_ = NULL; |
99 Dart_Port ServiceIsolate::port_ = ILLEGAL_PORT; | 94 Dart_Port ServiceIsolate::port_ = ILLEGAL_PORT; |
100 Dart_Port ServiceIsolate::load_port_ = ILLEGAL_PORT; | 95 Dart_Port ServiceIsolate::load_port_ = ILLEGAL_PORT; |
101 Dart_Port ServiceIsolate::origin_ = ILLEGAL_PORT; | 96 Dart_Port ServiceIsolate::origin_ = ILLEGAL_PORT; |
102 Dart_IsolateCreateCallback ServiceIsolate::create_callback_ = NULL; | 97 Dart_IsolateCreateCallback ServiceIsolate::create_callback_ = NULL; |
103 uint8_t* ServiceIsolate::exit_message_ = NULL; | 98 uint8_t* ServiceIsolate::exit_message_ = NULL; |
104 intptr_t ServiceIsolate::exit_message_length_ = 0; | 99 intptr_t ServiceIsolate::exit_message_length_ = 0; |
105 Monitor* ServiceIsolate::monitor_ = new Monitor(); | 100 Monitor* ServiceIsolate::monitor_ = new Monitor(); |
106 bool ServiceIsolate::initializing_ = true; | 101 bool ServiceIsolate::initializing_ = true; |
107 bool ServiceIsolate::shutting_down_ = false; | 102 bool ServiceIsolate::shutting_down_ = false; |
108 char* ServiceIsolate::server_address_ = NULL; | 103 char* ServiceIsolate::server_address_ = NULL; |
109 | 104 |
110 void ServiceIsolate::RequestServerInfo(const SendPort& sp) { | 105 void ServiceIsolate::RequestServerInfo(const SendPort& sp) { |
111 const Array& message = Array::Handle(MakeServerControlMessage( | 106 const Array& message = Array::Handle(MakeServerControlMessage( |
112 sp, VM_SERVICE_SERVER_INFO_MESSAGE_ID, false /* ignored */)); | 107 sp, VM_SERVICE_SERVER_INFO_MESSAGE_ID, false /* ignored */)); |
113 ASSERT(!message.IsNull()); | 108 ASSERT(!message.IsNull()); |
114 uint8_t* data = NULL; | 109 uint8_t* data = NULL; |
115 MessageWriter writer(&data, &malloc_allocator, &malloc_deallocator, false); | 110 MessageWriter writer(&data, &malloc_allocator, &malloc_deallocator, false); |
116 writer.WriteMessage(message); | 111 writer.WriteMessage(message); |
117 intptr_t len = writer.BytesWritten(); | 112 intptr_t len = writer.BytesWritten(); |
118 PortMap::PostMessage(new Message(port_, data, len, Message::kNormalPriority)); | 113 PortMap::PostMessage(new Message(port_, data, len, Message::kNormalPriority)); |
119 } | 114 } |
120 | 115 |
121 | |
122 void ServiceIsolate::ControlWebServer(const SendPort& sp, bool enable) { | 116 void ServiceIsolate::ControlWebServer(const SendPort& sp, bool enable) { |
123 const Array& message = Array::Handle(MakeServerControlMessage( | 117 const Array& message = Array::Handle(MakeServerControlMessage( |
124 sp, VM_SERVICE_WEB_SERVER_CONTROL_MESSAGE_ID, enable)); | 118 sp, VM_SERVICE_WEB_SERVER_CONTROL_MESSAGE_ID, enable)); |
125 ASSERT(!message.IsNull()); | 119 ASSERT(!message.IsNull()); |
126 uint8_t* data = NULL; | 120 uint8_t* data = NULL; |
127 MessageWriter writer(&data, &malloc_allocator, &malloc_deallocator, false); | 121 MessageWriter writer(&data, &malloc_allocator, &malloc_deallocator, false); |
128 writer.WriteMessage(message); | 122 writer.WriteMessage(message); |
129 intptr_t len = writer.BytesWritten(); | 123 intptr_t len = writer.BytesWritten(); |
130 PortMap::PostMessage(new Message(port_, data, len, Message::kNormalPriority)); | 124 PortMap::PostMessage(new Message(port_, data, len, Message::kNormalPriority)); |
131 } | 125 } |
132 | 126 |
133 | |
134 void ServiceIsolate::SetServerAddress(const char* address) { | 127 void ServiceIsolate::SetServerAddress(const char* address) { |
135 if (server_address_ != NULL) { | 128 if (server_address_ != NULL) { |
136 free(server_address_); | 129 free(server_address_); |
137 server_address_ = NULL; | 130 server_address_ = NULL; |
138 } | 131 } |
139 if (address == NULL) { | 132 if (address == NULL) { |
140 return; | 133 return; |
141 } | 134 } |
142 server_address_ = strdup(address); | 135 server_address_ = strdup(address); |
143 } | 136 } |
144 | 137 |
145 | |
146 bool ServiceIsolate::NameEquals(const char* name) { | 138 bool ServiceIsolate::NameEquals(const char* name) { |
147 ASSERT(name != NULL); | 139 ASSERT(name != NULL); |
148 return strcmp(name, kName) == 0; | 140 return strcmp(name, kName) == 0; |
149 } | 141 } |
150 | 142 |
151 | |
152 bool ServiceIsolate::Exists() { | 143 bool ServiceIsolate::Exists() { |
153 MonitorLocker ml(monitor_); | 144 MonitorLocker ml(monitor_); |
154 return isolate_ != NULL; | 145 return isolate_ != NULL; |
155 } | 146 } |
156 | 147 |
157 | |
158 bool ServiceIsolate::IsRunning() { | 148 bool ServiceIsolate::IsRunning() { |
159 MonitorLocker ml(monitor_); | 149 MonitorLocker ml(monitor_); |
160 return (port_ != ILLEGAL_PORT) && (isolate_ != NULL); | 150 return (port_ != ILLEGAL_PORT) && (isolate_ != NULL); |
161 } | 151 } |
162 | 152 |
163 | |
164 bool ServiceIsolate::IsServiceIsolate(const Isolate* isolate) { | 153 bool ServiceIsolate::IsServiceIsolate(const Isolate* isolate) { |
165 MonitorLocker ml(monitor_); | 154 MonitorLocker ml(monitor_); |
166 return isolate == isolate_; | 155 return isolate == isolate_; |
167 } | 156 } |
168 | 157 |
169 | |
170 bool ServiceIsolate::IsServiceIsolateDescendant(const Isolate* isolate) { | 158 bool ServiceIsolate::IsServiceIsolateDescendant(const Isolate* isolate) { |
171 MonitorLocker ml(monitor_); | 159 MonitorLocker ml(monitor_); |
172 return isolate->origin_id() == origin_; | 160 return isolate->origin_id() == origin_; |
173 } | 161 } |
174 | 162 |
175 | |
176 Dart_Port ServiceIsolate::Port() { | 163 Dart_Port ServiceIsolate::Port() { |
177 MonitorLocker ml(monitor_); | 164 MonitorLocker ml(monitor_); |
178 return port_; | 165 return port_; |
179 } | 166 } |
180 | 167 |
181 | |
182 Dart_Port ServiceIsolate::WaitForLoadPort() { | 168 Dart_Port ServiceIsolate::WaitForLoadPort() { |
183 MonitorLocker ml(monitor_); | 169 MonitorLocker ml(monitor_); |
184 while (initializing_ && (load_port_ == ILLEGAL_PORT)) { | 170 while (initializing_ && (load_port_ == ILLEGAL_PORT)) { |
185 ml.Wait(); | 171 ml.Wait(); |
186 } | 172 } |
187 return load_port_; | 173 return load_port_; |
188 } | 174 } |
189 | 175 |
190 | |
191 Dart_Port ServiceIsolate::LoadPort() { | 176 Dart_Port ServiceIsolate::LoadPort() { |
192 MonitorLocker ml(monitor_); | 177 MonitorLocker ml(monitor_); |
193 return load_port_; | 178 return load_port_; |
194 } | 179 } |
195 | 180 |
196 | |
197 bool ServiceIsolate::SendIsolateStartupMessage() { | 181 bool ServiceIsolate::SendIsolateStartupMessage() { |
198 if (!IsRunning()) { | 182 if (!IsRunning()) { |
199 return false; | 183 return false; |
200 } | 184 } |
201 Thread* thread = Thread::Current(); | 185 Thread* thread = Thread::Current(); |
202 Isolate* isolate = thread->isolate(); | 186 Isolate* isolate = thread->isolate(); |
203 if (IsServiceIsolateDescendant(isolate)) { | 187 if (IsServiceIsolateDescendant(isolate)) { |
204 return false; | 188 return false; |
205 } | 189 } |
206 ASSERT(isolate != NULL); | 190 ASSERT(isolate != NULL); |
207 HANDLESCOPE(thread); | 191 HANDLESCOPE(thread); |
208 const String& name = String::Handle(String::New(isolate->name())); | 192 const String& name = String::Handle(String::New(isolate->name())); |
209 ASSERT(!name.IsNull()); | 193 ASSERT(!name.IsNull()); |
210 const Array& list = Array::Handle(MakeServiceControlMessage( | 194 const Array& list = Array::Handle(MakeServiceControlMessage( |
211 Dart_GetMainPortId(), VM_SERVICE_ISOLATE_STARTUP_MESSAGE_ID, name)); | 195 Dart_GetMainPortId(), VM_SERVICE_ISOLATE_STARTUP_MESSAGE_ID, name)); |
212 ASSERT(!list.IsNull()); | 196 ASSERT(!list.IsNull()); |
213 uint8_t* data = NULL; | 197 uint8_t* data = NULL; |
214 MessageWriter writer(&data, &malloc_allocator, &malloc_deallocator, false); | 198 MessageWriter writer(&data, &malloc_allocator, &malloc_deallocator, false); |
215 writer.WriteMessage(list); | 199 writer.WriteMessage(list); |
216 intptr_t len = writer.BytesWritten(); | 200 intptr_t len = writer.BytesWritten(); |
217 if (FLAG_trace_service) { | 201 if (FLAG_trace_service) { |
218 OS::Print("vm-service: Isolate %s %" Pd64 " registered.\n", | 202 OS::Print("vm-service: Isolate %s %" Pd64 " registered.\n", |
219 name.ToCString(), Dart_GetMainPortId()); | 203 name.ToCString(), Dart_GetMainPortId()); |
220 } | 204 } |
221 return PortMap::PostMessage( | 205 return PortMap::PostMessage( |
222 new Message(port_, data, len, Message::kNormalPriority)); | 206 new Message(port_, data, len, Message::kNormalPriority)); |
223 } | 207 } |
224 | 208 |
225 | |
226 bool ServiceIsolate::SendIsolateShutdownMessage() { | 209 bool ServiceIsolate::SendIsolateShutdownMessage() { |
227 if (!IsRunning()) { | 210 if (!IsRunning()) { |
228 return false; | 211 return false; |
229 } | 212 } |
230 Thread* thread = Thread::Current(); | 213 Thread* thread = Thread::Current(); |
231 Isolate* isolate = thread->isolate(); | 214 Isolate* isolate = thread->isolate(); |
232 if (IsServiceIsolateDescendant(isolate)) { | 215 if (IsServiceIsolateDescendant(isolate)) { |
233 return false; | 216 return false; |
234 } | 217 } |
235 ASSERT(isolate != NULL); | 218 ASSERT(isolate != NULL); |
236 HANDLESCOPE(thread); | 219 HANDLESCOPE(thread); |
237 const String& name = String::Handle(String::New(isolate->name())); | 220 const String& name = String::Handle(String::New(isolate->name())); |
238 ASSERT(!name.IsNull()); | 221 ASSERT(!name.IsNull()); |
239 const Array& list = Array::Handle(MakeServiceControlMessage( | 222 const Array& list = Array::Handle(MakeServiceControlMessage( |
240 Dart_GetMainPortId(), VM_SERVICE_ISOLATE_SHUTDOWN_MESSAGE_ID, name)); | 223 Dart_GetMainPortId(), VM_SERVICE_ISOLATE_SHUTDOWN_MESSAGE_ID, name)); |
241 ASSERT(!list.IsNull()); | 224 ASSERT(!list.IsNull()); |
242 uint8_t* data = NULL; | 225 uint8_t* data = NULL; |
243 MessageWriter writer(&data, &malloc_allocator, &malloc_deallocator, false); | 226 MessageWriter writer(&data, &malloc_allocator, &malloc_deallocator, false); |
244 writer.WriteMessage(list); | 227 writer.WriteMessage(list); |
245 intptr_t len = writer.BytesWritten(); | 228 intptr_t len = writer.BytesWritten(); |
246 if (FLAG_trace_service) { | 229 if (FLAG_trace_service) { |
247 OS::Print("vm-service: Isolate %s %" Pd64 " deregistered.\n", | 230 OS::Print("vm-service: Isolate %s %" Pd64 " deregistered.\n", |
248 name.ToCString(), Dart_GetMainPortId()); | 231 name.ToCString(), Dart_GetMainPortId()); |
249 } | 232 } |
250 return PortMap::PostMessage( | 233 return PortMap::PostMessage( |
251 new Message(port_, data, len, Message::kNormalPriority)); | 234 new Message(port_, data, len, Message::kNormalPriority)); |
252 } | 235 } |
253 | 236 |
254 | |
255 void ServiceIsolate::SendServiceExitMessage() { | 237 void ServiceIsolate::SendServiceExitMessage() { |
256 if (!IsRunning()) { | 238 if (!IsRunning()) { |
257 return; | 239 return; |
258 } | 240 } |
259 if ((exit_message_ == NULL) || (exit_message_length_ == 0)) { | 241 if ((exit_message_ == NULL) || (exit_message_length_ == 0)) { |
260 return; | 242 return; |
261 } | 243 } |
262 if (FLAG_trace_service) { | 244 if (FLAG_trace_service) { |
263 OS::Print("vm-service: sending service exit message.\n"); | 245 OS::Print("vm-service: sending service exit message.\n"); |
264 } | 246 } |
265 PortMap::PostMessage(new Message(port_, exit_message_, exit_message_length_, | 247 PortMap::PostMessage(new Message(port_, exit_message_, exit_message_length_, |
266 Message::kNormalPriority)); | 248 Message::kNormalPriority)); |
267 } | 249 } |
268 | 250 |
269 | |
270 void ServiceIsolate::SetServicePort(Dart_Port port) { | 251 void ServiceIsolate::SetServicePort(Dart_Port port) { |
271 MonitorLocker ml(monitor_); | 252 MonitorLocker ml(monitor_); |
272 port_ = port; | 253 port_ = port; |
273 } | 254 } |
274 | 255 |
275 | |
276 void ServiceIsolate::SetServiceIsolate(Isolate* isolate) { | 256 void ServiceIsolate::SetServiceIsolate(Isolate* isolate) { |
277 MonitorLocker ml(monitor_); | 257 MonitorLocker ml(monitor_); |
278 isolate_ = isolate; | 258 isolate_ = isolate; |
279 if (isolate_ != NULL) { | 259 if (isolate_ != NULL) { |
280 isolate_->is_service_isolate_ = true; | 260 isolate_->is_service_isolate_ = true; |
281 origin_ = isolate_->origin_id(); | 261 origin_ = isolate_->origin_id(); |
282 } | 262 } |
283 } | 263 } |
284 | 264 |
285 void ServiceIsolate::SetLoadPort(Dart_Port port) { | 265 void ServiceIsolate::SetLoadPort(Dart_Port port) { |
286 MonitorLocker ml(monitor_); | 266 MonitorLocker ml(monitor_); |
287 load_port_ = port; | 267 load_port_ = port; |
288 } | 268 } |
289 | 269 |
290 | |
291 void ServiceIsolate::MaybeMakeServiceIsolate(Isolate* I) { | 270 void ServiceIsolate::MaybeMakeServiceIsolate(Isolate* I) { |
292 Thread* T = Thread::Current(); | 271 Thread* T = Thread::Current(); |
293 ASSERT(I == T->isolate()); | 272 ASSERT(I == T->isolate()); |
294 ASSERT(I != NULL); | 273 ASSERT(I != NULL); |
295 ASSERT(I->name() != NULL); | 274 ASSERT(I->name() != NULL); |
296 if (!ServiceIsolate::NameEquals(I->name())) { | 275 if (!ServiceIsolate::NameEquals(I->name())) { |
297 // Not service isolate. | 276 // Not service isolate. |
298 return; | 277 return; |
299 } | 278 } |
300 if (Exists()) { | 279 if (Exists()) { |
301 // Service isolate already exists. | 280 // Service isolate already exists. |
302 return; | 281 return; |
303 } | 282 } |
304 SetServiceIsolate(I); | 283 SetServiceIsolate(I); |
305 } | 284 } |
306 | 285 |
307 | |
308 void ServiceIsolate::ConstructExitMessageAndCache(Isolate* I) { | 286 void ServiceIsolate::ConstructExitMessageAndCache(Isolate* I) { |
309 // Construct and cache exit message here so we can send it without needing an | 287 // Construct and cache exit message here so we can send it without needing an |
310 // isolate. | 288 // isolate. |
311 Thread* T = Thread::Current(); | 289 Thread* T = Thread::Current(); |
312 ASSERT(I == T->isolate()); | 290 ASSERT(I == T->isolate()); |
313 ASSERT(I != NULL); | 291 ASSERT(I != NULL); |
314 StackZone zone(T); | 292 StackZone zone(T); |
315 HANDLESCOPE(T); | 293 HANDLESCOPE(T); |
316 ASSERT(exit_message_ == NULL); | 294 ASSERT(exit_message_ == NULL); |
317 ASSERT(exit_message_length_ == 0); | 295 ASSERT(exit_message_length_ == 0); |
318 const Array& list = Array::Handle(Z, MakeServiceExitMessage()); | 296 const Array& list = Array::Handle(Z, MakeServiceExitMessage()); |
319 ASSERT(!list.IsNull()); | 297 ASSERT(!list.IsNull()); |
320 MessageWriter writer(&exit_message_, &malloc_allocator, &malloc_deallocator, | 298 MessageWriter writer(&exit_message_, &malloc_allocator, &malloc_deallocator, |
321 false); | 299 false); |
322 writer.WriteMessage(list); | 300 writer.WriteMessage(list); |
323 exit_message_length_ = writer.BytesWritten(); | 301 exit_message_length_ = writer.BytesWritten(); |
324 ASSERT(exit_message_ != NULL); | 302 ASSERT(exit_message_ != NULL); |
325 ASSERT(exit_message_length_ != 0); | 303 ASSERT(exit_message_length_ != 0); |
326 } | 304 } |
327 | 305 |
328 | |
329 void ServiceIsolate::FinishedExiting() { | 306 void ServiceIsolate::FinishedExiting() { |
330 MonitorLocker ml(monitor_); | 307 MonitorLocker ml(monitor_); |
331 shutting_down_ = false; | 308 shutting_down_ = false; |
332 ml.NotifyAll(); | 309 ml.NotifyAll(); |
333 } | 310 } |
334 | 311 |
335 | |
336 void ServiceIsolate::FinishedInitializing() { | 312 void ServiceIsolate::FinishedInitializing() { |
337 MonitorLocker ml(monitor_); | 313 MonitorLocker ml(monitor_); |
338 initializing_ = false; | 314 initializing_ = false; |
339 ml.NotifyAll(); | 315 ml.NotifyAll(); |
340 } | 316 } |
341 | 317 |
342 | |
343 class RunServiceTask : public ThreadPool::Task { | 318 class RunServiceTask : public ThreadPool::Task { |
344 public: | 319 public: |
345 virtual void Run() { | 320 virtual void Run() { |
346 ASSERT(Isolate::Current() == NULL); | 321 ASSERT(Isolate::Current() == NULL); |
347 #ifndef PRODUCT | 322 #ifndef PRODUCT |
348 TimelineDurationScope tds(Timeline::GetVMStream(), "ServiceIsolateStartup"); | 323 TimelineDurationScope tds(Timeline::GetVMStream(), "ServiceIsolateStartup"); |
349 #endif // !PRODUCT | 324 #endif // !PRODUCT |
350 char* error = NULL; | 325 char* error = NULL; |
351 Isolate* isolate = NULL; | 326 Isolate* isolate = NULL; |
352 | 327 |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
474 } | 449 } |
475 return false; | 450 return false; |
476 } | 451 } |
477 ASSERT(result.IsReceivePort()); | 452 ASSERT(result.IsReceivePort()); |
478 const ReceivePort& rp = ReceivePort::Cast(result); | 453 const ReceivePort& rp = ReceivePort::Cast(result); |
479 ServiceIsolate::SetLoadPort(rp.Id()); | 454 ServiceIsolate::SetLoadPort(rp.Id()); |
480 return false; | 455 return false; |
481 } | 456 } |
482 }; | 457 }; |
483 | 458 |
484 | |
485 void ServiceIsolate::Run() { | 459 void ServiceIsolate::Run() { |
486 // Grab the isolate create callback here to avoid race conditions with tests | 460 // Grab the isolate create callback here to avoid race conditions with tests |
487 // that change this after Dart_Initialize returns. | 461 // that change this after Dart_Initialize returns. |
488 create_callback_ = Isolate::CreateCallback(); | 462 create_callback_ = Isolate::CreateCallback(); |
489 Dart::thread_pool()->Run(new RunServiceTask()); | 463 Dart::thread_pool()->Run(new RunServiceTask()); |
490 } | 464 } |
491 | 465 |
492 | |
493 void ServiceIsolate::KillServiceIsolate() { | 466 void ServiceIsolate::KillServiceIsolate() { |
494 { | 467 { |
495 MonitorLocker ml(monitor_); | 468 MonitorLocker ml(monitor_); |
496 shutting_down_ = true; | 469 shutting_down_ = true; |
497 } | 470 } |
498 Isolate::KillIfExists(isolate_, Isolate::kInternalKillMsg); | 471 Isolate::KillIfExists(isolate_, Isolate::kInternalKillMsg); |
499 { | 472 { |
500 MonitorLocker ml(monitor_); | 473 MonitorLocker ml(monitor_); |
501 while (shutting_down_) { | 474 while (shutting_down_) { |
502 ml.Wait(); | 475 ml.Wait(); |
503 } | 476 } |
504 } | 477 } |
505 } | 478 } |
506 | 479 |
507 | |
508 void ServiceIsolate::Shutdown() { | 480 void ServiceIsolate::Shutdown() { |
509 if (IsRunning()) { | 481 if (IsRunning()) { |
510 { | 482 { |
511 MonitorLocker ml(monitor_); | 483 MonitorLocker ml(monitor_); |
512 shutting_down_ = true; | 484 shutting_down_ = true; |
513 } | 485 } |
514 SendServiceExitMessage(); | 486 SendServiceExitMessage(); |
515 { | 487 { |
516 MonitorLocker ml(monitor_); | 488 MonitorLocker ml(monitor_); |
517 while (shutting_down_ && (port_ != ILLEGAL_PORT)) { | 489 while (shutting_down_ && (port_ != ILLEGAL_PORT)) { |
518 ml.Wait(); | 490 ml.Wait(); |
519 } | 491 } |
520 } | 492 } |
521 } else { | 493 } else { |
522 if (isolate_ != NULL) { | 494 if (isolate_ != NULL) { |
523 // TODO(johnmccutchan,turnidge) When it is possible to properly create | 495 // TODO(johnmccutchan,turnidge) When it is possible to properly create |
524 // the VMService object and set up its shutdown handler in the service | 496 // the VMService object and set up its shutdown handler in the service |
525 // isolate's main() function, this case will no longer be possible and | 497 // isolate's main() function, this case will no longer be possible and |
526 // can be removed. | 498 // can be removed. |
527 KillServiceIsolate(); | 499 KillServiceIsolate(); |
528 } | 500 } |
529 } | 501 } |
530 if (server_address_ != NULL) { | 502 if (server_address_ != NULL) { |
531 free(server_address_); | 503 free(server_address_); |
532 server_address_ = NULL; | 504 server_address_ = NULL; |
533 } | 505 } |
534 } | 506 } |
535 | 507 |
536 | |
537 void ServiceIsolate::BootVmServiceLibrary() { | 508 void ServiceIsolate::BootVmServiceLibrary() { |
538 Thread* thread = Thread::Current(); | 509 Thread* thread = Thread::Current(); |
539 const Library& vmservice_library = | 510 const Library& vmservice_library = |
540 Library::Handle(Library::LookupLibrary(thread, Symbols::DartVMService())); | 511 Library::Handle(Library::LookupLibrary(thread, Symbols::DartVMService())); |
541 ASSERT(!vmservice_library.IsNull()); | 512 ASSERT(!vmservice_library.IsNull()); |
542 const String& boot_function_name = String::Handle(String::New("boot")); | 513 const String& boot_function_name = String::Handle(String::New("boot")); |
543 const Function& boot_function = Function::Handle( | 514 const Function& boot_function = Function::Handle( |
544 vmservice_library.LookupFunctionAllowPrivate(boot_function_name)); | 515 vmservice_library.LookupFunctionAllowPrivate(boot_function_name)); |
545 ASSERT(!boot_function.IsNull()); | 516 ASSERT(!boot_function.IsNull()); |
546 const Object& result = Object::Handle( | 517 const Object& result = Object::Handle( |
547 DartEntry::InvokeFunction(boot_function, Object::empty_array())); | 518 DartEntry::InvokeFunction(boot_function, Object::empty_array())); |
548 ASSERT(!result.IsNull()); | 519 ASSERT(!result.IsNull()); |
549 if (result.IsUnwindError() || result.IsUnhandledException()) { | 520 if (result.IsUnwindError() || result.IsUnhandledException()) { |
550 Exceptions::PropagateError(Error::Cast(result)); | 521 Exceptions::PropagateError(Error::Cast(result)); |
551 } | 522 } |
552 Dart_Port port = ILLEGAL_PORT; | 523 Dart_Port port = ILLEGAL_PORT; |
553 if (result.IsReceivePort()) { | 524 if (result.IsReceivePort()) { |
554 port = ReceivePort::Cast(result).Id(); | 525 port = ReceivePort::Cast(result).Id(); |
555 } | 526 } |
556 ASSERT(port != ILLEGAL_PORT); | 527 ASSERT(port != ILLEGAL_PORT); |
557 ServiceIsolate::SetServicePort(port); | 528 ServiceIsolate::SetServicePort(port); |
558 } | 529 } |
559 | 530 |
560 | |
561 void ServiceIsolate::VisitObjectPointers(ObjectPointerVisitor* visitor) {} | 531 void ServiceIsolate::VisitObjectPointers(ObjectPointerVisitor* visitor) {} |
562 | 532 |
563 } // namespace dart | 533 } // namespace dart |
OLD | NEW |