| 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 |