| Index: runtime/vm/isolate.cc
|
| diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
|
| index 2ba8ae05af06d7e83f8c6aad08e010064a5e0476..09010a010987b423d16e55f31c66eb14cba05e92 100644
|
| --- a/runtime/vm/isolate.cc
|
| +++ b/runtime/vm/isolate.cc
|
| @@ -774,6 +774,8 @@ Isolate::Isolate(const Dart_IsolateFlags& api_flags)
|
| simulator_(NULL),
|
| 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),
|
| @@ -1029,16 +1031,6 @@ void Isolate::ClearStackLimit() {
|
| }
|
|
|
|
|
| -void Isolate::ScheduleInterrupts(uword interrupt_bits) {
|
| - MutexLocker ml(mutex_);
|
| - ASSERT((interrupt_bits & ~kInterruptsMask) == 0); // Must fit in mask.
|
| - if (stack_limit_ == saved_stack_limit_) {
|
| - stack_limit_ = (~static_cast<uword>(0)) & ~kInterruptsMask;
|
| - }
|
| - stack_limit_ |= interrupt_bits;
|
| -}
|
| -
|
| -
|
| void Isolate::DoneLoading() {
|
| GrowableObjectArray& libs = GrowableObjectArray::Handle(current_zone(),
|
| object_store()->libraries());
|
| @@ -1439,6 +1431,27 @@ 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_) {
|
| @@ -1450,6 +1463,40 @@ uword Isolate::GetAndClearInterrupts() {
|
| }
|
|
|
|
|
| +void Isolate::DeferMessageInterrupts() {
|
| + 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_;
|
| + }
|
| + }
|
| +}
|
| +
|
| +
|
| +void Isolate::RestoreMessageInterrupts() {
|
| + 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;
|
| + }
|
| +}
|
| +
|
| +
|
| RawError* Isolate::HandleInterrupts() {
|
| uword interrupt_bits = GetAndClearInterrupts();
|
| if ((interrupt_bits & kVMInterrupt) != 0) {
|
|
|