Skip to content

Commit 6d18391

Browse files
committed
[GR-20464] Use CallSpecial nodes in library message implementations
PullRequest: graalpython/782
2 parents 8e36f2c + 9f12693 commit 6d18391

File tree

83 files changed

+1606
-788
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

83 files changed

+1606
-788
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,5 @@ Python3.g4.stamp
6666
/graalpython/include/*
6767
/graalpython/com.oracle.graal.python.test/src/tests/cpyext/As_FileDescriptor_Testfile
6868
/.*.csv*
69+
/graal_dumps
70+
*.jfr

ci.jsonnet

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{ overlay: "3bc2cb30863e4ed818ce72065a64774bc44e9281" }
1+
{ overlay: "0804360960e04fffe3fc4ed87c6b5f8b65641c78" }
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
2+
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3+
#
4+
# The Universal Permissive License (UPL), Version 1.0
5+
#
6+
# Subject to the condition set forth below, permission is hereby granted to any
7+
# person obtaining a copy of this software, associated documentation and/or
8+
# data (collectively the "Software"), free of charge and under any and all
9+
# copyright rights in the Software, and any and all patent rights owned or
10+
# freely licensable by each licensor hereunder covering either (i) the
11+
# unmodified Software as contributed to or provided by such licensor, or (ii)
12+
# the Larger Works (as defined below), to deal in both
13+
#
14+
# (a) the Software, and
15+
#
16+
# (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
17+
# one is included with the Software each a "Larger Work" to which the Software
18+
# is contributed by such licensors),
19+
#
20+
# without restriction, including without limitation the rights to copy, create
21+
# derivative works of, display, perform, and distribute the Software and make,
22+
# use, sell, offer for sale, import, export, have made, and have sold the
23+
# Software and the Larger Work(s), and to sublicense the foregoing rights on
24+
# either these or other terms.
25+
#
26+
# This license is subject to the following condition:
27+
#
28+
# The above copyright notice and either this complete permission notice or at a
29+
# minimum a reference to the UPL must be included in all copies or substantial
30+
# portions of the Software.
31+
#
32+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
33+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
34+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
35+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
36+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
37+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
38+
# SOFTWARE.
39+
40+
class sub_int(int):
41+
pass
42+
43+
44+
def getitem(d, num):
45+
for t in range(num):
46+
item = d.get(num)
47+
item2 = d.get(sub_int(num))
48+
49+
return item, item2
50+
51+
52+
def measure(num):
53+
d = {x: x**x for x in range(1000)}
54+
last_items = getitem(d, num) # 1000000
55+
print("Last items ", last_items)
56+
57+
58+
def __benchmark__(num=1000000):
59+
measure(num)

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/Builtin.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2017, 2019, Oracle and/or its affiliates.
2+
* Copyright (c) 2017, 2020, Oracle and/or its affiliates.
33
* Copyright (c) 2013, Regents of the University of California
44
*
55
* All rights reserved.
@@ -63,6 +63,13 @@
6363

6464
boolean isStaticmethod() default false;
6565

66+
/**
67+
* Most built-ins don't ever need the frame or they should be able to deal with receiving a
68+
* {@code null} frame. This should be set to {@code true} for those builtins that do need a full
69+
* frame.
70+
*/
71+
boolean needsFrame() default false;
72+
6673
/**
6774
* By default the caller frame bit is set on-demand, but for some builtins it might be useful to
6875
* always force passing the caller frame.

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/PythonBuiltinClassType.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,10 @@
2828
import java.util.HashSet;
2929

3030
import com.oracle.graal.python.PythonLanguage;
31+
import com.oracle.graal.python.builtins.objects.function.PArguments.ThreadState;
3132
import com.oracle.graal.python.builtins.objects.object.PythonObjectLibrary;
3233
import com.oracle.graal.python.builtins.objects.type.LazyPythonClass;
34+
import com.oracle.graal.python.builtins.objects.type.PythonBuiltinClass;
3335
import com.oracle.graal.python.nodes.BuiltinNames;
3436
import com.oracle.graal.python.runtime.PythonContext;
3537
import com.oracle.truffle.api.CompilerAsserts;
@@ -469,4 +471,15 @@ static long hash(PythonBuiltinClassType type,
469471
static LazyPythonClass getLazyPythonClass(@SuppressWarnings("unused") PythonBuiltinClassType type) {
470472
return PythonClass;
471473
}
474+
475+
@ExportMessage
476+
static int equalsInternal(PythonBuiltinClassType self, Object other, @SuppressWarnings("unused") ThreadState state) {
477+
if (self == other) {
478+
return 1;
479+
} else if (other instanceof PythonBuiltinClass) {
480+
return self == ((PythonBuiltinClass) other).getType() ? 1 : 0;
481+
} else {
482+
return 0;
483+
}
484+
}
472485
}

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

Lines changed: 9 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2017, 2019, Oracle and/or its affiliates.
2+
* Copyright (c) 2017, 2020, Oracle and/or its affiliates.
33
* Copyright (c) 2013, Regents of the University of California
44
*
55
* All rights reserved.
@@ -1454,43 +1454,18 @@ protected final PythonObjectFactory factory() {
14541454
@Builtin(name = BOOL, minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 2, constructsClass = PythonBuiltinClassType.Boolean, base = PythonBuiltinClassType.PInt)
14551455
@GenerateNodeFactory
14561456
@SuppressWarnings("unused")
1457+
@ReportPolymorphism
14571458
public abstract static class BoolNode extends PythonBinaryBuiltinNode {
1458-
1459-
@Specialization
1460-
public boolean boolB(Object cls, boolean arg) {
1461-
return arg;
1462-
}
1463-
1464-
@Specialization
1465-
public boolean boolI(Object cls, int arg) {
1466-
return arg != 0;
1467-
}
1468-
1469-
@Specialization
1470-
public boolean boolD(Object cls, double arg) {
1471-
return arg != 0.0;
1472-
}
1473-
1474-
@Specialization
1475-
public boolean boolS(Object cls, String arg) {
1476-
return !arg.isEmpty();
1477-
}
1478-
1479-
@Specialization
1480-
public boolean boolN(Object cls, PNone arg) {
1481-
return false;
1482-
}
1483-
1484-
@Specialization
1459+
@Specialization(limit = "getCallSiteInlineCacheMaxDepth()")
14851460
public boolean bool(VirtualFrame frame, Object cls, Object obj,
1486-
@Cached("create(__BOOL__)") LookupAndCallUnaryNode callNode) {
1487-
try {
1488-
return callNode.executeBoolean(frame, obj);
1489-
} catch (UnexpectedResultException ex) {
1490-
throw raise(PythonErrorType.TypeError, "__bool__ should return bool, returned %p", ex.getResult());
1461+
@Cached("createBinaryProfile()") ConditionProfile hasFrame,
1462+
@CachedLibrary("obj") PythonObjectLibrary lib) {
1463+
if (hasFrame.profile(frame != null)) {
1464+
return lib.isTrueWithState(obj, PArguments.getThreadState(frame));
1465+
} else {
1466+
return lib.isTrue(obj);
14911467
}
14921468
}
1493-
14941469
}
14951470

14961471
// list([iterable])

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

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@
147147
import com.oracle.graal.python.nodes.control.GetNextNode;
148148
import com.oracle.graal.python.nodes.expression.BinaryArithmetic;
149149
import com.oracle.graal.python.nodes.expression.BinaryComparisonNode;
150-
import com.oracle.graal.python.nodes.expression.CastToBooleanNode;
150+
import com.oracle.graal.python.nodes.expression.CoerceToBooleanNode;
151151
import com.oracle.graal.python.nodes.expression.IsExpressionNode;
152152
import com.oracle.graal.python.nodes.expression.TernaryArithmetic;
153153
import com.oracle.graal.python.nodes.frame.MaterializeFrameNode;
@@ -304,12 +304,18 @@ String doPI(PInt x) {
304304

305305
@Specialization(replaces = {"doL", "doD", "doPI"})
306306
String doO(VirtualFrame frame, Object x,
307+
@Cached("createBinaryProfile()") ConditionProfile hasFrame,
307308
@Cached IsSubtypeNode isSubtype,
308309
@CachedLibrary(limit = "getCallSiteInlineCacheMaxDepth()") PythonObjectLibrary lib,
309310
@Cached BranchProfile isInt,
310311
@Cached BranchProfile isLong,
311312
@Cached BranchProfile isPInt) {
312-
Object index = lib.asIndexWithState(x, PArguments.getThreadState(frame));
313+
Object index;
314+
if (hasFrame.profile(frame != null)) {
315+
index = lib.asIndexWithState(x, PArguments.getThreadState(frame));
316+
} else {
317+
index = lib.asIndex(x);
318+
}
313319
if (isSubtype.execute(lib.getLazyPythonClass(index), PythonBuiltinClassType.PInt)) {
314320
if (index instanceof Boolean || index instanceof Integer) {
315321
isInt.enter();
@@ -1045,7 +1051,7 @@ private long getId(PythonObject obj) {
10451051
public abstract static class IsInstanceNode extends PythonBinaryBuiltinNode {
10461052
@Child private GetClassNode getClassNode = GetClassNode.create();
10471053
@Child private LookupAndCallBinaryNode instanceCheckNode = LookupAndCallBinaryNode.create(__INSTANCECHECK__);
1048-
@Child private CastToBooleanNode castToBooleanNode = CastToBooleanNode.createIfTrueNode();
1054+
@Child private CoerceToBooleanNode castToBooleanNode = CoerceToBooleanNode.createIfTrueNode();
10491055
@Child private TypeBuiltins.InstanceCheckNode typeInstanceCheckNode = TypeBuiltins.InstanceCheckNode.create();
10501056
@Child private SequenceStorageNodes.LenNode lenNode;
10511057
@Child private GetObjectArrayNode getObjectArrayNode;
@@ -1122,7 +1128,7 @@ private Object[] getArray(PTuple tuple) {
11221128
@GenerateNodeFactory
11231129
public abstract static class IsSubClassNode extends PythonBinaryBuiltinNode {
11241130
@Child private LookupAndCallBinaryNode subclassCheckNode = LookupAndCallBinaryNode.create(__SUBCLASSCHECK__);
1125-
@Child private CastToBooleanNode castToBooleanNode = CastToBooleanNode.createIfTrueNode();
1131+
@Child private CoerceToBooleanNode castToBooleanNode = CoerceToBooleanNode.createIfTrueNode();
11261132
@Child private IsSubtypeNode isSubtypeNode = IsSubtypeNode.create();
11271133
@Child private SequenceStorageNodes.LenNode lenNode;
11281134
@Child private GetObjectArrayNode getObjectArrayNode;
@@ -1209,8 +1215,13 @@ public Object iter(Object callable, Object sentinel) {
12091215
public abstract static class LenNode extends PythonUnaryBuiltinNode {
12101216
@Specialization(limit = "getCallSiteInlineCacheMaxDepth()")
12111217
public int len(VirtualFrame frame, Object obj,
1218+
@Cached("createBinaryProfile()") ConditionProfile hasFrame,
12121219
@CachedLibrary("obj") PythonObjectLibrary lib) {
1213-
return lib.lengthWithState(obj, PArguments.getThreadState(frame));
1220+
if (hasFrame.profile(frame != null)) {
1221+
return lib.lengthWithState(obj, PArguments.getThreadState(frame));
1222+
} else {
1223+
return lib.length(obj);
1224+
}
12141225
}
12151226
}
12161227

@@ -1272,7 +1283,7 @@ Object minmaxSequenceWithKey(VirtualFrame frame, PythonObject arg1, @SuppressWar
12721283
Object minmaxBinary(VirtualFrame frame, Object arg1, Object[] args, @SuppressWarnings("unused") PNone keywordArg,
12731284
@Cached("createComparison()") BinaryComparisonNode compare,
12741285
@Cached("createBinaryProfile()") ConditionProfile moreThanTwo,
1275-
@Shared("castToBooleanNode") @Cached("createIfTrueNode()") CastToBooleanNode castToBooleanNode) {
1286+
@Shared("castToBooleanNode") @Cached("createIfTrueNode()") CoerceToBooleanNode castToBooleanNode) {
12761287
return minmaxBinaryWithKey(frame, arg1, args, null, compare, null, moreThanTwo, castToBooleanNode);
12771288
}
12781289

@@ -1281,7 +1292,7 @@ Object minmaxBinaryWithKey(VirtualFrame frame, Object arg1, Object[] args, Pytho
12811292
@Cached("createComparison()") BinaryComparisonNode compare,
12821293
@Cached CallNode keyCall,
12831294
@Cached("createBinaryProfile()") ConditionProfile moreThanTwo,
1284-
@Shared("castToBooleanNode") @Cached("createIfTrueNode()") CastToBooleanNode castToBooleanNode) {
1295+
@Shared("castToBooleanNode") @Cached("createIfTrueNode()") CoerceToBooleanNode castToBooleanNode) {
12851296
Object currentValue = arg1;
12861297
Object currentKey = applyKeyFunction(frame, keywordArg, keyCall, currentValue);
12871298
Object nextValue = args[0];
@@ -1454,7 +1465,7 @@ PNone printAllGiven(VirtualFrame frame, Object[] values, String sep, String end,
14541465
PNone printGeneric(VirtualFrame frame, Object[] values, Object sepIn, Object endIn, Object fileIn, Object flushIn,
14551466
@Cached CastToJavaStringNode castSep,
14561467
@Cached CastToJavaStringNode castEnd,
1457-
@Cached("createIfTrueNode()") CastToBooleanNode castFlush,
1468+
@Cached("createIfTrueNode()") CoerceToBooleanNode castFlush,
14581469
@Cached PRaiseNode raiseNode) {
14591470
String sep = sepIn instanceof PNone ? DEFAULT_SEPARATOR : castSep.execute(sepIn);
14601471
if (sep == null) {
@@ -1919,7 +1930,7 @@ public static GlobalsNode create() {
19191930
}
19201931
}
19211932

1922-
@Builtin(name = "locals", minNumOfPositionalArgs = 0)
1933+
@Builtin(name = "locals", minNumOfPositionalArgs = 0, needsFrame = true)
19231934
@GenerateNodeFactory
19241935
abstract static class LocalsNode extends PythonBuiltinNode {
19251936

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@
6868
import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes.GetInternalByteArrayNode;
6969
import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodesFactory.GetInternalByteArrayNodeGen;
7070
import com.oracle.graal.python.builtins.objects.tuple.PTuple;
71-
import com.oracle.graal.python.nodes.expression.CastToBooleanNode;
71+
import com.oracle.graal.python.nodes.expression.CoerceToBooleanNode;
7272
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
7373
import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
7474
import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
@@ -506,7 +506,7 @@ private Object[] encodeString(String self, String errors) {
506506
abstract static class CodecsDecodeNode extends EncodeBaseNode {
507507
@Child private GetInternalByteArrayNode toByteArrayNode;
508508
@Child private CastToJavaStringNode castEncodingToStringNode;
509-
@Child private CastToBooleanNode castToBooleanNode;
509+
@Child private CoerceToBooleanNode castToBooleanNode;
510510

511511
@Specialization
512512
Object decode(VirtualFrame frame, PIBytesLike bytes, @SuppressWarnings("unused") PNone encoding, @SuppressWarnings("unused") PNone errors, Object finalData) {
@@ -583,7 +583,7 @@ private boolean castToBoolean(VirtualFrame frame, Object object) {
583583
}
584584
if (castToBooleanNode == null) {
585585
CompilerDirectives.transferToInterpreterAndInvalidate();
586-
castToBooleanNode = insert(CastToBooleanNode.createIfTrueNode());
586+
castToBooleanNode = insert(CoerceToBooleanNode.createIfTrueNode());
587587
}
588588
return castToBooleanNode.executeBoolean(frame, object);
589589
}

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2019, 2020, 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
@@ -50,7 +50,7 @@
5050
import com.oracle.graal.python.builtins.objects.code.PCode;
5151
import com.oracle.graal.python.nodes.SpecialMethodNames;
5252
import com.oracle.graal.python.nodes.call.special.LookupAndCallBinaryNode;
53-
import com.oracle.graal.python.nodes.expression.CastToBooleanNode;
53+
import com.oracle.graal.python.nodes.expression.CoerceToBooleanNode;
5454
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
5555
import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
5656
import com.oracle.truffle.api.dsl.Cached;
@@ -74,7 +74,7 @@ abstract static class GetCodeGlobalVarsNode extends PythonUnaryBuiltinNode {
7474
@Specialization
7575
protected Object get(VirtualFrame frame, PCode code,
7676
@Cached GlobalsNode globalsNode,
77-
@Cached("createIfTrueNode()") CastToBooleanNode isTrue,
77+
@Cached("createIfTrueNode()") CoerceToBooleanNode isTrue,
7878
@Cached("create(__CONTAINS__)") LookupAndCallBinaryNode containsNode) {
7979
Object[] varNames = code.getGlobalAndBuiltinVarNames();
8080
if (varNames != null) {

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

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1233,11 +1233,18 @@ int gcd(@SuppressWarnings("unused") PInt x, @SuppressWarnings("unused") double y
12331233

12341234
@Specialization(guards = "!isNumber(x) || !isNumber(y)")
12351235
Object gcd(VirtualFrame frame, Object x, Object y,
1236+
@Cached("createBinaryProfile()") ConditionProfile hasFrame,
12361237
@CachedLibrary(limit = "2") PythonObjectLibrary lib,
12371238
@Cached("create()") GcdNode recursiveNode) {
1238-
ThreadState threadState = PArguments.getThreadState(frame);
1239-
Object xValue = lib.asIndexWithState(x, threadState);
1240-
Object yValue = lib.asIndexWithState(y, threadState);
1239+
Object xValue, yValue;
1240+
if (hasFrame.profile(frame != null)) {
1241+
ThreadState threadState = PArguments.getThreadState(frame);
1242+
xValue = lib.asIndexWithState(x, threadState);
1243+
yValue = lib.asIndexWithState(y, threadState);
1244+
} else {
1245+
xValue = lib.asIndex(x);
1246+
yValue = lib.asIndex(y);
1247+
}
12411248
return recursiveNode.execute(frame, xValue, yValue);
12421249
}
12431250

0 commit comments

Comments
 (0)