Skip to content

Commit a6e156e

Browse files
committed
WiP: refactor stack overflow checks for virtual threads.
1 parent 9bf3a91 commit a6e156e

File tree

1 file changed

+32
-15
lines changed

1 file changed

+32
-15
lines changed

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/graal/snippets/StackOverflowCheckImpl.java

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)