| Index: runtime/vm/isolate.cc
|
| diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
|
| index e84906da1b6e89b0edeed826418051b89df82f8c..3214d5f048da92426e00d18bc2d9105b86759acf 100644
|
| --- a/runtime/vm/isolate.cc
|
| +++ b/runtime/vm/isolate.cc
|
| @@ -154,6 +154,17 @@ static Message* SerializeMessage(
|
| }
|
|
|
|
|
| +NoOOBMessageScope::NoOOBMessageScope(Thread* thread) : StackResource(thread) {
|
| + isolate()->DeferOOBMessageInterrupts();
|
| +}
|
| +
|
| +
|
| +NoOOBMessageScope::~NoOOBMessageScope() {
|
| + isolate()->RestoreOOBMessageInterrupts();
|
| +}
|
| +
|
| +
|
| +
|
| void Isolate::RegisterClass(const Class& cls) {
|
| class_table()->Register(cls);
|
| }
|
| @@ -788,6 +799,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),
|
| @@ -1053,16 +1066,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());
|
| @@ -1466,6 +1469,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_) {
|
| @@ -1477,6 +1501,40 @@ uword Isolate::GetAndClearInterrupts() {
|
| }
|
|
|
|
|
| +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_;
|
| + }
|
| + }
|
| +}
|
| +
|
| +
|
| +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;
|
| + }
|
| +}
|
| +
|
| +
|
| RawError* Isolate::HandleInterrupts() {
|
| uword interrupt_bits = GetAndClearInterrupts();
|
| if ((interrupt_bits & kVMInterrupt) != 0) {
|
|
|