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 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
170 } | 170 } |
171 | 171 |
172 | 172 |
173 class IsolateMessageHandler : public MessageHandler { | 173 class IsolateMessageHandler : public MessageHandler { |
174 public: | 174 public: |
175 explicit IsolateMessageHandler(Isolate* isolate); | 175 explicit IsolateMessageHandler(Isolate* isolate); |
176 ~IsolateMessageHandler(); | 176 ~IsolateMessageHandler(); |
177 | 177 |
178 const char* name() const; | 178 const char* name() const; |
179 void MessageNotify(Message::Priority priority); | 179 void MessageNotify(Message::Priority priority); |
180 bool HandleMessage(Message* message); | 180 MessageStatus HandleMessage(Message* message); |
181 void NotifyPauseOnStart(); | 181 void NotifyPauseOnStart(); |
182 void NotifyPauseOnExit(); | 182 void NotifyPauseOnExit(); |
183 | 183 |
184 #if defined(DEBUG) | 184 #if defined(DEBUG) |
185 // Check that it is safe to access this handler. | 185 // Check that it is safe to access this handler. |
186 void CheckAccess(); | 186 void CheckAccess(); |
187 #endif | 187 #endif |
188 bool IsCurrentIsolate() const; | 188 bool IsCurrentIsolate() const; |
189 virtual Isolate* isolate() const { return isolate_; } | 189 virtual Isolate* isolate() const { return isolate_; } |
190 | 190 |
191 private: | 191 private: |
192 // A result of false indicates that the isolate should terminate the | 192 // A result of false indicates that the isolate should terminate the |
193 // processing of further events. | 193 // processing of further events. |
194 RawError* HandleLibMessage(const Array& message); | 194 RawError* HandleLibMessage(const Array& message); |
195 | 195 |
196 bool ProcessUnhandledException(const Error& result); | 196 MessageStatus ProcessUnhandledException(const Error& result); |
197 Isolate* isolate_; | 197 Isolate* isolate_; |
198 }; | 198 }; |
199 | 199 |
200 | 200 |
201 IsolateMessageHandler::IsolateMessageHandler(Isolate* isolate) | 201 IsolateMessageHandler::IsolateMessageHandler(Isolate* isolate) |
202 : isolate_(isolate) { | 202 : isolate_(isolate) { |
203 } | 203 } |
204 | 204 |
205 | 205 |
206 IsolateMessageHandler::~IsolateMessageHandler() { | 206 IsolateMessageHandler::~IsolateMessageHandler() { |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
277 SerializeObject(message, &data, &len, false); | 277 SerializeObject(message, &data, &len, false); |
278 this->PostMessage( | 278 this->PostMessage( |
279 new Message(Message::kIllegalPort, | 279 new Message(Message::kIllegalPort, |
280 data, len, | 280 data, len, |
281 Message::kNormalPriority), | 281 Message::kNormalPriority), |
282 priority == Isolate::kBeforeNextEventAction /* at_head */); | 282 priority == Isolate::kBeforeNextEventAction /* at_head */); |
283 } | 283 } |
284 break; | 284 break; |
285 } | 285 } |
286 case Isolate::kKillMsg: | 286 case Isolate::kKillMsg: |
287 case Isolate::kInternalKillMsg: { | 287 case Isolate::kInternalKillMsg: |
288 case Isolate::kVMRestartMsg: { | |
288 // [ OOB, kKillMsg, terminate capability, priority ] | 289 // [ OOB, kKillMsg, terminate capability, priority ] |
289 if (message.Length() != 4) return Error::null(); | 290 if (message.Length() != 4) return Error::null(); |
290 Object& obj = Object::Handle(I, message.At(3)); | 291 Object& obj = Object::Handle(I, message.At(3)); |
291 if (!obj.IsSmi()) return Error::null(); | 292 if (!obj.IsSmi()) return Error::null(); |
292 const intptr_t priority = Smi::Cast(obj).Value(); | 293 const intptr_t priority = Smi::Cast(obj).Value(); |
293 if (priority == Isolate::kImmediateAction) { | 294 if (priority == Isolate::kImmediateAction) { |
294 obj = message.At(2); | 295 obj = message.At(2); |
295 // Signal that the isolate should stop execution. | 296 // Signal that the isolate should stop execution. |
296 if (I->VerifyTerminateCapability(obj)) { | 297 if (I->VerifyTerminateCapability(obj)) { |
297 if (msg_type == Isolate::kKillMsg) { | 298 if (msg_type == Isolate::kKillMsg) { |
298 const String& msg = String::Handle(String::New( | 299 const String& msg = String::Handle(String::New( |
299 "isolate terminated by Isolate.kill")); | 300 "isolate terminated by Isolate.kill")); |
300 const UnwindError& error = | 301 const UnwindError& error = |
301 UnwindError::Handle(UnwindError::New(msg)); | 302 UnwindError::Handle(UnwindError::New(msg)); |
302 error.set_is_user_initiated(true); | 303 error.set_is_user_initiated(true); |
303 return error.raw(); | 304 return error.raw(); |
304 } else { | 305 } else if (msg_type == Isolate::kInternalKillMsg) { |
305 // TODO(turnidge): We should give the message handler a way | |
306 // to detect when an isolate is unwinding. | |
307 I->message_handler()->set_pause_on_start(false); | |
308 I->message_handler()->set_pause_on_exit(false); | |
309 const String& msg = String::Handle(String::New( | 306 const String& msg = String::Handle(String::New( |
310 "isolate terminated by vm")); | 307 "isolate terminated by vm")); |
311 return UnwindError::New(msg); | 308 return UnwindError::New(msg); |
309 } else if (msg_type == Isolate::kVMRestartMsg) { | |
310 const String& msg = String::Handle(String::New( | |
Cutch
2015/10/05 18:10:46
Maybe a comment here that this path kills the curr
turnidge
2015/10/05 22:18:24
Done.
| |
311 "isolate terminated for vm restart")); | |
312 const UnwindError& error = | |
313 UnwindError::Handle(UnwindError::New(msg)); | |
314 error.set_is_vm_restart(true); | |
315 return error.raw(); | |
316 } else { | |
317 UNREACHABLE(); | |
312 } | 318 } |
313 } else { | 319 } else { |
314 return Error::null(); | 320 return Error::null(); |
315 } | 321 } |
316 } else { | 322 } else { |
317 ASSERT((priority == Isolate::kBeforeNextEventAction) || | 323 ASSERT((priority == Isolate::kBeforeNextEventAction) || |
318 (priority == Isolate::kAsEventAction)); | 324 (priority == Isolate::kAsEventAction)); |
319 // Update the message so that it will be handled immediately when it | 325 // Update the message so that it will be handled immediately when it |
320 // is picked up from the message queue the next time. | 326 // is picked up from the message queue the next time. |
321 message.SetAt( | 327 message.SetAt( |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
413 I->ScheduleInterrupts(Isolate::kMessageInterrupt); | 419 I->ScheduleInterrupts(Isolate::kMessageInterrupt); |
414 } | 420 } |
415 Dart_MessageNotifyCallback callback = I->message_notify_callback(); | 421 Dart_MessageNotifyCallback callback = I->message_notify_callback(); |
416 if (callback) { | 422 if (callback) { |
417 // Allow the embedder to handle message notification. | 423 // Allow the embedder to handle message notification. |
418 (*callback)(Api::CastIsolate(I)); | 424 (*callback)(Api::CastIsolate(I)); |
419 } | 425 } |
420 } | 426 } |
421 | 427 |
422 | 428 |
423 bool IsolateMessageHandler::HandleMessage(Message* message) { | 429 MessageHandler::MessageStatus IsolateMessageHandler::HandleMessage( |
430 Message* message) { | |
424 ASSERT(IsCurrentIsolate()); | 431 ASSERT(IsCurrentIsolate()); |
425 Thread* thread = Thread::Current(); | 432 Thread* thread = Thread::Current(); |
426 StackZone stack_zone(thread); | 433 StackZone stack_zone(thread); |
427 Zone* zone = stack_zone.GetZone(); | 434 Zone* zone = stack_zone.GetZone(); |
428 HandleScope handle_scope(thread); | 435 HandleScope handle_scope(thread); |
429 TimelineDurationScope tds(thread, I->GetIsolateStream(), "HandleMessage"); | 436 TimelineDurationScope tds(thread, I->GetIsolateStream(), "HandleMessage"); |
430 tds.SetNumArguments(1); | 437 tds.SetNumArguments(1); |
431 tds.CopyArgument(0, "isolateName", I->name()); | 438 tds.CopyArgument(0, "isolateName", I->name()); |
432 | 439 |
433 // If the message is in band we lookup the handler to dispatch to. If the | 440 // If the message is in band we lookup the handler to dispatch to. If the |
434 // receive port was closed, we drop the message without deserializing it. | 441 // receive port was closed, we drop the message without deserializing it. |
435 // Illegal port is a special case for artificially enqueued isolate library | 442 // Illegal port is a special case for artificially enqueued isolate library |
436 // messages which are handled in C++ code below. | 443 // messages which are handled in C++ code below. |
437 Object& msg_handler = Object::Handle(zone); | 444 Object& msg_handler = Object::Handle(zone); |
438 if (!message->IsOOB() && (message->dest_port() != Message::kIllegalPort)) { | 445 if (!message->IsOOB() && (message->dest_port() != Message::kIllegalPort)) { |
439 msg_handler = DartLibraryCalls::LookupHandler(message->dest_port()); | 446 msg_handler = DartLibraryCalls::LookupHandler(message->dest_port()); |
440 if (msg_handler.IsError()) { | 447 if (msg_handler.IsError()) { |
441 delete message; | 448 delete message; |
442 return ProcessUnhandledException(Error::Cast(msg_handler)); | 449 return ProcessUnhandledException(Error::Cast(msg_handler)); |
443 } | 450 } |
444 if (msg_handler.IsNull()) { | 451 if (msg_handler.IsNull()) { |
445 // If the port has been closed then the message will be dropped at this | 452 // If the port has been closed then the message will be dropped at this |
446 // point. Make sure to post to the delivery failure port in that case. | 453 // point. Make sure to post to the delivery failure port in that case. |
447 if (message->RedirectToDeliveryFailurePort()) { | 454 if (message->RedirectToDeliveryFailurePort()) { |
448 PortMap::PostMessage(message); | 455 PortMap::PostMessage(message); |
449 } else { | 456 } else { |
450 delete message; | 457 delete message; |
451 } | 458 } |
452 return true; | 459 return kOK; |
453 } | 460 } |
454 } | 461 } |
455 | 462 |
456 // Parse the message. | 463 // Parse the message. |
457 MessageSnapshotReader reader(message->data(), message->len(), thread); | 464 MessageSnapshotReader reader(message->data(), message->len(), thread); |
458 const Object& msg_obj = Object::Handle(zone, reader.ReadObject()); | 465 const Object& msg_obj = Object::Handle(zone, reader.ReadObject()); |
459 if (msg_obj.IsError()) { | 466 if (msg_obj.IsError()) { |
460 // An error occurred while reading the message. | 467 // An error occurred while reading the message. |
461 delete message; | 468 delete message; |
462 return ProcessUnhandledException(Error::Cast(msg_obj)); | 469 return ProcessUnhandledException(Error::Cast(msg_obj)); |
463 } | 470 } |
464 if (!msg_obj.IsNull() && !msg_obj.IsInstance()) { | 471 if (!msg_obj.IsNull() && !msg_obj.IsInstance()) { |
465 // TODO(turnidge): We need to decide what an isolate does with | 472 // TODO(turnidge): We need to decide what an isolate does with |
466 // malformed messages. If they (eventually) come from a remote | 473 // malformed messages. If they (eventually) come from a remote |
467 // machine, then it might make sense to drop the message entirely. | 474 // machine, then it might make sense to drop the message entirely. |
468 // In the case that the message originated locally, which is | 475 // In the case that the message originated locally, which is |
469 // always true for now, then this should never occur. | 476 // always true for now, then this should never occur. |
470 UNREACHABLE(); | 477 UNREACHABLE(); |
471 } | 478 } |
472 | 479 |
473 Instance& msg = Instance::Handle(zone); | 480 Instance& msg = Instance::Handle(zone); |
474 msg ^= msg_obj.raw(); // Can't use Instance::Cast because may be null. | 481 msg ^= msg_obj.raw(); // Can't use Instance::Cast because may be null. |
475 | 482 |
476 bool success = true; | 483 MessageStatus status = kOK; |
477 if (message->IsOOB()) { | 484 if (message->IsOOB()) { |
478 // OOB messages are expected to be fixed length arrays where the first | 485 // OOB messages are expected to be fixed length arrays where the first |
479 // element is a Smi describing the OOB destination. Messages that do not | 486 // element is a Smi describing the OOB destination. Messages that do not |
480 // confirm to this layout are silently ignored. | 487 // confirm to this layout are silently ignored. |
481 if (msg.IsArray()) { | 488 if (msg.IsArray()) { |
482 const Array& oob_msg = Array::Cast(msg); | 489 const Array& oob_msg = Array::Cast(msg); |
483 if (oob_msg.Length() > 0) { | 490 if (oob_msg.Length() > 0) { |
484 const Object& oob_tag = Object::Handle(zone, oob_msg.At(0)); | 491 const Object& oob_tag = Object::Handle(zone, oob_msg.At(0)); |
485 if (oob_tag.IsSmi()) { | 492 if (oob_tag.IsSmi()) { |
486 switch (Smi::Cast(oob_tag).Value()) { | 493 switch (Smi::Cast(oob_tag).Value()) { |
487 case Message::kServiceOOBMsg: { | 494 case Message::kServiceOOBMsg: { |
488 Service::HandleIsolateMessage(I, oob_msg); | 495 Service::HandleIsolateMessage(I, oob_msg); |
489 break; | 496 break; |
490 } | 497 } |
491 case Message::kIsolateLibOOBMsg: { | 498 case Message::kIsolateLibOOBMsg: { |
492 const Error& error = Error::Handle(HandleLibMessage(oob_msg)); | 499 const Error& error = Error::Handle(HandleLibMessage(oob_msg)); |
493 if (!error.IsNull()) { | 500 if (!error.IsNull()) { |
494 success = ProcessUnhandledException(error); | 501 status = ProcessUnhandledException(error); |
495 } | 502 } |
496 break; | 503 break; |
497 } | 504 } |
498 #if defined(DEBUG) | 505 #if defined(DEBUG) |
499 // Malformed OOB messages are silently ignored in release builds. | 506 // Malformed OOB messages are silently ignored in release builds. |
500 default: { | 507 default: { |
501 UNREACHABLE(); | 508 UNREACHABLE(); |
502 break; | 509 break; |
503 } | 510 } |
504 #endif // defined(DEBUG) | 511 #endif // defined(DEBUG) |
505 } | 512 } |
506 } | 513 } |
507 } | 514 } |
508 } | 515 } |
509 } else if (message->dest_port() == Message::kIllegalPort) { | 516 } else if (message->dest_port() == Message::kIllegalPort) { |
510 // Check whether this is a delayed OOB message which needed handling as | 517 // Check whether this is a delayed OOB message which needed handling as |
511 // part of the regular message dispatch. All other messages are dropped on | 518 // part of the regular message dispatch. All other messages are dropped on |
512 // the floor. | 519 // the floor. |
513 if (msg.IsArray()) { | 520 if (msg.IsArray()) { |
514 const Array& msg_arr = Array::Cast(msg); | 521 const Array& msg_arr = Array::Cast(msg); |
515 if (msg_arr.Length() > 0) { | 522 if (msg_arr.Length() > 0) { |
516 const Object& oob_tag = Object::Handle(zone, msg_arr.At(0)); | 523 const Object& oob_tag = Object::Handle(zone, msg_arr.At(0)); |
517 if (oob_tag.IsSmi() && | 524 if (oob_tag.IsSmi() && |
518 (Smi::Cast(oob_tag).Value() == Message::kDelayedIsolateLibOOBMsg)) { | 525 (Smi::Cast(oob_tag).Value() == Message::kDelayedIsolateLibOOBMsg)) { |
519 const Error& error = Error::Handle(HandleLibMessage(msg_arr)); | 526 const Error& error = Error::Handle(HandleLibMessage(msg_arr)); |
520 if (!error.IsNull()) { | 527 if (!error.IsNull()) { |
521 success = ProcessUnhandledException(error); | 528 status = ProcessUnhandledException(error); |
522 } | 529 } |
523 } | 530 } |
524 } | 531 } |
525 } | 532 } |
526 } else { | 533 } else { |
527 const Object& result = Object::Handle(zone, | 534 const Object& result = Object::Handle(zone, |
528 DartLibraryCalls::HandleMessage(msg_handler, msg)); | 535 DartLibraryCalls::HandleMessage(msg_handler, msg)); |
529 if (result.IsError()) { | 536 if (result.IsError()) { |
530 success = ProcessUnhandledException(Error::Cast(result)); | 537 status = ProcessUnhandledException(Error::Cast(result)); |
531 } else { | 538 } else { |
532 ASSERT(result.IsNull()); | 539 ASSERT(result.IsNull()); |
533 } | 540 } |
534 } | 541 } |
535 delete message; | 542 delete message; |
536 if (success) { | 543 if (status == kOK) { |
537 const Object& result = | 544 const Object& result = |
538 Object::Handle(zone, I->InvokePendingServiceExtensionCalls()); | 545 Object::Handle(zone, I->InvokePendingServiceExtensionCalls()); |
539 if (result.IsError()) { | 546 if (result.IsError()) { |
540 success = ProcessUnhandledException(Error::Cast(result)); | 547 status = ProcessUnhandledException(Error::Cast(result)); |
541 } else { | 548 } else { |
542 ASSERT(result.IsNull()); | 549 ASSERT(result.IsNull()); |
543 } | 550 } |
544 } | 551 } |
545 return success; | 552 return status; |
546 } | 553 } |
547 | 554 |
548 | 555 |
549 void IsolateMessageHandler::NotifyPauseOnStart() { | 556 void IsolateMessageHandler::NotifyPauseOnStart() { |
550 if (Service::debug_stream.enabled()) { | 557 if (Service::debug_stream.enabled()) { |
551 StartIsolateScope start_isolate(I); | 558 StartIsolateScope start_isolate(I); |
552 StackZone zone(T); | 559 StackZone zone(T); |
553 HandleScope handle_scope(T); | 560 HandleScope handle_scope(T); |
554 ServiceEvent pause_event(I, ServiceEvent::kPauseStart); | 561 ServiceEvent pause_event(I, ServiceEvent::kPauseStart); |
555 Service::HandleEvent(&pause_event); | 562 Service::HandleEvent(&pause_event); |
(...skipping 23 matching lines...) Expand all Loading... | |
579 ASSERT(IsCurrentIsolate()); | 586 ASSERT(IsCurrentIsolate()); |
580 } | 587 } |
581 #endif | 588 #endif |
582 | 589 |
583 | 590 |
584 bool IsolateMessageHandler::IsCurrentIsolate() const { | 591 bool IsolateMessageHandler::IsCurrentIsolate() const { |
585 return (I == Isolate::Current()); | 592 return (I == Isolate::Current()); |
586 } | 593 } |
587 | 594 |
588 | 595 |
589 bool IsolateMessageHandler::ProcessUnhandledException(const Error& result) { | 596 MessageHandler::MessageStatus IsolateMessageHandler::ProcessUnhandledException( |
597 const Error& result) { | |
590 // Notify the debugger about specific unhandled exceptions which are withheld | 598 // Notify the debugger about specific unhandled exceptions which are withheld |
591 // when being thrown. | 599 // when being thrown. |
592 if (result.IsUnhandledException()) { | 600 if (result.IsUnhandledException()) { |
593 const UnhandledException& error = UnhandledException::Cast(result); | 601 const UnhandledException& error = UnhandledException::Cast(result); |
594 RawInstance* exception = error.exception(); | 602 RawInstance* exception = error.exception(); |
595 if ((exception == I->object_store()->out_of_memory()) || | 603 if ((exception == I->object_store()->out_of_memory()) || |
596 (exception == I->object_store()->stack_overflow())) { | 604 (exception == I->object_store()->stack_overflow())) { |
597 // We didn't notify the debugger when the stack was full. Do it now. | 605 // We didn't notify the debugger when the stack was full. Do it now. |
598 I->debugger()->SignalExceptionThrown(Instance::Handle(exception)); | 606 I->debugger()->SignalExceptionThrown(Instance::Handle(exception)); |
599 } | 607 } |
(...skipping 23 matching lines...) Expand all Loading... | |
623 const Instance& stacktrace = Instance::Handle(I, uhe.stacktrace()); | 631 const Instance& stacktrace = Instance::Handle(I, uhe.stacktrace()); |
624 tmp = DartLibraryCalls::ToString(stacktrace); | 632 tmp = DartLibraryCalls::ToString(stacktrace); |
625 if (!tmp.IsString()) { | 633 if (!tmp.IsString()) { |
626 tmp = String::New(stacktrace.ToCString()); | 634 tmp = String::New(stacktrace.ToCString()); |
627 } | 635 } |
628 stacktrace_str ^= tmp.raw();; | 636 stacktrace_str ^= tmp.raw();; |
629 } else { | 637 } else { |
630 exc_str = String::New(result.ToErrorCString()); | 638 exc_str = String::New(result.ToErrorCString()); |
631 } | 639 } |
632 if (result.IsUnwindError()) { | 640 if (result.IsUnwindError()) { |
633 // Unwind errors are always fatal and don't notify listeners. | 641 // Unwind errors are always fatal and don't notify listeners. |
zra
2015/10/05 16:56:47
Is this comment still correct?
turnidge
2015/10/05 22:18:24
Updated.
| |
634 I->object_store()->set_sticky_error(result); | 642 I->object_store()->set_sticky_error(result); |
635 return false; | 643 const UnwindError& unwind = UnwindError::Cast(result); |
644 if (unwind.is_user_initiated()) { | |
645 return kError; | |
646 } else if (unwind.is_vm_restart()) { | |
647 return kRestart; | |
648 } else { | |
649 return kShutdown; | |
650 } | |
636 } else { | 651 } else { |
637 bool has_listener = I->NotifyErrorListeners(exc_str, stacktrace_str); | 652 bool has_listener = I->NotifyErrorListeners(exc_str, stacktrace_str); |
638 if (I->ErrorsFatal()) { | 653 if (I->ErrorsFatal()) { |
639 if (has_listener) { | 654 if (has_listener) { |
640 I->object_store()->clear_sticky_error(); | 655 I->object_store()->clear_sticky_error(); |
641 } else { | 656 } else { |
642 I->object_store()->set_sticky_error(result); | 657 I->object_store()->set_sticky_error(result); |
643 } | 658 } |
644 return false; | 659 return kError; |
645 } | 660 } |
646 } | 661 } |
647 return true; | 662 return kOK; |
648 } | 663 } |
649 | 664 |
650 | 665 |
651 Isolate::Flags::Flags() | 666 Isolate::Flags::Flags() |
652 : type_checks_(FLAG_enable_type_checks), | 667 : type_checks_(FLAG_enable_type_checks), |
653 asserts_(FLAG_enable_asserts), | 668 asserts_(FLAG_enable_asserts), |
654 error_on_bad_type_(FLAG_error_on_bad_type), | 669 error_on_bad_type_(FLAG_error_on_bad_type), |
655 error_on_bad_override_(FLAG_error_on_bad_override) {} | 670 error_on_bad_override_(FLAG_error_on_bad_override) {} |
656 | 671 |
657 | 672 |
(...skipping 638 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1296 intptr_t len = 0; | 1311 intptr_t len = 0; |
1297 SerializeObject(arr, &data, &len, false); | 1312 SerializeObject(arr, &data, &len, false); |
1298 Message* msg = new Message(port_id, data, len, Message::kNormalPriority); | 1313 Message* msg = new Message(port_id, data, len, Message::kNormalPriority); |
1299 PortMap::PostMessage(msg); | 1314 PortMap::PostMessage(msg); |
1300 } | 1315 } |
1301 } | 1316 } |
1302 return listeners.Length() > 0; | 1317 return listeners.Length() > 0; |
1303 } | 1318 } |
1304 | 1319 |
1305 | 1320 |
1306 static void StoreError(Isolate* isolate, const Object& obj) { | 1321 static |
zra
2015/10/05 16:56:47
It looks like we'd usually break the long line in
turnidge
2015/10/05 22:18:24
Done.
| |
1307 ASSERT(obj.IsError()); | 1322 MessageHandler::MessageStatus StoreError(Isolate* isolate, const Error& error) { |
1308 isolate->object_store()->set_sticky_error(Error::Cast(obj)); | 1323 isolate->object_store()->set_sticky_error(error); |
1324 if (error.IsUnwindError()) { | |
1325 const UnwindError& unwind = UnwindError::Cast(error); | |
1326 if (!unwind.is_user_initiated()) { | |
1327 if (unwind.is_vm_restart()) { | |
1328 return MessageHandler::kRestart; | |
1329 } else { | |
1330 return MessageHandler::kShutdown; | |
1331 } | |
1332 } | |
1333 } | |
1334 return MessageHandler::kError; | |
1309 } | 1335 } |
1310 | 1336 |
1311 | 1337 |
1312 static bool RunIsolate(uword parameter) { | 1338 static MessageHandler::MessageStatus RunIsolate(uword parameter) { |
1313 Isolate* isolate = reinterpret_cast<Isolate*>(parameter); | 1339 Isolate* isolate = reinterpret_cast<Isolate*>(parameter); |
1314 IsolateSpawnState* state = NULL; | 1340 IsolateSpawnState* state = NULL; |
1315 Thread* thread = Thread::Current(); | 1341 Thread* thread = Thread::Current(); |
1316 { | 1342 { |
1317 // TODO(turnidge): Is this locking required here at all anymore? | 1343 // TODO(turnidge): Is this locking required here at all anymore? |
1318 MutexLocker ml(isolate->mutex()); | 1344 MutexLocker ml(isolate->mutex()); |
1319 state = isolate->spawn_state(); | 1345 state = isolate->spawn_state(); |
1320 } | 1346 } |
1321 { | 1347 { |
1322 StartIsolateScope start_scope(isolate); | 1348 StartIsolateScope start_scope(isolate); |
(...skipping 13 matching lines...) Expand all Loading... | |
1336 const SendPort& listener = | 1362 const SendPort& listener = |
1337 SendPort::Handle(SendPort::New(state->on_error_port())); | 1363 SendPort::Handle(SendPort::New(state->on_error_port())); |
1338 isolate->AddErrorListener(listener); | 1364 isolate->AddErrorListener(listener); |
1339 } | 1365 } |
1340 | 1366 |
1341 // Switch back to spawning isolate. | 1367 // Switch back to spawning isolate. |
1342 | 1368 |
1343 | 1369 |
1344 if (!ClassFinalizer::ProcessPendingClasses()) { | 1370 if (!ClassFinalizer::ProcessPendingClasses()) { |
1345 // Error is in sticky error already. | 1371 // Error is in sticky error already. |
1346 return false; | 1372 #if defined(DEBUG) |
1373 const Error& error = | |
1374 Error::Handle(isolate->object_store()->sticky_error()); | |
1375 ASSERT(!error.IsUnwindError()); | |
1376 #endif | |
1377 return MessageHandler::kError; | |
1347 } | 1378 } |
1348 | 1379 |
1349 Object& result = Object::Handle(); | 1380 Object& result = Object::Handle(); |
1350 result = state->ResolveFunction(); | 1381 result = state->ResolveFunction(); |
1351 bool is_spawn_uri = state->is_spawn_uri(); | 1382 bool is_spawn_uri = state->is_spawn_uri(); |
1352 if (result.IsError()) { | 1383 if (result.IsError()) { |
1353 StoreError(isolate, result); | 1384 return StoreError(isolate, Error::Cast(result)); |
1354 return false; | |
1355 } | 1385 } |
1356 ASSERT(result.IsFunction()); | 1386 ASSERT(result.IsFunction()); |
1357 Function& func = Function::Handle(isolate); | 1387 Function& func = Function::Handle(isolate); |
1358 func ^= result.raw(); | 1388 func ^= result.raw(); |
1359 | 1389 |
1360 // TODO(turnidge): Currently we need a way to force a one-time | 1390 // TODO(turnidge): Currently we need a way to force a one-time |
1361 // breakpoint for all spawned isolates to support isolate | 1391 // breakpoint for all spawned isolates to support isolate |
1362 // debugging. Remove this once the vmservice becomes the standard | 1392 // debugging. Remove this once the vmservice becomes the standard |
1363 // way to debug. Set the breakpoint on the static function instead | 1393 // way to debug. Set the breakpoint on the static function instead |
1364 // of its implicit closure function because that latter is merely | 1394 // of its implicit closure function because that latter is merely |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1399 args.SetAt(6, capabilities); | 1429 args.SetAt(6, capabilities); |
1400 | 1430 |
1401 const Library& lib = Library::Handle(Library::IsolateLibrary()); | 1431 const Library& lib = Library::Handle(Library::IsolateLibrary()); |
1402 const String& entry_name = String::Handle(String::New("_startIsolate")); | 1432 const String& entry_name = String::Handle(String::New("_startIsolate")); |
1403 const Function& entry_point = | 1433 const Function& entry_point = |
1404 Function::Handle(lib.LookupLocalFunction(entry_name)); | 1434 Function::Handle(lib.LookupLocalFunction(entry_name)); |
1405 ASSERT(entry_point.IsFunction() && !entry_point.IsNull()); | 1435 ASSERT(entry_point.IsFunction() && !entry_point.IsNull()); |
1406 | 1436 |
1407 result = DartEntry::InvokeFunction(entry_point, args); | 1437 result = DartEntry::InvokeFunction(entry_point, args); |
1408 if (result.IsError()) { | 1438 if (result.IsError()) { |
1409 StoreError(isolate, result); | 1439 return StoreError(isolate, Error::Cast(result)); |
1410 return false; | |
1411 } | 1440 } |
1412 } | 1441 } |
1413 return true; | 1442 return MessageHandler::kOK; |
1414 } | 1443 } |
1415 | 1444 |
1416 | 1445 |
1417 static void ShutdownIsolate(uword parameter) { | 1446 static void ShutdownIsolate(uword parameter) { |
1418 Isolate* isolate = reinterpret_cast<Isolate*>(parameter); | 1447 Isolate* isolate = reinterpret_cast<Isolate*>(parameter); |
1419 { | 1448 { |
1420 // Print the error if there is one. This may execute dart code to | 1449 // Print the error if there is one. This may execute dart code to |
1421 // print the exception object, so we need to use a StartIsolateScope. | 1450 // print the exception object, so we need to use a StartIsolateScope. |
1422 Thread* thread = Thread::Current(); | 1451 Thread* thread = Thread::Current(); |
1423 StartIsolateScope start_scope(isolate); | 1452 StartIsolateScope start_scope(isolate); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1462 if ((interrupt_bits & kVMInterrupt) != 0) { | 1491 if ((interrupt_bits & kVMInterrupt) != 0) { |
1463 thread_registry()->CheckSafepoint(); | 1492 thread_registry()->CheckSafepoint(); |
1464 if (store_buffer()->Overflowed()) { | 1493 if (store_buffer()->Overflowed()) { |
1465 if (FLAG_verbose_gc) { | 1494 if (FLAG_verbose_gc) { |
1466 OS::PrintErr("Scavenge scheduled by store buffer overflow.\n"); | 1495 OS::PrintErr("Scavenge scheduled by store buffer overflow.\n"); |
1467 } | 1496 } |
1468 heap()->CollectGarbage(Heap::kNew); | 1497 heap()->CollectGarbage(Heap::kNew); |
1469 } | 1498 } |
1470 } | 1499 } |
1471 if ((interrupt_bits & kMessageInterrupt) != 0) { | 1500 if ((interrupt_bits & kMessageInterrupt) != 0) { |
1472 bool ok = message_handler()->HandleOOBMessages(); | 1501 MessageHandler::MessageStatus status = |
1473 if (!ok) { | 1502 message_handler()->HandleOOBMessages(); |
1503 if (status != MessageHandler::kOK) { | |
1474 // False result from HandleOOBMessages signals that the isolate should | 1504 // False result from HandleOOBMessages signals that the isolate should |
1475 // be terminating. | 1505 // be terminating. |
1476 if (FLAG_trace_isolates) { | 1506 if (FLAG_trace_isolates) { |
1477 OS::Print("[!] Terminating isolate due to OOB message:\n" | 1507 OS::Print("[!] Terminating isolate due to OOB message:\n" |
1478 "\tisolate: %s\n", name()); | 1508 "\tisolate: %s\n", name()); |
1479 } | 1509 } |
1480 const Error& error = Error::Handle(object_store()->sticky_error()); | 1510 const Error& error = Error::Handle(object_store()->sticky_error()); |
1511 ASSERT(!error.IsNull() && error.IsUnwindError()); | |
1481 object_store()->clear_sticky_error(); | 1512 object_store()->clear_sticky_error(); |
1482 ASSERT(!error.IsNull()); | |
1483 return error.raw(); | 1513 return error.raw(); |
1484 } | 1514 } |
1485 } | 1515 } |
1486 return Error::null(); | 1516 return Error::null(); |
1487 } | 1517 } |
1488 | 1518 |
1489 | 1519 |
1490 uword Isolate::GetAndClearStackOverflowFlags() { | 1520 uword Isolate::GetAndClearStackOverflowFlags() { |
1491 uword stack_overflow_flags = stack_overflow_flags_; | 1521 uword stack_overflow_flags = stack_overflow_flags_; |
1492 stack_overflow_flags_ = 0; | 1522 stack_overflow_flags_ = 0; |
(...skipping 776 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2269 | 2299 |
2270 | 2300 |
2271 template<class C> | 2301 template<class C> |
2272 C* Isolate::AllocateReusableHandle() { | 2302 C* Isolate::AllocateReusableHandle() { |
2273 C* handle = reinterpret_cast<C*>(reusable_handles_.AllocateScopedHandle()); | 2303 C* handle = reinterpret_cast<C*>(reusable_handles_.AllocateScopedHandle()); |
2274 C::initializeHandle(handle, C::null()); | 2304 C::initializeHandle(handle, C::null()); |
2275 return handle; | 2305 return handle; |
2276 } | 2306 } |
2277 | 2307 |
2278 | 2308 |
2279 void Isolate::KillLocked() { | 2309 void Isolate::KillLocked(LibMsgId msg_id) { |
2280 Dart_CObject kill_msg; | 2310 Dart_CObject kill_msg; |
2281 Dart_CObject* list_values[4]; | 2311 Dart_CObject* list_values[4]; |
2282 kill_msg.type = Dart_CObject_kArray; | 2312 kill_msg.type = Dart_CObject_kArray; |
2283 kill_msg.value.as_array.length = 4; | 2313 kill_msg.value.as_array.length = 4; |
2284 kill_msg.value.as_array.values = list_values; | 2314 kill_msg.value.as_array.values = list_values; |
2285 | 2315 |
2286 Dart_CObject oob; | 2316 Dart_CObject oob; |
2287 oob.type = Dart_CObject_kInt32; | 2317 oob.type = Dart_CObject_kInt32; |
2288 oob.value.as_int32 = Message::kIsolateLibOOBMsg; | 2318 oob.value.as_int32 = Message::kIsolateLibOOBMsg; |
2289 list_values[0] = &oob; | 2319 list_values[0] = &oob; |
2290 | 2320 |
2291 Dart_CObject msg_type; | 2321 Dart_CObject msg_type; |
2292 msg_type.type = Dart_CObject_kInt32; | 2322 msg_type.type = Dart_CObject_kInt32; |
2293 msg_type.value.as_int32 = Isolate::kInternalKillMsg; | 2323 msg_type.value.as_int32 = msg_id; |
2294 list_values[1] = &msg_type; | 2324 list_values[1] = &msg_type; |
2295 | 2325 |
2296 Dart_CObject cap; | 2326 Dart_CObject cap; |
2297 cap.type = Dart_CObject_kCapability; | 2327 cap.type = Dart_CObject_kCapability; |
2298 cap.value.as_capability.id = terminate_capability(); | 2328 cap.value.as_capability.id = terminate_capability(); |
2299 list_values[2] = ∩ | 2329 list_values[2] = ∩ |
2300 | 2330 |
2301 Dart_CObject imm; | 2331 Dart_CObject imm; |
2302 imm.type = Dart_CObject_kInt32; | 2332 imm.type = Dart_CObject_kInt32; |
2303 imm.value.as_int32 = Isolate::kImmediateAction; | 2333 imm.value.as_int32 = Isolate::kImmediateAction; |
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2558 serialized_message_, serialized_message_len_); | 2588 serialized_message_, serialized_message_len_); |
2559 } | 2589 } |
2560 | 2590 |
2561 | 2591 |
2562 void IsolateSpawnState::Cleanup() { | 2592 void IsolateSpawnState::Cleanup() { |
2563 SwitchIsolateScope switch_scope(I); | 2593 SwitchIsolateScope switch_scope(I); |
2564 Dart::ShutdownIsolate(); | 2594 Dart::ShutdownIsolate(); |
2565 } | 2595 } |
2566 | 2596 |
2567 } // namespace dart | 2597 } // namespace dart |
OLD | NEW |