Skip to content

Commit 80ce326

Browse files
committed
[GR-45966] Avoid using InteropLibrary when not necessary.
PullRequest: graalpython/2775
2 parents f64907b + 04b86a7 commit 80ce326

File tree

13 files changed

+302
-180
lines changed

13 files changed

+302
-180
lines changed

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@
136136
import com.oracle.graal.python.builtins.objects.type.TypeNodes;
137137
import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetMroStorageNode;
138138
import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetNameNode;
139+
import com.oracle.graal.python.builtins.objects.type.TypeNodes.IsTypeNode;
139140
import com.oracle.graal.python.builtins.objects.type.TypeNodes.ProfileClassNode;
140141
import com.oracle.graal.python.lib.PyFloatAsDoubleNode;
141142
import com.oracle.graal.python.lib.PyObjectLookupAttr;
@@ -517,10 +518,10 @@ static Object doPythonTypeUncached(PythonBuiltinClassType object,
517518
return PythonClassNativeWrapper.wrap(PythonContext.get(getNameNode).lookupType(object), getNameNode.execute(object));
518519
}
519520

520-
@Specialization(guards = {"!isClass(object, lib)", "!isNativeObject(object)", "!isSpecialSingleton(object)"})
521+
@Specialization(guards = {"!isClass(object, isTypeNode)", "!isNativeObject(object)", "!isSpecialSingleton(object)"})
521522
static Object runAbstractObject(PythonAbstractObject object,
522523
@Cached ConditionProfile noWrapperProfile,
523-
@SuppressWarnings("unused") @CachedLibrary(limit = "3") InteropLibrary lib) {
524+
@SuppressWarnings("unused") @Cached IsTypeNode isTypeNode) {
524525
assert object != PNone.NO_VALUE;
525526
return PythonObjectNativeWrapper.wrap(object, noWrapperProfile);
526527
}

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

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
import com.oracle.graal.python.builtins.objects.ints.PInt;
5656
import com.oracle.graal.python.builtins.objects.type.PythonManagedClass;
5757
import com.oracle.graal.python.builtins.objects.type.TypeNodes;
58+
import com.oracle.graal.python.builtins.objects.type.TypeNodes.IsTypeNode;
5859
import com.oracle.graal.python.nodes.PGuards;
5960
import com.oracle.graal.python.nodes.PNodeWithContext;
6061
import com.oracle.graal.python.nodes.object.IsForeignObjectNode;
@@ -66,8 +67,6 @@
6667
import com.oracle.truffle.api.dsl.GenerateUncached;
6768
import com.oracle.truffle.api.dsl.ImportStatic;
6869
import com.oracle.truffle.api.dsl.Specialization;
69-
import com.oracle.truffle.api.interop.InteropLibrary;
70-
import com.oracle.truffle.api.library.CachedLibrary;
7170
import com.oracle.truffle.api.profiles.ConditionProfile;
7271
import com.oracle.truffle.api.strings.TruffleString;
7372

@@ -180,10 +179,10 @@ static PythonNativeWrapper doPythonTypeUncached(PythonBuiltinClassType object,
180179
return PythonClassNativeWrapper.wrap(PythonContext.get(getNameNode).lookupType(object), getNameNode.execute(object));
181180
}
182181

