From 20e8743dbc56c4e619afc397da452287941a7167 Mon Sep 17 00:00:00 2001 From: asselyam Date: Wed, 15 Oct 2025 11:20:31 +0200 Subject: [PATCH 1/5] Update ObjectHandlesImpl.java Removed HandleWeakReference and made ObjectHandlesImpl to be a storage class --- .../svm/core/handles/ObjectHandlesImpl.java | 20 ------------------- 1 file changed, 20 deletions(-) diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/handles/ObjectHandlesImpl.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/handles/ObjectHandlesImpl.java index 6c5d6417dd45..3c27f7a866cf 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/handles/ObjectHandlesImpl.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/handles/ObjectHandlesImpl.java @@ -54,11 +54,6 @@ public final class ObjectHandlesImpl implements ObjectHandles { /** Private subclass to distinguish from regular handles to {@link WeakReference} objects. */ - private static final class HandleWeakReference extends WeakReference { - HandleWeakReference(T referent) { - super(referent); - } - } private static final int MAX_FIRST_BUCKET_CAPACITY = 1024; static { // must be a power of 2 for the arithmetic below to work @@ -210,17 +205,10 @@ public ObjectHandle create(Object obj) { } } - public ObjectHandle createWeak(Object obj) { - return create(new HandleWeakReference<>(obj)); - } - @SuppressWarnings("unchecked") @Override public T get(ObjectHandle handle) { Object obj = doGet(handle); - if (obj instanceof HandleWeakReference) { - obj = ((HandleWeakReference) obj).get(); - } return (T) obj; } @@ -240,10 +228,6 @@ private Object doGet(ObjectHandle handle) { return Unsafe.getUnsafe().getReferenceVolatile(bucket, getObjectArrayByteOffset(indexInBucket)); } - public boolean isWeak(ObjectHandle handle) { - return (doGet(handle) instanceof HandleWeakReference); - } - @Override public void destroy(ObjectHandle handle) { if (handle.equal(nullHandle)) { @@ -261,10 +245,6 @@ public void destroy(ObjectHandle handle) { Unsafe.getUnsafe().putReferenceRelease(bucket, getObjectArrayByteOffset(indexInBucket), null); } - public void destroyWeak(ObjectHandle handle) { - destroy(handle); - } - public long computeCurrentCount() { long count = 0; int bucketIndex = 0; From 8a1490eea8c54a5929f506b0c22fcaceefa089d6 Mon Sep 17 00:00:00 2001 From: asselyam Date: Wed, 15 Oct 2025 11:26:18 +0200 Subject: [PATCH 2/5] Update JNIObjectHandles.java In JNIGlobalHandles created 2 instances of ObjectHandlesImpl (one for strong and one for weak hadles). I divided the total global handels range into two halfs at bit 62. Bit 62 is 0 for strong global handles and 1 for weak global handles. Therefore a validation tag is redused from 32 bit to 31 bit --- .../oracle/svm/core/jni/JNIObjectHandles.java | 78 +++++++++++++++---- 1 file changed, 61 insertions(+), 17 deletions(-) diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/JNIObjectHandles.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/JNIObjectHandles.java index 91b39f6ec6eb..0599fb93c020 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/JNIObjectHandles.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/JNIObjectHandles.java @@ -65,7 +65,7 @@ * */ public final class JNIObjectHandles { - @Fold + @Fold // replaces with true/false at compile time and removes unnecessary runtime checks static boolean haveAssertions() { return RuntimeAssertionsSupport.singleton().desiredAssertionStatus(JNIObjectHandles.class); } @@ -219,7 +219,7 @@ public static void deleteLocalRef(JNIObjectHandle localRef) { getOrCreateLocals().delete(decodeLocal(localRef)); } } - + // in frames are local handles stored public static int pushLocalFrame(int capacity) { return getOrCreateLocals().pushFrame(capacity); } @@ -227,7 +227,7 @@ public static int pushLocalFrame(int capacity) { public static void popLocalFrame() { getExistingLocals().popFrame(); } - + // pops frames down to a specific starting point identified by the int frame @Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true) public static void popLocalFramesIncluding(int frame) { getExistingLocals().popFramesIncluding(frame); @@ -293,19 +293,36 @@ static long computeCurrentGlobalHandleCount() { * for example by native code that is unaware of isolates. */ final class JNIGlobalHandles { - static final SignedWord MIN_VALUE = Word.signed(Long.MIN_VALUE); - static final SignedWord MAX_VALUE = JNIObjectHandles.nullHandle().subtract(1); + static final SignedWord MIN_VALUE = Word.signed(Long.MIN_VALUE); // -2^63 + static final SignedWord MAX_VALUE = JNIObjectHandles.nullHandle().subtract(1); // -1 static { assert JNIObjectHandles.nullHandle().equal(Word.zero()); } + // Handle=(MSB)+(Validation Tag)+(Handle Index) private static final int HANDLE_BITS_COUNT = 31; private static final SignedWord HANDLE_BITS_MASK = Word.signed((1L << HANDLE_BITS_COUNT) - 1); private static final int VALIDATION_BITS_SHIFT = HANDLE_BITS_COUNT; - private static final int VALIDATION_BITS_COUNT = 32; + private static final int VALIDATION_BITS_COUNT = 31; private static final SignedWord VALIDATION_BITS_MASK = Word.signed((1L << VALIDATION_BITS_COUNT) - 1).shiftLeft(VALIDATION_BITS_SHIFT); + private static final SignedWord WEAK_HANDLE_FLAG = Word.signed(1L << 62); private static final SignedWord MSB = Word.signed(1L << 63); - private static final ObjectHandlesImpl globalHandles = new ObjectHandlesImpl(JNIObjectHandles.nullHandle().add(1), HANDLE_BITS_MASK, JNIObjectHandles.nullHandle()); + + // Define the mid-point to split the range in half + private static final SignedWord GLOBAL_RANGE_SPLIT_POINT = Word.signed(1L << 62); + + // Strong global handles will occupy the lower half of the global handles range + public static final SignedWord STRONG_GLOBAL_RANGE_MIN = MIN_VALUE; + public static final SignedWord STRONG_GLOBAL_RANGE_MAX = GLOBAL_RANGE_SPLIT_POINT.substract(1); + + // Weak global handles will occupy the upper half of the global handles range + public static final SignedWord WEAK_GLOBAL_RANGE_MIN = GLOBAL_RANGE_SPLIT_POINT; + public static final SignedWord WEAK_GLOBAL_RANGE_MAX = MAX_VALUE; + + private static final ObjectHandlesImpl strongGlobalHandles + = new ObjectHandlesImpl(STRONG_GLOBAL_RANGE_MIN.add(1), STRONG_GLOBAL_RANGE_MAX, JNIObjectHandles.nullHandle()); + private static final ObjectHandlesImpl weakGlobalHandles + = new ObjectHandlesImpl(WEAK_GLOBAL_RANGE_MIN.add(1), WEAK_GLOBAL_RANGE_MAX, JNIObjectHandles.nullHandle()); @Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true) static boolean isInRange(JNIObjectHandle handle) { @@ -317,7 +334,7 @@ private static Word isolateHash() { return Word.unsigned(isolateHash); } - private static JNIObjectHandle encode(ObjectHandle handle) { + private static JNIObjectHandle encodeStrong(ObjectHandle handle) { SignedWord h = (Word) handle; if (JNIObjectHandles.haveAssertions()) { assert h.and(HANDLE_BITS_MASK).equal(h) : "unencoded handle must fit in range"; @@ -330,6 +347,20 @@ private static JNIObjectHandle encode(ObjectHandle handle) { return (JNIObjectHandle) h; } + private static JNIObjectHandle encodeWeak(ObjectHandle handle) { + SignedWord h = (Word) handle; + if (JNIObjectHandles.haveAssertions()) { + assert h.and(HANDLE_BITS_MASK).equal(h) : "unencoded handle must fit in range"; + Word v = isolateHash().shiftLeft(VALIDATION_BITS_SHIFT); + assert v.and(VALIDATION_BITS_MASK).equal(v) : "validation value must fit in its range"; + h = h.or(v); + } + h = h.or(MSB); + h = h.or(WEAK_HANDLE_FLAG); // Set bit 62 to mark it as weak + assert isInRange((JNIObjectHandle) h); + return (JNIObjectHandle) h; + } + private static ObjectHandle decode(JNIObjectHandle handle) { assert isInRange(handle); assert ((Word) handle).and(VALIDATION_BITS_MASK).unsignedShiftRight(VALIDATION_BITS_SHIFT) @@ -338,35 +369,48 @@ private static ObjectHandle decode(JNIObjectHandle handle) { } static T getObject(JNIObjectHandle handle) { - return globalHandles.get(decode(handle)); + SignedWord handleValue = (Word) handle; + if (handleValue.greaterOrEqual(STRONG_GLOBAL_RANGE_MIN) && handleValue.lessOrEqual(STRONG_GLOBAL_RANGE_MAX)) { + return strongGlobalHandles.get(decode(handle)); + } + + if (handleValue.greaterOrEqual(WEAK_GLOBAL_RANGE_MIN) && handleValue.lessOrEqual(WEAK_GLOBAL_RANGE_MAX)) { + return weakGlobalHandles.get(decode((handle))); + } + + throw throwIllegalArgumentException(); } static JNIObjectRefType getHandleType(JNIObjectHandle handle) { - assert isInRange(handle); - if (globalHandles.isWeak(decode(handle))) { + SignedWord handleValue = (Word) handle; + if (handleValue.greaterOrEqual(STRONG_GLOBAL_RANGE_MIN) && handleValue.lessOrEqual(STRONG_GLOBAL_RANGE_MAX)) { + return JNIObjectRefType.Global; + } + + if (handleValue.greaterOrEqual(WEAK_GLOBAL_RANGE_MIN) && handleValue.lessOrEqual(WEAK_GLOBAL_RANGE_MAX)) { return JNIObjectRefType.WeakGlobal; } - return JNIObjectRefType.Global; + return JNIObjectRefType.Invalid; } static JNIObjectHandle create(Object obj) { - return encode(globalHandles.create(obj)); + return encodeStrong(strongGlobalHandles.create(obj)); } static void destroy(JNIObjectHandle handle) { - globalHandles.destroy(decode(handle)); + strongGlobalHandles.destroy(decode(handle)); } static JNIObjectHandle createWeak(Object obj) { - return encode(globalHandles.createWeak(obj)); + return encodeWeak(weakGlobalHandles.create(obj)); } static void destroyWeak(JNIObjectHandle weakRef) { - globalHandles.destroyWeak(decode(weakRef)); + weakGlobalHandles.destroy(decode(weakRef)); } public static long computeCurrentCount() { - return globalHandles.computeCurrentCount(); + return strongGlobalHandles.computeCurrentCount() + weakGlobalHandles.computeCurrentCount(); } } From a5f5a0c141b19d5223930a5265646726609cc89a Mon Sep 17 00:00:00 2001 From: asselyam Date: Thu, 16 Oct 2025 23:18:55 +0200 Subject: [PATCH 3/5] Update JNIObjectHandles.java resolved some grammar mistakes and updated the split point in JNIGlobalHandles and replaced it from bit 62 to bit 30, because it did not fit in the global handles range --- .../oracle/svm/core/jni/JNIObjectHandles.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/JNIObjectHandles.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/JNIObjectHandles.java index 0599fb93c020..93af57c7761f 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/JNIObjectHandles.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/JNIObjectHandles.java @@ -309,20 +309,20 @@ final class JNIGlobalHandles { private static final SignedWord MSB = Word.signed(1L << 63); // Define the mid-point to split the range in half - private static final SignedWord GLOBAL_RANGE_SPLIT_POINT = Word.signed(1L << 62); + private static final SignedWord HANDLE_RANGE_SPLIT_POINT = Word.signed(1L << 30); // Strong global handles will occupy the lower half of the global handles range - public static final SignedWord STRONG_GLOBAL_RANGE_MIN = MIN_VALUE; - public static final SignedWord STRONG_GLOBAL_RANGE_MAX = GLOBAL_RANGE_SPLIT_POINT.substract(1); + public static final SignedWord STRONG_GLOBAL_RANGE_MIN = JNIObjectHandles.nullHandle().add(1);; + public static final SignedWord STRONG_GLOBAL_RANGE_MAX = HANDLE_RANGE_SPLIT_POINT.subtract(1); // Weak global handles will occupy the upper half of the global handles range - public static final SignedWord WEAK_GLOBAL_RANGE_MIN = GLOBAL_RANGE_SPLIT_POINT; - public static final SignedWord WEAK_GLOBAL_RANGE_MAX = MAX_VALUE; + public static final SignedWord WEAK_GLOBAL_RANGE_MIN = HANDLE_RANGE_SPLIT_POINT; + public static final SignedWord WEAK_GLOBAL_RANGE_MAX = HANDLE_BITS_MASK; private static final ObjectHandlesImpl strongGlobalHandles - = new ObjectHandlesImpl(STRONG_GLOBAL_RANGE_MIN.add(1), STRONG_GLOBAL_RANGE_MAX, JNIObjectHandles.nullHandle()); + = new ObjectHandlesImpl(STRONG_GLOBAL_RANGE_MIN, STRONG_GLOBAL_RANGE_MAX, JNIObjectHandles.nullHandle()); private static final ObjectHandlesImpl weakGlobalHandles - = new ObjectHandlesImpl(WEAK_GLOBAL_RANGE_MIN.add(1), WEAK_GLOBAL_RANGE_MAX, JNIObjectHandles.nullHandle()); + = new ObjectHandlesImpl(WEAK_GLOBAL_RANGE_MIN, WEAK_GLOBAL_RANGE_MAX, JNIObjectHandles.nullHandle()); @Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true) static boolean isInRange(JNIObjectHandle handle) { @@ -378,7 +378,7 @@ static T getObject(JNIObjectHandle handle) { return weakGlobalHandles.get(decode((handle))); } - throw throwIllegalArgumentException(); + throw new IllegalArgumentException("Invalid handle"); } static JNIObjectRefType getHandleType(JNIObjectHandle handle) { From 29dee8df0ed51bb3ca4d538a51d1ce19f2642d4c Mon Sep 17 00:00:00 2001 From: asselyam Date: Tue, 21 Oct 2025 17:18:09 +0200 Subject: [PATCH 4/5] Final cleanup for handle encoding --- .../svm/core/handles/ObjectHandlesImpl.java | 7 +- .../oracle/svm/core/jni/JNIObjectHandles.java | 69 ++++++++++++++----- 2 files changed, 54 insertions(+), 22 deletions(-) diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/handles/ObjectHandlesImpl.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/handles/ObjectHandlesImpl.java index 3c27f7a866cf..8269d6e98ef4 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/handles/ObjectHandlesImpl.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/handles/ObjectHandlesImpl.java @@ -38,10 +38,7 @@ * This class implements {@link ObjectHandle word}-sized integer handles that refer to Java objects. * {@link #create(Object) Creating}, {@link #get(ObjectHandle) dereferencing} and * {@link #destroy(ObjectHandle) destroying} handles is thread-safe and the handles themselves are - * valid across threads. This class also supports weak handles, with which the referenced object may - * be garbage-collected, after which {@link #get(ObjectHandle)} returns {@code null}. Still, weak - * handles must also be {@link #destroyWeak(ObjectHandle) explicitly destroyed} to reclaim their - * handle value. + * valid across threads. *

* The implementation uses a variable number of object arrays, in which each array element * represents a handle. The array element's index determines the handle's integer value, and the @@ -53,8 +50,6 @@ */ public final class ObjectHandlesImpl implements ObjectHandles { - /** Private subclass to distinguish from regular handles to {@link WeakReference} objects. */ - private static final int MAX_FIRST_BUCKET_CAPACITY = 1024; static { // must be a power of 2 for the arithmetic below to work assert Integer.lowestOneBit(MAX_FIRST_BUCKET_CAPACITY) == MAX_FIRST_BUCKET_CAPACITY; diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/JNIObjectHandles.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/JNIObjectHandles.java index 93af57c7761f..61b2176311ae 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/JNIObjectHandles.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/JNIObjectHandles.java @@ -65,7 +65,7 @@ * */ public final class JNIObjectHandles { - @Fold // replaces with true/false at compile time and removes unnecessary runtime checks + @Fold static boolean haveAssertions() { return RuntimeAssertionsSupport.singleton().desiredAssertionStatus(JNIObjectHandles.class); } @@ -219,6 +219,7 @@ public static void deleteLocalRef(JNIObjectHandle localRef) { getOrCreateLocals().delete(decodeLocal(localRef)); } } + // in frames are local handles stored public static int pushLocalFrame(int capacity) { return getOrCreateLocals().pushFrame(capacity); @@ -227,6 +228,7 @@ public static int pushLocalFrame(int capacity) { public static void popLocalFrame() { getExistingLocals().popFrame(); } + // pops frames down to a specific starting point identified by the int frame @Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true) public static void popLocalFramesIncluding(int frame) { @@ -295,6 +297,7 @@ static long computeCurrentGlobalHandleCount() { final class JNIGlobalHandles { static final SignedWord MIN_VALUE = Word.signed(Long.MIN_VALUE); // -2^63 static final SignedWord MAX_VALUE = JNIObjectHandles.nullHandle().subtract(1); // -1 + static { assert JNIObjectHandles.nullHandle().equal(Word.zero()); } @@ -311,6 +314,23 @@ final class JNIGlobalHandles { // Define the mid-point to split the range in half private static final SignedWord HANDLE_RANGE_SPLIT_POINT = Word.signed(1L << 30); + // Strong global handles will occupy the lower half of the global handles range + public static final SignedWord STRONG_GLOBAL_RANGE_MIN = JNIObjectHandles.nullHandle().add(1); + ; + public static final SignedWord STRONG_GLOBAL_RANGE_MAX = HANDLE_RANGE_SPLIT_POINT.subtract(1); + + // Weak global handles will occupy the upper half of the global handles range + public static final SignedWord WEAK_GLOBAL_RANGE_MIN = HANDLE_RANGE_SPLIT_POINT; + public static final SignedWord WEAK_GLOBAL_RANGE_MAX = HANDLE_BITS_MASK; + + private static final ObjectHandlesImpl strongGlobalHandles + = new ObjectHandlesImpl(STRONG_GLOBAL_RANGE_MIN, STRONG_GLOBAL_RANGE_MAX, JNIObjectHandles.nullHandle()); + private static final ObjectHandlesImpl weakGlobalHandles + = new ObjectHandlesImpl(WEAK_GLOBAL_RANGE_MIN, WEAK_GLOBAL_RANGE_MAX, JNIObjectHandles.nullHandle()); + + // Define the mid-point to split the range in half + private static final SignedWord HANDLE_RANGE_SPLIT_POINT = Word.signed(1L << 30); + // Strong global handles will occupy the lower half of the global handles range public static final SignedWord STRONG_GLOBAL_RANGE_MIN = JNIObjectHandles.nullHandle().add(1);; public static final SignedWord STRONG_GLOBAL_RANGE_MAX = HANDLE_RANGE_SPLIT_POINT.subtract(1); @@ -334,6 +354,19 @@ private static Word isolateHash() { return Word.unsigned(isolateHash); } + /** + * Encodes a raw {@code ObjectHandle} into a strong {@code JNIObjectHandle}. + * * A strong handle guarantees the referenced object remains alive as long as + * the handle itself exists. + * * The handle is encoded by: + * 1. Asserting the handle fits within the available bit range. + * 2. Inserting validation bits (derived from the isolate hash) for security. + * 3. Setting the Most Significant Bit (MSB, bit 63) to mark it as an encoded handle. + * 4. The WEAK_HANDLE_FLAG bit (bit 62) remains 0. + * + * @param handle The raw, unencoded handle to the Java object. + * @return The resulting strong JNI object handle with embedded metadata. + */ private static JNIObjectHandle encodeStrong(ObjectHandle handle) { SignedWord h = (Word) handle; if (JNIObjectHandles.haveAssertions()) { @@ -347,16 +380,20 @@ private static JNIObjectHandle encodeStrong(ObjectHandle handle) { return (JNIObjectHandle) h; } + /** + * Encodes a raw {@code ObjectHandle} into a weak {@code JNIObjectHandle}. + * * A weak handle allows the referenced object to be garbage collected even + * if the handle exists. The handle will be cleared when the object dies. + * * This method calls {@link #encodeStrong(ObjectHandle)} to perform all + * common encoding steps, and then explicitly sets the {@code WEAK_HANDLE_FLAG} + * bit (bit 62) to mark the handle as weak. + * + * @param handle The raw, unencoded handle to the Java object. + * @return The resulting weak JNI object handle with embedded metadata. + */ private static JNIObjectHandle encodeWeak(ObjectHandle handle) { - SignedWord h = (Word) handle; - if (JNIObjectHandles.haveAssertions()) { - assert h.and(HANDLE_BITS_MASK).equal(h) : "unencoded handle must fit in range"; - Word v = isolateHash().shiftLeft(VALIDATION_BITS_SHIFT); - assert v.and(VALIDATION_BITS_MASK).equal(v) : "validation value must fit in its range"; - h = h.or(v); - } - h = h.or(MSB); - h = h.or(WEAK_HANDLE_FLAG); // Set bit 62 to mark it as weak + SignedWord h = (Word) encodeStrong(handle); + h = h.or(WEAK_HANDLE_FLAG); assert isInRange((JNIObjectHandle) h); return (JNIObjectHandle) h; } @@ -364,17 +401,17 @@ private static JNIObjectHandle encodeWeak(ObjectHandle handle) { private static ObjectHandle decode(JNIObjectHandle handle) { assert isInRange(handle); assert ((Word) handle).and(VALIDATION_BITS_MASK).unsignedShiftRight(VALIDATION_BITS_SHIFT) - .equal(isolateHash()) : "mismatching validation value -- passed a handle from a different isolate?"; + .equal(isolateHash()) : "mismatching validation value -- passed a handle from a different isolate?"; return (ObjectHandle) HANDLE_BITS_MASK.and((Word) handle); } static T getObject(JNIObjectHandle handle) { SignedWord handleValue = (Word) handle; - if (handleValue.greaterOrEqual(STRONG_GLOBAL_RANGE_MIN) && handleValue.lessOrEqual(STRONG_GLOBAL_RANGE_MAX)) { + if ((handleValue.toLong() & WEAK_HANDLE_FLAG.toLong()) == 0) { return strongGlobalHandles.get(decode(handle)); } - if (handleValue.greaterOrEqual(WEAK_GLOBAL_RANGE_MIN) && handleValue.lessOrEqual(WEAK_GLOBAL_RANGE_MAX)) { + if ((handleValue.toLong() & WEAK_HANDLE_FLAG.toLong()) == 1) { return weakGlobalHandles.get(decode((handle))); } @@ -383,11 +420,11 @@ static T getObject(JNIObjectHandle handle) { static JNIObjectRefType getHandleType(JNIObjectHandle handle) { SignedWord handleValue = (Word) handle; - if (handleValue.greaterOrEqual(STRONG_GLOBAL_RANGE_MIN) && handleValue.lessOrEqual(STRONG_GLOBAL_RANGE_MAX)) { + if ((handleValue.toLong() & WEAK_HANDLE_FLAG.toLong()) == 0) { return JNIObjectRefType.Global; } - if (handleValue.greaterOrEqual(WEAK_GLOBAL_RANGE_MIN) && handleValue.lessOrEqual(WEAK_GLOBAL_RANGE_MAX)) { + if ((handleValue.toLong() & WEAK_HANDLE_FLAG.toLong()) == 1) { return JNIObjectRefType.WeakGlobal; } return JNIObjectRefType.Invalid; @@ -419,7 +456,7 @@ public static long computeCurrentCount() { * move and are not garbage-collected, so the handle just contains an object's offset in the image * heap. This approach has the major benefit that handles are valid across isolates that are created * from the same image, which helps with native code that is unaware of multiple isolates. - * + *

* Although this type of handle doesn't need explicit management, we still distinguish between * local, global and weak-global references by means of a bit pattern in order to comply with the * JNI specification (in particular, for function {@code GetObjectRefType}). From 3dfc9e60dabcb2d64f216d6b35de4122426094b7 Mon Sep 17 00:00:00 2001 From: asselyam Date: Wed, 29 Oct 2025 17:27:52 +0100 Subject: [PATCH 5/5] Update JNIObjectHandles.java Delected the duplicated variables in JNIGlobalHandles --- .../oracle/svm/core/jni/JNIObjectHandles.java | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/JNIObjectHandles.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/JNIObjectHandles.java index 61b2176311ae..13e8a954716d 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/JNIObjectHandles.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/JNIObjectHandles.java @@ -314,23 +314,6 @@ final class JNIGlobalHandles { // Define the mid-point to split the range in half private static final SignedWord HANDLE_RANGE_SPLIT_POINT = Word.signed(1L << 30); - // Strong global handles will occupy the lower half of the global handles range - public static final SignedWord STRONG_GLOBAL_RANGE_MIN = JNIObjectHandles.nullHandle().add(1); - ; - public static final SignedWord STRONG_GLOBAL_RANGE_MAX = HANDLE_RANGE_SPLIT_POINT.subtract(1); - - // Weak global handles will occupy the upper half of the global handles range - public static final SignedWord WEAK_GLOBAL_RANGE_MIN = HANDLE_RANGE_SPLIT_POINT; - public static final SignedWord WEAK_GLOBAL_RANGE_MAX = HANDLE_BITS_MASK; - - private static final ObjectHandlesImpl strongGlobalHandles - = new ObjectHandlesImpl(STRONG_GLOBAL_RANGE_MIN, STRONG_GLOBAL_RANGE_MAX, JNIObjectHandles.nullHandle()); - private static final ObjectHandlesImpl weakGlobalHandles - = new ObjectHandlesImpl(WEAK_GLOBAL_RANGE_MIN, WEAK_GLOBAL_RANGE_MAX, JNIObjectHandles.nullHandle()); - - // Define the mid-point to split the range in half - private static final SignedWord HANDLE_RANGE_SPLIT_POINT = Word.signed(1L << 30); - // Strong global handles will occupy the lower half of the global handles range public static final SignedWord STRONG_GLOBAL_RANGE_MIN = JNIObjectHandles.nullHandle().add(1);; public static final SignedWord STRONG_GLOBAL_RANGE_MAX = HANDLE_RANGE_SPLIT_POINT.subtract(1);