Skip to content

fix(Bytecode DSL): deduplicate constants by identity instead of equals - #14537

Open
The-Alchemist wants to merge 1 commit into
oracle:masterfrom
The-Alchemist:truffle/bytecode-constant-identity-dedup
Open

The-Alchemist wants to merge 1 commit into
oracle:masterfrom
The-Alchemist:truffle/bytecode-constant-identity-dedup

Conversation

@The-Alchemist

@The-Alchemist The-Alchemist commented Sep 26, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • BytecodeSupport.ConstantsBuffer.add deduplicated constants with == or equals, so two distinct but equal objects passed to separate emitLoadConstant calls or constant operands collapsed into one pool slot. Operations could observe the substitution through ==, getClass(), or state not covered by equals. Serialization had the same problem independently, because the generated SerializationState.objects was a HashMap.
  • The constant pool now deduplicates by reference identity (== and System.identityHashCode). Boxed primitives and the Bytecode DSL accessor types (LocalAccessor, MaterializedLocalAccessor, LocalRangeAccessor) are still deduplicated by value, because their identity is already unspecified (boxing caches and constantOf caches) and pure identity would only grow the pool. Double/Float now compare by raw bits, so 0.0/-0.0 and different NaN payloads are no longer merged.
  • Serialization now uses an IdentityHashMap. That exposed an issue equals merging used to hide: a finally generator is serialized once but deserialized once per emitted handler, so a reference in a finally body came back as a separate instance per replay. Objects first seen inside a finally generator are now created in the outermost serialization context whose root nodes they reference, and the generator refers to them with a new CODE_$CREATE_OUTER_OBJECT record. Objects that reference root nodes built inside the generator are still re-created per replay. Old serialized data still deserializes, since only a record type was added.
  • Tests: ConstantsBufferTest covers equal-but-distinct objects below and above HASH_THRESHOLD, same-reference sharing, value-based boxed types, and raw-bit floats. The new ConstantIdentityTest covers LoadConstant, constant operands, and sharing across finally-generator replays, each both directly and through a serialization round trip. The com.oracle.truffle.api.bytecode.test package passes.

Questions

  • Footprint note: languages that emit equal literals as distinct instances (for example, parser-created strings) now get separate pool slots. If that's too much, a @GenerateBytecode-level policy controlling both paths would be another option.

Feedback welcome!

ConstantsBuffer deduplicated constants using equals, so two distinct but
equal objects passed to separate LoadConstant calls or constant operands
were collapsed into one pool slot. Operations could observe the
substitution through ==, getClass(), or state not covered by equals.
Serialization had the same problem because SerializationState.objects
was a HashMap.

Constants are now deduplicated by reference identity. Boxed primitives
and the Bytecode DSL accessor types keep value-based deduplication since
their identity is unspecified; floating-point values compare by raw bits.

Serialization now uses an IdentityHashMap. Because finally generators are
serialized once but deserialized once per emitted handler, objects first
seen inside a finally generator are now created in the outermost
serialization context whose root nodes they reference, and inner contexts
refer to them with a new CODE_$CREATE_OUTER_OBJECT record. This keeps
repeated references shared across handler replays and with the enclosing
code after a round trip, which equals-based merging used to hide.

Signed-off-by: The-Alchemist <kap4020@gmail.com>
@oracle-contributor-agreement oracle-contributor-agreement Bot added the OCA Verified All contributors have signed the Oracle Contributor Agreement. label Sep 26, 2026
@The-Alchemist
The-Alchemist marked this pull request as ready for review September 26, 2026 22:46
@The-Alchemist The-Alchemist changed the title Bytecode DSL: deduplicate constants by identity instead of equals fix(Bytecode DSL): deduplicate constants by identity instead of equals Sep 26, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

OCA Verified All contributors have signed the Oracle Contributor Agreement.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant