@@ -140,23 +140,38 @@ public void initialize(IsolateThread thread) {
140140 yellowZoneStateTL .set (thread , STATE_YELLOW_ENABLED );
141141 }
142142
143+ @ Uninterruptible (reason = "Atomically manipulating state of multiple thread local variables." )
144+ private static void updateYellowZoneState (int newState ) {
145+ int oldState = yellowZoneStateTL .get ();
146+ yellowZoneStateTL .set (newState );
147+
148+ if (newState > oldState ) {
149+ onYellowZoneMadeAvailable (oldState , newState );
150+ } else if (newState < oldState ) {
151+ onYellowZoneProtected (oldState , newState );
152+ }
153+ }
154+
143155 @ Uninterruptible (reason = "Atomically manipulating state of multiple thread local variables." )
144156 @ Override
145157 public void makeYellowZoneAvailable () {
146- /*
147- * Even though "yellow zones" and "recurring callbacks" are orthogonal features, running a
148- * recurring callback in the yellow zone is dangerous because a stack overflow in the
149- * recurring callback would then lead to a fatal error.
150- */
151- ThreadingSupportImpl .pauseRecurringCallback ("Recurring callbacks are considered user code and must not run in yellow zone" );
158+ updateYellowZoneState (yellowZoneStateTL .get () + 1 );
159+ }
152160
153- int state = yellowZoneStateTL .get ();
154- VMError .guarantee (state >= STATE_YELLOW_ENABLED , "StackOverflowSupport.disableYellowZone: Illegal state" );
161+ @ Uninterruptible (reason = "Atomically manipulating state of multiple thread local variables." )
162+ private static void onYellowZoneMadeAvailable (int oldState , int newState ) {
163+ VMError .guarantee (newState > oldState && newState > STATE_YELLOW_ENABLED , "StackOverflowCheckImpl.onYellowZoneMadeAvailable: Illegal state" );
164+
165+ if (oldState == STATE_YELLOW_ENABLED ) {
166+ /*
167+ * Even though "yellow zones" and "recurring callbacks" are orthogonal features, running
168+ * a recurring callback in the yellow zone is dangerous because a stack overflow in the
169+ * recurring callback would then lead to a fatal error.
170+ */
171+ ThreadingSupportImpl .pauseRecurringCallback ("Recurring callbacks are considered user code and must not run in yellow zone" );
155172
156- if (state == STATE_YELLOW_ENABLED ) {
157173 stackBoundaryTL .set (stackBoundaryTL .get ().subtract (Options .StackYellowZoneSize .getValue ()));
158174 }
159- yellowZoneStateTL .set (state + 1 );
160175
161176 /*
162177 * Check that after enabling the yellow zone there is actually stack space available again.
@@ -180,14 +195,16 @@ public boolean isYellowZoneAvailable() {
180195 @ Uninterruptible (reason = "Atomically manipulating state of multiple thread local variables." )
181196 @ Override
182197 public void protectYellowZone () {
183- ThreadingSupportImpl .resumeRecurringCallbackAtNextSafepoint ();
198+ updateYellowZoneState (yellowZoneStateTL .get () - 1 );
199+ }
184200
185- int state = yellowZoneStateTL .get ();
186- VMError .guarantee (state > STATE_YELLOW_ENABLED , "StackOverflowSupport.enableYellowZone: Illegal state" );
201+ @ Uninterruptible (reason = "Atomically manipulating state of multiple thread local variables." )
202+ private static void onYellowZoneProtected (int oldState , int newState ) {
203+ VMError .guarantee (newState < oldState && newState >= STATE_YELLOW_ENABLED , "StackOverflowCheckImpl.onYellowZoneProtected: Illegal state" );
187204
188- int newState = state - 1 ;
189- yellowZoneStateTL .set (newState );
190205 if (newState == STATE_YELLOW_ENABLED ) {
206+ ThreadingSupportImpl .resumeRecurringCallbackAtNextSafepoint ();
207+
191208 stackBoundaryTL .set (stackBoundaryTL .get ().add (Options .StackYellowZoneSize .getValue ()));
192209 }
193210 }
0 commit comments