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 774 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
785 background_compiler_(NULL), | 785 background_compiler_(NULL), |
786 pending_service_extension_calls_(GrowableObjectArray::null()), | 786 pending_service_extension_calls_(GrowableObjectArray::null()), |
787 registered_service_extension_handlers_(GrowableObjectArray::null()), | 787 registered_service_extension_handlers_(GrowableObjectArray::null()), |
788 metrics_list_head_(NULL), | 788 metrics_list_head_(NULL), |
789 compilation_allowed_(true), | 789 compilation_allowed_(true), |
790 all_classes_finalized_(false), | 790 all_classes_finalized_(false), |
791 next_(NULL), | 791 next_(NULL), |
792 pause_loop_monitor_(NULL), | 792 pause_loop_monitor_(NULL), |
793 cha_invalidation_gen_(kInvalidGen), | 793 cha_invalidation_gen_(kInvalidGen), |
794 field_invalidation_gen_(kInvalidGen), | 794 field_invalidation_gen_(kInvalidGen), |
795 prefix_invalidation_gen_(kInvalidGen) { | 795 prefix_invalidation_gen_(kInvalidGen), |
| 796 spawn_count_monitor_(new Monitor()), |
| 797 spawn_count_(0) { |
796 flags_.CopyFrom(api_flags); | 798 flags_.CopyFrom(api_flags); |
797 // TODO(asiva): A Thread is not available here, need to figure out | 799 // TODO(asiva): A Thread is not available here, need to figure out |
798 // how the vm_tag (kEmbedderTagId) can be set, these tags need to | 800 // how the vm_tag (kEmbedderTagId) can be set, these tags need to |
799 // move to the OSThread structure. | 801 // move to the OSThread structure. |
800 set_user_tag(UserTags::kDefaultUserTag); | 802 set_user_tag(UserTags::kDefaultUserTag); |
801 } | 803 } |
802 | 804 |
803 #undef REUSABLE_HANDLE_SCOPE_INIT | 805 #undef REUSABLE_HANDLE_SCOPE_INIT |
804 #undef REUSABLE_HANDLE_INITIALIZERS | 806 #undef REUSABLE_HANDLE_INITIALIZERS |
805 | 807 |
(...skipping 11 matching lines...) Expand all Loading... |
817 delete mutex_; | 819 delete mutex_; |
818 mutex_ = NULL; // Fail fast if interrupts are scheduled on a dead isolate. | 820 mutex_ = NULL; // Fail fast if interrupts are scheduled on a dead isolate. |
819 delete message_handler_; | 821 delete message_handler_; |
820 message_handler_ = NULL; // Fail fast if we send messages to a dead isolate. | 822 message_handler_ = NULL; // Fail fast if we send messages to a dead isolate. |
821 ASSERT(deopt_context_ == NULL); // No deopt in progress when isolate deleted. | 823 ASSERT(deopt_context_ == NULL); // No deopt in progress when isolate deleted. |
822 delete spawn_state_; | 824 delete spawn_state_; |
823 delete object_id_ring_; | 825 delete object_id_ring_; |
824 object_id_ring_ = NULL; | 826 object_id_ring_ = NULL; |
825 delete pause_loop_monitor_; | 827 delete pause_loop_monitor_; |
826 pause_loop_monitor_ = NULL; | 828 pause_loop_monitor_ = NULL; |
| 829 ASSERT(spawn_count_ == 0); |
| 830 delete spawn_count_monitor_; |
827 if (compiler_stats_ != NULL) { | 831 if (compiler_stats_ != NULL) { |
828 delete compiler_stats_; | 832 delete compiler_stats_; |
829 compiler_stats_ = NULL; | 833 compiler_stats_ = NULL; |
830 } | 834 } |
831 delete thread_registry_; | 835 delete thread_registry_; |
832 } | 836 } |
833 | 837 |
834 | 838 |
835 #if defined(DEBUG) | 839 #if defined(DEBUG) |
836 bool Isolate::IsIsolateOf(Thread* thread) { | 840 bool Isolate::IsIsolateOf(Thread* thread) { |
(...skipping 555 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1392 if (result.IsError()) { | 1396 if (result.IsError()) { |
1393 return StoreError(isolate, Error::Cast(result)); | 1397 return StoreError(isolate, Error::Cast(result)); |
1394 } | 1398 } |
1395 } | 1399 } |
1396 return MessageHandler::kOK; | 1400 return MessageHandler::kOK; |
1397 } | 1401 } |
1398 | 1402 |
1399 | 1403 |
1400 static void ShutdownIsolate(uword parameter) { | 1404 static void ShutdownIsolate(uword parameter) { |
1401 Isolate* isolate = reinterpret_cast<Isolate*>(parameter); | 1405 Isolate* isolate = reinterpret_cast<Isolate*>(parameter); |
| 1406 // We must wait for any outstanding spawn calls to complete before |
| 1407 // running the shutdown callback. |
| 1408 isolate->WaitForOutstandingSpawns(); |
1402 { | 1409 { |
1403 // Print the error if there is one. This may execute dart code to | 1410 // Print the error if there is one. This may execute dart code to |
1404 // print the exception object, so we need to use a StartIsolateScope. | 1411 // print the exception object, so we need to use a StartIsolateScope. |
1405 StartIsolateScope start_scope(isolate); | 1412 StartIsolateScope start_scope(isolate); |
1406 Thread* thread = Thread::Current(); | 1413 Thread* thread = Thread::Current(); |
1407 ASSERT(thread->isolate() == isolate); | 1414 ASSERT(thread->isolate() == isolate); |
1408 StackZone zone(thread); | 1415 StackZone zone(thread); |
1409 HandleScope handle_scope(thread); | 1416 HandleScope handle_scope(thread); |
1410 const Error& error = Error::Handle(isolate->object_store()->sticky_error()); | 1417 const Error& error = Error::Handle(isolate->object_store()->sticky_error()); |
1411 if (!error.IsNull() && !error.IsUnwindError()) { | 1418 if (!error.IsNull() && !error.IsUnwindError()) { |
(...skipping 885 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2297 VisitIsolates(&visitor); | 2304 VisitIsolates(&visitor); |
2298 } | 2305 } |
2299 | 2306 |
2300 | 2307 |
2301 void Isolate::KillIfExists(Isolate* isolate, LibMsgId msg_id) { | 2308 void Isolate::KillIfExists(Isolate* isolate, LibMsgId msg_id) { |
2302 IsolateKillerVisitor visitor(isolate, msg_id); | 2309 IsolateKillerVisitor visitor(isolate, msg_id); |
2303 VisitIsolates(&visitor); | 2310 VisitIsolates(&visitor); |
2304 } | 2311 } |
2305 | 2312 |
2306 | 2313 |
| 2314 void Isolate::IncrementSpawnCount() { |
| 2315 MonitorLocker ml(spawn_count_monitor_); |
| 2316 spawn_count_++; |
| 2317 } |
| 2318 |
| 2319 |
| 2320 void Isolate::WaitForOutstandingSpawns() { |
| 2321 MonitorLocker ml(spawn_count_monitor_); |
| 2322 while (spawn_count_ > 0) { |
| 2323 ml.Wait(); |
| 2324 } |
| 2325 } |
| 2326 |
| 2327 |
2307 static RawInstance* DeserializeObject(Thread* thread, | 2328 static RawInstance* DeserializeObject(Thread* thread, |
2308 uint8_t* obj_data, | 2329 uint8_t* obj_data, |
2309 intptr_t obj_len) { | 2330 intptr_t obj_len) { |
2310 if (obj_data == NULL) { | 2331 if (obj_data == NULL) { |
2311 return Instance::null(); | 2332 return Instance::null(); |
2312 } | 2333 } |
2313 MessageSnapshotReader reader(obj_data, obj_len, thread); | 2334 MessageSnapshotReader reader(obj_data, obj_len, thread); |
2314 Zone* zone = thread->zone(); | 2335 Zone* zone = thread->zone(); |
2315 const Object& obj = Object::Handle(zone, reader.ReadObject()); | 2336 const Object& obj = Object::Handle(zone, reader.ReadObject()); |
2316 ASSERT(!obj.IsError()); | 2337 ASSERT(!obj.IsError()); |
2317 Instance& instance = Instance::Handle(zone); | 2338 Instance& instance = Instance::Handle(zone); |
2318 instance ^= obj.raw(); // Can't use Instance::Cast because may be null. | 2339 instance ^= obj.raw(); // Can't use Instance::Cast because may be null. |
2319 return instance.raw(); | 2340 return instance.raw(); |
2320 } | 2341 } |
2321 | 2342 |
2322 | 2343 |
2323 static const char* NewConstChar(const char* chars) { | 2344 static const char* NewConstChar(const char* chars) { |
2324 size_t len = strlen(chars); | 2345 size_t len = strlen(chars); |
2325 char* mem = new char[len + 1]; | 2346 char* mem = new char[len + 1]; |
2326 memmove(mem, chars, len + 1); | 2347 memmove(mem, chars, len + 1); |
2327 return mem; | 2348 return mem; |
2328 } | 2349 } |
2329 | 2350 |
2330 | 2351 |
2331 IsolateSpawnState::IsolateSpawnState(Dart_Port parent_port, | 2352 IsolateSpawnState::IsolateSpawnState(Dart_Port parent_port, |
2332 Dart_Port origin_id, | 2353 Dart_Port origin_id, |
2333 void* init_data, | 2354 void* init_data, |
2334 const Function& func, | 2355 const Function& func, |
2335 const Instance& message, | 2356 const Instance& message, |
| 2357 Monitor* spawn_count_monitor, |
| 2358 intptr_t* spawn_count, |
2336 bool paused, | 2359 bool paused, |
2337 bool errors_are_fatal, | 2360 bool errors_are_fatal, |
2338 Dart_Port on_exit_port, | 2361 Dart_Port on_exit_port, |
2339 Dart_Port on_error_port) | 2362 Dart_Port on_error_port) |
2340 : isolate_(NULL), | 2363 : isolate_(NULL), |
2341 parent_port_(parent_port), | 2364 parent_port_(parent_port), |
2342 origin_id_(origin_id), | 2365 origin_id_(origin_id), |
2343 init_data_(init_data), | 2366 init_data_(init_data), |
2344 on_exit_port_(on_exit_port), | 2367 on_exit_port_(on_exit_port), |
2345 on_error_port_(on_error_port), | 2368 on_error_port_(on_error_port), |
2346 script_url_(NULL), | 2369 script_url_(NULL), |
2347 package_root_(NULL), | 2370 package_root_(NULL), |
2348 package_map_(NULL), | 2371 package_map_(NULL), |
2349 library_url_(NULL), | 2372 library_url_(NULL), |
2350 class_name_(NULL), | 2373 class_name_(NULL), |
2351 function_name_(NULL), | 2374 function_name_(NULL), |
2352 serialized_args_(NULL), | 2375 serialized_args_(NULL), |
2353 serialized_args_len_(0), | 2376 serialized_args_len_(0), |
2354 serialized_message_(NULL), | 2377 serialized_message_(NULL), |
2355 serialized_message_len_(0), | 2378 serialized_message_len_(0), |
| 2379 spawn_count_monitor_(spawn_count_monitor), |
| 2380 spawn_count_(spawn_count), |
2356 isolate_flags_(), | 2381 isolate_flags_(), |
2357 paused_(paused), | 2382 paused_(paused), |
2358 errors_are_fatal_(errors_are_fatal) { | 2383 errors_are_fatal_(errors_are_fatal) { |
2359 const Class& cls = Class::Handle(func.Owner()); | 2384 const Class& cls = Class::Handle(func.Owner()); |
2360 const Library& lib = Library::Handle(cls.library()); | 2385 const Library& lib = Library::Handle(cls.library()); |
2361 const String& lib_url = String::Handle(lib.url()); | 2386 const String& lib_url = String::Handle(lib.url()); |
2362 library_url_ = NewConstChar(lib_url.ToCString()); | 2387 library_url_ = NewConstChar(lib_url.ToCString()); |
2363 | 2388 |
2364 const String& func_name = String::Handle(func.name()); | 2389 const String& func_name = String::Handle(func.name()); |
2365 function_name_ = NewConstChar(func_name.ToCString()); | 2390 function_name_ = NewConstChar(func_name.ToCString()); |
(...skipping 11 matching lines...) Expand all Loading... |
2377 } | 2402 } |
2378 | 2403 |
2379 | 2404 |
2380 IsolateSpawnState::IsolateSpawnState(Dart_Port parent_port, | 2405 IsolateSpawnState::IsolateSpawnState(Dart_Port parent_port, |
2381 void* init_data, | 2406 void* init_data, |
2382 const char* script_url, | 2407 const char* script_url, |
2383 const char* package_root, | 2408 const char* package_root, |
2384 const char** package_map, | 2409 const char** package_map, |
2385 const Instance& args, | 2410 const Instance& args, |
2386 const Instance& message, | 2411 const Instance& message, |
| 2412 Monitor* spawn_count_monitor, |
| 2413 intptr_t* spawn_count, |
2387 bool paused, | 2414 bool paused, |
2388 bool errors_are_fatal, | 2415 bool errors_are_fatal, |
2389 Dart_Port on_exit_port, | 2416 Dart_Port on_exit_port, |
2390 Dart_Port on_error_port) | 2417 Dart_Port on_error_port) |
2391 : isolate_(NULL), | 2418 : isolate_(NULL), |
2392 parent_port_(parent_port), | 2419 parent_port_(parent_port), |
2393 origin_id_(ILLEGAL_PORT), | 2420 origin_id_(ILLEGAL_PORT), |
2394 init_data_(init_data), | 2421 init_data_(init_data), |
2395 on_exit_port_(on_exit_port), | 2422 on_exit_port_(on_exit_port), |
2396 on_error_port_(on_error_port), | 2423 on_error_port_(on_error_port), |
2397 script_url_(script_url), | 2424 script_url_(script_url), |
2398 package_root_(package_root), | 2425 package_root_(package_root), |
2399 package_map_(package_map), | 2426 package_map_(package_map), |
2400 library_url_(NULL), | 2427 library_url_(NULL), |
2401 class_name_(NULL), | 2428 class_name_(NULL), |
2402 function_name_(NULL), | 2429 function_name_(NULL), |
2403 serialized_args_(NULL), | 2430 serialized_args_(NULL), |
2404 serialized_args_len_(0), | 2431 serialized_args_len_(0), |
2405 serialized_message_(NULL), | 2432 serialized_message_(NULL), |
2406 serialized_message_len_(0), | 2433 serialized_message_len_(0), |
| 2434 spawn_count_monitor_(spawn_count_monitor), |
| 2435 spawn_count_(spawn_count), |
2407 isolate_flags_(), | 2436 isolate_flags_(), |
2408 paused_(paused), | 2437 paused_(paused), |
2409 errors_are_fatal_(errors_are_fatal) { | 2438 errors_are_fatal_(errors_are_fatal) { |
2410 function_name_ = NewConstChar("main"); | 2439 function_name_ = NewConstChar("main"); |
2411 bool can_send_any_object = false; | 2440 bool can_send_any_object = false; |
2412 SerializeObject(args, | 2441 SerializeObject(args, |
2413 &serialized_args_, | 2442 &serialized_args_, |
2414 &serialized_args_len_, | 2443 &serialized_args_len_, |
2415 can_send_any_object); | 2444 can_send_any_object); |
2416 SerializeObject(message, | 2445 SerializeObject(message, |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2514 return DeserializeObject(thread, serialized_args_, serialized_args_len_); | 2543 return DeserializeObject(thread, serialized_args_, serialized_args_len_); |
2515 } | 2544 } |
2516 | 2545 |
2517 | 2546 |
2518 RawInstance* IsolateSpawnState::BuildMessage(Thread* thread) { | 2547 RawInstance* IsolateSpawnState::BuildMessage(Thread* thread) { |
2519 return DeserializeObject(thread, | 2548 return DeserializeObject(thread, |
2520 serialized_message_, serialized_message_len_); | 2549 serialized_message_, serialized_message_len_); |
2521 } | 2550 } |
2522 | 2551 |
2523 | 2552 |
| 2553 void IsolateSpawnState::DecrementSpawnCount() { |
| 2554 ASSERT(spawn_count_monitor_ != NULL); |
| 2555 ASSERT(spawn_count_ != NULL); |
| 2556 MonitorLocker ml(spawn_count_monitor_); |
| 2557 ASSERT(*spawn_count_ > 0); |
| 2558 *spawn_count_ = *spawn_count_ - 1; |
| 2559 ml.Notify(); |
| 2560 } |
| 2561 |
2524 } // namespace dart | 2562 } // namespace dart |
OLD | NEW |