@@ -140,23 +140,44 @@ public void initialize(IsolateThread thread) {
140140 yellowZoneStateTL .set (thread , STATE_YELLOW_ENABLED );
141141 }
142142
143+ @ Override
144+ public int getState () {
145+ return yellowZoneStateTL .get ();
146+ }
147+
148+ @ Override
149+ @ Uninterruptible (reason = "Atomically manipulating state of multiple thread local variables." )
150+ public void setState (int newState ) {
151+ int oldState = yellowZoneStateTL .get ();
152+ yellowZoneStateTL .set (newState );
153+
154+ if (newState > oldState ) {
155+ onYellowZoneMadeAvailable (oldState , newState );
156+ } else if (newState < oldState ) {
157+ onYellowZoneProtected (oldState , newState );
158+ }
159+ }
160+
143161 @ Uninterruptible (reason = "Atomically manipulating state of multiple thread local variables." )
144162 @ Override
145163 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" );
164+ setState (yellowZoneStateTL .get () + 1 );
165+ }
152166
153- int state = yellowZoneStateTL .get ();
154- VMError .guarantee (state >= STATE_YELLOW_ENABLED , "StackOverflowSupport.disableYellowZone: Illegal state" );
167+ @ Uninterruptible (reason = "Atomically manipulating state of multiple thread local variables." )
168+ private static void onYellowZoneMadeAvailable (int oldState , int newState ) {
169+ VMError .guarantee (newState > oldState && newState > STATE_YELLOW_ENABLED , "StackOverflowCheckImpl.onYellowZoneMadeAvailable: Illegal state" );
170+
171+ if (oldState == STATE_YELLOW_ENABLED ) {
172+ /*
173+ * Even though "yellow zones" and "recurring callbacks" are orthogonal features, running
174+ * a recurring callback in the yellow zone is dangerous because a stack overflow in the
175+ * recurring callback would then lead to a fatal error.
176+ */
177+ ThreadingSupportImpl .pauseRecurringCallback ("Recurring callbacks are considered user code and must not run in yellow zone" );
155178
156- if (state == STATE_YELLOW_ENABLED ) {
157179 stackBoundaryTL .set (stackBoundaryTL .get ().subtract (Options .StackYellowZoneSize .getValue ()));
158180 }
159- yellowZoneStateTL .set (state + 1 );
160181
161182 /*
162183 * Check that after enabling the yellow zone there is actually stack space available again.
@@ -180,14 +201,16 @@ public boolean isYellowZoneAvailable() {
180201 @ Uninterruptible (reason = "Atomically manipulating state of multiple thread local variables." )
181202 @ Override
182203 public void protectYellowZone () {
183- ThreadingSupportImpl .resumeRecurringCallbackAtNextSafepoint ();
204+ setState (yellowZoneStateTL .get () - 1 );
205+ }
184206
185- int state = yellowZoneStateTL .get ();
186- VMError .guarantee (state > STATE_YELLOW_ENABLED , "StackOverflowSupport.enableYellowZone: Illegal state" );
207+ @ Uninterruptible (reason = "Atomically manipulating state of multiple thread local variables." )
208+ private static void onYellowZoneProtected (int oldState , int newState ) {
209+ VMError .guarantee (newState < oldState && newState >= STATE_YELLOW_ENABLED , "StackOverflowCheckImpl.onYellowZoneProtected: Illegal state" );
187210
188- int newState = state - 1 ;
189- yellowZoneStateTL .set (newState );
190211 if (newState == STATE_YELLOW_ENABLED ) {
212+ ThreadingSupportImpl .resumeRecurringCallbackAtNextSafepoint ();
213+
191214 stackBoundaryTL .set (stackBoundaryTL .get ().add (Options .StackYellowZoneSize .getValue ()));
192215 }
193216 }
0 commit comments