@@ -256,8 +256,8 @@ public static void pollReferenceQueue() {
256
256
if (entry instanceof PythonObjectReference reference ) {
257
257
LOGGER .finer (() -> PythonUtils .formatJString ("releasing PythonObjectReference %s" , reference ));
258
258
259
- if (HandleTester .pointsToPyHandleSpace (reference .pointer )) {
260
- int index = ( int ) ( reference .pointer - HandleFactory . HANDLE_BASE );
259
+ if (HandlePointerConverter .pointsToPyHandleSpace (reference .pointer )) {
260
+ int index = HandlePointerConverter . pointerToHandleIndex ( reference .pointer );
261
261
assert context .nativeHandles .get (index ) != null ;
262
262
context .nativeHandles .set (index , null );
263
263
context .nativeHandlesFreeStack .push (index );
@@ -360,7 +360,7 @@ public Object execute(Object[] args,
360
360
throw CompilerDirectives .shouldNotReachHere (e );
361
361
}
362
362
}
363
- assert HandleTester .pointsToPyHandleSpace (pointer );
363
+ assert HandlePointerConverter .pointsToPyHandleSpace (pointer );
364
364
release (pointer );
365
365
return 0 ;
366
366
}
@@ -402,11 +402,7 @@ public Object execute(Object[] args,
402
402
throw CompilerDirectives .shouldNotReachHere (e );
403
403
}
404
404
}
405
- return pointsToPyHandleSpace (pointer ) ? 1 : 0 ;
406
- }
407
-
408
- public static boolean pointsToPyHandleSpace (long pointer ) {
409
- return (pointer & HandleFactory .HANDLE_BASE ) != 0 ;
405
+ return HandlePointerConverter .pointsToPyHandleSpace (pointer ) ? 1 : 0 ;
410
406
}
411
407
}
412
408
@@ -427,7 +423,7 @@ public Object execute(Object[] args) {
427
423
}
428
424
429
425
public static PythonNativeWrapper resolve (long pointer ) {
430
- PythonNativeWrapper wrapper = getContext ().nativeHandles .get (( int ) ( pointer - HandleFactory . HANDLE_BASE )).get ();
426
+ PythonNativeWrapper wrapper = getContext ().nativeHandles .get (HandlePointerConverter . pointerToHandleIndex ( pointer )).get ();
431
427
assert wrapper != null : "reference was collected: " + Long .toHexString (pointer );
432
428
incRef (wrapper , 1 );
433
429
return wrapper ;
@@ -451,15 +447,35 @@ public Object execute(Object[] args) {
451
447
}
452
448
453
449
public static PythonNativeWrapper resolve (long pointer ) {
454
- PythonNativeWrapper wrapper = getContext ().nativeHandles .get (( int ) ( pointer - HandleFactory . HANDLE_BASE )).get ();
450
+ PythonNativeWrapper wrapper = getContext ().nativeHandles .get (HandlePointerConverter . pointerToHandleIndex ( pointer )).get ();
455
451
assert wrapper != null : "reference was collected: " + Long .toHexString (pointer );
456
452
return wrapper ;
457
453
}
458
454
}
459
455
460
- public static final class HandleFactory {
456
+ public static final class HandlePointerConverter {
457
+
458
+ private static final long HANDLE_BASE = 0x8000_0000_0000_0000L ;
461
459
462
- public static final long HANDLE_BASE = 0x8000_0000_0000_0000L ;
460
+ /**
461
+ * We need to shift the pointers because some libraries, notably cffi, do pointer tagging.
462
+ */
463
+ private static final int HANDLE_SHIFT = 3 ;
464
+
465
+ public static long handleIndexToPointer (int idx ) {
466
+ return ((long ) idx << HANDLE_SHIFT ) | HANDLE_BASE ;
467
+ }
468
+
469
+ public static int pointerToHandleIndex (long pointer ) {
470
+ return (int ) ((pointer & ~HANDLE_BASE ) >>> HANDLE_SHIFT );
471
+ }
472
+
473
+ public static boolean pointsToPyHandleSpace (long pointer ) {
474
+ return (pointer & HANDLE_BASE ) != 0 ;
475
+ }
476
+ }
477
+
478
+ public static final class HandleFactory {
463
479
464
480
public static long create (PythonNativeWrapper wrapper ) {
465
481
CompilerAsserts .neverPartOfCompilation ();
@@ -470,11 +486,11 @@ public static long create(PythonNativeWrapper wrapper) {
470
486
int idx = handleContext .nativeHandlesFreeStack .pop ();
471
487
long pointer ;
472
488
if (idx == -1 ) {
473
- pointer = HANDLE_BASE + handleContext .nativeHandles .size ();
489
+ pointer = HandlePointerConverter . handleIndexToPointer ( handleContext .nativeHandles .size () );
474
490
handleContext .nativeHandles .add (new PythonObjectReference (wrapper , pointer ));
475
491
} else {
476
492
assert idx >= 0 ;
477
- pointer = HANDLE_BASE + idx ;
493
+ pointer = HandlePointerConverter . handleIndexToPointer ( idx ) ;
478
494
handleContext .nativeHandles .set (idx , new PythonObjectReference (wrapper , pointer ));
479
495
}
480
496
return pointer ;
@@ -661,7 +677,7 @@ public static Object nativeCharToJava(Object value) {
661
677
} catch (UnsupportedMessageException e ) {
662
678
throw CompilerDirectives .shouldNotReachHere (e );
663
679
}
664
- if (HandleTester .pointsToPyHandleSpace (pointer )) {
680
+ if (HandlePointerConverter .pointsToPyHandleSpace (pointer )) {
665
681
PythonNativeWrapper obj = HandleResolver .resolve (pointer );
666
682
if (obj != null ) {
667
683
return logResult (obj .getDelegate ());
@@ -842,8 +858,8 @@ Object doNonWrapper(Object value,
842
858
return PNone .NO_VALUE ;
843
859
}
844
860
assert pythonContext .ownsGil ();
845
- if (isHandleSpaceProfile .profile (inliningTarget , HandleTester .pointsToPyHandleSpace (pointer ))) {
846
- PythonObjectReference reference = nativeContext .nativeHandles .get (( int ) ( pointer - HandleFactory . HANDLE_BASE ));
861
+ if (isHandleSpaceProfile .profile (inliningTarget , HandlePointerConverter .pointsToPyHandleSpace (pointer ))) {
862
+ PythonObjectReference reference = nativeContext .nativeHandles .get (HandlePointerConverter . pointerToHandleIndex ( pointer ));
847
863
if (reference == null ) {
848
864
CompilerDirectives .transferToInterpreterAndInvalidate ();
849
865
throw CompilerDirectives .shouldNotReachHere ("reference was freed: " + Long .toHexString (pointer ));
@@ -1005,8 +1021,8 @@ public static PythonNativeWrapper nativeToPythonWrapper(Object obj) {
1005
1021
}
1006
1022
assert PythonContext .get (null ).ownsGil ();
1007
1023
PythonNativeWrapper wrapper ;
1008
- if (HandleTester .pointsToPyHandleSpace (pointer )) {
1009
- PythonObjectReference reference = getContext ().nativeHandles .get (( int ) ( pointer - HandleFactory . HANDLE_BASE ));
1024
+ if (HandlePointerConverter .pointsToPyHandleSpace (pointer )) {
1025
+ PythonObjectReference reference = getContext ().nativeHandles .get (HandlePointerConverter . pointerToHandleIndex ( pointer ));
1010
1026
if (reference == null || (wrapper = reference .get ()) == null ) {
1011
1027
throw CompilerDirectives .shouldNotReachHere ("reference was collected: " + Long .toHexString (pointer ));
1012
1028
}
0 commit comments