Read HashTable field offsets from HashTable, not EqHashTable - #312
Merged
Conversation
XCollectionsInternals computed the size, keys and values offsets from EqHashTable and applied them to HashTable instances. EqHashTable has an additional field, so its layout is shifted and the offsets do not address the intended fields. Every restored HashTable was therefore written at wrong offsets by BinaryHandlerHashTable.updateState. With standard object headers the writes still landed inside the larger instance and silently corrupted a neighbouring field. With compact object headers the instance is smaller and the offset points past its end, so the write hits the following object's mark word, which then carries the klass pointer: the next garbage collection decodes a corrupt klass and the JVM dies.
There was a problem hiding this comment.
Pull request overview
Fixes a critical binary persistence corruption bug by ensuring HashTable field offsets are computed from HashTable itself (not EqHashTable), preventing incorrect XMemory writes during restore that could corrupt adjacent fields or crash the JVM (notably with compact object headers).
Changes:
- Compute
OFFSET_HashTable_{size,keys,values}fromHashTable.classinstead ofEqHashTable.class. - Replace the wildcard collections import with explicit imports for the types referenced in
XCollectionsInternals.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
fh-ms
approved these changes
Aug 3, 2026
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.
XCollectionsInternals computed the size, keys and values offsets from EqHashTable and applied them to HashTable instances. EqHashTable has an additional field, so its layout is shifted and the offsets do not address the intended fields.
Every restored HashTable was therefore written at wrong offsets by BinaryHandlerHashTable.updateState. With standard object headers the writes still landed inside the larger instance and silently corrupted a neighbouring field. With compact object headers the instance is smaller and the offset points past its end, so the write hits the following object's mark word, which then carries the klass pointer: the next garbage collection decodes a corrupt klass and the JVM dies.