Skip to content

Commit 11f59f0

Browse files
committed
Profile if HPy handle is allocated
1 parent b3ae653 commit 11f59f0

File tree

5 files changed

+50
-31
lines changed

5 files changed

+50
-31
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPyContextFunctions.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -227,14 +227,15 @@ public static final class GraalHPyClose extends GraalHPyContextFunction {
227227
@ExportMessage
228228
Object execute(Object[] arguments,
229229
@Cached HPyAsContextNode asContextNode,
230+
@Cached ConditionProfile isAllocatedProfile,
230231
@Cached HPyEnsureHandleNode ensureHandleNode) throws ArityException {
231232
if (arguments.length != 2) {
232233
CompilerDirectives.transferToInterpreterAndInvalidate();
233234
throw ArityException.create(2, arguments.length);
234235
}
235236
GraalHPyContext hpyContext = asContextNode.execute(arguments[0]);
236237
GraalHPyHandle handle = ensureHandleNode.execute(hpyContext, arguments[1]);
237-
handle.close(hpyContext);
238+
handle.close(hpyContext, isAllocatedProfile);
238239
return 0;
239240
}
240241
}
@@ -1830,14 +1831,15 @@ public static final class GraalHPyBuilderCancel extends GraalHPyContextFunction
18301831
Object execute(Object[] arguments,
18311832
@Cached HPyAsContextNode asContextNode,
18321833
@Cached HPyEnsureHandleNode ensureHandleNode,
1834+
@Cached ConditionProfile isAllocatedProfile,
18331835
@Cached HPyAsPythonObjectNode asPythonObjectNode) throws ArityException, UnsupportedTypeException {
18341836
if (arguments.length != 2) {
18351837
CompilerDirectives.transferToInterpreterAndInvalidate();
18361838
throw ArityException.create(2, arguments.length);
18371839
}
18381840
GraalHPyContext nativeContext = asContextNode.execute(arguments[0]);
18391841
GraalHPyHandle hpyHandle = ensureHandleNode.execute(nativeContext, arguments[1]);
1840-
hpyHandle.close(nativeContext);
1842+
hpyHandle.close(nativeContext, isAllocatedProfile);
18411843

18421844
// be pedantic and also check what we are cancelling
18431845
ObjectSequenceStorage builder = cast(asPythonObjectNode.execute(nativeContext, hpyHandle));

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPyHandle.java

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -40,16 +40,14 @@
4040
*/
4141
package com.oracle.graal.python.builtins.objects.cext.hpy;
4242

43-
import java.lang.ref.PhantomReference;
44-
import java.lang.ref.ReferenceQueue;
45-
4643
import com.oracle.graal.python.PythonLanguage;
4744
import com.oracle.graal.python.builtins.objects.PythonAbstractObject;
4845
import com.oracle.graal.python.builtins.objects.cext.PythonNativeWrapperLibrary;
4946
import com.oracle.graal.python.runtime.PythonContext;
5047
import com.oracle.truffle.api.Assumption;
5148
import com.oracle.truffle.api.CompilerDirectives;
5249
import com.oracle.truffle.api.dsl.Cached;
50+
import com.oracle.truffle.api.dsl.Cached.Shared;
5351
import com.oracle.truffle.api.dsl.CachedContext;
5452
import com.oracle.truffle.api.dsl.Specialization;
5553
import com.oracle.truffle.api.interop.InteropLibrary;
@@ -83,13 +81,15 @@ public GraalHPyHandle(Object delegate) {
8381
}
8482

8583
@ExportMessage
86-
boolean isPointer() {
87-
return id != -1;
84+
boolean isPointer(
85+
@Shared("isAllocatedProfile") @Cached ConditionProfile isAllocatedProfile) {
86+
return isAllocatedProfile.profile(id != -1);
8887
}
8988

9089
@ExportMessage
91-
long asPointer() throws UnsupportedMessageException {
92-
if (!isPointer()) {
90+
long asPointer(
91+
@Shared("isAllocatedProfile") @Cached ConditionProfile isAllocatedProfile) throws UnsupportedMessageException {
92+
if (!isPointer(isAllocatedProfile)) {
9393
CompilerDirectives.transferToInterpreterAndInvalidate();
9494
throw UnsupportedMessageException.create();
9595
}
@@ -98,9 +98,10 @@ long asPointer() throws UnsupportedMessageException {
9898

9999
@ExportMessage
100100
void toNative(
101+
@Shared("isAllocatedProfile") @Cached ConditionProfile isAllocatedProfile,
101102
@CachedContext(PythonLanguage.class) PythonContext context,
102103
@Cached("createCountingProfile()") ConditionProfile notNativeProfile) {
103-
if (notNativeProfile.profile(!isPointer())) {
104+
if (notNativeProfile.profile(!isPointer(isAllocatedProfile))) {
104105
id = context.getHPyContext().getHPyHandleForObject(this);
105106
}
106107
}
@@ -140,13 +141,15 @@ Object getDelegate() {
140141
}
141142

142143
@ExportMessage
143-
Object getNativePointer() {
144-
return isPointer() ? id : null;
144+
Object getNativePointer(
145+
@Shared("isAllocatedProfile") @Cached ConditionProfile isAllocatedProfile) {
146+
return isPointer(isAllocatedProfile) ? id : null;
145147
}
146148

147149
@ExportMessage
148-
boolean isNative() {
149-
return isPointer();
150+
boolean isNative(
151+
@Shared("isAllocatedProfile") @Cached ConditionProfile isAllocatedProfile) {
152+
return isPointer(isAllocatedProfile);
150153
}
151154

152155
@ExportMessage
@@ -179,10 +182,10 @@ public GraalHPyHandle copy() {
179182
return new GraalHPyHandle(delegate);
180183
}
181184

182-
public void close(GraalHPyContext hpyContext) {
183-
if (isPointer()) {
185+
public void close(GraalHPyContext hpyContext, ConditionProfile isAllocatedProfile) {
186+
if (isPointer(isAllocatedProfile)) {
184187
try {
185-
hpyContext.releaseHPyHandleForObject((int) asPointer());
188+
hpyContext.releaseHPyHandleForObject((int) asPointer(isAllocatedProfile));
186189
id = -1;
187190
} catch (UnsupportedMessageException e) {
188191
CompilerDirectives.transferToInterpreterAndInvalidate();

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPyNodes.java

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@
138138
import com.oracle.truffle.api.nodes.Node;
139139
import com.oracle.truffle.api.object.HiddenKey;
140140
import com.oracle.truffle.api.profiles.BranchProfile;
141+
import com.oracle.truffle.api.profiles.ConditionProfile;
141142

142143
public class GraalHPyNodes {
143144

@@ -1225,8 +1226,9 @@ public abstract static class HPyVarargsHandleCloseNode extends HPyCloseArgHandle
12251226
@Specialization
12261227
static void doConvert(GraalHPyContext hpyContext, Object[] dest, int destOffset,
12271228
@Cached HPyEnsureHandleNode ensureHandleNode,
1229+
@Cached ConditionProfile isAllocatedProfile,
12281230
@Cached HPyCloseArrayWrapperNode closeArrayWrapperNode) {
1229-
ensureHandleNode.execute(hpyContext, dest[destOffset]).close(hpyContext);
1231+
ensureHandleNode.execute(hpyContext, dest[destOffset]).close(hpyContext, isAllocatedProfile);
12301232
closeArrayWrapperNode.execute(hpyContext, (HPyArrayWrapper) dest[destOffset + 1]);
12311233
}
12321234
}
@@ -1238,8 +1240,9 @@ public abstract static class HPySelfHandleCloseNode extends HPyCloseArgHandlesNo
12381240

12391241
@Specialization
12401242
static void doConvert(GraalHPyContext hpyContext, Object[] dest, int destOffset,
1243+
@Cached ConditionProfile isAllocatedProfile,
12411244
@Cached HPyEnsureHandleNode ensureHandleNode) {
1242-
ensureHandleNode.execute(hpyContext, dest[destOffset]).close(hpyContext);
1245+
ensureHandleNode.execute(hpyContext, dest[destOffset]).close(hpyContext, isAllocatedProfile);
12431246
}
12441247
}
12451248

@@ -1269,10 +1272,11 @@ public abstract static class HPyKeywordsHandleCloseNode extends HPyCloseArgHandl
12691272
@Specialization
12701273
static void doConvert(GraalHPyContext hpyContext, Object[] dest, int destOffset,
12711274
@Cached HPyEnsureHandleNode ensureHandleNode,
1275+
@Cached ConditionProfile isAllocatedProfile,
12721276
@Cached HPyCloseArrayWrapperNode closeArrayWrapperNode) {
1273-
ensureHandleNode.execute(hpyContext, dest[destOffset]).close(hpyContext);
1277+
ensureHandleNode.execute(hpyContext, dest[destOffset]).close(hpyContext, isAllocatedProfile);
12741278
closeArrayWrapperNode.execute(hpyContext, (HPyArrayWrapper) dest[destOffset + 1]);
1275-
ensureHandleNode.execute(hpyContext, dest[destOffset + 3]).close(hpyContext);
1279+
ensureHandleNode.execute(hpyContext, dest[destOffset + 3]).close(hpyContext, isAllocatedProfile);
12761280
}
12771281
}
12781282

@@ -1331,19 +1335,21 @@ static void cached0(GraalHPyContext hpyContext, Object[] dest, int destOffset) {
13311335
@ExplodeLoop
13321336
static void cachedLoop(GraalHPyContext hpyContext, Object[] dest, int destOffset,
13331337
@Cached("dest.length") int cachedLength,
1338+
@Cached ConditionProfile isAllocatedProfile,
13341339
@Cached HPyEnsureHandleNode ensureHandleNode) {
13351340
CompilerAsserts.partialEvaluationConstant(destOffset);
13361341
for (int i = 0; i < cachedLength - destOffset; i++) {
1337-
ensureHandleNode.execute(hpyContext, dest[destOffset + i]).close(hpyContext);
1342+
ensureHandleNode.execute(hpyContext, dest[destOffset + i]).close(hpyContext, isAllocatedProfile);
13381343
}
13391344
}
13401345

13411346
@Specialization(replaces = {"cached0", "cachedLoop"})
13421347
static void uncached(GraalHPyContext hpyContext, Object[] dest, int destOffset,
1348+
@Cached ConditionProfile isAllocatedProfile,
13431349
@Cached HPyEnsureHandleNode ensureHandleNode) {
13441350
int len = dest.length;
13451351
for (int i = 0; i < len - destOffset; i++) {
1346-
ensureHandleNode.execute(hpyContext, dest[destOffset + i]).close(hpyContext);
1352+
ensureHandleNode.execute(hpyContext, dest[destOffset + i]).close(hpyContext, isAllocatedProfile);
13471353
}
13481354
}
13491355

@@ -1398,9 +1404,10 @@ public abstract static class HPyGetSetSetterHandleCloseNode extends HPyCloseArgH
13981404

13991405
@Specialization
14001406
static void doConvert(GraalHPyContext hpyContext, Object[] dest, int destOffset,
1407+
@Cached ConditionProfile isAllocatedProfile,
14011408
@Cached HPyEnsureHandleNode ensureHandleNode) {
1402-
ensureHandleNode.execute(hpyContext, dest[destOffset]).close(hpyContext);
1403-
ensureHandleNode.execute(hpyContext, dest[destOffset + 1]).close(hpyContext);
1409+
ensureHandleNode.execute(hpyContext, dest[destOffset]).close(hpyContext, isAllocatedProfile);
1410+
ensureHandleNode.execute(hpyContext, dest[destOffset + 1]).close(hpyContext, isAllocatedProfile);
14041411
}
14051412
}
14061413

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/HPyArrayWrappers.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -321,12 +321,13 @@ abstract static class HPyCloseArrayWrapperNode extends Node {
321321
static void doCachedLen(GraalHPyContext hPyContext, HPyArrayWrapper wrapper,
322322
@CachedLibrary("wrapper") InteropLibrary lib,
323323
@Cached("size(lib, wrapper)") int cachedLen,
324+
@Cached ConditionProfile isAllocatedProfile,
324325
@Cached(value = "createProfiles(cachedLen)", dimensions = 1) ConditionProfile[] profiles) {
325326
try {
326327
for (int i = 0; i < cachedLen; i++) {
327328
Object element = lib.readArrayElement(wrapper, i);
328329
if (profiles[i].profile(isAllocatedHandle(element))) {
329-
((GraalHPyHandle) element).close(hPyContext);
330+
((GraalHPyHandle) element).close(hPyContext, isAllocatedProfile);
330331
}
331332
}
332333
} catch (InteropException e) {
@@ -336,12 +337,13 @@ static void doCachedLen(GraalHPyContext hPyContext, HPyArrayWrapper wrapper,
336337

337338
@Specialization(replaces = "doCachedLen")
338339
static void doLoop(GraalHPyContext hPyContext, HPyArrayWrapper wrapper,
340+
@Cached ConditionProfile isAllocatedProfile,
339341
@Cached ConditionProfile profile) {
340342
Object[] array = wrapper.getDelegate();
341343
for (int i = 0; i < array.length; i++) {
342344
Object element = array[i];
343345
if (profile.profile(isAllocatedHandle(element))) {
344-
((GraalHPyHandle) element).close(hPyContext);
346+
((GraalHPyHandle) element).close(hPyContext, isAllocatedProfile);
345347
}
346348
}
347349
}
@@ -358,7 +360,9 @@ static int size(InteropLibrary lib, HPyArrayWrapper wrapper) {
358360
}
359361

360362
static boolean isAllocatedHandle(Object element) {
361-
return element instanceof GraalHPyHandle && ((GraalHPyHandle) element).isPointer();
363+
// n.b. we pass the uncached instance to 'isPointer' since we profile this whole
364+
// condition
365+
return element instanceof GraalHPyHandle && ((GraalHPyHandle) element).isPointer(ConditionProfile.getUncached());
362366
}
363367

364368
static ConditionProfile[] createProfiles(int n) {

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/HPyExternalFunctionNodes.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -740,19 +740,21 @@ Object doNullHandle(GraalHPyContext nativeContext, String name, @SuppressWarning
740740

741741
@Specialization(guards = "!isNullHandle(nativeContext, handle)", replaces = "doNullHandle")
742742
Object doNonNullHandle(GraalHPyContext nativeContext, String name, GraalHPyHandle handle,
743+
@Cached ConditionProfile isAllocatedProfile,
743744
@Exclusive @Cached HPyAsPythonObjectNode asPythonObjectNode,
744745
@Shared("language") @CachedLanguage PythonLanguage language,
745746
@Shared("fact") @Cached PythonObjectFactory factory,
746747
@Shared("raiseNode") @Cached PRaiseNode raiseNode) {
747748
// Python land is receiving a handle from an HPy extension, so we are now owning the
748749
// handle and we don't need it any longer. So, close it in every case.
749-
handle.close(nativeContext);
750+
handle.close(nativeContext, isAllocatedProfile);
750751
checkFunctionResult(name, false, nativeContext, raiseNode, factory, language);
751752
return asPythonObjectNode.execute(nativeContext, handle);
752753
}
753754

754755
@Specialization(replaces = {"doIntegerNull", "doNonNullHandle"})
755756
Object doHandle(GraalHPyContext nativeContext, String name, GraalHPyHandle handle,
757+
@Cached ConditionProfile isAllocatedProfile,
756758
@Exclusive @Cached HPyAsPythonObjectNode asPythonObjectNode,
757759
@Shared("language") @CachedLanguage PythonLanguage language,
758760
@Shared("fact") @Cached PythonObjectFactory factory,
@@ -761,7 +763,7 @@ Object doHandle(GraalHPyContext nativeContext, String name, GraalHPyHandle handl
761763
if (!isNullHandle) {
762764
// Python land is receiving a handle from an HPy extension, so we are now owning the
763765
// handle and we don't need it any longer. So, close it in every case.
764-
handle.close(nativeContext);
766+
handle.close(nativeContext, isAllocatedProfile);
765767
}
766768
checkFunctionResult(name, isNullHandle, nativeContext, raiseNode, factory, language);
767769
return asPythonObjectNode.execute(nativeContext, handle);
@@ -770,14 +772,15 @@ Object doHandle(GraalHPyContext nativeContext, String name, GraalHPyHandle handl
770772
@Specialization(replaces = {"doIntegerNull", "doInteger", "doLongNull", "doLong", "doNullHandle", "doNonNullHandle", "doHandle"})
771773
Object doGeneric(GraalHPyContext nativeContext, String name, Object value,
772774
@Cached HPyEnsureHandleNode ensureHandleNode,
775+
@Cached ConditionProfile isAllocatedProfile,
773776
@Cached HPyAsPythonObjectNode asPythonObjectNode,
774777
@Shared("language") @CachedLanguage PythonLanguage language,
775778
@Shared("fact") @Cached PythonObjectFactory factory,
776779
@Shared("raiseNode") @Cached PRaiseNode raiseNode) {
777780
GraalHPyHandle handle = ensureHandleNode.execute(nativeContext, value);
778781
// Python land is receiving a handle from an HPy extension, so we are now owning the
779782
// handle and we don't need it any longer. So, close it in every case.
780-
handle.close(nativeContext);
783+
handle.close(nativeContext, isAllocatedProfile);
781784
checkFunctionResult(name, isNullHandle(nativeContext, handle), nativeContext, raiseNode, factory, language);
782785
return asPythonObjectNode.execute(nativeContext, handle);
783786
}

0 commit comments

Comments
 (0)