Skip to content

Dist: give the runtime its base CDS archive, drop the AppCDS archive that was never made - #1386

Merged
Frotty merged 2 commits into
masterfrom
appcds-base-archive
Oct 8, 2026
Merged

Frotty merged 2 commits into
masterfrom
appcds-base-archive

Conversation

@Frotty

@Frotty Frotty commented Oct 8, 2026 •

Copy link
Copy Markdown
Member

What

The distribution has always tried to ship an AppCDS archive for the language server, and it never worked.

  • generateAppCdsArchive made the archive with -XX:ArchiveClassesAtExit. Such an archive sits on the base archive of the runtime, and the slim jlink runtime had none (no classes.jsa next to jvm.dll), so the JVM could not write it. The task was best effort and only warned.
  • Nothing passed the archive to a JVM either: not wurst4vscode, not grill, not the launchers.
  • An installed runtime confirms it: no .jsa anywhere under ~/.wurst.

This change:

  • runs jlink with --generate-cds-archive and leaves the 14 MB classes_nocoops.jsa out of the copy (it is for heaps above 32 GB);
  • makes assembleSlimCompilerDist fail when the runtime has no classes.jsa (bin/server or lib/server; macOS copies a full JDK, which has one), because the failure was silent;
  • removes the dead task and its -languageServerAppCdsTrain option (RunArgs, Main, LanguageServerStarter, RunArgsTests);
  • documents the contract in AGENTS.md.

The archive of the application itself cannot be shipped: the JVM refuses an archive for another jar path or modification time (I saw the path mismatch). It is written by the JVM on the user's machine, which wurst4vscode now does (companion PR: wurstscript/wurst4vscode#153).

Measured

Language server, start to the initial build being ready, interleaved, median of four starts, with the extension's flags (-XX:+AutoCreateSharedArchive -XX:SharedArchiveFile=… -Xlog:disable):

no archives (today) base archive only base and application archive
small project (stdlib, one file) 4.39 s 4.42 s 3.71 s (−16%)
castle fight 18.98 s 19.25 s 17.28 s (−9%)

The base archive alone changes nothing; it is what makes the application archive possible. The first session pays about 1.2 s more when it ends (it writes 28 MB). With the real distribution built from this branch: 3.5 s then 2.75 s on the small project.

Two things the JVM does that this relies on being handled by the caller (done in the extension): it does not replace an archive that no longer fits (a new jar), and it exits with a crash status when it cannot write the archive.

Checks

  • ./gradlew assembleSlimCompilerDist builds on Windows: runtime has bin/server/classes.jsa, no classes_nocoops.jsa, guard passes.
  • RunArgsTests, LanguageWorkerTest.
  • Not run here: the Linux and macOS distributions (CI builds them; the guard fails the build if a runtime lacks the archive).

…that was never made

The distribution tried to ship an AppCDS archive for the language server
(generateAppCdsArchive, -XX:ArchiveClassesAtExit). An archive like that sits on
the base archive of the runtime, and the slim runtime built by jlink had none
(no classes.jsa next to jvm.dll), so the JVM could not write it, the task only
warned, and nothing ever passed the archive to a JVM anyway. An installed
runtime confirms it: no .jsa anywhere.

jlink now runs with --generate-cds-archive, the 14 MB variant for heaps above
32 GB is left out of the copy, and assembleSlimCompilerDist fails if the
runtime has no classes.jsa (bin/server or lib/server; macOS copies a full JDK,
which has one), because the failure was silent before. The dead task and the
-languageServerAppCdsTrain option it used are removed.

The archive of the application is written by the JVM itself on the user's
machine: wurst4vscode starts the server with -XX:+AutoCreateSharedArchive. An
archive recorded at build time cannot be shipped, as the JVM refuses one for
another jar path or modification time.

Language server start to ready, interleaved, median of four starts:
  small project   no archives 4.39 s, base archive only 4.42 s, both 3.71 s
  castle fight    no archives 18.98 s, base archive only 19.25 s, both 17.28 s
The base archive alone changes nothing; it is what makes the second possible.
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-08T12:28:09.584831Z e711ad3 Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: dfe57916e5

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread de.peeeq.wurstscript/deploy.gradle
jlink writes the archive with a JVM of its own, and that JVM takes on the
object header mode of the options it is started with. The CI exports
JAVA_TOOL_OPTIONS=-XX:+UseCompactObjectHeaders for the tests, so jlink made
only classes_coh.jsa and classes_nocoops_coh.jsa, no classes.jsa, and the guard
added by this change failed the master build (reproduced with that environment
and a clean dist folder: "The runtime has no base CDS archive"). A runtime
which is started without the option, as the language server and grill do,
cannot use a _coh archive.

The jlink step now runs without JAVA_TOOL_OPTIONS, _JAVA_OPTIONS and
JDK_JAVA_OPTIONS. The guard is also made on the jlink image itself: the dist
folder is only added to by the copy, so an archive left by an earlier build
could hide a missing one there.

Under that environment, from a clean dist folder: classes.jsa is made and ends
up in the runtime, classes_nocoops.jsa is left out.
@Frotty

Frotty commented Oct 8, 2026

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. You're on a roll.

Reviewed commit: e711ad3fe0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@Frotty
Frotty merged commit 2aea669 into master Oct 8, 2026
3 checks passed
@Frotty
Frotty deleted the appcds-base-archive branch October 8, 2026 12:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant