public interface StackOverflowCheck
StackOverflowCheckImpl
.
Substrate VM uses explicit stack overflow checks: at the beginning of every method, the current
stack pointer is compared with the allowed boundary of the stack pointer. The boundary is stored
in a thread local variable
. So the fast-path cost of a stack overflow
check is one memory load, a comparison, and a conditional branch instruction.
When a stack overflow is detected, a StackOverflowError
is thrown. Allocating the error
object, filling in the stack trace, and performing the stack unwinding to find the matching
exception handler is all implemented in Java code too. Therefore, a stack overflow must be
detected while there is still sufficient stack memory available to execute these Java functions
(and they of course must not recursively throw a StackOverflowError
again). Therefore, we
designate two zones toward the end of the stack: the "yellow zone" and the "red zone".
The yellow zone can be made available to regular Java code by modifying the thread local variable
that holds the boundary. Calling StackOverflowCheck.makeYellowZoneAvailable()
makes the yellow zone
available, and a matching call of StackOverflowCheck.protectYellowZone()
makes the yellow zone unavailable
again for usage. The yellow zone is fairly commonly used by Substrate VM Java code, but it is not
intended for application code, i.e., the yellow zone should not be made available in places where
the VM calls back to application code. VMOperation
such as the GC always make the yellow
zone available: a StackOverflowError
during GC would be a fatal error because
interrupting GC leaves the heap in an inconsistent state. So it is better to make the yellow zone
available upfront. The yellow zone is sized (by empirical measurement and testing) so that a GC
can be executed in it.
The red zone is reserved for last-resort error handling on the Java and C side. Code marked as
Uninterruptible
can use the red zone because such methods do not start with a stack
overflow check. C code can also use the red zone, e.g., for exiting the VM in case of a fatal
error. The red zone is small and sized just to do something slightly better than a segmentation
fault.Modifier and Type | Interface and Description |
---|---|
static class |
StackOverflowCheck.Options |
static interface |
StackOverflowCheck.OSSupport
Operating system abstraction: The OS needs to provide end of the physical stack memory.
|
Modifier and Type | Method and Description |
---|---|
void |
disableStackOverflowChecksForFatalError()
Disables all stack overflow checks for this thread.
|
void |
initialize(org.graalvm.nativeimage.IsolateThread thread)
Called for each thread when the thread is attached to the VM.
|
void |
makeYellowZoneAvailable()
Make the yellow zone of the stack available for usage.
|
void |
protectYellowZone()
The inverse operation of
StackOverflowCheck.makeYellowZoneAvailable() . |
static StackOverflowCheck |
singleton() |
int |
yellowAndRedZoneSize()
Returns the combined size of the yellow and red zone.
|
static StackOverflowCheck singleton()
void initialize(org.graalvm.nativeimage.IsolateThread thread)
void makeYellowZoneAvailable()
StackOverflowCheck.protectYellowZone()
. Nested calls are supported: if the yellow zone is
already available, this function is a no-op.void protectYellowZone()
StackOverflowCheck.makeYellowZoneAvailable()
.int yellowAndRedZoneSize()
void disableStackOverflowChecksForFatalError()