Index: runtime/vm/isolate.cc |
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc |
index 0c6a6622ae5c419ed55f6f4ff45759b44e523c31..3149f38159a0888f2feabffdea0395d682ef23dc 100644 |
--- a/runtime/vm/isolate.cc |
+++ b/runtime/vm/isolate.cc |
@@ -53,7 +53,6 @@ namespace dart { |
DECLARE_FLAG(bool, print_metrics); |
DECLARE_FLAG(bool, timing); |
DECLARE_FLAG(bool, trace_service); |
-DECLARE_FLAG(bool, trace_service_verbose); |
DEFINE_FLAG(bool, trace_isolates, false, |
"Trace isolate creation and shut down."); |
@@ -149,12 +148,12 @@ static Message* SerializeMessage( |
NoOOBMessageScope::NoOOBMessageScope(Thread* thread) : StackResource(thread) { |
- isolate()->DeferOOBMessageInterrupts(); |
+ thread->DeferOOBMessageInterrupts(); |
} |
NoOOBMessageScope::~NoOOBMessageScope() { |
- isolate()->RestoreOOBMessageInterrupts(); |
+ thread()->RestoreOOBMessageInterrupts(); |
} |
@@ -432,8 +431,8 @@ RawError* IsolateMessageHandler::HandleLibMessage(const Array& message) { |
void IsolateMessageHandler::MessageNotify(Message::Priority priority) { |
if (priority >= Message::kOOBPriority) { |
- // Handle out of band messages even if the isolate is busy. |
- I->ScheduleInterrupts(Isolate::kMessageInterrupt); |
+ // Handle out of band messages even if the mutator thread is busy. |
+ I->ScheduleMessageInterrupts(); |
} |
Dart_MessageNotifyCallback callback = I->message_notify_callback(); |
if (callback) { |
@@ -757,8 +756,7 @@ void BaseIsolate::AssertCurrentThreadIsMutator() const { |
// TODO(srdjan): Some Isolate monitors can be shared. Replace their usage with |
// that shared monitor. |
Isolate::Isolate(const Dart_IsolateFlags& api_flags) |
- : stack_limit_(0), |
- store_buffer_(new StoreBuffer()), |
+ : store_buffer_(new StoreBuffer()), |
heap_(NULL), |
user_tag_(0), |
current_tag_(UserTag::null()), |
@@ -792,11 +790,6 @@ Isolate::Isolate(const Dart_IsolateFlags& api_flags) |
symbols_mutex_(new Mutex()), |
type_canonicalization_mutex_(new Mutex()), |
constant_canonicalization_mutex_(new Mutex()), |
- saved_stack_limit_(0), |
- deferred_interrupts_mask_(0), |
- deferred_interrupts_(0), |
- stack_overflow_flags_(0), |
- stack_overflow_count_(0), |
message_handler_(NULL), |
spawn_state_(NULL), |
is_runnable_(false), |
@@ -979,28 +972,6 @@ Isolate* Isolate::Init(const char* name_prefix, |
} |
-/* static */ |
-uword Isolate::GetCurrentStackPointer() { |
- // Since AddressSanitizer's detect_stack_use_after_return instruments the |
- // C++ code to give out fake stack addresses, we call a stub in that case. |
- uword (*func)() = reinterpret_cast<uword (*)()>( |
- StubCode::GetStackPointer_entry()->EntryPoint()); |
- // But for performance (and to support simulators), we normally use a local. |
-#if defined(__has_feature) |
-#if __has_feature(address_sanitizer) |
- uword current_sp = func(); |
- return current_sp; |
-#else |
- uword stack_allocated_local_address = reinterpret_cast<uword>(&func); |
- return stack_allocated_local_address; |
-#endif |
-#else |
- uword stack_allocated_local_address = reinterpret_cast<uword>(&func); |
- return stack_allocated_local_address; |
-#endif |
-} |
- |
- |
void Isolate::SetupInstructionsSnapshotPage( |
const uint8_t* instructions_snapshot_buffer) { |
InstructionsSnapshot snapshot(instructions_snapshot_buffer); |
@@ -1034,6 +1005,16 @@ void Isolate::SetupDataSnapshotPage(const uint8_t* data_snapshot_buffer) { |
} |
+void Isolate::ScheduleMessageInterrupts() { |
+ // We take the threads lock here to ensure that the mutator thread does not |
+ // exit the isolate while we are trying to schedule interrupts on it. |
+ MonitorLocker ml(threads_lock()); |
+ Thread* mthread = mutator_thread(); |
+ if (mthread != NULL) { |
+ mthread->ScheduleInterrupts(Thread::kMessageInterrupt); |
+ } |
+} |
+ |
void Isolate::set_debugger_name(const char* name) { |
free(debugger_name_); |
@@ -1055,36 +1036,6 @@ void Isolate::BuildName(const char* name_prefix) { |
} |
-void Isolate::SetStackLimitFromStackBase(uword stack_base) { |
- // Set stack limit. |
-#if defined(USING_SIMULATOR) |
- // Ignore passed-in native stack top and use Simulator stack top. |
- Simulator* sim = Simulator::Current(); // May allocate a simulator. |
- ASSERT(simulator() == sim); // This isolate's simulator is the current one. |
- stack_base = sim->StackTop(); |
- // The overflow area is accounted for by the simulator. |
-#endif |
- SetStackLimit(stack_base - OSThread::GetSpecifiedStackSize()); |
-} |
- |
- |
-void Isolate::SetStackLimit(uword limit) { |
- // The isolate setting the stack limit is not necessarily the isolate which |
- // the stack limit is being set on. |
- MutexLocker ml(mutex_); |
- if (stack_limit_ == saved_stack_limit_) { |
- // No interrupt pending, set stack_limit_ too. |
- stack_limit_ = limit; |
- } |
- saved_stack_limit_ = limit; |
-} |
- |
- |
-void Isolate::ClearStackLimit() { |
- SetStackLimit(~static_cast<uword>(0)); |
-} |
- |
- |
void Isolate::DoneLoading() { |
GrowableObjectArray& libs = GrowableObjectArray::Handle(current_zone(), |
object_store()->libraries()); |
@@ -1488,118 +1439,6 @@ void Isolate::Run() { |
} |
-void Isolate::ScheduleInterrupts(uword interrupt_bits) { |
- MutexLocker ml(mutex_); |
- ASSERT((interrupt_bits & ~kInterruptsMask) == 0); // Must fit in mask. |
- |
- // Check to see if any of the requested interrupts should be deferred. |
- uword defer_bits = interrupt_bits & deferred_interrupts_mask_; |
- if (defer_bits != 0) { |
- deferred_interrupts_ |= defer_bits; |
- interrupt_bits &= ~deferred_interrupts_mask_; |
- if (interrupt_bits == 0) { |
- return; |
- } |
- } |
- |
- if (stack_limit_ == saved_stack_limit_) { |
- stack_limit_ = (~static_cast<uword>(0)) & ~kInterruptsMask; |
- } |
- stack_limit_ |= interrupt_bits; |
-} |
- |
- |
-uword Isolate::GetAndClearInterrupts() { |
- MutexLocker ml(mutex_); |
- if (stack_limit_ == saved_stack_limit_) { |
- return 0; // No interrupt was requested. |
- } |
- uword interrupt_bits = stack_limit_ & kInterruptsMask; |
- stack_limit_ = saved_stack_limit_; |
- return interrupt_bits; |
-} |
- |
- |
-void Isolate::DeferOOBMessageInterrupts() { |
- MutexLocker ml(mutex_); |
- ASSERT(deferred_interrupts_mask_ == 0); |
- deferred_interrupts_mask_ = kMessageInterrupt; |
- |
- if (stack_limit_ != saved_stack_limit_) { |
- // Defer any interrupts which are currently pending. |
- deferred_interrupts_ = stack_limit_ & deferred_interrupts_mask_; |
- |
- // Clear deferrable interrupts, if present. |
- stack_limit_ &= ~deferred_interrupts_mask_; |
- |
- if ((stack_limit_ & kInterruptsMask) == 0) { |
- // No other pending interrupts. Restore normal stack limit. |
- stack_limit_ = saved_stack_limit_; |
- } |
- } |
- if (FLAG_trace_service && FLAG_trace_service_verbose) { |
- OS::Print("[+%" Pd64 "ms] Isolate %s deferring OOB interrupts\n", |
- Dart::timestamp(), name()); |
- } |
-} |
- |
- |
-void Isolate::RestoreOOBMessageInterrupts() { |
- MutexLocker ml(mutex_); |
- ASSERT(deferred_interrupts_mask_ == kMessageInterrupt); |
- deferred_interrupts_mask_ = 0; |
- if (deferred_interrupts_ != 0) { |
- if (stack_limit_ == saved_stack_limit_) { |
- stack_limit_ = (~static_cast<uword>(0)) & ~kInterruptsMask; |
- } |
- stack_limit_ |= deferred_interrupts_; |
- deferred_interrupts_ = 0; |
- } |
- if (FLAG_trace_service && FLAG_trace_service_verbose) { |
- OS::Print("[+%" Pd64 "ms] Isolate %s restoring OOB interrupts\n", |
- Dart::timestamp(), name()); |
- } |
-} |
- |
- |
-RawError* Isolate::HandleInterrupts() { |
- uword interrupt_bits = GetAndClearInterrupts(); |
- if ((interrupt_bits & kVMInterrupt) != 0) { |
- if (store_buffer()->Overflowed()) { |
- if (FLAG_verbose_gc) { |
- OS::PrintErr("Scavenge scheduled by store buffer overflow.\n"); |
- } |
- heap()->CollectGarbage(Heap::kNew); |
- } |
- } |
- if ((interrupt_bits & kMessageInterrupt) != 0) { |
- MessageHandler::MessageStatus status = |
- message_handler()->HandleOOBMessages(); |
- if (status != MessageHandler::kOK) { |
- // False result from HandleOOBMessages signals that the isolate should |
- // be terminating. |
- if (FLAG_trace_isolates) { |
- OS::Print("[!] Terminating isolate due to OOB message:\n" |
- "\tisolate: %s\n", name()); |
- } |
- Thread* thread = Thread::Current(); |
- const Error& error = Error::Handle(thread->sticky_error()); |
- ASSERT(!error.IsNull() && error.IsUnwindError()); |
- thread->clear_sticky_error(); |
- return error.raw(); |
- } |
- } |
- return Error::null(); |
-} |
- |
- |
-uword Isolate::GetAndClearStackOverflowFlags() { |
- uword stack_overflow_flags = stack_overflow_flags_; |
- stack_overflow_flags_ = 0; |
- return stack_overflow_flags; |
-} |
- |
- |
void Isolate::AddClosureFunction(const Function& function) const { |
GrowableObjectArray& closures = |
GrowableObjectArray::Handle(object_store()->closure_functions()); |
@@ -1757,7 +1596,7 @@ void Isolate::Shutdown() { |
Thread* thread = Thread::Current(); |
// Don't allow anymore dart code to execution on this isolate. |
- ClearStackLimit(); |
+ thread->ClearStackLimit(); |
// First, perform higher-level cleanup that may need to allocate. |
{ |