Skip to content

Commit 0bb93c0

Browse files
committed
Signal low space semaphore on StackOverflowError
Related issue: #174
1 parent 1b08ecc commit 0bb93c0

File tree

3 files changed

+38
-2
lines changed

3 files changed

+38
-2
lines changed

src/de.hpi.swa.trufflesqueak/src/de/hpi/swa/trufflesqueak/image/SqueakImageContext.java

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@
7070
import de.hpi.swa.trufflesqueak.nodes.plugins.JPEGReader;
7171
import de.hpi.swa.trufflesqueak.nodes.plugins.Zip;
7272
import de.hpi.swa.trufflesqueak.nodes.plugins.ffi.InterpreterProxy;
73+
import de.hpi.swa.trufflesqueak.nodes.process.SignalSemaphoreNodeGen;
7374
import de.hpi.swa.trufflesqueak.shared.SqueakImageLocator;
7475
import de.hpi.swa.trufflesqueak.tools.SqueakMessageInterceptor;
7576
import de.hpi.swa.trufflesqueak.util.ArrayUtils;
@@ -168,6 +169,10 @@ public final class SqueakImageContext {
168169
private ContextObject interopExceptionThrowingContextPrototype;
169170
public ContextObject lastSeenContext;
170171

172+
/* Low space handling */
173+
private static final int LOW_SPACE_NUM_SKIPPED_SENDS = 4;
174+
private int lowSpaceSkippedSendsCount;
175+
171176
@CompilationFinal private ClassObject fractionClass;
172177
private PointersObject parserSharedInstance;
173178
private AbstractSqueakObject requestorSharedInstanceOrNil;
@@ -679,6 +684,34 @@ public void setSemaphore(final int index, final AbstractSqueakObject semaphore)
679684
setSpecialObject(index, semaphore);
680685
}
681686

687+
/**
688+
* Ensure the active process is saved and try to signal low space semaphore (see
689+
* #setSignalLowSpaceFlagAndSaveProcess). The JVM has just thrown a {@link StackOverflowError},
690+
* so thread stack space is limited. To avoid hitting the limit again, free up some space by
691+
* unwinding a couple of sends before actually signaling the low space semaphore.
692+
*/
693+
public StackOverflowError tryToSignalLowSpace(final VirtualFrame frame, final StackOverflowError error) {
694+
CompilerAsserts.neverPartOfCompilation();
695+
final Object lastSavedProcess = getSpecialObject(SPECIAL_OBJECT.PROCESS_SIGNALING_LOW_SPACE);
696+
if (lastSavedProcess == NilObject.SINGLETON) {
697+
setSpecialObject(SPECIAL_OBJECT.PROCESS_SIGNALING_LOW_SPACE, getActiveProcessSlow());
698+
}
699+
if (lowSpaceSkippedSendsCount < LOW_SPACE_NUM_SKIPPED_SENDS) {
700+
lowSpaceSkippedSendsCount++;
701+
throw error; // continue further up the sender chain
702+
} else {
703+
final Object lowSpaceSemaphoreOrNil = getSpecialObject(SPECIAL_OBJECT.THE_LOW_SPACE_SEMAPHORE);
704+
try {
705+
SignalSemaphoreNodeGen.executeUncached(frame, this, lowSpaceSemaphoreOrNil);
706+
} catch (final ProcessSwitch ps) {
707+
// success! reset counter and continue in new process
708+
lowSpaceSkippedSendsCount = 0;
709+
throw ps;
710+
}
711+
throw CompilerDirectives.shouldNotReachHere("Failed to signal low space semaphore.", error);
712+
}
713+
}
714+
682715
public boolean hasDisplay() {
683716
return display != null;
684717
}

src/de.hpi.swa.trufflesqueak/src/de/hpi/swa/trufflesqueak/model/layout/ObjectLayouts.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,7 @@ public static final class SPECIAL_OBJECT {
315315
public static final int CLASS_CHARACTER = 19;
316316
public static final int SELECTOR_DOES_NOT_UNDERSTAND = 20;
317317
public static final int SELECTOR_CANNOT_RETURN = 21;
318-
public static final int THE_INPUT_SEMAPHORE = 22;
318+
public static final int PROCESS_SIGNALING_LOW_SPACE = 22;
319319
public static final int SPECIAL_SELECTORS = 23;
320320
public static final int CHARACTER_TABLE = 24;
321321
public static final int SELECTOR_MUST_BE_BOOLEAN = 25;

src/de.hpi.swa.trufflesqueak/src/de/hpi/swa/trufflesqueak/nodes/ExecuteBytecodeNode.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,11 @@ public Object execute(final VirtualFrame frame, final int startPC) {
5252
try {
5353
return interpretBytecode(frame, startPC);
5454
} catch (final NonLocalReturn nlr) {
55-
/** {@link getHandleNonLocalReturnNode()} acts as {@link BranchProfile} */
55+
/* {@link getHandleNonLocalReturnNode()} acts as {@link BranchProfile} */
5656
return getHandleNonLocalReturnNode().executeHandle(frame, nlr);
57+
} catch (final StackOverflowError e) {
58+
CompilerDirectives.transferToInterpreter();
59+
throw getContext().tryToSignalLowSpace(frame, e);
5760
}
5861
}
5962

0 commit comments

Comments
 (0)