Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(104)

Side by Side Diff: runtime/vm/isolate.cc

Issue 1371193005: VM restart + shutdown fixes (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: more code review Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/isolate.h ('k') | runtime/vm/message_handler.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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] = &cap; 2342 list_values[2] = &cap;
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/isolate.h ('k') | runtime/vm/message_handler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698