-
Notifications
You must be signed in to change notification settings - Fork 435
ParparVM collector: long-shift codegen fix, live-set heap goal, and an arm64 parallel-mark run #5717
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
ParparVM collector: long-shift codegen fix, live-set heap goal, and an arm64 parallel-mark run #5717
Changes from all commits
Commits
Show all changes
25 commits
Select commit
Hold shift + click to select a range
024b51d
Shift a long CONSTANT as a long, not as an int
shai-almog 4502d7f
Size the heap goal against the live set, not against a constant
shai-almog 3ce4561
Run the GC suite against a parallel marker on arm64 Linux
shai-almog 6791382
Address review: park through the handshake, reach every test, bound t…
shai-almog 169f2a1
Keep low memory on the constant trigger, and let the floor raise as w…
shai-almog 7269ca8
Let the live-set floor only raise the trigger, never lower it
shai-almog e4cddd7
Close the assist mark-termination race and make the alloc profile exa…
shai-almog 1493d4b
Record why the alloc profile and allocatedKb are not comparable
shai-almog 70dad8d
Enforce the trigger floor in the survival dead band, and stop the pro…
shai-almog 2ef47c8
Give the allocation profile a size histogram
shai-almog 9b80656
Keep memory pressure an upper bound on the live-set trigger floor
shai-almog 05b6bec
Claim allocation-size buckets with a compare-exchange
shai-almog daa1bab
Trigger the parallel-mark matrix for everything it actually runs
shai-almog 409ee59
Let a collapsed live set take the trigger floor down with it
shai-almog 78150e7
Believe a live-set collapse only when the sweep actually saw the heap
shai-almog 9bb011e
Shift left through the unsigned type, and publish profiled class poin…
shai-almog f28e2a8
Make the profile's highest-seen class id an atomic fetch-max
shai-almog 3d0209c
Ask only a major sweep about the live set, and ask it for all of it
shai-almog 99ba28b
Drop the live-set floor: this collector cannot measure a live set
shai-almog b1d7f46
Scale the quiet-sweep cutoff with the trigger in force
shai-almog d28d451
Let low-memory mode lower the trigger, never raise it
shai-almog 38d9fd2
Trace page release in the GC suite so the next page-floor failure exp…
shai-almog 37656fb
Scope the page-release tracing to the test that needs it
shai-almog d4c5354
Snapshot the alloc report, drop the orphaned growth knob, keep the re…
shai-almog 5ad2848
Keep the allocation profile working: 8192 slots, live counters, docum…
shai-almog File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,138 @@ | ||
| # Runs the collector's own tests against a PARALLEL marker on real arm64 Linux. | ||
| # | ||
| # gcMarkResolveThreadCount compiles the mark pool out by default, and the comment | ||
| # there reads as a standing verdict: arm64 Linux corrupted the heap with the pool | ||
| # on, and "a SECOND ordering hole remains somewhere in the branch-only | ||
| # parallel-GC work". Read in isolation that says parallel marking is broken. | ||
| # | ||
| # The history says something narrower. Inside PR #5327 the sequence was: | ||
| # | ||
| # Jul 3 30257f5234 acquire-load the mark word in parallel marking (arm64 corruption) | ||
| # Jul 3 3ad67971e9 default parallel marking to serial -- "arm64 isolation experiment" | ||
| # Jul 4 78752a21a2 gcMarkObject must reject freed BiBOP slots | ||
| # Jul 5 ff7a1f1947 SATB write barrier, closing the concurrent-mark cross-thread race | ||
| # Jul 5 017168581c drain grace-object subtrees before sweep (swept-while-reachable) | ||
| # Jul 5 60ef4c7d85 belt pass: guarantee mark-drain completeness before sweep | ||
| # Jul 5 4888b66cd0 stop-the-world final mark, looped to a fixpoint | ||
| # Jul 6 c6144beb7a object-bearing frameless OFF: "unsound under conservative GC on arm64" | ||
| # Jul 10 ff93b1c415 clazz-registry invariant (arm64 SIGSEGV in cn1GcRegisterClazz) | ||
| # | ||
| # The experiment that produced the comment ran on Jul 3. Every mechanism that | ||
| # makes concurrent marking sound arrived after it -- the SATB barrier most of | ||
| # all, which did not exist when the conclusion was drawn -- and at least one | ||
| # other arm64 heap corruptor was found and disabled on Jul 6 that had nothing to | ||
| # do with the mark pool. Parallel marking was never re-tested at any point after | ||
| # Jul 3, and gcMarkDrainParallel, gcMarkObject, gcMarkFlushLocal and | ||
| # gcMarkWorklistPush have all been reworked since. | ||
| # | ||
| # So the comment records what was believed on one day, before the fixes, and the | ||
| # switch under it was never revisited. This workflow is how that gets settled | ||
| # with evidence instead of archaeology. | ||
| # | ||
| # The cost of leaving it alone is measured. On the GcPause benchmark -- one | ||
| # mutator, 20M short-lived objects, a 4096-node live set -- the worst mutator | ||
| # pause is 2.2-3.3s with one marker and 0.3-0.9s with four, against Go's 20ms on | ||
| # the identical loop. Median and p99 already match Go at 32ns/64ns, so the single | ||
| # marker is a large part of why the tail loses. | ||
| # | ||
| # It could not be reproduced on an Apple-silicon podman guest: GcPause ran clean | ||
| # with four markers, and a multi-threaded stress with graph rewiring and | ||
| # cross-thread resurrection ran clean too -- but that second result proves | ||
| # nothing, because the same stress passes with the SATB barrier compiled out | ||
| # (-DCN1_DISABLE_SATB) and under -DCN1_GC_VERIFY at 6.6M references checked. A | ||
| # four-CPU hypervisor guest is a weak generator of store interleavings. These | ||
| # runners are native arm64 hardware, which is where the corruption was seen. | ||
| # | ||
| # NOTHING HERE CHANGES A DEFAULT. The pool is switched on for this workflow only, | ||
| # through CN1_TEST_EXTRA_CFLAGS; every other build still compiles it out. | ||
| name: ParparVM parallel mark (arm64 Linux) | ||
|
|
||
| on: | ||
| workflow_dispatch: | ||
| pull_request: | ||
| paths: | ||
| - 'vm/ByteCodeTranslator/src/cn1_globals.m' | ||
| - 'vm/ByteCodeTranslator/src/cn1_globals.h' | ||
| # One entry per test the matrix below runs, plus the helper that injects | ||
| # CN1_TEST_EXTRA_CFLAGS. Keep this list and the -Dtest list in sync: a glob | ||
| # is what went wrong here, because Gc*.java matched three of the six tests | ||
| # and silently let the other three -- and every change to the flag plumbing | ||
| # every arm depends on to select its marker count -- land without the | ||
| # workflow that exercises them ever running. | ||
| - 'vm/tests/src/test/java/com/codename1/tools/translator/GcHeapIntegrityIntegrationTest.java' | ||
| - 'vm/tests/src/test/java/com/codename1/tools/translator/GcOverflowSpiralIntegrationTest.java' | ||
| - 'vm/tests/src/test/java/com/codename1/tools/translator/GcUncooperativeThreadIntegrationTest.java' | ||
| - 'vm/tests/src/test/java/com/codename1/tools/translator/LargeArrayGcIntegrationTest.java' | ||
| - 'vm/tests/src/test/java/com/codename1/tools/translator/LowMemoryThrottleIntegrationTest.java' | ||
| - 'vm/tests/src/test/java/com/codename1/tools/translator/BibopPageFloorIntegrationTest.java' | ||
| - 'vm/tests/src/test/java/com/codename1/tools/translator/CompilerHelper.java' | ||
| - '.github/workflows/parparvm-parallel-mark.yml' | ||
|
|
||
| concurrency: | ||
| group: parparvm-parallel-mark-${{ github.ref }} | ||
| cancel-in-progress: true | ||
|
|
||
| jobs: | ||
| gc-suite: | ||
| name: GC suite (${{ matrix.markers }} marker(s), ${{ matrix.arch }}) | ||
| runs-on: ${{ matrix.runner }} | ||
| timeout-minutes: 90 | ||
| strategy: | ||
| fail-fast: false | ||
| matrix: | ||
| include: | ||
| # The control. A failure here is not the parallel path and the arm below | ||
| # cannot be read as evidence of anything until this one is green. | ||
| - arch: arm64 | ||
| runner: ubuntu-24.04-arm | ||
| markers: 1 | ||
| cflags: '' | ||
| - arch: arm64 | ||
| runner: ubuntu-24.04-arm | ||
| markers: 4 | ||
| cflags: '-DCN1_GC_MARK_THREADS=4' | ||
| # x64 as well, so a failure can be attributed to the architecture rather | ||
| # than to the pool itself. | ||
| - arch: x64 | ||
| runner: ubuntu-latest | ||
| markers: 4 | ||
| cflags: '-DCN1_GC_MARK_THREADS=4' | ||
| steps: | ||
| - name: Check out repository | ||
| uses: actions/checkout@v6 | ||
|
|
||
| - name: Set up JDK 8 | ||
| uses: actions/setup-java@v4 | ||
| with: | ||
| distribution: temurin | ||
| java-version: '8' | ||
|
|
||
| - name: Install clang and cmake | ||
| run: bash scripts/ci/apt-get-install.sh clang cmake | ||
|
|
||
| # Package first, then test with -am: the integration tests reload the | ||
| # translator from its PACKAGED jar, and the reactor is what resolves the | ||
| # dependency. Packaging alone without -am (and without install) leaves | ||
| # nothing for the tests module to resolve against, which is how the first | ||
| # revision of this workflow failed on all three arms including the control. | ||
| # This mirrors parparvm-tests.yml. | ||
| - name: Build JavaAPI and the translator | ||
| run: mvn -B clean package -pl JavaAPI -am -DskipTests | ||
| working-directory: vm | ||
|
|
||
| - name: GC suite | ||
| env: | ||
| CN1_TEST_EXTRA_CFLAGS: ${{ matrix.cflags }} | ||
| run: | | ||
| mvn -B test -pl tests -am \ | ||
| -Dsurefire.failIfNoSpecifiedTests=false \ | ||
| -Dtest='GcHeapIntegrityIntegrationTest,GcOverflowSpiralIntegrationTest,GcUncooperativeThreadIntegrationTest,LargeArrayGcIntegrationTest,LowMemoryThrottleIntegrationTest,BibopPageFloorIntegrationTest' | ||
| working-directory: vm | ||
|
|
||
| - name: Surefire reports | ||
| if: always() | ||
| uses: actions/upload-artifact@v4 | ||
| with: | ||
| name: gc-suite-${{ matrix.arch }}-${{ matrix.markers }}marker | ||
| path: vm/tests/target/surefire-reports/ | ||
| if-no-files-found: ignore | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.