> Prior to this patch, the `StackYellowPages` and `StackRedPages`
> influenced the total reserved stack memory, but they didn't change the
> minimum stack size specified as required by HotSpot to Windows. This
> patch adds the call to `SetThreadStackGuarantee()` to set the minimum
> stack size.
>
> The key change here is that the argument to `SetThreadStackGuarantee()`
> is set to one less than the total number of yellow pages. The one less
> page is because Windows uses a guard page (access to which tells Windows
> to commit more stack pages); in the terminal case, we want the guard
> page to coincide with the top-most yellow stack page, thus leaving all
> except one yellow page available as the stack size.
>
> Importantly, however, we do not use the red page count as the argument
> to `SetThreadStackGurantee()`, since the red stack pages are unavailable
> for handling recoverable overflows. The red page count impacts the
> _total reserved_ stack size, just not the _minimum_ stack size. Still,
> forcing the red stack page count to be included into the computation of
> the argument to `SetThreadStackGurantee()` causes HotSpot to fail with
> the assertion `assert(!in_vm) failed: Undersized StackShadowPages`,
> since Windows is unable to commit more stack pages due to the minimum
> stack size now being larger than just the yellow page count minus one.
>
> The accompanying test passes zero to `SetThreadStackGuarantee()` to
> probe the current minimum stack size, which we then compare against the
> expected size based on the yellow page count. The same test fails
> without this patch on both Windows/x64 and on Windows/ARM64.
>
> Validated this patch by running through all tier 1, 2, and 3 HotSpot
> jtreg tests on Windows/x64 and Windows/ARM64 in FastDebug config.
>
> ---------
> - [x] I confirm that I make this contribution in accordance with the [OpenJDK
> Interim AI Policy](https://openjdk.org/legal/ai).
Ashay Rane has updated the pull request incrementally with eight additional
commits since the last revision:
- [Section 4.6] Add supporting tests
- TestWindowsStackOverflow.java tests both recoverable and unrecoverable
overflows.
- In particular, since recoverable overflow handling has two entry
points (first overflow using EXCEPTION_STACK_OVERFLOW and subsequent
overflows using EXCEPTION_ACCESS_VIOLATION), this test induces
multiple recoverable stack overflows.
- The unrecoverable overflow test triggers a separate JVM execution that
executes native code that bangs into the red zone. The triggering JVM
then checks the return code and the output message.
- TestWindowsStackPages.java makes the older TestWindowsStackYellowPages
test more broad, by checking the default and configurable values for
both Red and Yellow pages.
- [Section 4.5.2] Match default stack size across OSes on AArch64
Both Linux and macOS on AArch64 use a 2MB stack. Without this patch,
the SOEDeeplyNestedBlockTest.java test fails on Windows/ARM64.
- [Section 4.5.1] Include the allocated frame in the stack bang
- [Section 4.4] Handle Subsequent Stack Overflows
Update handler for EXCEPTION_ACCESS_VIOLATION to report fatal versus
recoverable overflow errors depending on red zone or yellow zone memory
access
- [Section 4.3] Handle Windows' Stack Overflow Exceptions
- Change protection of guard zone to use PAGE_NOACCESS instead of
PAGE_GUARD
- Update handler for EXCEPTION_STACK_OVERFLOW to detect nested overflow
exceptions
- Protect the red zone with PAGE_NOACCESS to detect runaway stack usage
- If thread is executing Java code, report a StackOverflowError
exception; for native or VM threads, continue execution
- [Section 4.2] Match HotSpot's Guard Zone with Windows' Stack Guarantee
- Set the (logical) yellow zone size to be the same for Windows as all
other OSes
- Request the stack guarantee based on the red page count and the
logical yellow page count
- If the actual stack guarantee is larger than the requested value, then
expand the yellow zone (see `stack_yellow_reserved_zone_size()`)
- Update the TestWindowsStackYellowPages.java test to reflect the
updated minimum yellow page count
- [Section 4.1] Grow stack on demand
- Update handler for EXCEPTION_ACCESS_VIOLATION to detect memory
accesses in the usable stack but beyond `StackLimit`
- Sequentially touch pages until `StackLimit` grows to include the page
that corresponds to the faulting memory access.
- Revert all changes so far.
-------------
Changes:
- all: https://git.openjdk.org/jdk/pull/32365/files
- new: https://git.openjdk.org/jdk/pull/32365/files/8ce162dc..8189a507
Webrevs:
- full: https://webrevs.openjdk.org/?repo=jdk&pr=32365&range=07
- incr: https://webrevs.openjdk.org/?repo=jdk&pr=32365&range=06-07
Stats: 600 lines in 16 files changed: 353 ins; 192 del; 55 mod
Patch: https://git.openjdk.org/jdk/pull/32365.diff
Fetch: git fetch https://git.openjdk.org/jdk.git pull/32365/head:pull/32365
PR: https://git.openjdk.org/jdk/pull/32365