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