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 "platform/assert.h" | 8 #include "platform/assert.h" |
9 #include "platform/json.h" | 9 #include "platform/json.h" |
10 #include "lib/mirrors.h" | 10 #include "lib/mirrors.h" |
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
330 simulator_(NULL), | 330 simulator_(NULL), |
331 long_jump_base_(NULL), | 331 long_jump_base_(NULL), |
332 timer_list_(), | 332 timer_list_(), |
333 deopt_id_(0), | 333 deopt_id_(0), |
334 ic_data_array_(Array::null()), | 334 ic_data_array_(Array::null()), |
335 mutex_(new Mutex()), | 335 mutex_(new Mutex()), |
336 stack_limit_(0), | 336 stack_limit_(0), |
337 saved_stack_limit_(0), | 337 saved_stack_limit_(0), |
338 message_handler_(NULL), | 338 message_handler_(NULL), |
339 spawn_data_(0), | 339 spawn_data_(0), |
| 340 is_runnable_(false), |
340 gc_prologue_callbacks_(), | 341 gc_prologue_callbacks_(), |
341 gc_epilogue_callbacks_(), | 342 gc_epilogue_callbacks_(), |
342 deopt_cpu_registers_copy_(NULL), | 343 deopt_cpu_registers_copy_(NULL), |
343 deopt_fpu_registers_copy_(NULL), | 344 deopt_fpu_registers_copy_(NULL), |
344 deopt_frame_copy_(NULL), | 345 deopt_frame_copy_(NULL), |
345 deopt_frame_copy_size_(0), | 346 deopt_frame_copy_size_(0), |
346 deferred_objects_(NULL), | 347 deferred_objects_(NULL), |
347 stacktrace_(NULL), | 348 stacktrace_(NULL), |
348 stack_frame_index_(-1) { | 349 stack_frame_index_(-1) { |
349 } | 350 } |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
473 mutex_->Lock(); | 474 mutex_->Lock(); |
474 ASSERT((interrupt_bits & ~kInterruptsMask) == 0); // Must fit in mask. | 475 ASSERT((interrupt_bits & ~kInterruptsMask) == 0); // Must fit in mask. |
475 if (stack_limit_ == saved_stack_limit_) { | 476 if (stack_limit_ == saved_stack_limit_) { |
476 stack_limit_ = (~static_cast<uword>(0)) & ~kInterruptsMask; | 477 stack_limit_ = (~static_cast<uword>(0)) & ~kInterruptsMask; |
477 } | 478 } |
478 stack_limit_ |= interrupt_bits; | 479 stack_limit_ |= interrupt_bits; |
479 mutex_->Unlock(); | 480 mutex_->Unlock(); |
480 } | 481 } |
481 | 482 |
482 | 483 |
| 484 bool Isolate::MakeRunnable() { |
| 485 ASSERT(Isolate::Current() == NULL); |
| 486 // Can't use MutexLocker here because MutexLocker is |
| 487 // a StackResource, which requires a current isolate. |
| 488 mutex_->Lock(); |
| 489 // Check if we are in a valid state to make the isolate runnable. |
| 490 if (is_runnable_ == true) { |
| 491 mutex_->Unlock(); |
| 492 return false; // Already runnable. |
| 493 } |
| 494 // Set the isolate as runnable and if we are being spawned schedule |
| 495 // isolate on thread pool for execution. |
| 496 is_runnable_ = true; |
| 497 IsolateSpawnState* state = reinterpret_cast<IsolateSpawnState*>(spawn_data()); |
| 498 if (state != NULL) { |
| 499 ASSERT(this == state->isolate()); |
| 500 Run(); |
| 501 } |
| 502 mutex_->Unlock(); |
| 503 return true; |
| 504 } |
| 505 |
| 506 |
| 507 static void StoreError(Isolate* isolate, const Object& obj) { |
| 508 ASSERT(obj.IsError()); |
| 509 isolate->object_store()->set_sticky_error(Error::Cast(obj)); |
| 510 } |
| 511 |
| 512 |
| 513 static bool RunIsolate(uword parameter) { |
| 514 Isolate* isolate = reinterpret_cast<Isolate*>(parameter); |
| 515 IsolateSpawnState* state = NULL; |
| 516 { |
| 517 MutexLocker ml(isolate->mutex()); |
| 518 state = reinterpret_cast<IsolateSpawnState*>(isolate->spawn_data()); |
| 519 isolate->set_spawn_data(0); |
| 520 } |
| 521 { |
| 522 StartIsolateScope start_scope(isolate); |
| 523 StackZone zone(isolate); |
| 524 HandleScope handle_scope(isolate); |
| 525 if (!ClassFinalizer::FinalizePendingClasses()) { |
| 526 // Error is in sticky error already. |
| 527 return false; |
| 528 } |
| 529 |
| 530 // Set up specific unhandled exception handler. |
| 531 const String& callback_name = String::Handle( |
| 532 isolate, String::New(state->exception_callback_name())); |
| 533 isolate->object_store()-> |
| 534 set_unhandled_exception_handler(callback_name); |
| 535 |
| 536 Object& result = Object::Handle(); |
| 537 result = state->ResolveFunction(); |
| 538 delete state; |
| 539 state = NULL; |
| 540 if (result.IsError()) { |
| 541 StoreError(isolate, result); |
| 542 return false; |
| 543 } |
| 544 ASSERT(result.IsFunction()); |
| 545 Function& func = Function::Handle(isolate); |
| 546 func ^= result.raw(); |
| 547 result = DartEntry::InvokeFunction(func, Object::empty_array()); |
| 548 if (result.IsError()) { |
| 549 StoreError(isolate, result); |
| 550 return false; |
| 551 } |
| 552 } |
| 553 return true; |
| 554 } |
| 555 |
| 556 |
| 557 static void ShutdownIsolate(uword parameter) { |
| 558 Isolate* isolate = reinterpret_cast<Isolate*>(parameter); |
| 559 { |
| 560 // Print the error if there is one. This may execute dart code to |
| 561 // print the exception object, so we need to use a StartIsolateScope. |
| 562 StartIsolateScope start_scope(isolate); |
| 563 StackZone zone(isolate); |
| 564 HandleScope handle_scope(isolate); |
| 565 Error& error = Error::Handle(); |
| 566 error = isolate->object_store()->sticky_error(); |
| 567 if (!error.IsNull()) { |
| 568 OS::PrintErr("in ShutdownIsolate: %s\n", error.ToErrorCString()); |
| 569 } |
| 570 } |
| 571 { |
| 572 // Shut the isolate down. |
| 573 SwitchIsolateScope switch_scope(isolate); |
| 574 Dart::ShutdownIsolate(); |
| 575 } |
| 576 } |
| 577 |
| 578 |
| 579 void Isolate::Run() { |
| 580 message_handler()->Run(Dart::thread_pool(), |
| 581 RunIsolate, |
| 582 ShutdownIsolate, |
| 583 reinterpret_cast<uword>(this)); |
| 584 } |
| 585 |
| 586 |
483 uword Isolate::GetAndClearInterrupts() { | 587 uword Isolate::GetAndClearInterrupts() { |
484 MutexLocker ml(mutex_); | 588 MutexLocker ml(mutex_); |
485 if (stack_limit_ == saved_stack_limit_) { | 589 if (stack_limit_ == saved_stack_limit_) { |
486 return 0; // No interrupt was requested. | 590 return 0; // No interrupt was requested. |
487 } | 591 } |
488 uword interrupt_bits = stack_limit_ & kInterruptsMask; | 592 uword interrupt_bits = stack_limit_ & kInterruptsMask; |
489 stack_limit_ = saved_stack_limit_; | 593 stack_limit_ = saved_stack_limit_; |
490 return interrupt_bits; | 594 return interrupt_bits; |
491 } | 595 } |
492 | 596 |
(...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
871 if (frame_index >= 0) { | 975 if (frame_index >= 0) { |
872 return isolate->GetStatusStackFrame(frame_index); | 976 return isolate->GetStatusStackFrame(frame_index); |
873 } | 977 } |
874 } | 978 } |
875 | 979 |
876 // TODO(tball): "/isolate/<handle>/stacktrace/<frame-index>"/disassemble" | 980 // TODO(tball): "/isolate/<handle>/stacktrace/<frame-index>"/disassemble" |
877 | 981 |
878 return NULL; // Unimplemented query. | 982 return NULL; // Unimplemented query. |
879 } | 983 } |
880 | 984 |
| 985 |
| 986 static char* GetRootScriptUri(Isolate* isolate) { |
| 987 const Library& library = |
| 988 Library::Handle(isolate->object_store()->root_library()); |
| 989 ASSERT(!library.IsNull()); |
| 990 const String& script_name = String::Handle(library.url()); |
| 991 return isolate->current_zone()->MakeCopyOfString(script_name.ToCString()); |
| 992 } |
| 993 |
| 994 |
| 995 IsolateSpawnState::IsolateSpawnState(const Function& func, |
| 996 const Function& callback_func) |
| 997 : isolate_(NULL), |
| 998 script_url_(NULL), |
| 999 library_url_(NULL), |
| 1000 function_name_(NULL), |
| 1001 exception_callback_name_(NULL) { |
| 1002 script_url_ = strdup(GetRootScriptUri(Isolate::Current())); |
| 1003 const Class& cls = Class::Handle(func.Owner()); |
| 1004 ASSERT(cls.IsTopLevel()); |
| 1005 const Library& lib = Library::Handle(cls.library()); |
| 1006 const String& lib_url = String::Handle(lib.url()); |
| 1007 library_url_ = strdup(lib_url.ToCString()); |
| 1008 |
| 1009 const String& func_name = String::Handle(func.name()); |
| 1010 function_name_ = strdup(func_name.ToCString()); |
| 1011 if (!callback_func.IsNull()) { |
| 1012 const String& callback_name = String::Handle(callback_func.name()); |
| 1013 exception_callback_name_ = strdup(callback_name.ToCString()); |
| 1014 } else { |
| 1015 exception_callback_name_ = strdup("_unhandledExceptionCallback"); |
| 1016 } |
| 1017 } |
| 1018 |
| 1019 |
| 1020 IsolateSpawnState::IsolateSpawnState(const char* script_url) |
| 1021 : isolate_(NULL), |
| 1022 library_url_(NULL), |
| 1023 function_name_(NULL), |
| 1024 exception_callback_name_(NULL) { |
| 1025 script_url_ = strdup(script_url); |
| 1026 library_url_ = NULL; |
| 1027 function_name_ = strdup("main"); |
| 1028 exception_callback_name_ = strdup("_unhandledExceptionCallback"); |
| 1029 } |
| 1030 |
| 1031 |
| 1032 IsolateSpawnState::~IsolateSpawnState() { |
| 1033 free(script_url_); |
| 1034 free(library_url_); |
| 1035 free(function_name_); |
| 1036 free(exception_callback_name_); |
| 1037 } |
| 1038 |
| 1039 |
| 1040 RawObject* IsolateSpawnState::ResolveFunction() { |
| 1041 // Resolve the library. |
| 1042 Library& lib = Library::Handle(); |
| 1043 if (library_url()) { |
| 1044 const String& lib_url = String::Handle(String::New(library_url())); |
| 1045 lib = Library::LookupLibrary(lib_url); |
| 1046 if (lib.IsNull() || lib.IsError()) { |
| 1047 const String& msg = String::Handle(String::NewFormatted( |
| 1048 "Unable to find library '%s'.", library_url())); |
| 1049 return LanguageError::New(msg); |
| 1050 } |
| 1051 } else { |
| 1052 lib = isolate()->object_store()->root_library(); |
| 1053 } |
| 1054 ASSERT(!lib.IsNull()); |
| 1055 |
| 1056 // Resolve the function. |
| 1057 const String& func_name = |
| 1058 String::Handle(String::New(function_name())); |
| 1059 const Function& func = Function::Handle(lib.LookupLocalFunction(func_name)); |
| 1060 if (func.IsNull()) { |
| 1061 const String& msg = String::Handle(String::NewFormatted( |
| 1062 "Unable to resolve function '%s' in library '%s'.", |
| 1063 function_name(), (library_url() ? library_url() : script_url()))); |
| 1064 return LanguageError::New(msg); |
| 1065 } |
| 1066 return func.raw(); |
| 1067 } |
| 1068 |
| 1069 |
| 1070 void IsolateSpawnState::Cleanup() { |
| 1071 SwitchIsolateScope switch_scope(isolate()); |
| 1072 Dart::ShutdownIsolate(); |
| 1073 } |
| 1074 |
881 } // namespace dart | 1075 } // namespace dart |
OLD | NEW |