Skip to content

Commit 06441f0

Browse files
committed
Shift handle pointers to keep space for libraries doing pointer tagging
1 parent ed28348 commit 06441f0

File tree

4 files changed

+42
-26
lines changed

4 files changed

+42
-26
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextBuiltins.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,8 @@
103103
import com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor;
104104
import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTiming;
105105
import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions;
106+
import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions.HandlePointerConverter;
106107
import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions.HandleReleaser;
107-
import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions.HandleTester;
108108
import com.oracle.graal.python.builtins.objects.cext.common.CArrayWrappers.CArrayWrapper;
109109
import com.oracle.graal.python.builtins.objects.cext.common.CExtParseArgumentsNode;
110110
import com.oracle.graal.python.builtins.objects.cext.common.CExtParseArgumentsNode.SplitFormatStringNode;
@@ -1385,7 +1385,7 @@ static void doNativeWrapper(PythonNativeWrapper nativeWrapper,
13851385
if (LOGGER.isLoggable(Level.FINER)) {
13861386
LOGGER.finer(() -> PythonUtils.formatJString("Releasing handle: %x (object: %s)", nativePointer, nativeWrapper));
13871387
}
1388-
if (HandleTester.pointsToPyHandleSpace(nativePointer)) {
1388+
if (HandlePointerConverter.pointsToPyHandleSpace(nativePointer)) {
13891389
HandleReleaser.release(nativePointer);
13901390
} else {
13911391
callReleaseHandleNode.call(NativeCAPISymbol.FUN_PY_TRUFFLE_FREE, nativePointer);

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CExtNodes.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,8 @@
9292
import com.oracle.graal.python.builtins.objects.cext.capi.PyTruffleObjectFree.FreeNode;
9393
import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions;
9494
import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions.CharPtrToPythonNode;
95+
import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions.HandlePointerConverter;
9596
import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions.HandleResolver;
96-
import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions.HandleTester;
9797
import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions.NativeToPythonNode;
9898
import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions.NativeToPythonStealingNode;
9999
import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions.PythonToNativeNode;
@@ -2087,7 +2087,7 @@ Object resolveLongCached(long pointer) {
20872087
if (lookup != null) {
20882088
return lookup;
20892089
}
2090-
if (HandleTester.pointsToPyHandleSpace(pointer)) {
2090+
if (HandlePointerConverter.pointsToPyHandleSpace(pointer)) {
20912091
return HandleResolver.resolve(pointer);
20922092
}
20932093
return pointer;
@@ -2108,7 +2108,7 @@ Object resolveGeneric(Object pointerObject,
21082108
if (lookup != null) {
21092109
return lookup;
21102110
}
2111-
if (HandleTester.pointsToPyHandleSpace(pointer)) {
2111+
if (HandlePointerConverter.pointsToPyHandleSpace(pointer)) {
21122112
return HandleResolver.resolve(pointer);
21132113
}
21142114
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/PyTruffleObjectFree.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@
4444

4545
import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes.ClearNativeWrapperNode;
4646
import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes.PCallCapiFunction;
47+
import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions.HandlePointerConverter;
4748
import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions.HandleReleaser;
48-
import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions.HandleTester;
4949
import com.oracle.graal.python.builtins.objects.cext.common.CArrayWrappers.CArrayWrapper;
5050
import com.oracle.graal.python.util.PythonUtils;
5151
import com.oracle.truffle.api.TruffleLogger;
@@ -117,7 +117,7 @@ static void doNativeWrapper(PythonNativeWrapper nativeWrapper,
117117
if (LOGGER.isLoggable(Level.FINER)) {
118118
LOGGER.finer(() -> PythonUtils.formatJString("Releasing handle: %x (object: %s)", nativePointer, nativeWrapper));
119119
}
120-
if (HandleTester.pointsToPyHandleSpace(nativePointer)) {
120+
if (HandlePointerConverter.pointsToPyHandleSpace(nativePointer)) {
121121
HandleReleaser.release(nativePointer);
122122
} else {
123123
callReleaseHandleNode.call(NativeCAPISymbol.FUN_PY_TRUFFLE_FREE, nativePointer);

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/transitions/CApiTransitions.java

Lines changed: 35 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)