Expand description
autoload_cache submodule.
rkyv-backed bytecode cache for autoload functions.
Single-file shard at ~/.zshrs/autoloads.rkyv, keyed by function
name. zshrs-original — no C counterpart, so the design rule here
is correctness first: an entry that cannot be PROVEN to describe the
body about to be installed is a miss.
Storage layout (rkyv archived): AutoloadShard { header: { magic, format_version, zshrs_version, pointer_width, built_at_secs }, entries: HashMap<function_name, AutoloadEntry>, }
Inner chunk_blob is bincode-encoded fusevm::Chunk (same constraint as
crate::script_cache module — fusevm::Chunk is upstream and only derives serde).
§What identifies an entry
Three things have to match before a chunk may be run, because a chunk is a function of all three:
- the producing binary, as
(mtime, len)ofcurrent_exe(). Bytecode is not a stable interchange format: the builtin index table and the opcode lowering both move between builds, so a chunk emitted by a differentzshrsis meaningless here even whenzshrs_versionmatches. It routinely does match — a debug build and the installed release build share0.12.36— which is why the version string cannot carry this check. - the resolved fpath directory, because the same function name
lives in several directories on a real
$fpathand the cache is keyed by name alone. - the exact definition text, as a SHA-256 of the very string
that will be compiled. Not a
statof<dir>/<name>: the body the loader installs can come out of adir.zwcdigest instead of that file, and stamping a path that is not the source is how a chunk built from one text gets served for another.
The previous scheme stamped (mtime, len) of <dir>/<name> and
treated the binary check as one-directional (cached < current =
stale), so a chunk written by a NEWER binary was served to an older
one. On the corpus this was built for that meant _megacomplete
being “installed” from a chunk that never defined it, and every
<TAB> producing _megacomplete: function not defined by file and
zero matches.
Bulk-write: compinit prewarms 16k+ autoload bytecodes in one go. Per-batch
shard rewrites (the SQLite-era pattern) would re-serialize 16k entries
160 times. Instead put_many accumulates all entries in memory and
writes the shard once. The single-add put_one path remains for the
cold-start case where one autoload at a time is compiled by the
interactive shell.
The on-disk shape mirrors ScriptShard — same header,
same magic-version-pointer_width discipline, same atomic-rename writes.
Structs§
- Archived
Autoload Entry - An archived
AutoloadEntry - Archived
Autoload Shard - An archived
AutoloadShard - Archived
File Stamp - An archived
FileStamp - Archived
Resolved Load - An archived
ResolvedLoad - Archived
Shard Header - An archived
ShardHeader - Autoload
Cache AutoloadCache— see fields for layout.- Autoload
Entry AutoloadEntry— see fields for layout.- Autoload
Entry Resolver - The resolver for an archived
AutoloadEntry - Autoload
Shard AutoloadShard— see fields for layout.- Autoload
Shard Resolver - The resolver for an archived
AutoloadShard - File
Stamp - One file’s identity at resolution time.
- File
Stamp Resolver - The resolver for an archived
FileStamp - Mmapped
Shard MmappedShard— see fields for layout.- Resolved
Load - The outcome of resolving and reading one autoload, as
loadautofnand the registration step computed it: the bodygetfpfuncled to and the definition text that body registers as. - Resolved
Load Resolver - The resolver for an archived
ResolvedLoad - Shard
Header ShardHeader— see fields for layout.- Shard
Header Resolver - The resolver for an archived
ShardHeader
Constants§
- SHARD_
FORMAT_ VERSION SHARD_FORMAT_VERSIONconstant.- SHARD_
MAGIC - “ZRAL” little-endian.
Statics§
- CACHE
CACHEstatic.
Functions§
- cache_
enabled cache_enabled— see implementation. Honors the process-localscript_cache::CACHE_DISABLEDAtomicBool first so parity-mode init can disable caches without exportingZSHRS_CACHE=0(which would otherwise leak into${(k)parameters}).- cached_
names cached_names— see implementation.- clear
clear— see implementation.- commit_
search - The registration step turned the staged body into
registered; record the whole resolution for the entry that compile is about to write. - default_
cache_ path default_cache_path— see implementation.- entry_
count entry_count— see implementation.- install_
atexit_ flush - Register [
atexit_flush_pending]. Idempotent; call once frommain. - note_
resolved - Remember
resolvedforname; it is written with the next write of that name’s entry (put_one/put_many). - record_
port_ probe - Record what a native-completer probe found:
namelives indirand its file readsbody. Stored as a resolution with no registration and no chunk, whichtry_port_bodyandtry_source_dirserve and the loader ignores. - source_
digest - SHA-256 of the definition text a chunk was compiled from.
- stage_
hit loadautofninstalledresolved.bodyfrom the shard.- stage_
search loadautofnsearched$fpathand readbodyout ofdir.- stamp_
candidates - The identity of every file
getfpfunccould have read fornameindir: the plain file, the per-function dump and the directory digest (c:Src/parse.c:3725try_dump_filetries<dir>.zwcand<dir>/<name>.zwcbefore<dir>/<name>). - stats
stats— see implementation.- take_
hit - The stored registration for a body
loadautofntook from the shard:(registered, from_wordcode, parse_failed).Noneunlessbodyand the ksh-style decision are the ones it was registered under. - try_
flush_ pending - Write out everything
put_onebuffered. SeeAutoloadCache::flush_pending. Called frompreprompt()(the batch boundary for an interactive shell — every autoload a command or a<TAB>triggered lands in one write) and fromzexit(the boundary for a script, which never reaches a prompt). - try_
load - Raw presence probe for
dbview autoloads <name>. SeeAutoloadCache::get. - try_
load_ for_ source - Execution-path lookup: the compiled definition program for
name, valid only for this exact directory and definition text. - try_
port_ body - The directory and file text for a native completer
name, read from the shard: what agetfpfuncexistence probe plus a read of<dir>/<name>would return.Nonefor a.zwc-resolved entry (its body is a deparse, not the file) and for anything stale. - try_
put_ many - Bulk write-through for the prewarm path. See
AutoloadCache::put_many. - try_
remove - Drop a proven-wrong entry. See
AutoloadCache::remove. - try_
resolve - The directory and resolved body for
name, read from the shard instead of searching$fpathand reading the file. - try_
save_ one - Write-through after a real autoload compile.
- try_
source_ dir - The
$fpathdirectory the entry fornamewas resolved from, while that directory is still onfpathand still holds the file. The shard-backed answer to agetfpfuncexistence probe (test_only), with the same caveat astry_resolveabout a later shadowing file.