6565 * </ul>
6666 */
6767public final class JNIObjectHandles {
68- @ Fold
68+ @ Fold // replaces with true/false at compile time and removes unnecessary runtime checks
6969 static boolean haveAssertions () {
7070 return RuntimeAssertionsSupport .singleton ().desiredAssertionStatus (JNIObjectHandles .class );
7171 }
@@ -219,15 +219,15 @@ public static void deleteLocalRef(JNIObjectHandle localRef) {
219219 getOrCreateLocals ().delete (decodeLocal (localRef ));
220220 }
221221 }
222-
222+ // in frames are local handles stored
223223 public static int pushLocalFrame (int capacity ) {
224224 return getOrCreateLocals ().pushFrame (capacity );
225225 }
226226
227227 public static void popLocalFrame () {
228228 getExistingLocals ().popFrame ();
229229 }
230-
230+ // pops frames down to a specific starting point identified by the int frame
231231 @ Uninterruptible (reason = "Called from uninterruptible code." , mayBeInlined = true )
232232 public static void popLocalFramesIncluding (int frame ) {
233233 getExistingLocals ().popFramesIncluding (frame );
@@ -293,19 +293,36 @@ static long computeCurrentGlobalHandleCount() {
293293 * for example by native code that is unaware of isolates.
294294 */
295295final class JNIGlobalHandles {
296- static final SignedWord MIN_VALUE = Word .signed (Long .MIN_VALUE );
297- static final SignedWord MAX_VALUE = JNIObjectHandles .nullHandle ().subtract (1 );
296+ static final SignedWord MIN_VALUE = Word .signed (Long .MIN_VALUE ); // -2^63
297+ static final SignedWord MAX_VALUE = JNIObjectHandles .nullHandle ().subtract (1 ); // -1
298298 static {
299299 assert JNIObjectHandles .nullHandle ().equal (Word .zero ());
300300 }
301301
302+ // Handle=(MSB)+(Validation Tag)+(Handle Index)
302303 private static final int HANDLE_BITS_COUNT = 31 ;
303304 private static final SignedWord HANDLE_BITS_MASK = Word .signed ((1L << HANDLE_BITS_COUNT ) - 1 );
304305 private static final int VALIDATION_BITS_SHIFT = HANDLE_BITS_COUNT ;
305- private static final int VALIDATION_BITS_COUNT = 32 ;
306+ private static final int VALIDATION_BITS_COUNT = 31 ;
306307 private static final SignedWord VALIDATION_BITS_MASK = Word .signed ((1L << VALIDATION_BITS_COUNT ) - 1 ).shiftLeft (VALIDATION_BITS_SHIFT );
308+ private static final SignedWord WEAK_HANDLE_FLAG = Word .signed (1L << 62 );
307309 private static final SignedWord MSB = Word .signed (1L << 63 );
308- private static final ObjectHandlesImpl globalHandles = new ObjectHandlesImpl (JNIObjectHandles .nullHandle ().add (1 ), HANDLE_BITS_MASK , JNIObjectHandles .nullHandle ());
310+
311+ // Define the mid-point to split the range in half
312+ private static final SignedWord GLOBAL_RANGE_SPLIT_POINT = Word .signed (1L << 62 );
313+
314+ // Strong global handles will occupy the lower half of the global handles range
315+ public static final SignedWord STRONG_GLOBAL_RANGE_MIN = MIN_VALUE ;
316+ public static final SignedWord STRONG_GLOBAL_RANGE_MAX = GLOBAL_RANGE_SPLIT_POINT .substract (1 );
317+
318+ // Weak global handles will occupy the upper half of the global handles range
319+ public static final SignedWord WEAK_GLOBAL_RANGE_MIN = GLOBAL_RANGE_SPLIT_POINT ;
320+ public static final SignedWord WEAK_GLOBAL_RANGE_MAX = MAX_VALUE ;
321+
322+ private static final ObjectHandlesImpl strongGlobalHandles
323+ = new ObjectHandlesImpl (STRONG_GLOBAL_RANGE_MIN .add (1 ), STRONG_GLOBAL_RANGE_MAX , JNIObjectHandles .nullHandle ());
324+ private static final ObjectHandlesImpl weakGlobalHandles
325+ = new ObjectHandlesImpl (WEAK_GLOBAL_RANGE_MIN .add (1 ), WEAK_GLOBAL_RANGE_MAX , JNIObjectHandles .nullHandle ());
309326
310327 @ Uninterruptible (reason = "Called from uninterruptible code." , mayBeInlined = true )
311328 static boolean isInRange (JNIObjectHandle handle ) {
@@ -317,7 +334,7 @@ private static Word isolateHash() {
317334 return Word .unsigned (isolateHash );
318335 }
319336
320- private static JNIObjectHandle encode (ObjectHandle handle ) {
337+ private static JNIObjectHandle encodeStrong (ObjectHandle handle ) {
321338 SignedWord h = (Word ) handle ;
322339 if (JNIObjectHandles .haveAssertions ()) {
323340 assert h .and (HANDLE_BITS_MASK ).equal (h ) : "unencoded handle must fit in range" ;
@@ -330,6 +347,20 @@ private static JNIObjectHandle encode(ObjectHandle handle) {
330347 return (JNIObjectHandle ) h ;
331348 }
332349
350+ private static JNIObjectHandle encodeWeak (ObjectHandle handle ) {
351+ SignedWord h = (Word ) handle ;
352+ if (JNIObjectHandles .haveAssertions ()) {
353+ assert h .and (HANDLE_BITS_MASK ).equal (h ) : "unencoded handle must fit in range" ;
354+ Word v = isolateHash ().shiftLeft (VALIDATION_BITS_SHIFT );
355+ assert v .and (VALIDATION_BITS_MASK ).equal (v ) : "validation value must fit in its range" ;
356+ h = h .or (v );
357+ }
358+ h = h .or (MSB );
359+ h = h .or (WEAK_HANDLE_FLAG ); // Set bit 62 to mark it as weak
360+ assert isInRange ((JNIObjectHandle ) h );
361+ return (JNIObjectHandle ) h ;
362+ }
363+
333364 private static ObjectHandle decode (JNIObjectHandle handle ) {
334365 assert isInRange (handle );
335366 assert ((Word ) handle ).and (VALIDATION_BITS_MASK ).unsignedShiftRight (VALIDATION_BITS_SHIFT )
@@ -338,35 +369,48 @@ private static ObjectHandle decode(JNIObjectHandle handle) {
338369 }
339370
340371 static <T > T getObject (JNIObjectHandle handle ) {
341- return globalHandles .get (decode (handle ));
372+ SignedWord handleValue = (Word ) handle ;
373+ if (handleValue .greaterOrEqual (STRONG_GLOBAL_RANGE_MIN ) && handleValue .lessOrEqual (STRONG_GLOBAL_RANGE_MAX )) {
374+ return strongGlobalHandles .get (decode (handle ));
375+ }
376+
377+ if (handleValue .greaterOrEqual (WEAK_GLOBAL_RANGE_MIN ) && handleValue .lessOrEqual (WEAK_GLOBAL_RANGE_MAX )) {
378+ return weakGlobalHandles .get (decode ((handle )));
379+ }
380+
381+ throw throwIllegalArgumentException ();
342382 }
343383
344384 static JNIObjectRefType getHandleType (JNIObjectHandle handle ) {
345- assert isInRange (handle );
346- if (globalHandles .isWeak (decode (handle ))) {
385+ SignedWord handleValue = (Word ) handle ;
386+ if (handleValue .greaterOrEqual (STRONG_GLOBAL_RANGE_MIN ) && handleValue .lessOrEqual (STRONG_GLOBAL_RANGE_MAX )) {
387+ return JNIObjectRefType .Global ;
388+ }
389+
390+ if (handleValue .greaterOrEqual (WEAK_GLOBAL_RANGE_MIN ) && handleValue .lessOrEqual (WEAK_GLOBAL_RANGE_MAX )) {
347391 return JNIObjectRefType .WeakGlobal ;
348392 }
349- return JNIObjectRefType .Global ;
393+ return JNIObjectRefType .Invalid ;
350394 }
351395
352396 static JNIObjectHandle create (Object obj ) {
353- return encode ( globalHandles .create (obj ));
397+ return encodeStrong ( strongGlobalHandles .create (obj ));
354398 }
355399
356400 static void destroy (JNIObjectHandle handle ) {
357- globalHandles .destroy (decode (handle ));
401+ strongGlobalHandles .destroy (decode (handle ));
358402 }
359403
360404 static JNIObjectHandle createWeak (Object obj ) {
361- return encode ( globalHandles . createWeak (obj ));
405+ return encodeWeak ( weakGlobalHandles . create (obj ));
362406 }
363407
364408 static void destroyWeak (JNIObjectHandle weakRef ) {
365- globalHandles . destroyWeak (decode (weakRef ));
409+ weakGlobalHandles . destroy (decode (weakRef ));
366410 }
367411
368412 public static long computeCurrentCount () {
369- return globalHandles .computeCurrentCount ();
413+ return strongGlobalHandles . computeCurrentCount () + weakGlobalHandles .computeCurrentCount ();
370414 }
371415}
372416
0 commit comments