You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Replaces the runtime allocator that re-derived each Java-backed Python
object's layout from version-sensitive CPython internals (reading private
PyLongObject fields on every single value access) with fixed, type-baked
offsets resolved once at type-creation time. The abstract/concrete type
split makes this offset a hard invariant rather than something callers
branch on or recompute.
Builds on that to eliminate per-instance Java-value storage entirely for
the boxed Long/Boolean/Character wrapper family: their JPClass* moves onto
the shared metaclass (redundant per instance otherwise), and their jvalue
is reconstructed on demand from the instance's own native representation --
boxing via a real JNI call only when a boxed wrapper's value actually
crosses back into Java. This also removes a version-gated digit-layout
workaround that existed solely to keep a trailing value at a fixed offset
inside a variable-length PyLongObject subtype, along with a related heap
corruption bug it caused on Python 3.8-3.11 when combined with an implicit
__dict__ slot. A per-leaf-class null-boxed singleton represents
JObject(None, cls), since a genuinely null Java reference has no native
Python representation to reconstruct from.
No user-visible API change. Boxed wrapper instances no longer retain
Java-side reference identity across repeated round-trips through Python --
this was never guaranteed for freshly-converted values either, so the
change is specifically about previously-received-then-passed-back boxed
objects.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
0 commit comments