Skip to content

Commit e569ce1

Browse files
committed
[GR-30482] Replace isForeignObject message with a node
PullRequest: graalpython/1810
2 parents c844494 + 07a483a commit e569ce1

File tree

12 files changed

+192
-111
lines changed

12 files changed

+192
-111
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/JavaModuleBuiltins.java

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
6161
import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
6262
import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
63+
import com.oracle.graal.python.nodes.object.IsForeignObjectNode;
6364
import com.oracle.graal.python.nodes.util.CannotCastException;
6465
import com.oracle.graal.python.nodes.util.CastToJavaStringNode;
6566
import com.oracle.graal.python.runtime.GilNode;
@@ -70,6 +71,7 @@
7071
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
7172
import com.oracle.truffle.api.TruffleLanguage.Env;
7273
import com.oracle.truffle.api.dsl.Cached;
74+
import com.oracle.truffle.api.dsl.Cached.Shared;
7375
import com.oracle.truffle.api.dsl.Fallback;
7476
import com.oracle.truffle.api.dsl.GenerateNodeFactory;
7577
import com.oracle.truffle.api.dsl.NodeFactory;
@@ -213,10 +215,10 @@ boolean isType(Object object) {
213215
@Builtin(name = "instanceof", minNumOfPositionalArgs = 2)
214216
@GenerateNodeFactory
215217
abstract static class InstanceOfNode extends PythonBinaryBuiltinNode {
216-
@Specialization(guards = {"!iLibObject.isForeignObject(object)", "iLibKlass.isForeignObject(klass)"}, limit = "3")
218+
@Specialization(guards = {"!isForeign1.execute(object)", "isForeign2.execute(klass)"}, limit = "1")
217219
boolean check(Object object, TruffleObject klass,
218-
@SuppressWarnings("unused") @CachedLibrary("object") PythonObjectLibrary iLibObject,
219-
@SuppressWarnings("unused") @CachedLibrary("klass") PythonObjectLibrary iLibKlass) {
220+
@SuppressWarnings("unused") @Shared("isForeign1") @Cached IsForeignObjectNode isForeign1,
221+
@SuppressWarnings("unused") @Shared("isForeign2") @Cached IsForeignObjectNode isForeign2) {
220222
Env env = getContext().getEnv();
221223
try {
222224
Object hostKlass = env.asHostObject(klass);
@@ -229,10 +231,10 @@ boolean check(Object object, TruffleObject klass,
229231
return false;
230232
}
231233

232-
@Specialization(guards = {"iLibObject.isForeignObject(object)", "iLibKlass.isForeignObject(klass)"}, limit = "3")
234+
@Specialization(guards = {"isForeign1.execute(object)", "isForeign2.execute(klass)"}, limit = "1")
233235
boolean checkForeign(Object object, TruffleObject klass,
234-
@SuppressWarnings("unused") @CachedLibrary("object") PythonObjectLibrary iLibObject,
235-
@SuppressWarnings("unused") @CachedLibrary("klass") PythonObjectLibrary iLibKlass) {
236+
@SuppressWarnings("unused") @Shared("isForeign1") @Cached IsForeignObjectNode isForeign1,
237+
@SuppressWarnings("unused") @Shared("isForeign2") @Cached IsForeignObjectNode isForeign2) {
236238
Env env = getContext().getEnv();
237239
try {
238240
Object hostObject = env.asHostObject(object);

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

Lines changed: 36 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@
138138
import com.oracle.graal.python.nodes.expression.ExpressionNode;
139139
import com.oracle.graal.python.nodes.frame.GetCurrentFrameRef;
140140
import com.oracle.graal.python.nodes.object.GetClassNode;
141-
import com.oracle.graal.python.nodes.object.IsBuiltinClassProfile;
141+
import com.oracle.graal.python.nodes.object.IsForeignObjectNode;
142142
import com.oracle.graal.python.nodes.truffle.PythonTypes;
143143
import com.oracle.graal.python.nodes.util.CannotCastException;
144144
import com.oracle.graal.python.nodes.util.CastToJavaLongLossyNode;
@@ -500,15 +500,16 @@ static Object runAbstractObject(@SuppressWarnings("unused") CExtContext cextCont
500500
return PythonObjectNativeWrapper.wrap(object, noWrapperProfile);
501501
}
502502

503-
@Specialization(guards = {"lib.isForeignObject(object)", "!isNativeWrapper(object)", "!isNativeNull(object)"})
503+
@Specialization(guards = {"isForeignObjectNode.execute(object)", "!isNativeWrapper(object)", "!isNativeNull(object)"})
504504
static Object doForeignObject(@SuppressWarnings("unused") CExtContext cextContext, TruffleObject object,
505-
@SuppressWarnings("unused") @CachedLibrary(limit = "3") PythonObjectLibrary lib) {
505+
@SuppressWarnings("unused") @Cached IsForeignObjectNode isForeignObjectNode) {
506506
return TruffleObjectNativeWrapper.wrap(object);
507507
}
508508

509-
@Specialization(guards = "isFallback(object, lib)")
509+
@Specialization(guards = "isFallback(object, isForeignObjectNode)")
510510
static Object run(@SuppressWarnings("unused") CExtContext cextContext, Object object,
511-
@SuppressWarnings("unused") @CachedLibrary(limit = "3") PythonObjectLibrary lib) {
511+
@SuppressWarnings("unused") @Cached IsForeignObjectNode isForeignObjectNode,
512+
@CachedLibrary(limit = "3") PythonObjectLibrary lib) {
512513
assert object != null : "Java 'null' cannot be a Sulong value";
513514
Object o = lib.getDelegatedValue(object);
514515
assert CApiGuards.isNativeWrapper(o) : "unknown object cannot be a Sulong value";
@@ -523,10 +524,10 @@ protected static PythonClassNativeWrapper wrapNativeClass(PythonContext ctx, Pyt
523524
return PythonClassNativeWrapper.wrap(ctx.getCore().lookupType(object), GetNameNode.doSlowPath(object));
524525
}
525526

526-
static boolean isFallback(Object object, PythonObjectLibrary lib) {
527+
static boolean isFallback(Object object, IsForeignObjectNode isForeignObjectNode) {
527528
return !(object instanceof String || object instanceof Boolean || object instanceof Integer || object instanceof Long || object instanceof Double ||
528529
object instanceof PythonBuiltinClassType || object instanceof PythonNativeNull || object == DescriptorDeleteMarker.INSTANCE ||
529-
object instanceof PythonAbstractObject) && !(lib.isForeignObject(object) && !CApiGuards.isNativeWrapper(object));
530+
object instanceof PythonAbstractObject) && !(isForeignObjectNode.execute(object) && !CApiGuards.isNativeWrapper(object));
530531
}
531532

532533
protected static boolean isNaN(double d) {
@@ -757,17 +758,18 @@ static Object runAbstractObject(@SuppressWarnings("unused") CExtContext cextCont
757758
return PythonObjectNativeWrapper.wrapNewRef(object, noWrapperProfile);
758759
}
759760

760-
@Specialization(guards = {"lib.isForeignObject(object)", "!isNativeWrapper(object)", "!isNativeNull(object)"})
761+
@Specialization(guards = {"isForeignObjectNode.execute(object)", "!isNativeWrapper(object)", "!isNativeNull(object)"})
761762
static Object doForeignObject(CExtContext cextContext, TruffleObject object,
762-
@CachedLibrary(limit = "3") PythonObjectLibrary lib) {
763+
@Cached IsForeignObjectNode isForeignObjectNode) {
763764
// this will always be a new wrapper; it's implicitly always a new reference in any case
764-
return ToSulongNode.doForeignObject(cextContext, object, lib);
765+
return ToSulongNode.doForeignObject(cextContext, object, isForeignObjectNode);
765766
}
766767

767-
@Specialization(guards = "isFallback(object, lib)")
768+
@Specialization(guards = "isFallback(object, isForeignObjectNode)")
768769
static Object run(CExtContext cextContext, Object object,
770+
@Cached IsForeignObjectNode isForeignObjectNode,
769771
@CachedLibrary(limit = "3") PythonObjectLibrary lib) {
770-
return ToSulongNode.run(cextContext, object, lib);
772+
return ToSulongNode.run(cextContext, object, isForeignObjectNode, lib);
771773
}
772774

773775
protected static PythonClassNativeWrapper wrapNativeClass(PythonManagedClass object) {
@@ -778,8 +780,8 @@ protected static PythonClassNativeWrapper wrapNativeClass(PythonContext ctx, Pyt
778780
return PythonClassNativeWrapper.wrap(ctx.getCore().lookupType(object), GetNameNode.doSlowPath(object));
779781
}
780782

781-
static boolean isFallback(Object object, PythonObjectLibrary lib) {
782-
return ToSulongNode.isFallback(object, lib);
783+
static boolean isFallback(Object object, IsForeignObjectNode isForeignObjectNode) {
784+
return ToSulongNode.isFallback(object, isForeignObjectNode);
783785
}
784786

785787
protected static boolean isNaN(double d) {
@@ -940,17 +942,18 @@ static Object runAbstractObject(@SuppressWarnings("unused") CExtContext cextCont
940942
return PythonObjectNativeWrapper.wrapNewRef(object, noWrapperProfile);
941943
}
942944

943-
@Specialization(guards = {"lib.isForeignObject(object)", "!isNativeWrapper(object)", "!isNativeNull(object)"})
945+
@Specialization(guards = {"isForeignObjectNode.execute(object)", "!isNativeWrapper(object)", "!isNativeNull(object)"})
944946
static Object doForeignObject(CExtContext cextContext, TruffleObject object,
945-
@CachedLibrary(limit = "3") PythonObjectLibrary lib) {
947+
@Cached IsForeignObjectNode isForeignObjectNode) {
946948
// this will always be a new wrapper; it's implicitly always a new reference in any case
947-
return ToSulongNode.doForeignObject(cextContext, object, lib);
949+
return ToSulongNode.doForeignObject(cextContext, object, isForeignObjectNode);
948950
}
949951

950-
@Specialization(guards = "isFallback(object, lib)")
952+
@Specialization(guards = "isFallback(object, isForeignObjectNode)")
951953
static Object run(CExtContext cextContext, Object object,
954+
@Cached IsForeignObjectNode isForeignObjectNode,
952955
@CachedLibrary(limit = "3") PythonObjectLibrary lib) {
953-
return ToSulongNode.run(cextContext, object, lib);
956+
return ToSulongNode.run(cextContext, object, isForeignObjectNode, lib);
954957
}
955958

956959
protected static PythonClassNativeWrapper wrapNativeClass(PythonManagedClass object) {
@@ -961,8 +964,8 @@ protected static PythonClassNativeWrapper wrapNativeClass(PythonContext ctx, Pyt
961964
return PythonClassNativeWrapper.wrap(ctx.getCore().lookupType(object), GetNameNode.doSlowPath(object));
962965
}
963966

964-
static boolean isFallback(Object object, PythonObjectLibrary lib) {
965-
return ToSulongNode.isFallback(object, lib);
967+
static boolean isFallback(Object object, IsForeignObjectNode isForeignObjectNode) {
968+
return ToSulongNode.isFallback(object, isForeignObjectNode);
966969
}
967970

968971
protected static boolean isNaN(double d) {
@@ -1063,15 +1066,14 @@ static double doDouble(@SuppressWarnings("unused") CExtContext cextContext, doub
10631066
return d;
10641067
}
10651068

1066-
@Specialization(guards = "isFallback(obj, lib)", limit = "3")
1069+
@Specialization(guards = "isFallback(obj, isForeignObjectNode)", limit = "1")
10671070
static Object run(@SuppressWarnings("unused") CExtContext cextContext, Object obj,
1068-
@SuppressWarnings("unused") @CachedLibrary("obj") PythonObjectLibrary lib,
1069-
@Cached @SuppressWarnings("unused") IsBuiltinClassProfile isForeignClassProfile,
1071+
@SuppressWarnings("unused") @Cached IsForeignObjectNode isForeignObjectNode,
10701072
@Cached PRaiseNode raiseNode) {
10711073
throw raiseNode.raise(PythonErrorType.SystemError, ErrorMessages.INVALID_OBJ_FROM_NATIVE, obj);
10721074
}
10731075

1074-
protected static boolean isFallback(Object obj, PythonObjectLibrary lib) {
1076+
protected static boolean isFallback(Object obj, IsForeignObjectNode isForeignObjectNode) {
10751077
if (CApiGuards.isNativeWrapper(obj)) {
10761078
return false;
10771079
}
@@ -1084,7 +1086,7 @@ protected static boolean isFallback(Object obj, PythonObjectLibrary lib) {
10841086
if (PGuards.isAnyPythonObject(obj)) {
10851087
return false;
10861088
}
1087-
if (lib.isForeignObject(obj)) {
1089+
if (isForeignObjectNode.execute(obj)) {
10881090
return false;
10891091
}
10901092
if (PGuards.isString(obj)) {
@@ -1118,10 +1120,9 @@ protected static boolean isPrimitiveNativeWrapper(PythonNativeWrapper object) {
11181120
@ImportStatic({PGuards.class, CApiGuards.class})
11191121
public abstract static class AsPythonObjectNode extends AsPythonObjectBaseNode {
11201122

1121-
@Specialization(guards = {"plib.isForeignObject(object)", "!isNativeWrapper(object)", "!isNativeNull(object)"}, limit = "2")
1123+
@Specialization(guards = {"isForeignObjectNode.execute(object)", "!isNativeWrapper(object)", "!isNativeNull(object)"}, limit = "2")
11221124
static PythonAbstractObject doNativeObject(@SuppressWarnings("unused") CExtContext cextContext, TruffleObject object,
1123-
@SuppressWarnings("unused") @CachedLibrary("object") PythonObjectLibrary plib,
1124-
@Cached @SuppressWarnings("unused") IsBuiltinClassProfile isForeignClassProfile,
1125+
@SuppressWarnings("unused") @Cached IsForeignObjectNode isForeignObjectNode,
11251126
@CachedContext(PythonLanguage.class) PythonContext context,
11261127
@Cached ConditionProfile newRefProfile,
11271128
@Cached ConditionProfile validRefProfile,
@@ -1146,10 +1147,9 @@ static PythonAbstractObject doNativeObject(@SuppressWarnings("unused") CExtConte
11461147
@ImportStatic({PGuards.class, CApiGuards.class})
11471148
public abstract static class AsPythonObjectStealingNode extends AsPythonObjectBaseNode {
11481149

1149-
@Specialization(guards = {"plib.isForeignObject(object)", "!isNativeWrapper(object)", "!isNativeNull(object)"}, limit = "1")
1150+
@Specialization(guards = {"isForeignObjectNode.execute(object)", "!isNativeWrapper(object)", "!isNativeNull(object)"}, limit = "1")
11501151
static PythonAbstractObject doNativeObject(@SuppressWarnings("unused") CExtContext cextContext, TruffleObject object,
1151-
@SuppressWarnings("unused") @CachedLibrary("object") PythonObjectLibrary plib,
1152-
@Cached @SuppressWarnings("unused") IsBuiltinClassProfile isForeignClassProfile,
1152+
@SuppressWarnings("unused") @Cached IsForeignObjectNode isForeignObjectNode,
11531153
@Cached ConditionProfile newRefProfile,
11541154
@Cached ConditionProfile validRefProfile,
11551155
@Cached ConditionProfile resurrectProfile,
@@ -1173,10 +1173,9 @@ static PythonAbstractObject doNativeObject(@SuppressWarnings("unused") CExtConte
11731173
@ImportStatic({PGuards.class, CApiGuards.class})
11741174
public abstract static class WrapVoidPtrNode extends AsPythonObjectBaseNode {
11751175

1176-
@Specialization(guards = {"plib.isForeignObject(object)", "!isNativeWrapper(object)", "!isNativeNull(object)"}, limit = "1")
1176+
@Specialization(guards = {"isForeignObjectNode.execute(object)", "!isNativeWrapper(object)", "!isNativeNull(object)"}, limit = "1")
11771177
static Object doNativeObject(@SuppressWarnings("unused") CExtContext cextContext, TruffleObject object,
1178-
@SuppressWarnings("unused") @CachedLibrary("object") PythonObjectLibrary plib,
1179-
@Cached @SuppressWarnings("unused") IsBuiltinClassProfile isForeignClassProfile) {
1178+
@SuppressWarnings("unused") @Cached IsForeignObjectNode isForeignObjectNode) {
11801179
// TODO(fa): should we use a different wrapper for non-'PyObject*' pointers; they cannot
11811180
// be used in the user value space but might be passed-through
11821181

@@ -1190,10 +1189,9 @@ static Object doNativeObject(@SuppressWarnings("unused") CExtContext cextContext
11901189
@ImportStatic({PGuards.class, CApiGuards.class})
11911190
public abstract static class WrapCharPtrNode extends AsPythonObjectBaseNode {
11921191

1193-
@Specialization(guards = {"plib.isForeignObject(object)", "!isNativeWrapper(object)", "!isNativeNull(object)"}, limit = "1")
1192+
@Specialization(guards = {"isForeignObjectNode.execute(object)", "!isNativeWrapper(object)", "!isNativeNull(object)"}, limit = "1")
11941193
static Object doNativeObject(@SuppressWarnings("unused") CExtContext cextContext, TruffleObject object,
1195-
@SuppressWarnings("unused") @CachedLibrary("object") PythonObjectLibrary plib,
1196-
@Cached @SuppressWarnings("unused") IsBuiltinClassProfile isForeignClassProfile,
1194+
@SuppressWarnings("unused") @Cached IsForeignObjectNode isForeignObjectNode,
11971195
@Cached FromCharPointerNode fromCharPointerNode) {
11981196
return fromCharPointerNode.execute(object);
11991197
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/foreign/ForeignObjectBuiltins.java

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@
102102
import com.oracle.graal.python.nodes.function.builtins.PythonTernaryBuiltinNode;
103103
import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
104104
import com.oracle.graal.python.nodes.interop.PForeignToPTypeNode;
105+
import com.oracle.graal.python.nodes.object.IsForeignObjectNode;
105106
import com.oracle.graal.python.nodes.util.CannotCastException;
106107
import com.oracle.graal.python.nodes.util.CastToJavaStringNode;
107108
import com.oracle.graal.python.runtime.ExecutionContext.IndirectCallContext;
@@ -585,10 +586,10 @@ abstract static class NewNode extends PythonBuiltinNode {
585586
* A foreign function call specializes on the length of the passed arguments. Any
586587
* optimization based on the callee has to happen on the other side.a
587588
*/
588-
@Specialization(guards = {"plib.isForeignObject(callee)", "!isNoValue(callee)", "keywords.length == 0"}, limit = "3")
589+
@Specialization(guards = {"isForeignObjectNode.execute(callee)", "!isNoValue(callee)", "keywords.length == 0"}, limit = "1")
589590
protected Object doInteropCall(Object callee, Object[] arguments, @SuppressWarnings("unused") PKeyword[] keywords,
590-
@SuppressWarnings("unused") @CachedLibrary("callee") PythonObjectLibrary plib,
591-
@CachedLibrary("callee") InteropLibrary lib,
591+
@SuppressWarnings("unused") @Cached IsForeignObjectNode isForeignObjectNode,
592+
@CachedLibrary(limit = "3") InteropLibrary lib,
592593
@Cached PForeignToPTypeNode toPTypeNode) {
593594
try {
594595
Object res = lib.instantiate(callee, arguments);
@@ -618,11 +619,11 @@ public final Object executeWithArgs(VirtualFrame frame, Object callee, Object[]
618619
* A foreign function call specializes on the length of the passed arguments. Any
619620
* optimization based on the callee has to happen on the other side.
620621
*/
621-
@Specialization(guards = {"plib.isForeignObject(callee)", "!isNoValue(callee)", "keywords.length == 0"}, limit = "4")
622+
@Specialization(guards = {"isForeignObjectNode.execute(callee)", "!isNoValue(callee)", "keywords.length == 0"}, limit = "1")
622623
protected Object doInteropCall(VirtualFrame frame, Object callee, Object[] arguments, @SuppressWarnings("unused") PKeyword[] keywords,
623624
@CachedLanguage PythonLanguage language,
624-
@SuppressWarnings("unused") @CachedLibrary("callee") PythonObjectLibrary plib,
625-
@CachedLibrary("callee") InteropLibrary lib,
625+
@SuppressWarnings("unused") @Cached IsForeignObjectNode isForeignObjectNode,
626+
@CachedLibrary(limit = "4") InteropLibrary lib,
626627
@Cached PForeignToPTypeNode toPTypeNode) {
627628
try {
628629
Object state = IndirectCallContext.enter(frame, language, getContextRef(), this);

0 commit comments

Comments
 (0)