@@ -256,8 +256,8 @@ public static void pollReferenceQueue() {
256256 if (entry instanceof PythonObjectReference reference ) {
257257 LOGGER .finer (() -> PythonUtils .formatJString ("releasing PythonObjectReference %s" , reference ));
258258
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 );
261261 assert context .nativeHandles .get (index ) != null ;
262262 context .nativeHandles .set (index , null );
263263 context .nativeHandlesFreeStack .push (index );
@@ -360,7 +360,7 @@ public Object execute(Object[] args,
360360 throw CompilerDirectives .shouldNotReachHere (e );
361361 }
362362 }
363- assert HandleTester .pointsToPyHandleSpace (pointer );
363+ assert HandlePointerConverter .pointsToPyHandleSpace (pointer );
364364 release (pointer );
365365 return 0 ;
366366 }
@@ -402,11 +402,7 @@ public Object execute(Object[] args,
402402 throw CompilerDirectives .shouldNotReachHere (e );
403403 }
404404 }
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 ;
410406 }
411407 }
412408
@@ -427,7 +423,7 @@ public Object execute(Object[] args) {
427423 }
428424
429425 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 ();
431427 assert wrapper != null : "reference was collected: " + Long .toHexString (pointer );
432428 incRef (wrapper , 1 );
433429 return wrapper ;
@@ -451,15 +447,35 @@ public Object execute(Object[] args) {
451447 }
452448
453449 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 ();
455451 assert wrapper != null : "reference was collected: " + Long .toHexString (pointer );
456452 return wrapper ;
457453 }
458454 }
459455
460- public static final class HandleFactory {
456+ public static final class HandlePointerConverter {
457+
458+ private static final long HANDLE_BASE = 0x8000_0000_0000_0000L ;
461459
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 {
463479
464480 public static long create (PythonNativeWrapper wrapper ) {
465481 CompilerAsserts .neverPartOfCompilation ();
@@ -470,11 +486,11 @@ public static long create(PythonNativeWrapper wrapper) {
470486 int idx = handleContext .nativeHandlesFreeStack .pop ();
471487 long pointer ;
472488 if (idx == -1 ) {
473- pointer = HANDLE_BASE + handleContext .nativeHandles .size ();
489+ pointer = HandlePointerConverter . handleIndexToPointer ( handleContext .nativeHandles .size () );
474490 handleContext .nativeHandles .add (new PythonObjectReference (wrapper , pointer ));
475491 } else {
476492 assert idx >= 0 ;
477- pointer = HANDLE_BASE + idx ;
493+ pointer = HandlePointerConverter . handleIndexToPointer ( idx ) ;
478494 handleContext .nativeHandles .set (idx , new PythonObjectReference (wrapper , pointer ));
479495 }
480496 return pointer ;
@@ -661,7 +677,7 @@ public static Object nativeCharToJava(Object value) {
661677 } catch (UnsupportedMessageException e ) {
662678 throw CompilerDirectives .shouldNotReachHere (e );
663679 }
664- if (HandleTester .pointsToPyHandleSpace (pointer )) {
680+ if (HandlePointerConverter .pointsToPyHandleSpace (pointer )) {
665681 PythonNativeWrapper obj = HandleResolver .resolve (pointer );
666682 if (obj != null ) {
667683 return logResult (obj .getDelegate ());
@@ -842,8 +858,8 @@ Object doNonWrapper(Object value,
842858 return PNone .NO_VALUE ;
843859 }
844860 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 ));
847863 if (reference == null ) {
848864 CompilerDirectives .transferToInterpreterAndInvalidate ();
849865 throw CompilerDirectives .shouldNotReachHere ("reference was freed: " + Long .toHexString (pointer ));
@@ -1005,8 +1021,8 @@ public static PythonNativeWrapper nativeToPythonWrapper(Object obj) {
10051021 }
10061022 assert PythonContext .get (null ).ownsGil ();
10071023 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 ));
10101026 if (reference == null || (wrapper = reference .get ()) == null ) {
10111027 throw CompilerDirectives .shouldNotReachHere ("reference was collected: " + Long .toHexString (pointer ));
10121028 }
0 commit comments