Index: runtime/vm/isolate_test.cc |
diff --git a/runtime/vm/isolate_test.cc b/runtime/vm/isolate_test.cc |
index 4bf156d6faae91a598544a3199fba69673938f68..ef3ba53a63af1b0c96b069d945a3d4a623005451 100644 |
--- a/runtime/vm/isolate_test.cc |
+++ b/runtime/vm/isolate_test.cc |
@@ -149,4 +149,103 @@ TEST_CASE(StackLimitInterrupts) { |
barrier.Exit(); |
} |
+ |
+class IsolateTestHelper { |
+ public: |
+ static uword GetStackLimit(Isolate* isolate) { |
+ return isolate->stack_limit_; |
+ } |
+ static uword GetSavedStackLimit(Isolate* isolate) { |
+ return isolate->saved_stack_limit_; |
+ } |
+ static uword GetDeferredInterruptsMask(Isolate* isolate) { |
+ return isolate->deferred_interrupts_mask_; |
+ } |
+ static uword GetDeferredInterrupts(Isolate* isolate) { |
+ return isolate->deferred_interrupts_; |
+ } |
+}; |
+ |
+ |
+TEST_CASE(NoOOBMessageScope) { |
+ // EXPECT_EQ is picky about type agreement for its arguments. |
+ const uword kZero = 0; |
+ const uword kMessageInterrupt = Isolate::kMessageInterrupt; |
+ const uword kVMInterrupt = Isolate::kVMInterrupt; |
+ uword stack_limit; |
+ uword interrupt_bits; |
+ |
+ // Initially no interrupts are scheduled or deferred. |
+ Isolate* isolate = Thread::Current()->isolate(); |
+ EXPECT_EQ(IsolateTestHelper::GetStackLimit(isolate), |
+ IsolateTestHelper::GetSavedStackLimit(isolate)); |
+ EXPECT_EQ(kZero, IsolateTestHelper::GetDeferredInterruptsMask(isolate)); |
+ EXPECT_EQ(kZero, IsolateTestHelper::GetDeferredInterrupts(isolate)); |
+ |
+ { |
+ // Defer message interrupts. |
+ NoOOBMessageScope no_msg_scope(Thread::Current()); |
+ EXPECT_EQ(IsolateTestHelper::GetStackLimit(isolate), |
+ IsolateTestHelper::GetSavedStackLimit(isolate)); |
+ EXPECT_EQ(kMessageInterrupt, |
+ IsolateTestHelper::GetDeferredInterruptsMask(isolate)); |
+ EXPECT_EQ(kZero, IsolateTestHelper::GetDeferredInterrupts(isolate)); |
+ |
+ // Schedule a message, it is deferred. |
+ isolate->ScheduleInterrupts(Isolate::kMessageInterrupt); |
+ EXPECT_EQ(IsolateTestHelper::GetStackLimit(isolate), |
+ IsolateTestHelper::GetSavedStackLimit(isolate)); |
+ EXPECT_EQ(kMessageInterrupt, |
+ IsolateTestHelper::GetDeferredInterruptsMask(isolate)); |
+ EXPECT_EQ(kMessageInterrupt, |
+ IsolateTestHelper::GetDeferredInterrupts(isolate)); |
+ |
+ // Schedule a vm interrupt, it is not deferred. |
+ isolate->ScheduleInterrupts(Isolate::kVMInterrupt); |
+ stack_limit = IsolateTestHelper::GetStackLimit(isolate); |
+ EXPECT_NE(stack_limit, IsolateTestHelper::GetSavedStackLimit(isolate)); |
+ EXPECT((stack_limit & Isolate::kVMInterrupt) != 0); |
+ EXPECT_EQ(kMessageInterrupt, |
+ IsolateTestHelper::GetDeferredInterruptsMask(isolate)); |
+ EXPECT_EQ(kMessageInterrupt, |
+ IsolateTestHelper::GetDeferredInterrupts(isolate)); |
+ |
+ // Clear the vm interrupt. Message is still deferred. |
+ interrupt_bits = isolate->GetAndClearInterrupts(); |
+ EXPECT_EQ(kVMInterrupt, interrupt_bits); |
+ EXPECT_EQ(IsolateTestHelper::GetStackLimit(isolate), |
+ IsolateTestHelper::GetSavedStackLimit(isolate)); |
+ EXPECT_EQ(kMessageInterrupt, |
+ IsolateTestHelper::GetDeferredInterruptsMask(isolate)); |
+ EXPECT_EQ(kMessageInterrupt, |
+ IsolateTestHelper::GetDeferredInterrupts(isolate)); |
+ } |
+ |
+ // Restore message interrupts. Message is now pending. |
+ stack_limit = IsolateTestHelper::GetStackLimit(isolate); |
+ EXPECT_NE(stack_limit, IsolateTestHelper::GetSavedStackLimit(isolate)); |
+ EXPECT((stack_limit & Isolate::kMessageInterrupt) != 0); |
+ EXPECT_EQ(kZero, IsolateTestHelper::GetDeferredInterruptsMask(isolate)); |
+ EXPECT_EQ(kZero, IsolateTestHelper::GetDeferredInterrupts(isolate)); |
+ |
+ { |
+ // Defer message interrupts, again. The pending interrupt is deferred. |
+ NoOOBMessageScope no_msg_scope(Thread::Current()); |
+ EXPECT_EQ(IsolateTestHelper::GetStackLimit(isolate), |
+ IsolateTestHelper::GetSavedStackLimit(isolate)); |
+ EXPECT_EQ(kMessageInterrupt, |
+ IsolateTestHelper::GetDeferredInterruptsMask(isolate)); |
+ EXPECT_EQ(kMessageInterrupt, |
+ IsolateTestHelper::GetDeferredInterrupts(isolate)); |
+ } |
+ |
+ // Restore, then clear interrupts. The world is as it was. |
+ interrupt_bits = isolate->GetAndClearInterrupts(); |
+ EXPECT_EQ(kMessageInterrupt, interrupt_bits); |
+ EXPECT_EQ(IsolateTestHelper::GetStackLimit(isolate), |
+ IsolateTestHelper::GetSavedStackLimit(isolate)); |
+ EXPECT_EQ(kZero, IsolateTestHelper::GetDeferredInterruptsMask(isolate)); |
+ EXPECT_EQ(kZero, IsolateTestHelper::GetDeferredInterrupts(isolate)); |
+} |
+ |
} // namespace dart |