OLD | NEW |
---|---|
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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/isolate.h" | 5 #include "vm/isolate.h" |
6 | 6 |
7 #include "include/dart_api.h" | 7 #include "include/dart_api.h" |
8 #include "include/dart_native_api.h" | 8 #include "include/dart_native_api.h" |
9 #include "platform/assert.h" | 9 #include "platform/assert.h" |
10 #include "platform/json.h" | 10 #include "platform/json.h" |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
142 void Isolate::RegisterClassAt(intptr_t index, const Class& cls) { | 142 void Isolate::RegisterClassAt(intptr_t index, const Class& cls) { |
143 class_table()->RegisterAt(index, cls); | 143 class_table()->RegisterAt(index, cls); |
144 } | 144 } |
145 | 145 |
146 | 146 |
147 void Isolate::ValidateClassTable() { | 147 void Isolate::ValidateClassTable() { |
148 class_table()->Validate(); | 148 class_table()->Validate(); |
149 } | 149 } |
150 | 150 |
151 | 151 |
152 void Isolate::SendInternalLibMessage(LibMsgId msg_id, uint64_t capability) { | |
153 const Array& msg = Array::Handle(Array::New(3)); | |
154 Object& element = Object::Handle(); | |
155 | |
156 element = Smi::New(Message::kIsolateLibOOBMsg); | |
157 msg.SetAt(0, element); | |
158 element = Smi::New(msg_id); | |
159 msg.SetAt(1, element); | |
160 element = Capability::New(capability); | |
161 msg.SetAt(2, element); | |
162 | |
163 uint8_t* data = NULL; | |
164 MessageWriter writer(&data, &allocator, false); | |
165 writer.WriteMessage(msg); | |
166 | |
167 PortMap::PostMessage(new Message(main_port(), | |
168 data, writer.BytesWritten(), | |
169 Message::kOOBPriority)); | |
170 } | |
171 | |
172 | |
152 class IsolateMessageHandler : public MessageHandler { | 173 class IsolateMessageHandler : public MessageHandler { |
153 public: | 174 public: |
154 explicit IsolateMessageHandler(Isolate* isolate); | 175 explicit IsolateMessageHandler(Isolate* isolate); |
155 ~IsolateMessageHandler(); | 176 ~IsolateMessageHandler(); |
156 | 177 |
157 const char* name() const; | 178 const char* name() const; |
158 void MessageNotify(Message::Priority priority); | 179 void MessageNotify(Message::Priority priority); |
159 bool HandleMessage(Message* message); | 180 bool HandleMessage(Message* message); |
160 void NotifyPauseOnStart(); | 181 void NotifyPauseOnStart(); |
161 void NotifyPauseOnExit(); | 182 void NotifyPauseOnExit(); |
162 | 183 |
163 #if defined(DEBUG) | 184 #if defined(DEBUG) |
164 // Check that it is safe to access this handler. | 185 // Check that it is safe to access this handler. |
165 void CheckAccess(); | 186 void CheckAccess(); |
166 #endif | 187 #endif |
167 bool IsCurrentIsolate() const; | 188 bool IsCurrentIsolate() const; |
168 virtual Isolate* isolate() const { return isolate_; } | 189 virtual Isolate* isolate() const { return isolate_; } |
169 | 190 |
170 // Keep both these enums in sync with isolate_patch.dart. | |
171 // The different Isolate API message types. | |
172 enum { | |
173 kPauseMsg = 1, | |
174 kResumeMsg = 2, | |
175 kPingMsg = 3, | |
176 kKillMsg = 4, | |
177 kAddExitMsg = 5, | |
178 kDelExitMsg = 6, | |
179 kAddErrorMsg = 7, | |
180 kDelErrorMsg = 8, | |
181 kErrorFatalMsg = 9, | |
182 }; | |
183 // The different Isolate API message priorities for ping and kill messages. | |
184 enum { | |
185 kImmediateAction = 0, | |
186 kBeforeNextEventAction = 1, | |
187 kAsEventAction = 2 | |
188 }; | |
189 | |
190 private: | 191 private: |
191 // A result of false indicates that the isolate should terminate the | 192 // A result of false indicates that the isolate should terminate the |
192 // processing of further events. | 193 // processing of further events. |
193 bool HandleLibMessage(const Array& message); | 194 RawError* HandleLibMessage(const Array& message); |
194 | 195 |
195 bool ProcessUnhandledException(const Error& result); | 196 bool ProcessUnhandledException(const Error& result); |
196 Isolate* isolate_; | 197 Isolate* isolate_; |
197 }; | 198 }; |
198 | 199 |
199 | 200 |
200 IsolateMessageHandler::IsolateMessageHandler(Isolate* isolate) | 201 IsolateMessageHandler::IsolateMessageHandler(Isolate* isolate) |
201 : isolate_(isolate) { | 202 : isolate_(isolate) { |
202 } | 203 } |
203 | 204 |
204 | 205 |
205 IsolateMessageHandler::~IsolateMessageHandler() { | 206 IsolateMessageHandler::~IsolateMessageHandler() { |
206 } | 207 } |
207 | 208 |
208 const char* IsolateMessageHandler::name() const { | 209 const char* IsolateMessageHandler::name() const { |
209 return isolate_->name(); | 210 return isolate_->name(); |
210 } | 211 } |
211 | 212 |
212 | 213 |
213 // Isolate library OOB messages are fixed sized arrays which have the | 214 // Isolate library OOB messages are fixed sized arrays which have the |
214 // following format: | 215 // following format: |
215 // [ OOB dispatch, Isolate library dispatch, <message specific data> ] | 216 // [ OOB dispatch, Isolate library dispatch, <message specific data> ] |
216 bool IsolateMessageHandler::HandleLibMessage(const Array& message) { | 217 RawError* IsolateMessageHandler::HandleLibMessage(const Array& message) { |
217 if (message.Length() < 2) return true; | 218 if (message.Length() < 2) return Error::null(); |
218 const Object& type = Object::Handle(I, message.At(1)); | 219 const Object& type = Object::Handle(I, message.At(1)); |
219 if (!type.IsSmi()) return true; | 220 if (!type.IsSmi()) return Error::null(); |
220 const intptr_t msg_type = Smi::Cast(type).Value(); | 221 const intptr_t msg_type = Smi::Cast(type).Value(); |
221 switch (msg_type) { | 222 switch (msg_type) { |
222 case kPauseMsg: { | 223 case Isolate::kPauseMsg: { |
223 // [ OOB, kPauseMsg, pause capability, resume capability ] | 224 // [ OOB, kPauseMsg, pause capability, resume capability ] |
224 if (message.Length() != 4) return true; | 225 if (message.Length() != 4) return Error::null(); |
225 Object& obj = Object::Handle(I, message.At(2)); | 226 Object& obj = Object::Handle(I, message.At(2)); |
226 if (!I->VerifyPauseCapability(obj)) return true; | 227 if (!I->VerifyPauseCapability(obj)) return Error::null(); |
227 obj = message.At(3); | 228 obj = message.At(3); |
228 if (!obj.IsCapability()) return true; | 229 if (!obj.IsCapability()) return Error::null(); |
229 if (I->AddResumeCapability(Capability::Cast(obj))) { | 230 if (I->AddResumeCapability(Capability::Cast(obj))) { |
230 increment_paused(); | 231 increment_paused(); |
231 } | 232 } |
232 break; | 233 break; |
233 } | 234 } |
234 case kResumeMsg: { | 235 case Isolate::kResumeMsg: { |
235 // [ OOB, kResumeMsg, pause capability, resume capability ] | 236 // [ OOB, kResumeMsg, pause capability, resume capability ] |
236 if (message.Length() != 4) return true; | 237 if (message.Length() != 4) return Error::null(); |
237 Object& obj = Object::Handle(I, message.At(2)); | 238 Object& obj = Object::Handle(I, message.At(2)); |
238 if (!I->VerifyPauseCapability(obj)) return true; | 239 if (!I->VerifyPauseCapability(obj)) return Error::null(); |
239 obj = message.At(3); | 240 obj = message.At(3); |
240 if (!obj.IsCapability()) return true; | 241 if (!obj.IsCapability()) return Error::null(); |
241 if (I->RemoveResumeCapability(Capability::Cast(obj))) { | 242 if (I->RemoveResumeCapability(Capability::Cast(obj))) { |
242 decrement_paused(); | 243 decrement_paused(); |
243 } | 244 } |
244 break; | 245 break; |
245 } | 246 } |
246 case kPingMsg: { | 247 case Isolate::kPingMsg: { |
247 // [ OOB, kPingMsg, responsePort, priority, response ] | 248 // [ OOB, kPingMsg, responsePort, priority, response ] |
248 if (message.Length() != 5) return true; | 249 if (message.Length() != 5) return Error::null(); |
249 const Object& obj2 = Object::Handle(I, message.At(2)); | 250 const Object& obj2 = Object::Handle(I, message.At(2)); |
250 if (!obj2.IsSendPort()) return true; | 251 if (!obj2.IsSendPort()) return Error::null(); |
251 const SendPort& send_port = SendPort::Cast(obj2); | 252 const SendPort& send_port = SendPort::Cast(obj2); |
252 const Object& obj3 = Object::Handle(I, message.At(3)); | 253 const Object& obj3 = Object::Handle(I, message.At(3)); |
253 if (!obj3.IsSmi()) return true; | 254 if (!obj3.IsSmi()) return Error::null(); |
254 const intptr_t priority = Smi::Cast(obj3).Value(); | 255 const intptr_t priority = Smi::Cast(obj3).Value(); |
255 const Object& obj4 = Object::Handle(I, message.At(4)); | 256 const Object& obj4 = Object::Handle(I, message.At(4)); |
256 if (!obj4.IsInstance() && !obj4.IsNull()) return true; | 257 if (!obj4.IsInstance() && !obj4.IsNull()) return Error::null(); |
257 const Instance& response = | 258 const Instance& response = |
258 obj4.IsNull() ? Instance::null_instance() : Instance::Cast(obj4); | 259 obj4.IsNull() ? Instance::null_instance() : Instance::Cast(obj4); |
259 if (priority == kImmediateAction) { | 260 if (priority == Isolate::kImmediateAction) { |
260 uint8_t* data = NULL; | 261 uint8_t* data = NULL; |
261 intptr_t len = 0; | 262 intptr_t len = 0; |
262 SerializeObject(response, &data, &len, false); | 263 SerializeObject(response, &data, &len, false); |
263 PortMap::PostMessage(new Message(send_port.Id(), | 264 PortMap::PostMessage(new Message(send_port.Id(), |
264 data, len, | 265 data, len, |
265 Message::kNormalPriority)); | 266 Message::kNormalPriority)); |
266 } else { | 267 } else { |
267 ASSERT((priority == kBeforeNextEventAction) || | 268 ASSERT((priority == Isolate::kBeforeNextEventAction) || |
268 (priority == kAsEventAction)); | 269 (priority == Isolate::kAsEventAction)); |
269 // Update the message so that it will be handled immediately when it | 270 // Update the message so that it will be handled immediately when it |
270 // is picked up from the message queue the next time. | 271 // is picked up from the message queue the next time. |
271 message.SetAt( | 272 message.SetAt( |
272 0, Smi::Handle(I, Smi::New(Message::kDelayedIsolateLibOOBMsg))); | 273 0, Smi::Handle(I, Smi::New(Message::kDelayedIsolateLibOOBMsg))); |
273 message.SetAt(3, Smi::Handle(I, Smi::New(kImmediateAction))); | 274 message.SetAt(3, Smi::Handle(I, Smi::New(Isolate::kImmediateAction))); |
274 uint8_t* data = NULL; | 275 uint8_t* data = NULL; |
275 intptr_t len = 0; | 276 intptr_t len = 0; |
276 SerializeObject(message, &data, &len, false); | 277 SerializeObject(message, &data, &len, false); |
277 this->PostMessage(new Message(Message::kIllegalPort, | 278 this->PostMessage( |
278 data, len, | 279 new Message(Message::kIllegalPort, |
279 Message::kNormalPriority), | 280 data, len, |
280 priority == kBeforeNextEventAction /* at_head */); | 281 Message::kNormalPriority), |
282 priority == Isolate::kBeforeNextEventAction /* at_head */); | |
281 } | 283 } |
282 break; | 284 break; |
283 } | 285 } |
284 case kKillMsg: { | 286 case Isolate::kKillMsg: { |
285 // [ OOB, kKillMsg, terminate capability, priority ] | 287 // [ OOB, kKillMsg, terminate capability, priority ] |
286 if (message.Length() != 4) return true; | 288 if (message.Length() != 4) return Error::null(); |
287 Object& obj = Object::Handle(I, message.At(3)); | 289 Object& obj = Object::Handle(I, message.At(3)); |
288 if (!obj.IsSmi()) return true; | 290 if (!obj.IsSmi()) return Error::null(); |
289 const intptr_t priority = Smi::Cast(obj).Value(); | 291 const intptr_t priority = Smi::Cast(obj).Value(); |
290 if (priority == kImmediateAction) { | 292 if (priority == Isolate::kImmediateAction) { |
291 obj = message.At(2); | 293 obj = message.At(2); |
292 // Signal that the isolate should stop execution. | 294 // Signal that the isolate should stop execution. |
293 return !I->VerifyTerminateCapability(obj); | 295 if (I->VerifyTerminateCapability(obj)) { |
296 const String& msg = String::Handle(String::New( | |
297 "isolate terminated by Isolate.kill")); | |
298 return UnwindError::New(msg); | |
299 } else { | |
300 return Error::null(); | |
301 } | |
294 } else { | 302 } else { |
295 ASSERT((priority == kBeforeNextEventAction) || | 303 ASSERT((priority == Isolate::kBeforeNextEventAction) || |
296 (priority == kAsEventAction)); | 304 (priority == Isolate::kAsEventAction)); |
297 // Update the message so that it will be handled immediately when it | 305 // Update the message so that it will be handled immediately when it |
298 // is picked up from the message queue the next time. | 306 // is picked up from the message queue the next time. |
299 message.SetAt( | 307 message.SetAt( |
300 0, Smi::Handle(I, Smi::New(Message::kDelayedIsolateLibOOBMsg))); | 308 0, Smi::Handle(I, Smi::New(Message::kDelayedIsolateLibOOBMsg))); |
301 message.SetAt(3, Smi::Handle(I, Smi::New(kImmediateAction))); | 309 message.SetAt(3, Smi::Handle(I, Smi::New(Isolate::kImmediateAction))); |
302 uint8_t* data = NULL; | 310 uint8_t* data = NULL; |
303 intptr_t len = 0; | 311 intptr_t len = 0; |
304 SerializeObject(message, &data, &len, false); | 312 SerializeObject(message, &data, &len, false); |
305 this->PostMessage(new Message(Message::kIllegalPort, | 313 this->PostMessage( |
306 data, len, | 314 new Message(Message::kIllegalPort, |
307 Message::kNormalPriority), | 315 data, len, |
308 priority == kBeforeNextEventAction /* at_head */); | 316 Message::kNormalPriority), |
317 priority == Isolate::kBeforeNextEventAction /* at_head */); | |
309 } | 318 } |
310 break; | 319 break; |
311 } | 320 } |
312 case kAddExitMsg: | 321 case Isolate::kInterruptMsg: { |
313 case kDelExitMsg: | 322 // [ OOB, kInterruptMsg, pause capability ] |
314 case kAddErrorMsg: | 323 if (message.Length() != 3) return Error::null(); |
315 case kDelErrorMsg: { | 324 Object& obj = Object::Handle(I, message.At(2)); |
325 if (!I->VerifyPauseCapability(obj)) return Error::null(); | |
326 | |
327 // If we are already paused, don't pause again. | |
328 if (I->debugger()->PauseEvent() == NULL) { | |
329 return I->debugger()->SignalIsolateInterrupted(); | |
330 } | |
331 break; | |
332 } | |
333 | |
334 case Isolate::kAddExitMsg: | |
335 case Isolate::kDelExitMsg: | |
336 case Isolate::kAddErrorMsg: | |
337 case Isolate::kDelErrorMsg: { | |
316 // [ OOB, msg, listener port ] | 338 // [ OOB, msg, listener port ] |
317 if (message.Length() < 3) return true; | 339 if (message.Length() < 3) return Error::null(); |
318 const Object& obj = Object::Handle(I, message.At(2)); | 340 const Object& obj = Object::Handle(I, message.At(2)); |
319 if (!obj.IsSendPort()) return true; | 341 if (!obj.IsSendPort()) return Error::null(); |
320 const SendPort& listener = SendPort::Cast(obj); | 342 const SendPort& listener = SendPort::Cast(obj); |
321 switch (msg_type) { | 343 switch (msg_type) { |
322 case kAddExitMsg: { | 344 case Isolate::kAddExitMsg: { |
323 if (message.Length() != 4) return true; | 345 if (message.Length() != 4) return Error::null(); |
324 // [ OOB, msg, listener port, response object ] | 346 // [ OOB, msg, listener port, response object ] |
325 const Object& response = Object::Handle(I, message.At(3)); | 347 const Object& response = Object::Handle(I, message.At(3)); |
326 if (!response.IsInstance() && !response.IsNull()) return true; | 348 if (!response.IsInstance() && !response.IsNull()) { |
349 return Error::null(); | |
350 } | |
327 I->AddExitListener(listener, | 351 I->AddExitListener(listener, |
328 response.IsNull() ? Instance::null_instance() | 352 response.IsNull() ? Instance::null_instance() |
329 : Instance::Cast(response)); | 353 : Instance::Cast(response)); |
330 break; | 354 break; |
331 } | 355 } |
332 case kDelExitMsg: | 356 case Isolate::kDelExitMsg: |
333 if (message.Length() != 3) return true; | 357 if (message.Length() != 3) return Error::null(); |
334 I->RemoveExitListener(listener); | 358 I->RemoveExitListener(listener); |
335 break; | 359 break; |
336 case kAddErrorMsg: | 360 case Isolate::kAddErrorMsg: |
337 if (message.Length() != 3) return true; | 361 if (message.Length() != 3) return Error::null(); |
338 I->AddErrorListener(listener); | 362 I->AddErrorListener(listener); |
339 break; | 363 break; |
340 case kDelErrorMsg: | 364 case Isolate::kDelErrorMsg: |
341 if (message.Length() != 3) return true; | 365 if (message.Length() != 3) return Error::null(); |
342 I->RemoveErrorListener(listener); | 366 I->RemoveErrorListener(listener); |
343 break; | 367 break; |
344 default: | 368 default: |
345 UNREACHABLE(); | 369 UNREACHABLE(); |
346 } | 370 } |
347 break; | 371 break; |
348 } | 372 } |
349 case kErrorFatalMsg: { | 373 case Isolate::kErrorFatalMsg: { |
350 // [ OOB, kErrorFatalMsg, terminate capability, val ] | 374 // [ OOB, kErrorFatalMsg, terminate capability, val ] |
351 if (message.Length() != 4) return true; | 375 if (message.Length() != 4) return Error::null(); |
352 // Check that the terminate capability has been passed correctly. | 376 // Check that the terminate capability has been passed correctly. |
353 Object& obj = Object::Handle(I, message.At(2)); | 377 Object& obj = Object::Handle(I, message.At(2)); |
354 if (!I->VerifyTerminateCapability(obj)) return true; | 378 if (!I->VerifyTerminateCapability(obj)) return Error::null(); |
355 // Get the value to be set. | 379 // Get the value to be set. |
356 obj = message.At(3); | 380 obj = message.At(3); |
357 if (!obj.IsBool()) return true; | 381 if (!obj.IsBool()) return Error::null(); |
358 I->SetErrorsFatal(Bool::Cast(obj).value()); | 382 I->SetErrorsFatal(Bool::Cast(obj).value()); |
359 break; | 383 break; |
360 } | 384 } |
361 #if defined(DEBUG) | 385 #if defined(DEBUG) |
362 // Malformed OOB messages are silently ignored in release builds. | 386 // Malformed OOB messages are silently ignored in release builds. |
363 default: | 387 default: |
364 UNREACHABLE(); | 388 UNREACHABLE(); |
365 break; | 389 break; |
366 #endif // defined(DEBUG) | 390 #endif // defined(DEBUG) |
367 } | 391 } |
368 return true; | 392 return Error::null(); |
369 } | 393 } |
370 | 394 |
371 | 395 |
372 void IsolateMessageHandler::MessageNotify(Message::Priority priority) { | 396 void IsolateMessageHandler::MessageNotify(Message::Priority priority) { |
373 if (priority >= Message::kOOBPriority) { | 397 if (priority >= Message::kOOBPriority) { |
374 // Handle out of band messages even if the isolate is busy. | 398 // Handle out of band messages even if the isolate is busy. |
375 I->ScheduleInterrupts(Isolate::kMessageInterrupt); | 399 I->ScheduleInterrupts(Isolate::kMessageInterrupt); |
376 } | 400 } |
377 Dart_MessageNotifyCallback callback = I->message_notify_callback(); | 401 Dart_MessageNotifyCallback callback = I->message_notify_callback(); |
378 if (callback) { | 402 if (callback) { |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
448 const Array& oob_msg = Array::Cast(msg); | 472 const Array& oob_msg = Array::Cast(msg); |
449 if (oob_msg.Length() > 0) { | 473 if (oob_msg.Length() > 0) { |
450 const Object& oob_tag = Object::Handle(zone, oob_msg.At(0)); | 474 const Object& oob_tag = Object::Handle(zone, oob_msg.At(0)); |
451 if (oob_tag.IsSmi()) { | 475 if (oob_tag.IsSmi()) { |
452 switch (Smi::Cast(oob_tag).Value()) { | 476 switch (Smi::Cast(oob_tag).Value()) { |
453 case Message::kServiceOOBMsg: { | 477 case Message::kServiceOOBMsg: { |
454 Service::HandleIsolateMessage(I, oob_msg); | 478 Service::HandleIsolateMessage(I, oob_msg); |
455 break; | 479 break; |
456 } | 480 } |
457 case Message::kIsolateLibOOBMsg: { | 481 case Message::kIsolateLibOOBMsg: { |
458 success = HandleLibMessage(oob_msg); | 482 const Error& error = Error::Handle(HandleLibMessage(oob_msg)); |
483 if (!error.IsNull()) { | |
484 success = ProcessUnhandledException(error); | |
485 } | |
459 break; | 486 break; |
460 } | 487 } |
461 #if defined(DEBUG) | 488 #if defined(DEBUG) |
462 // Malformed OOB messages are silently ignored in release builds. | 489 // Malformed OOB messages are silently ignored in release builds. |
463 default: { | 490 default: { |
464 UNREACHABLE(); | 491 UNREACHABLE(); |
465 break; | 492 break; |
466 } | 493 } |
467 #endif // defined(DEBUG) | 494 #endif // defined(DEBUG) |
468 } | 495 } |
469 } | 496 } |
470 } | 497 } |
471 } | 498 } |
472 } else if (message->dest_port() == Message::kIllegalPort) { | 499 } else if (message->dest_port() == Message::kIllegalPort) { |
473 // Check whether this is a delayed OOB message which needed handling as | 500 // Check whether this is a delayed OOB message which needed handling as |
474 // part of the regular message dispatch. All other messages are dropped on | 501 // part of the regular message dispatch. All other messages are dropped on |
475 // the floor. | 502 // the floor. |
476 if (msg.IsArray()) { | 503 if (msg.IsArray()) { |
477 const Array& msg_arr = Array::Cast(msg); | 504 const Array& msg_arr = Array::Cast(msg); |
478 if (msg_arr.Length() > 0) { | 505 if (msg_arr.Length() > 0) { |
479 const Object& oob_tag = Object::Handle(zone, msg_arr.At(0)); | 506 const Object& oob_tag = Object::Handle(zone, msg_arr.At(0)); |
480 if (oob_tag.IsSmi() && | 507 if (oob_tag.IsSmi() && |
481 (Smi::Cast(oob_tag).Value() == Message::kDelayedIsolateLibOOBMsg)) { | 508 (Smi::Cast(oob_tag).Value() == Message::kDelayedIsolateLibOOBMsg)) { |
482 success = HandleLibMessage(Array::Cast(msg_arr)); | 509 const Error& error = Error::Handle(HandleLibMessage(msg_arr)); |
510 if (!error.IsNull()) { | |
511 success = ProcessUnhandledException(error); | |
512 } | |
483 } | 513 } |
484 } | 514 } |
485 } | 515 } |
486 } else { | 516 } else { |
487 const Object& result = Object::Handle(zone, | 517 const Object& result = Object::Handle(zone, |
488 DartLibraryCalls::HandleMessage(msg_handler, msg)); | 518 DartLibraryCalls::HandleMessage(msg_handler, msg)); |
489 if (result.IsError()) { | 519 if (result.IsError()) { |
490 success = ProcessUnhandledException(Error::Cast(result)); | 520 success = ProcessUnhandledException(Error::Cast(result)); |
491 } else { | 521 } else { |
492 ASSERT(result.IsNull()); | 522 ASSERT(result.IsNull()); |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
553 const UnhandledException& error = UnhandledException::Cast(result); | 583 const UnhandledException& error = UnhandledException::Cast(result); |
554 RawInstance* exception = error.exception(); | 584 RawInstance* exception = error.exception(); |
555 if ((exception == I->object_store()->out_of_memory()) || | 585 if ((exception == I->object_store()->out_of_memory()) || |
556 (exception == I->object_store()->stack_overflow())) { | 586 (exception == I->object_store()->stack_overflow())) { |
557 // We didn't notify the debugger when the stack was full. Do it now. | 587 // We didn't notify the debugger when the stack was full. Do it now. |
558 I->debugger()->SignalExceptionThrown(Instance::Handle(exception)); | 588 I->debugger()->SignalExceptionThrown(Instance::Handle(exception)); |
559 } | 589 } |
560 } | 590 } |
561 | 591 |
562 // Invoke the isolate's unhandled exception callback if there is one. | 592 // Invoke the isolate's unhandled exception callback if there is one. |
593 // | |
594 // TODO(turnidge): Should we skip this for UnwindErrors? | |
563 if (Isolate::UnhandledExceptionCallback() != NULL) { | 595 if (Isolate::UnhandledExceptionCallback() != NULL) { |
564 Dart_EnterScope(); | 596 Dart_EnterScope(); |
565 Dart_Handle error = Api::NewHandle(I, result.raw()); | 597 Dart_Handle error = Api::NewHandle(I, result.raw()); |
566 (Isolate::UnhandledExceptionCallback())(error); | 598 (Isolate::UnhandledExceptionCallback())(error); |
567 Dart_ExitScope(); | 599 Dart_ExitScope(); |
568 } | 600 } |
569 | 601 |
570 // Generate the error and stacktrace strings for the error message. | 602 // Generate the error and stacktrace strings for the error message. |
571 String& exc_str = String::Handle(I); | 603 String& exc_str = String::Handle(I); |
572 String& stacktrace_str = String::Handle(I); | 604 String& stacktrace_str = String::Handle(I); |
573 if (result.IsUnhandledException()) { | 605 if (result.IsUnhandledException()) { |
574 const UnhandledException& uhe = UnhandledException::Cast(result); | 606 const UnhandledException& uhe = UnhandledException::Cast(result); |
575 const Instance& exception = Instance::Handle(I, uhe.exception()); | 607 const Instance& exception = Instance::Handle(I, uhe.exception()); |
576 Object& tmp = Object::Handle(I); | 608 Object& tmp = Object::Handle(I); |
577 tmp = DartLibraryCalls::ToString(exception); | 609 tmp = DartLibraryCalls::ToString(exception); |
578 if (!tmp.IsString()) { | 610 if (!tmp.IsString()) { |
579 tmp = String::New(exception.ToCString()); | 611 tmp = String::New(exception.ToCString()); |
580 } | 612 } |
581 exc_str ^= tmp.raw(); | 613 exc_str ^= tmp.raw(); |
582 | 614 |
583 const Instance& stacktrace = Instance::Handle(I, uhe.stacktrace()); | 615 const Instance& stacktrace = Instance::Handle(I, uhe.stacktrace()); |
584 tmp = DartLibraryCalls::ToString(stacktrace); | 616 tmp = DartLibraryCalls::ToString(stacktrace); |
585 if (!tmp.IsString()) { | 617 if (!tmp.IsString()) { |
586 tmp = String::New(stacktrace.ToCString()); | 618 tmp = String::New(stacktrace.ToCString()); |
587 } | 619 } |
588 stacktrace_str ^= tmp.raw();; | 620 stacktrace_str ^= tmp.raw();; |
589 } else { | 621 } else { |
590 exc_str = String::New(result.ToErrorCString()); | 622 exc_str = String::New(result.ToErrorCString()); |
591 } | 623 } |
592 bool has_listener = I->NotifyErrorListeners(exc_str, stacktrace_str); | 624 if (result.IsUnwindError()) { |
593 | 625 // Unwind errors are always fatal and don't notify listeners. |
594 if (I->ErrorsFatal()) { | 626 I->object_store()->set_sticky_error(result); |
595 if (has_listener) { | 627 return false; |
596 I->object_store()->clear_sticky_error(); | 628 } else { |
597 } else { | 629 bool has_listener = I->NotifyErrorListeners(exc_str, stacktrace_str); |
598 I->object_store()->set_sticky_error(result); | 630 if (I->ErrorsFatal()) { |
631 if (has_listener) { | |
632 I->object_store()->clear_sticky_error(); | |
633 } else { | |
634 I->object_store()->set_sticky_error(result); | |
635 } | |
636 return false; | |
599 } | 637 } |
600 return false; | |
601 } | 638 } |
602 return true; | 639 return true; |
603 } | 640 } |
604 | 641 |
605 | 642 |
606 Isolate::Flags::Flags() | 643 Isolate::Flags::Flags() |
607 : type_checks_(FLAG_enable_type_checks), | 644 : type_checks_(FLAG_enable_type_checks), |
608 asserts_(FLAG_enable_asserts), | 645 asserts_(FLAG_enable_asserts), |
609 error_on_bad_type_(FLAG_error_on_bad_type), | 646 error_on_bad_type_(FLAG_error_on_bad_type), |
610 error_on_bad_override_(FLAG_error_on_bad_override) {} | 647 error_on_bad_override_(FLAG_error_on_bad_override) {} |
(...skipping 795 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1406 MutexLocker ml(mutex_); | 1443 MutexLocker ml(mutex_); |
1407 if (stack_limit_ == saved_stack_limit_) { | 1444 if (stack_limit_ == saved_stack_limit_) { |
1408 return 0; // No interrupt was requested. | 1445 return 0; // No interrupt was requested. |
1409 } | 1446 } |
1410 uword interrupt_bits = stack_limit_ & kInterruptsMask; | 1447 uword interrupt_bits = stack_limit_ & kInterruptsMask; |
1411 stack_limit_ = saved_stack_limit_; | 1448 stack_limit_ = saved_stack_limit_; |
1412 return interrupt_bits; | 1449 return interrupt_bits; |
1413 } | 1450 } |
1414 | 1451 |
1415 | 1452 |
1453 RawError* Isolate::HandleInterrupts() { | |
1454 uword interrupt_bits = GetAndClearInterrupts(); | |
1455 if ((interrupt_bits & kVMInterrupt) != 0) { | |
1456 thread_registry()->CheckSafepoint(); | |
1457 if (store_buffer()->Overflowed()) { | |
1458 if (FLAG_verbose_gc) { | |
1459 OS::PrintErr("Scavenge scheduled by store buffer overflow.\n"); | |
1460 } | |
1461 heap()->CollectGarbage(Heap::kNew); | |
1462 } | |
1463 } | |
1464 if ((interrupt_bits & kMessageInterrupt) != 0) { | |
1465 bool ok = message_handler()->HandleOOBMessages(); | |
1466 if (!ok) { | |
1467 // False result from HandleOOBMessages signals that the isolate should | |
1468 // be terminating. | |
1469 if (FLAG_trace_isolates) { | |
1470 OS::Print("[!] Terminating isolate due to OOB message:\n" | |
1471 "\tisolate: %s\n", name()); | |
1472 } | |
1473 message_handler()->set_pause_on_start(false); | |
1474 message_handler()->set_pause_on_exit(false); | |
Cutch
2015/09/22 18:21:01
If an isolate is terminated via an OOB message- do
turnidge
2015/09/23 18:18:43
Added a TODO
| |
1475 const String& msg = String::Handle(String::New("isolate terminated")); | |
1476 return UnwindError::New(msg); | |
1477 } | |
1478 } | |
1479 return Error::null(); | |
1480 } | |
1481 | |
1482 | |
1416 uword Isolate::GetAndClearStackOverflowFlags() { | 1483 uword Isolate::GetAndClearStackOverflowFlags() { |
1417 uword stack_overflow_flags = stack_overflow_flags_; | 1484 uword stack_overflow_flags = stack_overflow_flags_; |
1418 stack_overflow_flags_ = 0; | 1485 stack_overflow_flags_ = 0; |
1419 return stack_overflow_flags; | 1486 return stack_overflow_flags; |
1420 } | 1487 } |
1421 | 1488 |
1422 | 1489 |
1423 static int MostUsedFunctionFirst(const Function* const* a, | 1490 static int MostUsedFunctionFirst(const Function* const* a, |
1424 const Function* const* b) { | 1491 const Function* const* b) { |
1425 if ((*a)->usage_counter() > (*b)->usage_counter()) { | 1492 if ((*a)->usage_counter() > (*b)->usage_counter()) { |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1492 void Isolate::LowLevelShutdown() { | 1559 void Isolate::LowLevelShutdown() { |
1493 // Ensure we have a zone and handle scope so that we can call VM functions, | 1560 // Ensure we have a zone and handle scope so that we can call VM functions, |
1494 // but we no longer allocate new heap objects. | 1561 // but we no longer allocate new heap objects. |
1495 Thread* thread = Thread::Current(); | 1562 Thread* thread = Thread::Current(); |
1496 StackZone stack_zone(thread); | 1563 StackZone stack_zone(thread); |
1497 HandleScope handle_scope(thread); | 1564 HandleScope handle_scope(thread); |
1498 NoSafepointScope no_safepoint_scope; | 1565 NoSafepointScope no_safepoint_scope; |
1499 | 1566 |
1500 // Notify exit listeners that this isolate is shutting down. | 1567 // Notify exit listeners that this isolate is shutting down. |
1501 if (object_store() != NULL) { | 1568 if (object_store() != NULL) { |
1569 // TODO(turnidge): If the isolate is going down because it is | |
1570 // being killed due to the VM shutting down, do we really want to | |
1571 // call out to dart code here? Seems bad. | |
1502 NotifyExitListeners(); | 1572 NotifyExitListeners(); |
1503 } | 1573 } |
1504 | 1574 |
1505 // Clean up debugger resources. | 1575 // Clean up debugger resources. |
1506 debugger()->Shutdown(); | 1576 debugger()->Shutdown(); |
1507 | 1577 |
1508 // Close all the ports owned by this isolate. | 1578 // Close all the ports owned by this isolate. |
1509 PortMap::ClosePorts(message_handler()); | 1579 PortMap::ClosePorts(message_handler()); |
1510 | 1580 |
1511 // Fail fast if anybody tries to post any more messsages to this isolate. | 1581 // Fail fast if anybody tries to post any more messsages to this isolate. |
(...skipping 707 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2219 kill_msg.value.as_array.length = 4; | 2289 kill_msg.value.as_array.length = 4; |
2220 kill_msg.value.as_array.values = list_values; | 2290 kill_msg.value.as_array.values = list_values; |
2221 | 2291 |
2222 Dart_CObject oob; | 2292 Dart_CObject oob; |
2223 oob.type = Dart_CObject_kInt32; | 2293 oob.type = Dart_CObject_kInt32; |
2224 oob.value.as_int32 = Message::kIsolateLibOOBMsg; | 2294 oob.value.as_int32 = Message::kIsolateLibOOBMsg; |
2225 list_values[0] = &oob; | 2295 list_values[0] = &oob; |
2226 | 2296 |
2227 Dart_CObject kill; | 2297 Dart_CObject kill; |
2228 kill.type = Dart_CObject_kInt32; | 2298 kill.type = Dart_CObject_kInt32; |
2229 kill.value.as_int32 = IsolateMessageHandler::kKillMsg; | 2299 kill.value.as_int32 = Isolate::kKillMsg; |
2230 list_values[1] = &kill; | 2300 list_values[1] = &kill; |
2231 | 2301 |
2232 Dart_CObject cap; | 2302 Dart_CObject cap; |
2233 cap.type = Dart_CObject_kCapability; | 2303 cap.type = Dart_CObject_kCapability; |
2234 cap.value.as_capability.id = terminate_capability(); | 2304 cap.value.as_capability.id = terminate_capability(); |
2235 list_values[2] = ∩ | 2305 list_values[2] = ∩ |
2236 | 2306 |
2237 Dart_CObject imm; | 2307 Dart_CObject imm; |
2238 imm.type = Dart_CObject_kInt32; | 2308 imm.type = Dart_CObject_kInt32; |
2239 imm.value.as_int32 = IsolateMessageHandler::kImmediateAction; | 2309 imm.value.as_int32 = Isolate::kImmediateAction; |
2240 list_values[3] = &imm; | 2310 list_values[3] = &imm; |
2241 | 2311 |
2242 { | 2312 { |
2243 uint8_t* buffer = NULL; | 2313 uint8_t* buffer = NULL; |
2244 ApiMessageWriter writer(&buffer, allocator); | 2314 ApiMessageWriter writer(&buffer, allocator); |
2245 bool success = writer.WriteCMessage(&kill_msg); | 2315 bool success = writer.WriteCMessage(&kill_msg); |
2246 ASSERT(success); | 2316 ASSERT(success); |
2247 | 2317 |
2248 // Post the message at the given port. | 2318 // Post the message at the given port. |
2249 success = PortMap::PostMessage(new Message(main_port(), | 2319 success = PortMap::PostMessage(new Message(main_port(), |
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2494 serialized_message_, serialized_message_len_); | 2564 serialized_message_, serialized_message_len_); |
2495 } | 2565 } |
2496 | 2566 |
2497 | 2567 |
2498 void IsolateSpawnState::Cleanup() { | 2568 void IsolateSpawnState::Cleanup() { |
2499 SwitchIsolateScope switch_scope(I); | 2569 SwitchIsolateScope switch_scope(I); |
2500 Dart::ShutdownIsolate(); | 2570 Dart::ShutdownIsolate(); |
2501 } | 2571 } |
2502 | 2572 |
2503 } // namespace dart | 2573 } // namespace dart |
OLD | NEW |