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

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: fix ups 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
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 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
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
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
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
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] = &cap; 2329 list_values[2] = &cap;
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698