Repository navigation
serialize: a builtin module's cache hash covers its content - #4190
Merged
Merged
Conversation
aleksisch
force-pushed
the
aleksisch/strengthen-serialization
branch
from
October 2, 2026 19:57
a3c74d7 to
2af965c
Compare
aleksisch
force-pushed
the
aleksisch/strengthen-serialization
branch
5 times, most recently
from
October 5, 2026 10:28
d09228a to
2aca2b8
Compare
TypeDecl::getSemanticHash and TypeDecl::getOwnSemanticHash each hashed an enumeration type inline - its mangled name, base type, and every entry's name and folded value. Both call Enumeration::getOwnSemanticHash now, which feeds the same bytes in the same order, so every hash built on a TypeDecl keeps its value.
A record pinned each builtin module by a hash of its function mangled names only, so a changed signature, default, flag, constant, enum, structure or handled type served a stale record. Module::getOwnSemanticHash hashes all of it, computed once per serializer. dasbind hashes its C++ content once at construction, before a registrar's compile adds [extern] proxies. A hash miss now resumes like any failed record and the cache rewrites itself.
aleksisch
force-pushed
the
aleksisch/strengthen-serialization
branch
from
October 5, 2026 15:28
2aca2b8 to
0fc9e80
Compare
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Behavior change: an existing module cache misses once per builtin module whose hash now covers more, and rewrites itself on that run.
Why. A cache record pinned each builtin module by a hash of its function mangled names only. A changed result type, argument name, default, side effect, constant, enum or handled-type layout served a stale record. A hash miss was also treated as drift and never rewritten, so a real change left the cache partial forever.
What changes.
[extern]proxies, whose count grows during a run.Observable behavior.
[extern]registrars -> before: reparsed every run; after: served.Where to look.
Module::getOwnSemanticHashinast_module.cpp, dasbind's override inmodule_builtin_dasbind.cpp,AstSerializer::builtinHashinmodule_builtin_ast_serialize.cpp.Cost. The full hash is computed once per builtin module per serializer, then served from the serializer's cache. Measured on a script requiring 26 daslib modules (60 records, 10 builtin modules), warm run, Release, Linux x64:
ast_core$rtti_coresqlitemathstrings,fio_core,pugixml,debugapi,jobqueEach record after that pays a cache hit per builtin module in its library: about 0.1 us per hit, 0.55 us per record. Warm wall time 0.39-0.41 s.
#nightly
Validation, claims, ledger
Validation
tests/module_cache73/73,modules/dasLLVM/tests/llvm_cache_selfheal.das,tests-cpp-smallenv-serializer and dasbind cases 6/6,test_aot_subsetontests/language1839/1839 (the enumeration hash move keeps every AOT hash).$constant test fails with globals dropped from the hash;test_extern_between_registrars_servedfails withisDasbindProxydisabled (run with an earlier fixture set; the final fixtures pass, their control run was cut short by a concurrent build).Not done
ast_core's handled types are half the cost: each annotation's semantic hash walks its field types again with fresh dependency sets. Sharing the walk, or using the seal-timeownSemanticHash, would cut it.[extern]registrars are still reparsed every run, as on master. Serving them (the JIT'sllvm_func.dashas 1154 externs) needs their proxies replayed from the record, which is separate work.makeFieldType), builtin macros, keywords and options.