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 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
46 #include "vm/timeline_analysis.h" | 46 #include "vm/timeline_analysis.h" |
47 #include "vm/timer.h" | 47 #include "vm/timer.h" |
48 #include "vm/visitor.h" | 48 #include "vm/visitor.h" |
49 | 49 |
50 | 50 |
51 namespace dart { | 51 namespace dart { |
52 | 52 |
53 DECLARE_FLAG(bool, print_metrics); | 53 DECLARE_FLAG(bool, print_metrics); |
54 DECLARE_FLAG(bool, timing); | 54 DECLARE_FLAG(bool, timing); |
55 DECLARE_FLAG(bool, trace_service); | 55 DECLARE_FLAG(bool, trace_service); |
56 DECLARE_FLAG(bool, trace_service_verbose); | |
57 | 56 |
58 DEFINE_FLAG(bool, trace_isolates, false, | 57 DEFINE_FLAG(bool, trace_isolates, false, |
59 "Trace isolate creation and shut down."); | 58 "Trace isolate creation and shut down."); |
60 DEFINE_FLAG(bool, pause_isolates_on_start, false, | 59 DEFINE_FLAG(bool, pause_isolates_on_start, false, |
61 "Pause isolates before starting."); | 60 "Pause isolates before starting."); |
62 DEFINE_FLAG(bool, pause_isolates_on_exit, false, | 61 DEFINE_FLAG(bool, pause_isolates_on_exit, false, |
63 "Pause isolates exiting."); | 62 "Pause isolates exiting."); |
64 DEFINE_FLAG(bool, pause_isolates_on_unhandled_exceptions, false, | 63 DEFINE_FLAG(bool, pause_isolates_on_unhandled_exceptions, false, |
65 "Pause isolates on unhandled exceptions."); | 64 "Pause isolates on unhandled exceptions."); |
66 | 65 |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
142 } else { | 141 } else { |
143 uint8_t* obj_data; | 142 uint8_t* obj_data; |
144 intptr_t obj_len; | 143 intptr_t obj_len; |
145 SerializeObject(obj, &obj_data, &obj_len, false); | 144 SerializeObject(obj, &obj_data, &obj_len, false); |
146 return new Message(dest_port, obj_data, obj_len, Message::kNormalPriority); | 145 return new Message(dest_port, obj_data, obj_len, Message::kNormalPriority); |
147 } | 146 } |
148 } | 147 } |
149 | 148 |
150 | 149 |
151 NoOOBMessageScope::NoOOBMessageScope(Thread* thread) : StackResource(thread) { | 150 NoOOBMessageScope::NoOOBMessageScope(Thread* thread) : StackResource(thread) { |
152 isolate()->DeferOOBMessageInterrupts(); | 151 thread->DeferOOBMessageInterrupts(); |
153 } | 152 } |
154 | 153 |
155 | 154 |
156 NoOOBMessageScope::~NoOOBMessageScope() { | 155 NoOOBMessageScope::~NoOOBMessageScope() { |
157 isolate()->RestoreOOBMessageInterrupts(); | 156 thread()->RestoreOOBMessageInterrupts(); |
158 } | 157 } |
159 | 158 |
160 | 159 |
161 | 160 |
162 void Isolate::RegisterClass(const Class& cls) { | 161 void Isolate::RegisterClass(const Class& cls) { |
163 class_table()->Register(cls); | 162 class_table()->Register(cls); |
164 } | 163 } |
165 | 164 |
166 | 165 |
167 void Isolate::RegisterClassAt(intptr_t index, const Class& cls) { | 166 void Isolate::RegisterClassAt(intptr_t index, const Class& cls) { |
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
425 UNREACHABLE(); | 424 UNREACHABLE(); |
426 break; | 425 break; |
427 #endif // defined(DEBUG) | 426 #endif // defined(DEBUG) |
428 } | 427 } |
429 return Error::null(); | 428 return Error::null(); |
430 } | 429 } |
431 | 430 |
432 | 431 |
433 void IsolateMessageHandler::MessageNotify(Message::Priority priority) { | 432 void IsolateMessageHandler::MessageNotify(Message::Priority priority) { |
434 if (priority >= Message::kOOBPriority) { | 433 if (priority >= Message::kOOBPriority) { |
435 // Handle out of band messages even if the isolate is busy. | 434 // Handle out of band messages even if the mutator thread is busy. |
436 I->ScheduleInterrupts(Isolate::kMessageInterrupt); | 435 I->ScheduleMessageInterrupts(); |
437 } | 436 } |
438 Dart_MessageNotifyCallback callback = I->message_notify_callback(); | 437 Dart_MessageNotifyCallback callback = I->message_notify_callback(); |
439 if (callback) { | 438 if (callback) { |
440 // Allow the embedder to handle message notification. | 439 // Allow the embedder to handle message notification. |
441 (*callback)(Api::CastIsolate(I)); | 440 (*callback)(Api::CastIsolate(I)); |
442 } | 441 } |
443 } | 442 } |
444 | 443 |
445 | 444 |
446 MessageHandler::MessageStatus IsolateMessageHandler::HandleMessage( | 445 MessageHandler::MessageStatus IsolateMessageHandler::HandleMessage( |
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
750 #else | 749 #else |
751 #define REUSABLE_HANDLE_SCOPE_INIT(object) | 750 #define REUSABLE_HANDLE_SCOPE_INIT(object) |
752 #endif // defined(DEBUG) | 751 #endif // defined(DEBUG) |
753 | 752 |
754 #define REUSABLE_HANDLE_INITIALIZERS(object) \ | 753 #define REUSABLE_HANDLE_INITIALIZERS(object) \ |
755 object##_handle_(NULL), | 754 object##_handle_(NULL), |
756 | 755 |
757 // TODO(srdjan): Some Isolate monitors can be shared. Replace their usage with | 756 // TODO(srdjan): Some Isolate monitors can be shared. Replace their usage with |
758 // that shared monitor. | 757 // that shared monitor. |
759 Isolate::Isolate(const Dart_IsolateFlags& api_flags) | 758 Isolate::Isolate(const Dart_IsolateFlags& api_flags) |
760 : stack_limit_(0), | 759 : store_buffer_(new StoreBuffer()), |
761 store_buffer_(new StoreBuffer()), | |
762 heap_(NULL), | 760 heap_(NULL), |
763 user_tag_(0), | 761 user_tag_(0), |
764 current_tag_(UserTag::null()), | 762 current_tag_(UserTag::null()), |
765 default_tag_(UserTag::null()), | 763 default_tag_(UserTag::null()), |
766 class_table_(), | 764 class_table_(), |
767 single_step_(false), | 765 single_step_(false), |
768 thread_registry_(new ThreadRegistry()), | 766 thread_registry_(new ThreadRegistry()), |
769 safepoint_handler_(new SafepointHandler(this)), | 767 safepoint_handler_(new SafepointHandler(this)), |
770 message_notify_callback_(NULL), | 768 message_notify_callback_(NULL), |
771 name_(NULL), | 769 name_(NULL), |
(...skipping 13 matching lines...) Expand all Loading... |
785 debugger_(NULL), | 783 debugger_(NULL), |
786 resume_request_(false), | 784 resume_request_(false), |
787 last_resume_timestamp_(OS::GetCurrentTimeMillis()), | 785 last_resume_timestamp_(OS::GetCurrentTimeMillis()), |
788 has_compiled_code_(false), | 786 has_compiled_code_(false), |
789 random_(), | 787 random_(), |
790 simulator_(NULL), | 788 simulator_(NULL), |
791 mutex_(new Mutex()), | 789 mutex_(new Mutex()), |
792 symbols_mutex_(new Mutex()), | 790 symbols_mutex_(new Mutex()), |
793 type_canonicalization_mutex_(new Mutex()), | 791 type_canonicalization_mutex_(new Mutex()), |
794 constant_canonicalization_mutex_(new Mutex()), | 792 constant_canonicalization_mutex_(new Mutex()), |
795 saved_stack_limit_(0), | |
796 deferred_interrupts_mask_(0), | |
797 deferred_interrupts_(0), | |
798 stack_overflow_flags_(0), | |
799 stack_overflow_count_(0), | |
800 message_handler_(NULL), | 793 message_handler_(NULL), |
801 spawn_state_(NULL), | 794 spawn_state_(NULL), |
802 is_runnable_(false), | 795 is_runnable_(false), |
803 gc_prologue_callback_(NULL), | 796 gc_prologue_callback_(NULL), |
804 gc_epilogue_callback_(NULL), | 797 gc_epilogue_callback_(NULL), |
805 defer_finalization_count_(0), | 798 defer_finalization_count_(0), |
806 deopt_context_(NULL), | 799 deopt_context_(NULL), |
807 compiler_stats_(NULL), | 800 compiler_stats_(NULL), |
808 is_service_isolate_(false), | 801 is_service_isolate_(false), |
809 stacktrace_(NULL), | 802 stacktrace_(NULL), |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
972 result->LowLevelShutdown(); | 965 result->LowLevelShutdown(); |
973 Thread::ExitIsolate(); | 966 Thread::ExitIsolate(); |
974 delete result; | 967 delete result; |
975 return NULL; | 968 return NULL; |
976 } | 969 } |
977 | 970 |
978 return result; | 971 return result; |
979 } | 972 } |
980 | 973 |
981 | 974 |
982 /* static */ | |
983 uword Isolate::GetCurrentStackPointer() { | |
984 // Since AddressSanitizer's detect_stack_use_after_return instruments the | |
985 // C++ code to give out fake stack addresses, we call a stub in that case. | |
986 uword (*func)() = reinterpret_cast<uword (*)()>( | |
987 StubCode::GetStackPointer_entry()->EntryPoint()); | |
988 // But for performance (and to support simulators), we normally use a local. | |
989 #if defined(__has_feature) | |
990 #if __has_feature(address_sanitizer) | |
991 uword current_sp = func(); | |
992 return current_sp; | |
993 #else | |
994 uword stack_allocated_local_address = reinterpret_cast<uword>(&func); | |
995 return stack_allocated_local_address; | |
996 #endif | |
997 #else | |
998 uword stack_allocated_local_address = reinterpret_cast<uword>(&func); | |
999 return stack_allocated_local_address; | |
1000 #endif | |
1001 } | |
1002 | |
1003 | |
1004 void Isolate::SetupInstructionsSnapshotPage( | 975 void Isolate::SetupInstructionsSnapshotPage( |
1005 const uint8_t* instructions_snapshot_buffer) { | 976 const uint8_t* instructions_snapshot_buffer) { |
1006 InstructionsSnapshot snapshot(instructions_snapshot_buffer); | 977 InstructionsSnapshot snapshot(instructions_snapshot_buffer); |
1007 #if defined(DEBUG) | 978 #if defined(DEBUG) |
1008 if (FLAG_trace_isolates) { | 979 if (FLAG_trace_isolates) { |
1009 OS::Print("Precompiled instructions are at [0x%" Px ", 0x%" Px ")\n", | 980 OS::Print("Precompiled instructions are at [0x%" Px ", 0x%" Px ")\n", |
1010 reinterpret_cast<uword>(snapshot.instructions_start()), | 981 reinterpret_cast<uword>(snapshot.instructions_start()), |
1011 reinterpret_cast<uword>(snapshot.instructions_start()) + | 982 reinterpret_cast<uword>(snapshot.instructions_start()) + |
1012 snapshot.instructions_size()); | 983 snapshot.instructions_size()); |
1013 } | 984 } |
(...skipping 13 matching lines...) Expand all Loading... |
1027 reinterpret_cast<uword>(snapshot.data_start()) + | 998 reinterpret_cast<uword>(snapshot.data_start()) + |
1028 snapshot.data_size()); | 999 snapshot.data_size()); |
1029 } | 1000 } |
1030 #endif | 1001 #endif |
1031 heap_->SetupExternalPage(snapshot.data_start(), | 1002 heap_->SetupExternalPage(snapshot.data_start(), |
1032 snapshot.data_size(), | 1003 snapshot.data_size(), |
1033 /* is_executable = */ false); | 1004 /* is_executable = */ false); |
1034 } | 1005 } |
1035 | 1006 |
1036 | 1007 |
| 1008 void Isolate::ScheduleMessageInterrupts() { |
| 1009 // We take the threads lock here to ensure that the mutator thread does not |
| 1010 // exit the isolate while we are trying to schedule interrupts on it. |
| 1011 MonitorLocker ml(threads_lock()); |
| 1012 Thread* mthread = mutator_thread(); |
| 1013 if (mthread != NULL) { |
| 1014 mthread->ScheduleInterrupts(Thread::kMessageInterrupt); |
| 1015 } |
| 1016 } |
| 1017 |
1037 | 1018 |
1038 void Isolate::set_debugger_name(const char* name) { | 1019 void Isolate::set_debugger_name(const char* name) { |
1039 free(debugger_name_); | 1020 free(debugger_name_); |
1040 debugger_name_ = strdup(name); | 1021 debugger_name_ = strdup(name); |
1041 } | 1022 } |
1042 | 1023 |
1043 | 1024 |
1044 void Isolate::BuildName(const char* name_prefix) { | 1025 void Isolate::BuildName(const char* name_prefix) { |
1045 ASSERT(name_ == NULL); | 1026 ASSERT(name_ == NULL); |
1046 if (name_prefix == NULL) { | 1027 if (name_prefix == NULL) { |
1047 name_prefix = "isolate"; | 1028 name_prefix = "isolate"; |
1048 } | 1029 } |
1049 set_debugger_name(name_prefix); | 1030 set_debugger_name(name_prefix); |
1050 if (ServiceIsolate::NameEquals(name_prefix)) { | 1031 if (ServiceIsolate::NameEquals(name_prefix)) { |
1051 name_ = strdup(name_prefix); | 1032 name_ = strdup(name_prefix); |
1052 return; | 1033 return; |
1053 } | 1034 } |
1054 name_ = OS::SCreate(NULL, "%s-%" Pd64 "", name_prefix, main_port()); | 1035 name_ = OS::SCreate(NULL, "%s-%" Pd64 "", name_prefix, main_port()); |
1055 } | 1036 } |
1056 | 1037 |
1057 | 1038 |
1058 void Isolate::SetStackLimitFromStackBase(uword stack_base) { | |
1059 // Set stack limit. | |
1060 #if defined(USING_SIMULATOR) | |
1061 // Ignore passed-in native stack top and use Simulator stack top. | |
1062 Simulator* sim = Simulator::Current(); // May allocate a simulator. | |
1063 ASSERT(simulator() == sim); // This isolate's simulator is the current one. | |
1064 stack_base = sim->StackTop(); | |
1065 // The overflow area is accounted for by the simulator. | |
1066 #endif | |
1067 SetStackLimit(stack_base - OSThread::GetSpecifiedStackSize()); | |
1068 } | |
1069 | |
1070 | |
1071 void Isolate::SetStackLimit(uword limit) { | |
1072 // The isolate setting the stack limit is not necessarily the isolate which | |
1073 // the stack limit is being set on. | |
1074 MutexLocker ml(mutex_); | |
1075 if (stack_limit_ == saved_stack_limit_) { | |
1076 // No interrupt pending, set stack_limit_ too. | |
1077 stack_limit_ = limit; | |
1078 } | |
1079 saved_stack_limit_ = limit; | |
1080 } | |
1081 | |
1082 | |
1083 void Isolate::ClearStackLimit() { | |
1084 SetStackLimit(~static_cast<uword>(0)); | |
1085 } | |
1086 | |
1087 | |
1088 void Isolate::DoneLoading() { | 1039 void Isolate::DoneLoading() { |
1089 GrowableObjectArray& libs = GrowableObjectArray::Handle(current_zone(), | 1040 GrowableObjectArray& libs = GrowableObjectArray::Handle(current_zone(), |
1090 object_store()->libraries()); | 1041 object_store()->libraries()); |
1091 Library& lib = Library::Handle(current_zone()); | 1042 Library& lib = Library::Handle(current_zone()); |
1092 intptr_t num_libs = libs.Length(); | 1043 intptr_t num_libs = libs.Length(); |
1093 for (intptr_t i = 0; i < num_libs; i++) { | 1044 for (intptr_t i = 0; i < num_libs; i++) { |
1094 lib ^= libs.At(i); | 1045 lib ^= libs.At(i); |
1095 // If this library was loaded with Dart_LoadLibrary, it was marked | 1046 // If this library was loaded with Dart_LoadLibrary, it was marked |
1096 // as 'load in progres'. Set the status to 'loaded'. | 1047 // as 'load in progres'. Set the status to 'loaded'. |
1097 if (lib.LoadInProgress()) { | 1048 if (lib.LoadInProgress()) { |
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1481 | 1432 |
1482 | 1433 |
1483 void Isolate::Run() { | 1434 void Isolate::Run() { |
1484 message_handler()->Run(Dart::thread_pool(), | 1435 message_handler()->Run(Dart::thread_pool(), |
1485 RunIsolate, | 1436 RunIsolate, |
1486 ShutdownIsolate, | 1437 ShutdownIsolate, |
1487 reinterpret_cast<uword>(this)); | 1438 reinterpret_cast<uword>(this)); |
1488 } | 1439 } |
1489 | 1440 |
1490 | 1441 |
1491 void Isolate::ScheduleInterrupts(uword interrupt_bits) { | |
1492 MutexLocker ml(mutex_); | |
1493 ASSERT((interrupt_bits & ~kInterruptsMask) == 0); // Must fit in mask. | |
1494 | |
1495 // Check to see if any of the requested interrupts should be deferred. | |
1496 uword defer_bits = interrupt_bits & deferred_interrupts_mask_; | |
1497 if (defer_bits != 0) { | |
1498 deferred_interrupts_ |= defer_bits; | |
1499 interrupt_bits &= ~deferred_interrupts_mask_; | |
1500 if (interrupt_bits == 0) { | |
1501 return; | |
1502 } | |
1503 } | |
1504 | |
1505 if (stack_limit_ == saved_stack_limit_) { | |
1506 stack_limit_ = (~static_cast<uword>(0)) & ~kInterruptsMask; | |
1507 } | |
1508 stack_limit_ |= interrupt_bits; | |
1509 } | |
1510 | |
1511 | |
1512 uword Isolate::GetAndClearInterrupts() { | |
1513 MutexLocker ml(mutex_); | |
1514 if (stack_limit_ == saved_stack_limit_) { | |
1515 return 0; // No interrupt was requested. | |
1516 } | |
1517 uword interrupt_bits = stack_limit_ & kInterruptsMask; | |
1518 stack_limit_ = saved_stack_limit_; | |
1519 return interrupt_bits; | |
1520 } | |
1521 | |
1522 | |
1523 void Isolate::DeferOOBMessageInterrupts() { | |
1524 MutexLocker ml(mutex_); | |
1525 ASSERT(deferred_interrupts_mask_ == 0); | |
1526 deferred_interrupts_mask_ = kMessageInterrupt; | |
1527 | |
1528 if (stack_limit_ != saved_stack_limit_) { | |
1529 // Defer any interrupts which are currently pending. | |
1530 deferred_interrupts_ = stack_limit_ & deferred_interrupts_mask_; | |
1531 | |
1532 // Clear deferrable interrupts, if present. | |
1533 stack_limit_ &= ~deferred_interrupts_mask_; | |
1534 | |
1535 if ((stack_limit_ & kInterruptsMask) == 0) { | |
1536 // No other pending interrupts. Restore normal stack limit. | |
1537 stack_limit_ = saved_stack_limit_; | |
1538 } | |
1539 } | |
1540 if (FLAG_trace_service && FLAG_trace_service_verbose) { | |
1541 OS::Print("[+%" Pd64 "ms] Isolate %s deferring OOB interrupts\n", | |
1542 Dart::timestamp(), name()); | |
1543 } | |
1544 } | |
1545 | |
1546 | |
1547 void Isolate::RestoreOOBMessageInterrupts() { | |
1548 MutexLocker ml(mutex_); | |
1549 ASSERT(deferred_interrupts_mask_ == kMessageInterrupt); | |
1550 deferred_interrupts_mask_ = 0; | |
1551 if (deferred_interrupts_ != 0) { | |
1552 if (stack_limit_ == saved_stack_limit_) { | |
1553 stack_limit_ = (~static_cast<uword>(0)) & ~kInterruptsMask; | |
1554 } | |
1555 stack_limit_ |= deferred_interrupts_; | |
1556 deferred_interrupts_ = 0; | |
1557 } | |
1558 if (FLAG_trace_service && FLAG_trace_service_verbose) { | |
1559 OS::Print("[+%" Pd64 "ms] Isolate %s restoring OOB interrupts\n", | |
1560 Dart::timestamp(), name()); | |
1561 } | |
1562 } | |
1563 | |
1564 | |
1565 RawError* Isolate::HandleInterrupts() { | |
1566 uword interrupt_bits = GetAndClearInterrupts(); | |
1567 if ((interrupt_bits & kVMInterrupt) != 0) { | |
1568 if (store_buffer()->Overflowed()) { | |
1569 if (FLAG_verbose_gc) { | |
1570 OS::PrintErr("Scavenge scheduled by store buffer overflow.\n"); | |
1571 } | |
1572 heap()->CollectGarbage(Heap::kNew); | |
1573 } | |
1574 } | |
1575 if ((interrupt_bits & kMessageInterrupt) != 0) { | |
1576 MessageHandler::MessageStatus status = | |
1577 message_handler()->HandleOOBMessages(); | |
1578 if (status != MessageHandler::kOK) { | |
1579 // False result from HandleOOBMessages signals that the isolate should | |
1580 // be terminating. | |
1581 if (FLAG_trace_isolates) { | |
1582 OS::Print("[!] Terminating isolate due to OOB message:\n" | |
1583 "\tisolate: %s\n", name()); | |
1584 } | |
1585 Thread* thread = Thread::Current(); | |
1586 const Error& error = Error::Handle(thread->sticky_error()); | |
1587 ASSERT(!error.IsNull() && error.IsUnwindError()); | |
1588 thread->clear_sticky_error(); | |
1589 return error.raw(); | |
1590 } | |
1591 } | |
1592 return Error::null(); | |
1593 } | |
1594 | |
1595 | |
1596 uword Isolate::GetAndClearStackOverflowFlags() { | |
1597 uword stack_overflow_flags = stack_overflow_flags_; | |
1598 stack_overflow_flags_ = 0; | |
1599 return stack_overflow_flags; | |
1600 } | |
1601 | |
1602 | |
1603 void Isolate::AddClosureFunction(const Function& function) const { | 1442 void Isolate::AddClosureFunction(const Function& function) const { |
1604 GrowableObjectArray& closures = | 1443 GrowableObjectArray& closures = |
1605 GrowableObjectArray::Handle(object_store()->closure_functions()); | 1444 GrowableObjectArray::Handle(object_store()->closure_functions()); |
1606 ASSERT(!closures.IsNull()); | 1445 ASSERT(!closures.IsNull()); |
1607 ASSERT(function.IsNonImplicitClosureFunction()); | 1446 ASSERT(function.IsNonImplicitClosureFunction()); |
1608 closures.Add(function, Heap::kOld); | 1447 closures.Add(function, Heap::kOld); |
1609 } | 1448 } |
1610 | 1449 |
1611 | 1450 |
1612 // If the linear lookup turns out to be too expensive, the list | 1451 // If the linear lookup turns out to be too expensive, the list |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1750 #if defined(DEBUG) | 1589 #if defined(DEBUG) |
1751 if (heap_ != NULL) { | 1590 if (heap_ != NULL) { |
1752 // The VM isolate keeps all objects marked. | 1591 // The VM isolate keeps all objects marked. |
1753 heap_->Verify(this == Dart::vm_isolate() ? kRequireMarked : kForbidMarked); | 1592 heap_->Verify(this == Dart::vm_isolate() ? kRequireMarked : kForbidMarked); |
1754 } | 1593 } |
1755 #endif // DEBUG | 1594 #endif // DEBUG |
1756 | 1595 |
1757 Thread* thread = Thread::Current(); | 1596 Thread* thread = Thread::Current(); |
1758 | 1597 |
1759 // Don't allow anymore dart code to execution on this isolate. | 1598 // Don't allow anymore dart code to execution on this isolate. |
1760 ClearStackLimit(); | 1599 thread->ClearStackLimit(); |
1761 | 1600 |
1762 // First, perform higher-level cleanup that may need to allocate. | 1601 // First, perform higher-level cleanup that may need to allocate. |
1763 { | 1602 { |
1764 // Ensure we have a zone and handle scope so that we can call VM functions. | 1603 // Ensure we have a zone and handle scope so that we can call VM functions. |
1765 StackZone stack_zone(thread); | 1604 StackZone stack_zone(thread); |
1766 HandleScope handle_scope(thread); | 1605 HandleScope handle_scope(thread); |
1767 | 1606 |
1768 // Write out the coverage data if collection has been enabled. | 1607 // Write out the coverage data if collection has been enabled. |
1769 if ((this != Dart::vm_isolate()) && | 1608 if ((this != Dart::vm_isolate()) && |
1770 !ServiceIsolate::IsServiceIsolateDescendant(this)) { | 1609 !ServiceIsolate::IsServiceIsolateDescendant(this)) { |
(...skipping 1084 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2855 void IsolateSpawnState::DecrementSpawnCount() { | 2694 void IsolateSpawnState::DecrementSpawnCount() { |
2856 ASSERT(spawn_count_monitor_ != NULL); | 2695 ASSERT(spawn_count_monitor_ != NULL); |
2857 ASSERT(spawn_count_ != NULL); | 2696 ASSERT(spawn_count_ != NULL); |
2858 MonitorLocker ml(spawn_count_monitor_); | 2697 MonitorLocker ml(spawn_count_monitor_); |
2859 ASSERT(*spawn_count_ > 0); | 2698 ASSERT(*spawn_count_ > 0); |
2860 *spawn_count_ = *spawn_count_ - 1; | 2699 *spawn_count_ = *spawn_count_ - 1; |
2861 ml.Notify(); | 2700 ml.Notify(); |
2862 } | 2701 } |
2863 | 2702 |
2864 } // namespace dart | 2703 } // namespace dart |
OLD | NEW |