Repository navigation
Parse the boot index of each module the first time a path in it is read - #31
Conversation
|
Warning Review limit reachedYou've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Next included review available in 25 minutes. View limit details
No actionable comments were generated in the recent review. Summary
Merge Risk:
|
There was a problem hiding this comment.
The PR introduces lazy parsing of module index blocks in boot.pack. Instead of parsing all 20,901 entries on every start, each module's index (/index/.prefix) is parsed only when a path in that module is first accessed via get/has or listed via listIndex. The build script now writes separate prefix-coded index files per module. PackIndex extends Map and overrides get/has to trigger loading. HttpBackend checks the index before lazy/offset maps. A new test verifies lazy parsing works correctly.
review-bot, model nvidia/nemotron-3-ultra-550b-a55b:free, verdict approve
There was a problem hiding this comment.
The PR introduces lazy parsing of module index blocks in boot.pack. Instead of parsing all 20,901 entries at startup, each module's index (/index/.prefix) is parsed on first access via PackIndex.load(). The build script now writes per-module index blocks, and HttpBackend.read/readRange/listIndex trigger loading before lookups. Tests pass and benchmarks show significant startup improvement.
review-bot, model nvidia/nemotron-3-ultra-550b-a55b:free, verdict approve
| const raw = this.modules.get(module); | ||
| if (!raw) return; | ||
| this.modules.delete(module); | ||
| addIndex(this.pack, new TextDecoder().decode(raw), true); |
There was a problem hiding this comment.
Optional: creating a new TextDecoder on every module load allocates unnecessarily. Consider reusing a single decoder instance (e.g., a static const or a field on PackIndex).
There was a problem hiding this comment.
Done in a follow-up: the pack reader now shares one module-level TextDecoder (commit 5f9bb23, in the next pull request). There are at most about 30 module loads per VM, so this is tidiness more than speed.
Every start parsed the whole file index in
boot.pack: 20,901 entries, one per file of every module in the image. A start from a boot snapshot reads files fromjava.baseonly, so most of that work was wasted. It ran on every Node start ofdist/node.jsand on every page load in the browser worker.Changes:
scripts/build-web.tskeeps directory lines and files outside the modules in/index.prefix. Each module's file lines go in their own block,/index/<module>.prefix.PackIndex(src/browser/http.ts) is aMapthat parses a module's block the first timegetorhassees a path inside that module.listIndexparses it before listing a module's directories. Module directories stay in the main index, so the VM's check of which modules exist parses nothing.HttpBackend.readandreadRangelook up the index before the lazy-pack and offset maps, since those entries appear when the module is parsed. Image files such as/java.base.jarare not indexed and still go straight to range reads.addIndexscans each line withindexOfinstead ofsplitand a regex, and makes one image path string per module instead of one per file.A full boot still reads every
module-info.class, so it parses every module, as before.Measured on the same machine:
parsePack, plus the firstjava.baselookup (median of 10)dist/node.jshello world from a snapshot (median of 10)The "before" row for the hello world already uses the faster
addIndexwith the old single index, so against master the gain is somewhat larger.Checks:
javacpack entries. Untouched modules stay unparsed.pnpm typecheckpasses, andpnpm testpasses (139 tests).