183-
@Specialization(guards = {"!isClass(object, lib)", "!isNativeObject(object)", "!isSpecialSingleton(object)"})
182+
@Specialization(guards = {"!isClass(object, isTypeNode)", "!isNativeObject(object)", "!isSpecialSingleton(object)"}, limit = "1")
184183
static PythonNativeWrapper runAbstractObject(PythonAbstractObject object,
185184
@Exclusive @Cached ConditionProfile noWrapperProfile,
186-
@SuppressWarnings("unused") @CachedLibrary(limit = "3") InteropLibrary lib) {
185+
@SuppressWarnings("unused") @Cached IsTypeNode isTypeNode) {
187186
assert object != PNone.NO_VALUE;
188187
return PythonObjectNativeWrapper.wrap(object, noWrapperProfile);
189188
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
import com.oracle.graal.python.builtins.objects.str.PString;
7676
import com.oracle.graal.python.builtins.objects.str.StringNodes.StringLenNode;
7777
import com.oracle.graal.python.builtins.objects.tuple.PTuple;
78+
import com.oracle.graal.python.builtins.objects.type.TypeNodes.IsTypeNode;
7879
import com.oracle.graal.python.lib.PyObjectIsTrueNode;
7980
import com.oracle.graal.python.lib.PyObjectSizeNode;
8081
import com.oracle.graal.python.lib.PySequenceCheckNode;
@@ -684,7 +685,6 @@ static void doObject(@SuppressWarnings("unused") int c, int la, Object arg, Obje
684685
@Cached ExecuteConverterNode executeConverterNode,
685686
@Cached GetClassNode getClassNode,
686687
@Cached IsSubtypeNode isSubtypeNode,
687-
@CachedLibrary(limit = "2") InteropLibrary lib,
688688
@Cached NativeToPythonNode typeToJavaNode,
689689
@Cached ToSulongNode toNativeNode,
690690
@Shared("writeOutVarNode") @Cached WriteNextVaArgNode writeOutVarNode,
@@ -693,7 +693,7 @@ static void doObject(@SuppressWarnings("unused") int c, int la, Object arg, Obje
693693
/* formatIdx++; */
694694
Object argValue = getVaArgNode.getPyObjectPtr(varargs);
695695
Object typeObject = typeToJavaNode.execute(argValue);
696-
assert PGuards.isClass(typeObject, lib);
696+
assert PGuards.isClass(typeObject, IsTypeNode.getUncached());
697697
if (!isSubtypeNode.execute(getClassNode.execute(arg), typeObject)) {
698698
raiseNode.raiseIntWithoutFrame(0, TypeError, ErrorMessages.EXPECTED_OBJ_TYPE_P_GOT_P, typeObject, arg);
699699
throw ParseArgumentsException.raise();

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1696,7 +1696,7 @@ Object execute(Object[] arguments,
16961696

16971697
try {
16981698
Object newType = createTypeFromSpecNode.execute(context, typeSpec, typeSpecParamArray);
1699-
assert PGuards.isClass(newType, InteropLibrary.getUncached()) : "Object created from type spec is not a type";
1699+
assert PGuards.isClass(newType, IsTypeNode.getUncached()) : "Object created from type spec is not a type";
17001700
return asHandleNode.execute(newType);
17011701
} catch (PException e) {
17021702
transformExceptionToNativeNode.execute(context, e);

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2142,7 +2142,7 @@ private static PTuple extractBases(GraalHPyContext context, Object typeSpecParam
21422142
case GraalHPyDef.HPyType_SPEC_PARAM_BASE:
21432143
// In this case, the 'specParamObject' is a single handle. We add it to
21442144
// the list of bases.
2145-
assert PGuards.isClass(specParamObject, InteropLibrary.getUncached()) : "base object is not a Python class";
2145+
assert PGuards.isClass(specParamObject, IsTypeNode.getUncached()) : "base object is not a Python class";
21462146
basesList.add(specParamObject);
21472147
break;
21482148
case GraalHPyDef.HPyType_SPEC_PARAM_BASES_TUPLE:

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/iterator/IteratorNodes.java

Lines changed: 44 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,11 @@
5959
import com.oracle.graal.python.builtins.objects.tuple.PTuple;
6060
import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot;
6161
import com.oracle.graal.python.lib.GetNextNode;
62+
import com.oracle.graal.python.lib.GraalPyObjectSizeNode;
6263
import com.oracle.graal.python.lib.PyIndexCheckNode;
6364
import com.oracle.graal.python.lib.PyIterCheckNode;
6465
import com.oracle.graal.python.lib.PyNumberAsSizeNode;
6566
import com.oracle.graal.python.lib.PyObjectGetIter;
66-
import com.oracle.graal.python.lib.PyObjectSizeNode;
6767
import com.oracle.graal.python.nodes.ErrorMessages;
6868
import com.oracle.graal.python.nodes.PGuards;
6969
import com.oracle.graal.python.nodes.PNodeWithContext;
@@ -75,6 +75,7 @@
7575
import com.oracle.graal.python.nodes.call.special.LookupSpecialMethodSlotNode;
7676
import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile;
7777
import com.oracle.graal.python.nodes.object.InlinedGetClassNode;
78+
import com.oracle.graal.python.nodes.object.IsForeignObjectNode;
7879
import com.oracle.graal.python.nodes.util.CastToTruffleStringNode;
7980
import com.oracle.graal.python.runtime.GilNode;
8081
import com.oracle.graal.python.runtime.exception.PException;
@@ -86,6 +87,7 @@
8687
import com.oracle.truffle.api.dsl.Cached;
8788
import com.oracle.truffle.api.dsl.Cached.Shared;
8889
import com.oracle.truffle.api.dsl.Fallback;
90+
import com.oracle.truffle.api.dsl.GenerateInline;
8991
import com.oracle.truffle.api.dsl.GenerateUncached;
9092
import com.oracle.truffle.api.dsl.ImportStatic;
9193
import com.oracle.truffle.api.dsl.Specialization;
@@ -107,25 +109,22 @@ public abstract class IteratorNodes {
107109
* returned. If either has no viable or defaultvalue implementation then this node returns -1.
108110
*/
109111
@ImportStatic({PGuards.class, SpecialMethodNames.class, SpecialMethodSlot.class})
110-
public abstract static class GetLength extends PNodeWithContext {
112+
public abstract static class GetLength extends GraalPyObjectSizeNode {
111113

112114
public abstract int execute(VirtualFrame frame, Object iterable);
113115

114-
@Specialization(guards = {"isString(iterable)"})
115-
int length(VirtualFrame frame, Object iterable,
116-
@Cached PyObjectSizeNode sizeNode) {
117-
return sizeNode.execute(frame, iterable);
118-
}
116+
// Fast-path specializations for builtins are inherited
119117

120-
@Specialization(guards = {"isNoValue(iterable)"})
121-
static int length(@SuppressWarnings({"unused"}) VirtualFrame frame, @SuppressWarnings({"unused"}) Object iterable) {
118+
@Specialization(guards = "isNoValue(iterable)")
119+
static int length(@SuppressWarnings({"unused"}) VirtualFrame frame, @SuppressWarnings("unused") PNone iterable) {
122120
return -1;
123121
}
124122

125-
@Specialization(guards = {"!isNoValue(iterable)", "!isString(iterable)"}, limit = "4")
123+
@Fallback
126124
int length(VirtualFrame frame, Object iterable,
127125
@Bind("this") Node inliningTarget,
128-
@CachedLibrary("iterable") InteropLibrary iLib,
126+
@Cached IsForeignObjectNode isForeignObjectNode,
127+
@Cached GetLengthForeign getLengthForeign,
129128
@Cached InlinedGetClassNode getClassNode,
130129
@Cached PyIndexCheckNode indexCheckNode,
131130
@Cached PyNumberAsSizeNode asSizeNode,
@@ -135,18 +134,11 @@ int length(VirtualFrame frame, Object iterable,
135134
@Cached IsBuiltinObjectProfile errorProfile,
136135
@Cached InlinedConditionProfile hasLenProfile,
137136
@Cached InlinedConditionProfile hasLengthHintProfile,
138-
@Cached PRaiseNode raiseNode,
139-
@Cached TruffleString.SwitchEncodingNode switchEncodingNode,
140-
@Cached TruffleString.CodePointLengthNode codePointLengthNode,
141-
@Cached GilNode gil) {
142-
if (iLib.isString(iterable)) {
143-
gil.release(true);
144-
try {
145-
return codePointLengthNode.execute(switchEncodingNode.execute(iLib.asTruffleString(iterable), TS_ENCODING), TS_ENCODING);
146-
} catch (UnsupportedMessageException e) {
147-
throw CompilerDirectives.shouldNotReachHere();
148-
} finally {
149-
gil.acquire();
137+
@Cached PRaiseNode raiseNode) {
138+
if (isForeignObjectNode.execute(iterable)) {
139+
int foreignLen = getLengthForeign.execute(iterable);
140+
if (foreignLen != -1) {
141+
return foreignLen;
150142
}
151143
}
152144
Object clazz = getClassNode.execute(inliningTarget, iterable);
@@ -194,6 +186,35 @@ int length(VirtualFrame frame, Object iterable,
194186
}
195187
}
196188

189+
/**
190+
* Handles the special case of foreign Strings. If the input is not a string, returns -1.
191+
*/
192+
@GenerateInline(false) // Intentionally lazy initialized
193+
public abstract static class GetLengthForeign extends PNodeWithContext {
194+
public abstract int execute(Object foreign);
195+
196+
@Specialization
197+
static int doIt(Object foreign,
198+
@Bind("this") Node inliningTarget,
199+
@Cached InlinedConditionProfile isString,
200+
@CachedLibrary(limit = "3") InteropLibrary iLib,
201+
@Cached TruffleString.SwitchEncodingNode switchEncodingNode,
202+
@Cached TruffleString.CodePointLengthNode codePointLengthNode,
203+
@Cached GilNode gil) {
204+
if (isString.profile(inliningTarget, iLib.isString(foreign))) {
205+
gil.release(true);
206+
try {
207+
return codePointLengthNode.execute(switchEncodingNode.execute(iLib.asTruffleString(foreign), TS_ENCODING), TS_ENCODING);
208+
} catch (UnsupportedMessageException e) {
209+
throw CompilerDirectives.shouldNotReachHere();
210+
} finally {
211+
gil.acquire();
212+
}
213+
}
214+
return -1;
215+
}
216+
}
217+
197218
@ImportStatic(PGuards.class)
198219
@GenerateUncached
199220
public abstract static class GetInternalIteratorSequenceStorage extends Node {

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TypeBuiltins.java

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@
129129
import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetTypeFlagsNode;
130130
import com.oracle.graal.python.builtins.objects.type.TypeNodes.InlinedIsSameTypeNode;
131131
import com.oracle.graal.python.builtins.objects.type.TypeNodes.IsSameTypeNode;
132+
import com.oracle.graal.python.builtins.objects.type.TypeNodes.IsTypeNode;
132133
import com.oracle.graal.python.builtins.objects.type.TypeNodesFactory.IsSameTypeNodeGen;
133134
import com.oracle.graal.python.builtins.objects.types.GenericTypeNodes;
134135
import com.oracle.graal.python.lib.PyObjectIsTrueNode;
@@ -186,8 +187,6 @@
186187
import com.oracle.truffle.api.dsl.Specialization;
187188
import com.oracle.truffle.api.dsl.TypeSystemReference;
188189
import com.oracle.truffle.api.frame.VirtualFrame;
189-
import com.oracle.truffle.api.interop.InteropLibrary;
190-
import com.oracle.truffle.api.library.CachedLibrary;
191190
import com.oracle.truffle.api.nodes.Node;
192191
import com.oracle.truffle.api.object.HiddenKey;
193192
import com.oracle.truffle.api.profiles.InlinedBranchProfile;
@@ -1379,11 +1378,11 @@ Object setNative(@SuppressWarnings("unused") PythonAbstractNativeObject cls, @Su
13791378
@Builtin(name = J___FLAGS__, minNumOfPositionalArgs = 1, isGetter = true)
13801379
@GenerateNodeFactory
13811380
abstract static class FlagsNode extends PythonUnaryBuiltinNode {
1382-
@Specialization(limit = "3")
1381+
@Specialization
13831382
Object doGeneric(Object self,
1384-
@CachedLibrary("self") InteropLibrary lib,
1383+
@Cached IsTypeNode isTypeNode,
13851384
@Cached GetTypeFlagsNode getTypeFlagsNode) {
1386-
if (PGuards.isClass(self, lib)) {
1385+
if (PGuards.isClass(self, isTypeNode)) {
13871386
return getTypeFlagsNode.execute(self);
13881387
}
13891388
throw raise(PythonErrorType.TypeError, ErrorMessages.DESC_FLAG_FOR_TYPE_DOESNT_APPLY_TO_OBJ, self);

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TypeNodes.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -949,11 +949,11 @@ static PythonAbstractClass doNative(PythonNativeClass obj,
949949
@Cached PRaiseNode raise,
950950
@Cached GetTypeMemberNode getTpBaseNode,
951951
@Cached InlinedExactClassProfile resultTypeProfile,
952-
@SuppressWarnings("unused") @CachedLibrary(limit = "3") InteropLibrary lib) {
952+
@Cached IsTypeNode isTypeNode) {
953953
Object result = resultTypeProfile.profile(inliningTarget, getTpBaseNode.execute(obj, NativeMember.TP_BASE));
954954
if (PGuards.isPNone(result)) {
955955
return null;
956-
} else if (PGuards.isClass(result, lib)) {
956+
} else if (PGuards.isClass(result, isTypeNode)) {
957957
return (PythonAbstractClass) result;
958958
}
959959
CompilerDirectives.transferToInterpreter();

0 commit comments

Comments
 (0)