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(this == Isolate::Current()); |
| 486 if (is_runnable_ == true) { |
| 487 return false; |
| 488 } |
| 489 // Set the isolate as runnable and if we are being spawned schedule |
| 490 // isolate on thread pool for execution. |
| 491 is_runnable_ = true; |
| 492 IsolateSpawnState* state = reinterpret_cast<IsolateSpawnState*>(spawn_data()); |
| 493 if (state != NULL) { |
| 494 ASSERT(this == state->isolate()); |
| 495 Run(); |
| 496 } |
| 497 return true; |
| 498 } |
| 499 |
| 500 |
| 501 static void StoreError(Isolate* isolate, const Object& obj) { |
| 502 ASSERT(obj.IsError()); |
| 503 isolate->object_store()->set_sticky_error(Error::Cast(obj)); |
| 504 } |
| 505 |
| 506 |
| 507 static bool RunIsolate(uword parameter) { |
| 508 Isolate* isolate = reinterpret_cast<Isolate*>(parameter); |
| 509 IsolateSpawnState* state = |
| 510 reinterpret_cast<IsolateSpawnState*>(isolate->spawn_data()); |
| 511 { |
| 512 StartIsolateScope start_scope(isolate); |
| 513 isolate->set_spawn_data(0); |
| 514 StackZone zone(isolate); |
| 515 HandleScope handle_scope(isolate); |
| 516 if (!ClassFinalizer::FinalizePendingClasses()) { |
| 517 // Error is in sticky error already. |
| 518 return false; |
| 519 } |
| 520 |
| 521 Object& result = Object::Handle(); |
| 522 result = state->ResolveFunction(); |
| 523 delete state; |
| 524 state = NULL; |
| 525 if (result.IsError()) { |
| 526 StoreError(isolate, result); |
| 527 return false; |
| 528 } |
| 529 ASSERT(result.IsFunction()); |
| 530 Function& func = Function::Handle(isolate); |
| 531 func ^= result.raw(); |
| 532 result = DartEntry::InvokeFunction(func, Object::empty_array()); |
| 533 if (result.IsError()) { |
| 534 StoreError(isolate, result); |
| 535 return false; |
| 536 } |
| 537 } |
| 538 return true; |
| 539 } |
| 540 |
| 541 |
| 542 static void ShutdownIsolate(uword parameter) { |
| 543 Isolate* isolate = reinterpret_cast<Isolate*>(parameter); |
| 544 { |
| 545 // Print the error if there is one. This may execute dart code to |
| 546 // print the exception object, so we need to use a StartIsolateScope. |
| 547 StartIsolateScope start_scope(isolate); |
| 548 StackZone zone(isolate); |
| 549 HandleScope handle_scope(isolate); |
| 550 Error& error = Error::Handle(); |
| 551 error = isolate->object_store()->sticky_error(); |
| 552 if (!error.IsNull()) { |
| 553 OS::PrintErr("in ShutdownIsolate: %s\n", error.ToErrorCString()); |
| 554 } |
| 555 } |
| 556 { |
| 557 // Shut the isolate down. |
| 558 SwitchIsolateScope switch_scope(isolate); |
| 559 Dart::ShutdownIsolate(); |
| 560 } |
| 561 } |
| 562 |
| 563 |
| 564 void Isolate::Run() { |
| 565 message_handler()->Run(Dart::thread_pool(), |
| 566 RunIsolate, |
| 567 ShutdownIsolate, |
| 568 reinterpret_cast<uword>(this)); |
| 569 } |
| 570 |
| 571 |
483 uword Isolate::GetAndClearInterrupts() { | 572 uword Isolate::GetAndClearInterrupts() { |
484 MutexLocker ml(mutex_); | 573 MutexLocker ml(mutex_); |
485 if (stack_limit_ == saved_stack_limit_) { | 574 if (stack_limit_ == saved_stack_limit_) { |
486 return 0; // No interrupt was requested. | 575 return 0; // No interrupt was requested. |
487 } | 576 } |
488 uword interrupt_bits = stack_limit_ & kInterruptsMask; | 577 uword interrupt_bits = stack_limit_ & kInterruptsMask; |
489 stack_limit_ = saved_stack_limit_; | 578 stack_limit_ = saved_stack_limit_; |
490 return interrupt_bits; | 579 return interrupt_bits; |
491 } | 580 } |
492 | 581 |
(...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
871 if (frame_index >= 0) { | 960 if (frame_index >= 0) { |
872 return isolate->GetStatusStackFrame(frame_index); | 961 return isolate->GetStatusStackFrame(frame_index); |
873 } | 962 } |
874 } | 963 } |
875 | 964 |
876 // TODO(tball): "/isolate/<handle>/stacktrace/<frame-index>"/disassemble" | 965 // TODO(tball): "/isolate/<handle>/stacktrace/<frame-index>"/disassemble" |
877 | 966 |
878 return NULL; // Unimplemented query. | 967 return NULL; // Unimplemented query. |
879 } | 968 } |
880 | 969 |
| 970 |
| 971 static char* GetRootScriptUri(Isolate* isolate) { |
| 972 const Library& library = |
| 973 Library::Handle(isolate->object_store()->root_library()); |
| 974 ASSERT(!library.IsNull()); |
| 975 const String& script_name = String::Handle(library.url()); |
| 976 return isolate->current_zone()->MakeCopyOfString(script_name.ToCString()); |
| 977 } |
| 978 |
| 979 |
| 980 IsolateSpawnState::IsolateSpawnState(const Function& func, |
| 981 const Function& callback_func) |
| 982 : isolate_(NULL), |
| 983 script_url_(NULL), |
| 984 library_url_(NULL), |
| 985 function_name_(NULL), |
| 986 exception_callback_name_(NULL) { |
| 987 script_url_ = strdup(GetRootScriptUri(Isolate::Current())); |
| 988 const Class& cls = Class::Handle(func.Owner()); |
| 989 ASSERT(cls.IsTopLevel()); |
| 990 const Library& lib = Library::Handle(cls.library()); |
| 991 const String& lib_url = String::Handle(lib.url()); |
| 992 library_url_ = strdup(lib_url.ToCString()); |
| 993 |
| 994 const String& func_name = String::Handle(func.name()); |
| 995 function_name_ = strdup(func_name.ToCString()); |
| 996 if (!callback_func.IsNull()) { |
| 997 const String& callback_name = String::Handle(callback_func.name()); |
| 998 exception_callback_name_ = strdup(callback_name.ToCString()); |
| 999 } else { |
| 1000 exception_callback_name_ = strdup("_unhandledExceptionCallback"); |
| 1001 } |
| 1002 } |
| 1003 |
| 1004 |
| 1005 IsolateSpawnState::IsolateSpawnState(const char* script_url) |
| 1006 : isolate_(NULL), |
| 1007 library_url_(NULL), |
| 1008 function_name_(NULL), |
| 1009 exception_callback_name_(NULL) { |
| 1010 script_url_ = strdup(script_url); |
| 1011 library_url_ = NULL; |
| 1012 function_name_ = strdup("main"); |
| 1013 exception_callback_name_ = strdup("_unhandledExceptionCallback"); |
| 1014 } |
| 1015 |
| 1016 |
| 1017 IsolateSpawnState::~IsolateSpawnState() { |
| 1018 free(script_url_); |
| 1019 free(library_url_); |
| 1020 free(function_name_); |
| 1021 free(exception_callback_name_); |
| 1022 } |
| 1023 |
| 1024 |
| 1025 RawObject* IsolateSpawnState::ResolveFunction() { |
| 1026 // Resolve the library. |
| 1027 Library& lib = Library::Handle(); |
| 1028 if (library_url()) { |
| 1029 const String& lib_url = String::Handle(String::New(library_url())); |
| 1030 lib = Library::LookupLibrary(lib_url); |
| 1031 if (lib.IsNull() || lib.IsError()) { |
| 1032 const String& msg = String::Handle(String::NewFormatted( |
| 1033 "Unable to find library '%s'.", library_url())); |
| 1034 return LanguageError::New(msg); |
| 1035 } |
| 1036 } else { |
| 1037 lib = isolate()->object_store()->root_library(); |
| 1038 } |
| 1039 ASSERT(!lib.IsNull()); |
| 1040 |
| 1041 // Resolve the function. |
| 1042 const String& func_name = |
| 1043 String::Handle(String::New(function_name())); |
| 1044 const Function& func = Function::Handle(lib.LookupLocalFunction(func_name)); |
| 1045 if (func.IsNull()) { |
| 1046 const String& msg = String::Handle(String::NewFormatted( |
| 1047 "Unable to resolve function '%s' in library '%s'.", |
| 1048 function_name(), (library_url() ? library_url() : script_url()))); |
| 1049 return LanguageError::New(msg); |
| 1050 } |
| 1051 return func.raw(); |
| 1052 } |
| 1053 |
| 1054 |
| 1055 void IsolateSpawnState::Cleanup() { |
| 1056 SwitchIsolateScope switch_scope(isolate()); |
| 1057 Dart::ShutdownIsolate(); |
| 1058 } |
| 1059 |
881 } // namespace dart | 1060 } // namespace dart |
OLD | NEW |