| 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/text_buffer.h" | 10 #include "platform/text_buffer.h" |
| (...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 307 0, Smi::Handle(zone, Smi::New(Message::kDelayedIsolateLibOOBMsg))); | 307 0, Smi::Handle(zone, Smi::New(Message::kDelayedIsolateLibOOBMsg))); |
| 308 message.SetAt(3, | 308 message.SetAt(3, |
| 309 Smi::Handle(zone, Smi::New(Isolate::kImmediateAction))); | 309 Smi::Handle(zone, Smi::New(Isolate::kImmediateAction))); |
| 310 this->PostMessage( | 310 this->PostMessage( |
| 311 SerializeMessage(Message::kIllegalPort, message), | 311 SerializeMessage(Message::kIllegalPort, message), |
| 312 priority == Isolate::kBeforeNextEventAction /* at_head */); | 312 priority == Isolate::kBeforeNextEventAction /* at_head */); |
| 313 } | 313 } |
| 314 break; | 314 break; |
| 315 } | 315 } |
| 316 case Isolate::kKillMsg: | 316 case Isolate::kKillMsg: |
| 317 case Isolate::kInternalKillMsg: | 317 case Isolate::kInternalKillMsg: { |
| 318 case Isolate::kVMRestartMsg: { | |
| 319 // [ OOB, kKillMsg, terminate capability, priority ] | 318 // [ OOB, kKillMsg, terminate capability, priority ] |
| 320 if (message.Length() != 4) return Error::null(); | 319 if (message.Length() != 4) return Error::null(); |
| 321 Object& obj = Object::Handle(zone, message.At(3)); | 320 Object& obj = Object::Handle(zone, message.At(3)); |
| 322 if (!obj.IsSmi()) return Error::null(); | 321 if (!obj.IsSmi()) return Error::null(); |
| 323 const intptr_t priority = Smi::Cast(obj).Value(); | 322 const intptr_t priority = Smi::Cast(obj).Value(); |
| 324 if (priority == Isolate::kImmediateAction) { | 323 if (priority == Isolate::kImmediateAction) { |
| 325 obj = message.At(2); | 324 obj = message.At(2); |
| 326 if (I->VerifyTerminateCapability(obj)) { | 325 if (I->VerifyTerminateCapability(obj)) { |
| 327 // We will kill the current isolate by returning an UnwindError. | 326 // We will kill the current isolate by returning an UnwindError. |
| 328 if (msg_type == Isolate::kKillMsg) { | 327 if (msg_type == Isolate::kKillMsg) { |
| 329 const String& msg = String::Handle( | 328 const String& msg = String::Handle( |
| 330 String::New("isolate terminated by Isolate.kill")); | 329 String::New("isolate terminated by Isolate.kill")); |
| 331 const UnwindError& error = | 330 const UnwindError& error = |
| 332 UnwindError::Handle(UnwindError::New(msg)); | 331 UnwindError::Handle(UnwindError::New(msg)); |
| 333 error.set_is_user_initiated(true); | 332 error.set_is_user_initiated(true); |
| 334 return error.raw(); | 333 return error.raw(); |
| 335 } else if (msg_type == Isolate::kInternalKillMsg) { | 334 } else if (msg_type == Isolate::kInternalKillMsg) { |
| 336 const String& msg = | 335 const String& msg = |
| 337 String::Handle(String::New("isolate terminated by vm")); | 336 String::Handle(String::New("isolate terminated by vm")); |
| 338 return UnwindError::New(msg); | 337 return UnwindError::New(msg); |
| 339 } else if (msg_type == Isolate::kVMRestartMsg) { | |
| 340 // If this is the main isolate, this request to restart | |
| 341 // will be caught and handled in the embedder. Otherwise | |
| 342 // this unwind error will cause the isolate to exit. | |
| 343 const String& msg = String::Handle( | |
| 344 String::New("isolate terminated for vm restart")); | |
| 345 const UnwindError& error = | |
| 346 UnwindError::Handle(UnwindError::New(msg)); | |
| 347 error.set_is_vm_restart(true); | |
| 348 return error.raw(); | |
| 349 } else { | 338 } else { |
| 350 UNREACHABLE(); | 339 UNREACHABLE(); |
| 351 } | 340 } |
| 352 } else { | 341 } else { |
| 353 return Error::null(); | 342 return Error::null(); |
| 354 } | 343 } |
| 355 } else { | 344 } else { |
| 356 ASSERT((priority == Isolate::kBeforeNextEventAction) || | 345 ASSERT((priority == Isolate::kBeforeNextEventAction) || |
| 357 (priority == Isolate::kAsEventAction)); | 346 (priority == Isolate::kAsEventAction)); |
| 358 // Update the message so that it will be handled immediately when it | 347 // Update the message so that it will be handled immediately when it |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 524 // element is a Smi describing the OOB destination. Messages that do not | 513 // element is a Smi describing the OOB destination. Messages that do not |
| 525 // confirm to this layout are silently ignored. | 514 // confirm to this layout are silently ignored. |
| 526 if (msg.IsArray()) { | 515 if (msg.IsArray()) { |
| 527 const Array& oob_msg = Array::Cast(msg); | 516 const Array& oob_msg = Array::Cast(msg); |
| 528 if (oob_msg.Length() > 0) { | 517 if (oob_msg.Length() > 0) { |
| 529 const Object& oob_tag = Object::Handle(zone, oob_msg.At(0)); | 518 const Object& oob_tag = Object::Handle(zone, oob_msg.At(0)); |
| 530 if (oob_tag.IsSmi()) { | 519 if (oob_tag.IsSmi()) { |
| 531 switch (Smi::Cast(oob_tag).Value()) { | 520 switch (Smi::Cast(oob_tag).Value()) { |
| 532 case Message::kServiceOOBMsg: { | 521 case Message::kServiceOOBMsg: { |
| 533 if (FLAG_support_service) { | 522 if (FLAG_support_service) { |
| 534 Service::HandleIsolateMessage(I, oob_msg); | 523 const Error& error = |
| 524 Error::Handle(Service::HandleIsolateMessage(I, oob_msg)); |
| 525 if (!error.IsNull()) { |
| 526 status = ProcessUnhandledException(error); |
| 527 } |
| 535 } else { | 528 } else { |
| 536 UNREACHABLE(); | 529 UNREACHABLE(); |
| 537 } | 530 } |
| 538 break; | 531 break; |
| 539 } | 532 } |
| 540 case Message::kIsolateLibOOBMsg: { | 533 case Message::kIsolateLibOOBMsg: { |
| 541 const Error& error = Error::Handle(HandleLibMessage(oob_msg)); | 534 const Error& error = Error::Handle(HandleLibMessage(oob_msg)); |
| 542 if (!error.IsNull()) { | 535 if (!error.IsNull()) { |
| 543 status = ProcessUnhandledException(error); | 536 status = ProcessUnhandledException(error); |
| 544 } | 537 } |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 643 return (I == Isolate::Current()); | 636 return (I == Isolate::Current()); |
| 644 } | 637 } |
| 645 | 638 |
| 646 | 639 |
| 647 static MessageHandler::MessageStatus StoreError(Thread* thread, | 640 static MessageHandler::MessageStatus StoreError(Thread* thread, |
| 648 const Error& error) { | 641 const Error& error) { |
| 649 thread->set_sticky_error(error); | 642 thread->set_sticky_error(error); |
| 650 if (error.IsUnwindError()) { | 643 if (error.IsUnwindError()) { |
| 651 const UnwindError& unwind = UnwindError::Cast(error); | 644 const UnwindError& unwind = UnwindError::Cast(error); |
| 652 if (!unwind.is_user_initiated()) { | 645 if (!unwind.is_user_initiated()) { |
| 653 if (unwind.is_vm_restart()) { | 646 return MessageHandler::kShutdown; |
| 654 return MessageHandler::kRestart; | |
| 655 } else { | |
| 656 return MessageHandler::kShutdown; | |
| 657 } | |
| 658 } | 647 } |
| 659 } | 648 } |
| 660 return MessageHandler::kError; | 649 return MessageHandler::kError; |
| 661 } | 650 } |
| 662 | 651 |
| 663 | 652 |
| 664 MessageHandler::MessageStatus IsolateMessageHandler::ProcessUnhandledException( | 653 MessageHandler::MessageStatus IsolateMessageHandler::ProcessUnhandledException( |
| 665 const Error& result) { | 654 const Error& result) { |
| 666 // Generate the error and stacktrace strings for the error message. | 655 // Generate the error and stacktrace strings for the error message. |
| 667 String& exc_str = String::Handle(T->zone()); | 656 String& exc_str = String::Handle(T->zone()); |
| (...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1026 int64_t Isolate::UptimeMicros() const { | 1015 int64_t Isolate::UptimeMicros() const { |
| 1027 return OS::GetCurrentMonotonicMicros() - start_time_micros_; | 1016 return OS::GetCurrentMonotonicMicros() - start_time_micros_; |
| 1028 } | 1017 } |
| 1029 | 1018 |
| 1030 | 1019 |
| 1031 bool Isolate::IsPaused() const { | 1020 bool Isolate::IsPaused() const { |
| 1032 return (debugger_ != NULL) && (debugger_->PauseEvent() != NULL); | 1021 return (debugger_ != NULL) && (debugger_->PauseEvent() != NULL); |
| 1033 } | 1022 } |
| 1034 | 1023 |
| 1035 | 1024 |
| 1036 void Isolate::PausePostRequest() { | 1025 RawError* Isolate::PausePostRequest() { |
| 1037 if (!FLAG_support_debugger) { | 1026 if (!FLAG_support_debugger) { |
| 1038 return; | 1027 return Error::null(); |
| 1039 } | 1028 } |
| 1040 if (debugger_ == NULL) { | 1029 if (debugger_ == NULL) { |
| 1041 return; | 1030 return Error::null(); |
| 1042 } | 1031 } |
| 1043 ASSERT(!IsPaused()); | 1032 ASSERT(!IsPaused()); |
| 1044 const Error& error = Error::Handle(debugger_->PausePostRequest()); | 1033 const Error& error = Error::Handle(debugger_->PausePostRequest()); |
| 1045 if (!error.IsNull()) { | 1034 if (!error.IsNull()) { |
| 1046 Exceptions::PropagateError(error); | 1035 if (Thread::Current()->top_exit_frame_info() == 0) { |
| 1036 return error.raw(); |
| 1037 } else { |
| 1038 Exceptions::PropagateError(error); |
| 1039 UNREACHABLE(); |
| 1040 } |
| 1047 } | 1041 } |
| 1042 return Error::null(); |
| 1048 } | 1043 } |
| 1049 | 1044 |
| 1050 | 1045 |
| 1051 void Isolate::BuildName(const char* name_prefix) { | 1046 void Isolate::BuildName(const char* name_prefix) { |
| 1052 ASSERT(name_ == NULL); | 1047 ASSERT(name_ == NULL); |
| 1053 if (name_prefix == NULL) { | 1048 if (name_prefix == NULL) { |
| 1054 name_prefix = "isolate"; | 1049 name_prefix = "isolate"; |
| 1055 } | 1050 } |
| 1056 set_debugger_name(name_prefix); | 1051 set_debugger_name(name_prefix); |
| 1057 if (ServiceIsolate::NameEquals(name_prefix)) { | 1052 if (ServiceIsolate::NameEquals(name_prefix)) { |
| (...skipping 1891 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2949 void IsolateSpawnState::DecrementSpawnCount() { | 2944 void IsolateSpawnState::DecrementSpawnCount() { |
| 2950 ASSERT(spawn_count_monitor_ != NULL); | 2945 ASSERT(spawn_count_monitor_ != NULL); |
| 2951 ASSERT(spawn_count_ != NULL); | 2946 ASSERT(spawn_count_ != NULL); |
| 2952 MonitorLocker ml(spawn_count_monitor_); | 2947 MonitorLocker ml(spawn_count_monitor_); |
| 2953 ASSERT(*spawn_count_ > 0); | 2948 ASSERT(*spawn_count_ > 0); |
| 2954 *spawn_count_ = *spawn_count_ - 1; | 2949 *spawn_count_ = *spawn_count_ - 1; |
| 2955 ml.Notify(); | 2950 ml.Notify(); |
| 2956 } | 2951 } |
| 2957 | 2952 |
| 2958 } // namespace dart | 2953 } // namespace dart |
| OLD | NEW |