Skip to content

Commit d442f79

Browse files
committed
[GR-52437] Avoid HashMap lookup for resolving tagged pointers.
PullRequest: graalpython/3226
2 parents 2702528 + 134d317 commit d442f79

File tree

9 files changed

+223
-35
lines changed

9 files changed

+223
-35
lines changed

graalpython/com.oracle.graal.python.cext/src/capi.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,11 @@ typedef struct {
105105

106106
typedef struct {
107107
PyObject_VAR_HEAD
108+
int32_t handle_table_index;
109+
} GraalPyObject;
110+
111+
typedef struct {
112+
GraalPyObject ob_base;
108113
PyObject **ob_item;
109114
} GraalPyVarObject;
110115

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

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -44,7 +44,9 @@
4444

4545
import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes.ClearNativeWrapperNode;
4646
import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions;
47+
import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions.HandleContext;
4748
import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions.HandlePointerConverter;
49+
import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions.PythonObjectReference;
4850
import com.oracle.graal.python.builtins.objects.cext.common.CArrayWrappers.CArrayWrapper;
4951
import com.oracle.graal.python.builtins.objects.cext.structs.CStructAccess;
5052
import com.oracle.graal.python.builtins.objects.cext.structs.CStructAccessFactory;
@@ -123,12 +125,21 @@ static void releaseNativeWrapper(PythonNativeWrapper nativeWrapper, CStructAcces
123125
}
124126
if (HandlePointerConverter.pointsToPyHandleSpace(nativePointer)) {
125127
// In this case, we are up to free a native object stub.
126-
nativePointer = HandlePointerConverter.pointerToStub(nativePointer);
127-
assert CApiTransitions.nativeStubLookupGet(PythonContext.get(freeNode).nativeContext, nativePointer) == null;
128+
assert tableEntryRemoved(PythonContext.get(freeNode).nativeContext, nativeWrapper);
128129
} else {
129130
CApiTransitions.nativeLookupRemove(PythonContext.get(freeNode).nativeContext, nativePointer);
130131
}
131132
freeNode.free(nativePointer);
132133
}
133134
}
135+
136+
private static boolean tableEntryRemoved(HandleContext context, PythonNativeWrapper nativeWrapper) {
137+
PythonObjectReference ref = nativeWrapper.ref;
138+
if (ref != null) {
139+
int id = ref.getHandleTableIndex();
140+
return id <= 0 || CApiTransitions.nativeStubLookupGet(context, nativeWrapper.getNativePointer(), id) == null;
141+
}
142+
// there cannot be a table entry if the wrapper does not have a PythonObjectReference
143+
return true;
144+
}
134145
}

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

Lines changed: 168 additions & 29 deletions
Large diffs are not rendered by default.

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/common/CExtContext.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ private static String dlopenFlagsToString(int flags) {
314314
public static Object loadCExtModule(Node location, PythonContext context, ModuleSpec spec, CheckFunctionResultNode checkFunctionResultNode)
315315
throws IOException, ApiInitException, ImportException {
316316

317-
// we always need to load the CPython C API (even for HPy modules)
317+
// we always need to load the CPython C API
318318
CApiContext cApiContext = CApiContext.ensureCapiWasLoaded(location, context, spec.name, spec.path);
319319
Object library;
320320
InteropLibrary interopLib;

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/common/HandleStack.java

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -42,12 +42,21 @@
4242

4343
import java.util.Arrays;
4444

45+
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
46+
4547
public final class HandleStack {
4648
private int[] handles;
4749
private int top = 0;
4850

4951
public HandleStack(int initialCapacity) {
52+
this(initialCapacity, false);
53+
}
54+
55+
public HandleStack(int initialCapacity, boolean fill) {
5056
handles = new int[initialCapacity];
57+
if (fill) {
58+
pushRange(0, initialCapacity);
59+
}
5160
}
5261

5362
public void push(int i) {
@@ -57,6 +66,24 @@ public void push(int i) {
5766
handles[top++] = i;
5867
}
5968

69+
/**
70+
* Push a range of values to the stack.
71+
*
72+
* @param start The first value to push (inclusive).
73+
* @param end The last value to push (exclusive).
74+
*/
75+
@TruffleBoundary
76+
public void pushRange(int start, int end) {
77+
int n = end - start;
78+
if (top + n > handles.length) {
79+
handles = Arrays.copyOf(handles, top + n);
80+
}
81+
for (int i = 0; i < n; i++) {
82+
handles[top + i] = end - i - 1;
83+
}
84+
top += n;
85+
}
86+
6087
public int pop() {
6188
if (top <= 0) {
6289
return -1;

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/structs/CFields.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ public enum CFields {
116116

117117
PyVarObject__ob_size(Py_ssize_t),
118118

119+
GraalPyObject__handle_table_index(Int),
119120
GraalPyVarObject__ob_item(PyObjectPtr),
120121

121122
PyModuleDef__m_name(ConstCharPtr),

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/structs/CStructAccess.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -988,6 +988,10 @@ static void writeManaged(Object pointer, long offset, short value,
988988
@GenerateUncached
989989
public abstract static class WriteIntNode extends Node implements CStructAccessNode {
990990

991+
public static void writeUncached(Object pointer, CFields field, int value) {
992+
CStructAccessFactory.WriteIntNodeGen.getUncached().write(pointer, field, value);
993+
}
994+
991995
abstract void execute(Object pointer, long offset, int value);
992996

993997
public final void write(Object pointer, CFields field, int value) {

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/structs/CStructs.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ public enum CStructs {
5353
PyModuleDef_Slot,
5454
PyMethodDef,
5555
PyObject,
56+
GraalPyObject,
5657
PyBytesObject,
5758
PyByteArrayObject,
5859
PyListObject,

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PythonContext.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ public final class PythonContext extends Python3Core {
213213

214214
private static final TruffleLogger LOGGER = PythonLanguage.getLogger(PythonContext.class);
215215

216-
public final HandleContext nativeContext = new HandleContext();
216+
public final HandleContext nativeContext = new HandleContext(DEBUG_CAPI);
217217
private volatile boolean finalizing;
218218

219219
@TruffleBoundary

0 commit comments

Comments
 (0)