Skip to content

Commit f3ebc7f

Browse files
committed
Cache format string split.
1 parent 994ab92 commit f3ebc7f

File tree

2 files changed

+44
-21
lines changed

2 files changed

+44
-21
lines changed

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

Lines changed: 15 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@
157157
import com.oracle.graal.python.builtins.objects.cext.common.CExtCommonNodes.UnicodeFromWcharNode;
158158
import com.oracle.graal.python.builtins.objects.cext.common.CExtContext;
159159
import com.oracle.graal.python.builtins.objects.cext.common.CExtParseArgumentsNode;
160+
import com.oracle.graal.python.builtins.objects.cext.common.CExtParseArgumentsNode.SplitFormatStringNode;
160161
import com.oracle.graal.python.builtins.objects.cext.common.VaListWrapper;
161162
import com.oracle.graal.python.builtins.objects.code.PCode;
162163
import com.oracle.graal.python.builtins.objects.common.HashingCollectionNodes;
@@ -3276,34 +3277,27 @@ public Object varArgExecute(VirtualFrame frame, Object self, Object[] arguments,
32763277
}
32773278

32783279
public static int doConvert(CExtContext nativeContext, Object argv, Object nativeKwds, Object nativeFormat, Object nativeKwdnames, Object nativeVarargs,
3280+
SplitFormatStringNode splitFormatStringNode,
32793281
InteropLibrary kwdsRefLib,
32803282
InteropLibrary kwdnamesRefLib,
32813283
ConditionProfile kwdsProfile,
32823284
ConditionProfile kwdnamesProfile,
3283-
ConditionProfile functionNameProfile,
32843285
CExtAsPythonObjectNode kwdsToJavaNode,
32853286
CastToJavaStringNode castToStringNode,
32863287
CExtParseArgumentsNode.ParseTupleAndKeywordsNode parseTupleAndKeywordsNode) {
32873288

32883289
// force 'format' to be a String
3289-
String format;
3290+
String[] split;
32903291
try {
3291-
format = castToStringNode.execute(nativeFormat);
3292+
split = splitFormatStringNode.execute(castToStringNode.execute(nativeFormat));
3293+
assert split.length == 2;
32923294
} catch (CannotCastException e) {
32933295
CompilerDirectives.transferToInterpreterAndInvalidate();
32943296
throw new IllegalStateException();
32953297
}
3296-
String functionName = null;
32973298

3298-
int colonIdx = format.indexOf(":");
3299-
if (functionNameProfile.profile(colonIdx != -1)) {
3300-
// extract function name
3301-
// use 'colonIdx+1' because we do not want to include the colon
3302-
functionName = format.substring(colonIdx + 1);
3303-
3304-
// trim off function name
3305-
format = format.substring(0, colonIdx);
3306-
}
3299+
String format = split[0];
3300+
String functionName = split[1];
33073301

33083302
// sort out if kwds is native NULL
33093303
Object kwds;
@@ -3333,21 +3327,21 @@ static Object getKwdnames(Object[] arguments) {
33333327
abstract static class ParseTupleAndKeywordsNode extends ParseTupleAndKeywordsBaseNode {
33343328

33353329
@Specialization(guards = "arguments.length == 5", limit = "2")
3336-
static int doConvert(Object self, Object[] arguments, @SuppressWarnings("unused") PKeyword[] keywords,
3330+
static int doConvert(@SuppressWarnings("unused") Object self, Object[] arguments, @SuppressWarnings("unused") PKeyword[] keywords,
33373331
@CachedContext(PythonLanguage.class) PythonContext context,
3332+
@Cached SplitFormatStringNode splitFormatStringNode,
33383333
@CachedLibrary("getKwds(arguments)") InteropLibrary kwdsInteropLib,
33393334
@CachedLibrary("getKwdnames(arguments)") InteropLibrary kwdnamesRefLib,
33403335
@Cached("createBinaryProfile()") ConditionProfile kwdsProfile,
33413336
@Cached("createBinaryProfile()") ConditionProfile kwdnamesProfile,
3342-
@Cached("createBinaryProfile()") ConditionProfile functionNameProfile,
33433337
@Cached CExtNodes.AsPythonObjectNode argvToJavaNode,
33443338
@Cached CExtNodes.AsPythonObjectNode kwdsToJavaNode,
33453339
@Cached CastToJavaStringNode castToStringNode,
33463340
@Cached CExtParseArgumentsNode.ParseTupleAndKeywordsNode parseTupleAndKeywordsNode) {
33473341
CExtContext nativeContext = context.getCApiContext();
33483342
Object argv = argvToJavaNode.execute(arguments[0]);
3349-
return ParseTupleAndKeywordsBaseNode.doConvert(nativeContext, argv, arguments[1], arguments[2], arguments[3], arguments[4], kwdsInteropLib, kwdnamesRefLib, kwdsProfile,
3350-
kwdnamesProfile, functionNameProfile, kwdsToJavaNode, castToStringNode, parseTupleAndKeywordsNode);
3343+
return ParseTupleAndKeywordsBaseNode.doConvert(nativeContext, argv, arguments[1], arguments[2], arguments[3], arguments[4], splitFormatStringNode, kwdsInteropLib, kwdnamesRefLib,
3344+
kwdsProfile, kwdnamesProfile, kwdsToJavaNode, castToStringNode, parseTupleAndKeywordsNode);
33513345
}
33523346

33533347
}
@@ -3357,13 +3351,13 @@ static int doConvert(Object self, Object[] arguments, @SuppressWarnings("unused"
33573351
abstract static class ParseTupleAndKeywordsVaListNode extends ParseTupleAndKeywordsBaseNode {
33583352

33593353
@Specialization(guards = "arguments.length == 5", limit = "2")
3360-
static int doConvert(Object self, Object[] arguments, @SuppressWarnings("unused") PKeyword[] keywords,
3354+
static int doConvert(@SuppressWarnings("unused") Object self, Object[] arguments, @SuppressWarnings("unused") PKeyword[] keywords,
33613355
@CachedContext(PythonLanguage.class) PythonContext context,
3356+
@Cached SplitFormatStringNode splitFormatStringNode,
33623357
@CachedLibrary("getKwds(arguments)") InteropLibrary kwdsRefLib,
33633358
@CachedLibrary("getKwdnames(arguments)") InteropLibrary kwdnamesRefLib,
33643359
@Cached("createBinaryProfile()") ConditionProfile kwdsProfile,
33653360
@Cached("createBinaryProfile()") ConditionProfile kwdnamesProfile,
3366-
@Cached("createBinaryProfile()") ConditionProfile functionNameProfile,
33673361
@Cached PCallCExtFunction callMallocOutVarPtr,
33683362
@Cached CExtNodes.AsPythonObjectNode argvToJavaNode,
33693363
@Cached CExtNodes.AsPythonObjectNode kwdsToJavaNode,
@@ -3372,8 +3366,8 @@ static int doConvert(Object self, Object[] arguments, @SuppressWarnings("unused"
33723366
CExtContext nativeContext = context.getCApiContext();
33733367
Object argv = argvToJavaNode.execute(arguments[0]);
33743368
VaListWrapper varargs = new VaListWrapper(nativeContext, arguments[4], callMallocOutVarPtr.call(nativeContext, NativeCAPISymbols.FUN_ALLOCATE_OUTVAR));
3375-
return ParseTupleAndKeywordsBaseNode.doConvert(nativeContext, argv, arguments[1], arguments[2], arguments[3], varargs, kwdsRefLib, kwdnamesRefLib, kwdsProfile, kwdnamesProfile,
3376-
functionNameProfile, kwdsToJavaNode, castToStringNode, parseTupleAndKeywordsNode);
3369+
return ParseTupleAndKeywordsBaseNode.doConvert(nativeContext, argv, arguments[1], arguments[2], arguments[3], varargs, splitFormatStringNode, kwdsRefLib, kwdnamesRefLib, kwdsProfile,
3370+
kwdnamesProfile, kwdsToJavaNode, castToStringNode, parseTupleAndKeywordsNode);
33773371
}
33783372
}
33793373

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

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@
106106
import com.oracle.truffle.api.nodes.ExplodeLoop;
107107
import com.oracle.truffle.api.nodes.ExplodeLoop.LoopExplosionKind;
108108
import com.oracle.truffle.api.nodes.Node;
109+
import com.oracle.truffle.api.profiles.ConditionProfile;
109110

110111
public abstract class CExtParseArgumentsNode {
111112
static final char FORMAT_LOWER_S = 's';
@@ -1323,4 +1324,32 @@ static ParseArgumentsException raise() {
13231324
throw new ParseArgumentsException();
13241325
}
13251326
}
1327+
1328+
@GenerateUncached
1329+
public abstract static class SplitFormatStringNode extends Node {
1330+
1331+
public abstract String[] execute(String format);
1332+
1333+
@Specialization(guards = "cachedFormat.equals(format)", limit = "1")
1334+
static String[] doCached(@SuppressWarnings("unused") String format,
1335+
@Cached("format") @SuppressWarnings("unused") String cachedFormat,
1336+
@Cached(value = "extractFormatOnly(format)", dimensions = 1) String[] cachedResult) {
1337+
return cachedResult;
1338+
}
1339+
1340+
@Specialization(replaces = "doCached")
1341+
static String[] doGeneric(String format,
1342+
@Cached("createBinaryProfile()") ConditionProfile hasFunctionNameProfile) {
1343+
int colonIdx = format.indexOf(":");
1344+
if (hasFunctionNameProfile.profile(colonIdx != -1)) {
1345+
// trim off function name
1346+
return new String[]{format.substring(0, colonIdx), format.substring(colonIdx + 1)};
1347+
}
1348+
return new String[]{format, ""};
1349+
}
1350+
1351+
static String[] extractFormatOnly(String format) {
1352+
return doGeneric(format, ConditionProfile.getUncached());
1353+
}
1354+
}
13261355
}

0 commit comments

Comments
 (0)