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