Value slots, preencoded control flow, and bytecode codegen - #149
Draft
BernardoPe wants to merge 4 commits into
Draft
BernardoPe wants to merge 4 commits into
BernardoPe wants to merge 4 commits into
Conversation
Contributor
|
Please run |
textOf/rawOf/intOf/longOf/doubleOf/boolOf/attrOf/attrOfNullable bind a single value from the model without opening a dynamic() block; the preprocessor records each as a node in the same chain it already builds for static markup. forEachOf and whenOf do the same for loops and conditionals: each preencodes its body once, as its own sub-chain, instead of resolving it interpretively on every render. When a run of the chain holds only static blocks and value slots, it compiles once into a small generated class that writes straight to the render buffer, no interpretation loop and no boxing for numeric slots. The class file is hand-rolled (no bytecode library) since the generated method never branches and needs no StackMapTable. Anything that can't compile falls back to the interpreted chain; output is byte-identical either way.
The async chain hands off to the same synchronous continuation nodes value slots and forEachOf already use, so nothing async-specific is needed for them to work in a viewAsync()/viewSuspend() view. These tests are the proof: value slots on both sides of an await, and a render that matches the equivalent dynamic() block exactly.
textOf/intOf/attrOf/forEachOf/whenOf only worked through the preencoding visitor; HtmlViewVisitorHot threw UnsupportedOperationException for every one of them. Implement all ten against its existing model field: a slot applies its accessor to the current model and writes immediately, and forEachOf/whenOf swap the model in for the body's duration, the same way visitDynamic already hands it to a whole block.
BernardoPe
force-pushed
the
perf/value-slots
branch
from
September 12, 2026 18:20
ffb558d to
cf81962
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.
This PR adds value slots and preencoded control flow as a faster alternative to
dynamic(), and adds bytecode generation for simple chains.Value slots (
textOf,rawOf,intOf,longOf,doubleOf,boolOf,attrOf,attrOfNullable) let a view read a single value from the model without creating adynamic()block. The preprocessor stores each slot directly in the chain, so rendering does not need to resolve it as a dynamic block each time.The same idea is used for
forEachOfandwhenOf. Their bodies are preencoded once as separate sub-chains, then reused during rendering.For chains made up of static blocks and value slots, HtmlFlow can also generate a small class that writes directly to the output buffer. This removes the interpretation loop and avoids boxing for numeric slots. The generated bytecode is written directly, so this does not add a bytecode library dependency. If a chain cannot be compiled, it keeps using the interpreted version. Both paths produce the same output.
The changes also work with async views and hot reload.
template-benchmark when adapting the
presentationsandstocksviews to use these features (tested locally):Here is what the views look like:
Depends on
This depends on xmlet/xsd2poet#2, which adds the slot methods and
Slot<M>to the generated element API.For now, this branch uses
xsd2poet-java:1.0.9-SNAPSHOT, built locally.