Skip to content

Commit e831db9

Browse files
committed
[GR-17162] [GR-17163] Minor performance fixes
PullRequest: graalpython/592
2 parents 95834c4 + df49e0f commit e831db9

29 files changed

+599
-160
lines changed
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# Copyright (c) 2019, 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+
41+
def measure(l1, l2, l3, num):
42+
flag = False
43+
for i in range(num):
44+
for l in [l1, l2, l3]:
45+
flag = type(l)
46+
return flag
47+
48+
49+
def __benchmark__(num=5000):
50+
l1 = [1000] * num
51+
l2 = list(range(num))
52+
l3 = [x for x in range(num)]
53+
measure(l1, l2, l3, num)

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

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,24 @@
2727

2828
import java.util.HashSet;
2929

30+
import com.oracle.graal.python.PythonLanguage;
3031
import com.oracle.graal.python.builtins.objects.type.LazyPythonClass;
3132
import com.oracle.graal.python.nodes.BuiltinNames;
33+
import com.oracle.graal.python.runtime.PythonContext;
3234
import com.oracle.truffle.api.CompilerAsserts;
3335
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
36+
import com.oracle.truffle.api.dsl.CachedContext;
37+
import com.oracle.truffle.api.interop.ArityException;
38+
import com.oracle.truffle.api.interop.InteropLibrary;
39+
import com.oracle.truffle.api.interop.UnknownIdentifierException;
40+
import com.oracle.truffle.api.interop.UnsupportedMessageException;
41+
import com.oracle.truffle.api.interop.UnsupportedTypeException;
42+
import com.oracle.truffle.api.library.CachedLibrary;
43+
import com.oracle.truffle.api.library.ExportLibrary;
44+
import com.oracle.truffle.api.library.ExportMessage;
3445
import com.oracle.truffle.api.object.Shape;
3546

47+
@ExportLibrary(InteropLibrary.class)
3648
public enum PythonBuiltinClassType implements LazyPythonClass {
3749

3850
ForeignObject(BuiltinNames.FOREIGN),
@@ -299,4 +311,128 @@ public Shape getInstanceShape() {
299311
UnicodeWarning.base = Warning;
300312
UserWarning.base = Warning;
301313
}
314+
315+
/* InteropLibrary messages */
316+
@SuppressWarnings("static-method")
317+
@ExportMessage
318+
public boolean isExecutable() {
319+
return true;
320+
}
321+
322+
@ExportMessage
323+
public Object execute(Object[] arguments,
324+
@CachedLibrary(limit = "1") InteropLibrary lib,
325+
@CachedContext(PythonLanguage.class) PythonContext context) throws UnsupportedTypeException, ArityException, UnsupportedMessageException {
326+
return lib.execute(context.getCore().lookupType(this), arguments);
327+
}
328+
329+
@SuppressWarnings("static-method")
330+
@ExportMessage
331+
public boolean isInstantiable() {
332+
return true;
333+
}
334+
335+
@ExportMessage
336+
public Object instantiate(Object[] arguments,
337+
@CachedLibrary(limit = "1") InteropLibrary lib,
338+
@CachedContext(PythonLanguage.class) PythonContext context) throws UnsupportedTypeException, ArityException, UnsupportedMessageException {
339+
return lib.instantiate(context.getCore().lookupType(this), arguments);
340+
}
341+
342+
@SuppressWarnings("static-method")
343+
@ExportMessage
344+
public boolean hasMembers() {
345+
return true;
346+
}
347+
348+
@ExportMessage
349+
public Object getMembers(boolean includeInternal,
350+
@CachedLibrary(limit = "1") InteropLibrary lib,
351+
@CachedContext(PythonLanguage.class) PythonContext context) throws UnsupportedMessageException {
352+
return lib.getMembers(context.getCore().lookupType(this), includeInternal);
353+
}
354+
355+
@ExportMessage
356+
public boolean isMemberReadable(String key,
357+
@CachedLibrary(limit = "1") InteropLibrary lib,
358+
@CachedContext(PythonLanguage.class) PythonContext context) {
359+
return lib.isMemberReadable(context.getCore().lookupType(this), key);
360+
}
361+
362+
@ExportMessage
363+
public Object readMember(String key,
364+
@CachedLibrary(limit = "1") InteropLibrary lib,
365+
@CachedContext(PythonLanguage.class) PythonContext context) throws UnsupportedMessageException, UnknownIdentifierException {
366+
return lib.readMember(context.getCore().lookupType(this), key);
367+
}
368+
369+
@ExportMessage
370+
public boolean isMemberModifiable(String key,
371+
@CachedLibrary(limit = "1") InteropLibrary lib,
372+
@CachedContext(PythonLanguage.class) PythonContext context) {
373+
return lib.isMemberModifiable(context.getCore().lookupType(this), key);
374+
}
375+
376+
@ExportMessage
377+
public boolean isMemberInsertable(String key,
378+
@CachedLibrary(limit = "1") InteropLibrary lib,
379+
@CachedContext(PythonLanguage.class) PythonContext context) {
380+
return lib.isMemberInsertable(context.getCore().lookupType(this), key);
381+
}
382+
383+
@ExportMessage
384+
public void writeMember(String key, Object value,
385+
@CachedLibrary(limit = "1") InteropLibrary lib,
386+
@CachedContext(PythonLanguage.class) PythonContext context) throws UnsupportedMessageException, UnknownIdentifierException, UnsupportedTypeException {
387+
lib.writeMember(context.getCore().lookupType(this), key, value);
388+
}
389+
390+
@ExportMessage
391+
public boolean isMemberRemovable(String key,
392+
@CachedLibrary(limit = "1") InteropLibrary lib,
393+
@CachedContext(PythonLanguage.class) PythonContext context) {
394+
return lib.isMemberRemovable(context.getCore().lookupType(this), key);
395+
}
396+
397+
@ExportMessage
398+
public void removeMember(String key,
399+
@CachedLibrary(limit = "1") InteropLibrary lib,
400+
@CachedContext(PythonLanguage.class) PythonContext context) throws UnsupportedMessageException, UnknownIdentifierException {
401+
lib.removeMember(context.getCore().lookupType(this), key);
402+
}
403+
404+
@ExportMessage
405+
public boolean isMemberInvocable(String key,
406+
@CachedLibrary(limit = "1") InteropLibrary lib,
407+
@CachedContext(PythonLanguage.class) PythonContext context) {
408+
return lib.isMemberInvocable(context.getCore().lookupType(this), key);
409+
}
410+
411+
@ExportMessage
412+
public Object invokeMember(String key, Object[] arguments,
413+
@CachedLibrary(limit = "1") InteropLibrary lib,
414+
@CachedContext(PythonLanguage.class) PythonContext context) throws UnsupportedMessageException, ArityException, UnknownIdentifierException, UnsupportedTypeException {
415+
return lib.invokeMember(context.getCore().lookupType(this), key, arguments);
416+
}
417+
418+
@ExportMessage
419+
public boolean isMemberInternal(String key,
420+
@CachedLibrary(limit = "1") InteropLibrary lib,
421+
@CachedContext(PythonLanguage.class) PythonContext context) {
422+
return lib.isMemberInternal(context.getCore().lookupType(this), key);
423+
}
424+
425+
@ExportMessage
426+
public boolean hasMemberReadSideEffects(String key,
427+
@CachedLibrary(limit = "1") InteropLibrary lib,
428+
@CachedContext(PythonLanguage.class) PythonContext context) {
429+
return lib.hasMemberReadSideEffects(context.getCore().lookupType(this), key);
430+
}
431+
432+
@ExportMessage
433+
public boolean hasMemberWriteSideEffects(String key,
434+
@CachedLibrary(limit = "1") InteropLibrary lib,
435+
@CachedContext(PythonLanguage.class) PythonContext context) {
436+
return lib.hasMemberWriteSideEffects(context.getCore().lookupType(this), key);
437+
}
302438
}

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

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1451,7 +1451,6 @@ public boolean bool(VirtualFrame frame, Object cls, Object obj,
14511451
@Builtin(name = LIST, minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 2, constructsClass = PythonBuiltinClassType.PList)
14521452
@GenerateNodeFactory
14531453
public abstract static class ListNode extends PythonBinaryBuiltinNode {
1454-
14551454
@Specialization
14561455
protected PList constructList(LazyPythonClass cls, @SuppressWarnings("unused") Object value) {
14571456
return factory().createList(cls);
@@ -1483,12 +1482,18 @@ public final Object varArgExecute(VirtualFrame frame, Object[] arguments, PKeywo
14831482
return execute(frame, arguments[0], splitArgsNode.execute(arguments), keywords);
14841483
}
14851484

1486-
@Specialization(limit = "getCallSiteInlineCacheMaxDepth()", guards = {"self == cachedSelf", "!self.needsNativeAllocation()"})
1485+
@Specialization(limit = "getCallSiteInlineCacheMaxDepth()", guards = {"self == cachedSelf", "!self.needsNativeAllocation()"}, assumptions = "singleContextAssumption()")
14871486
Object doObjectDirect(@SuppressWarnings("unused") PythonManagedClass self, Object[] varargs, PKeyword[] kwargs,
14881487
@Cached("self") PythonManagedClass cachedSelf) {
14891488
return doObjectIndirect(cachedSelf, varargs, kwargs);
14901489
}
14911490

1491+
@Specialization(limit = "getCallSiteInlineCacheMaxDepth()", guards = {"self == cachedSelf"})
1492+
Object doObjectDirectType(@SuppressWarnings("unused") PythonBuiltinClassType self, Object[] varargs, PKeyword[] kwargs,
1493+
@Cached("self") PythonBuiltinClassType cachedSelf) {
1494+
return doObjectIndirectType(cachedSelf, varargs, kwargs);
1495+
}
1496+
14921497
@Specialization(limit = "getCallSiteInlineCacheMaxDepth()", //
14931498
guards = {"getInstanceShape(self) == cachedInstanceShape", "!self.needsNativeAllocation()"}, //
14941499
replaces = "doObjectDirect")
@@ -1505,6 +1510,14 @@ Object doObjectIndirect(PythonManagedClass self, Object[] varargs, PKeyword[] kw
15051510
return doObjectCachedInstanceShape(self, varargs, kwargs, getInstanceShape(self));
15061511
}
15071512

1513+
@Specialization(replaces = "doObjectDirectType")
1514+
Object doObjectIndirectType(PythonBuiltinClassType self, Object[] varargs, PKeyword[] kwargs) {
1515+
if (varargs.length > 0 || kwargs.length > 0) {
1516+
// TODO: tfel: this should throw an error only if init isn't overridden
1517+
}
1518+
return factory().createPythonObject(self, self.getInstanceShape());
1519+
}
1520+
15081521
@Specialization(guards = "self.needsNativeAllocation()")
15091522
Object doNativeObjectIndirect(PythonManagedClass self, Object[] varargs, PKeyword[] kwargs,
15101523
@Cached("create()") GetMroNode getMroNode) {
@@ -1949,14 +1962,14 @@ Object type(Object cls, Object obj, PNone bases, PNone dict, PKeyword[] kwds,
19491962
}
19501963

19511964
@Specialization
1952-
Object type(VirtualFrame frame, PythonAbstractClass cls, String name, PTuple bases, PDict namespace, PKeyword[] kwds,
1953-
@Cached("create()") GetClassNode getMetaclassNode,
1965+
Object type(VirtualFrame frame, LazyPythonClass cls, String name, PTuple bases, PDict namespace, PKeyword[] kwds,
1966+
@Cached GetLazyClassNode getMetaclassNode,
19541967
@Cached("create(__NEW__)") LookupInheritedAttributeNode getNewFuncNode,
19551968
@Cached("create(__INIT_SUBCLASS__)") GetAttributeNode getInitSubclassNode,
1956-
@Cached("create()") CallNode callInitSubclassNode,
1957-
@Cached("create()") CallNode callNewFuncNode) {
1969+
@Cached CallNode callInitSubclassNode,
1970+
@Cached CallNode callNewFuncNode) {
19581971
// Determine the proper metatype to deal with this
1959-
PythonAbstractClass metaclass = calculate_metaclass(frame, cls, bases, getMetaclassNode);
1972+
LazyPythonClass metaclass = calculate_metaclass(frame, cls, bases, getMetaclassNode);
19601973
if (metaclass != cls) {
19611974
Object newFunc = getNewFuncNode.execute(metaclass);
19621975
if (newFunc instanceof PBuiltinFunction && (((PBuiltinFunction) newFunc).getFunctionRootNode() == getRootNode())) {
@@ -2010,7 +2023,7 @@ private String getModuleNameFromGlobals(VirtualFrame frame, PythonObject globals
20102023
}
20112024

20122025
@SuppressWarnings("try")
2013-
private PythonClass typeMetaclass(VirtualFrame frame, String name, PTuple bases, PDict namespace, PythonAbstractClass metaclass) {
2026+
private PythonClass typeMetaclass(VirtualFrame frame, String name, PTuple bases, PDict namespace, LazyPythonClass metaclass) {
20142027

20152028
Object[] array = bases.getArray();
20162029

@@ -2288,10 +2301,10 @@ private PythonAbstractClass[] getMro(PythonAbstractClass pythonClass) {
22882301
return getMroNode.execute(pythonClass);
22892302
}
22902303

2291-
private PythonAbstractClass calculate_metaclass(VirtualFrame frame, PythonAbstractClass cls, PTuple bases, GetClassNode getMetaclassNode) {
2292-
PythonAbstractClass winner = cls;
2304+
private LazyPythonClass calculate_metaclass(VirtualFrame frame, LazyPythonClass cls, PTuple bases, GetLazyClassNode getMetaclassNode) {
2305+
LazyPythonClass winner = cls;
22932306
for (Object base : bases.getArray()) {
2294-
PythonAbstractClass typ = getMetaclassNode.execute(base);
2307+
LazyPythonClass typ = getMetaclassNode.execute(base);
22952308
if (isSubType(frame, winner, typ)) {
22962309
continue;
22972310
} else if (isSubType(frame, typ, winner)) {
@@ -2304,7 +2317,7 @@ private PythonAbstractClass calculate_metaclass(VirtualFrame frame, PythonAbstra
23042317
return winner;
23052318
}
23062319

2307-
protected boolean isSubType(VirtualFrame frame, PythonAbstractClass subclass, PythonAbstractClass superclass) {
2320+
protected boolean isSubType(VirtualFrame frame, LazyPythonClass subclass, LazyPythonClass superclass) {
23082321
if (isSubtypeNode == null) {
23092322
CompilerDirectives.transferToInterpreterAndInvalidate();
23102323
isSubtypeNode = insert(IsSubtypeNode.create());

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@
104104
import com.oracle.graal.python.builtins.objects.function.PFunction;
105105
import com.oracle.graal.python.builtins.objects.function.PKeyword;
106106
import com.oracle.graal.python.builtins.objects.function.Signature;
107+
import com.oracle.graal.python.builtins.objects.generator.PGenerator;
107108
import com.oracle.graal.python.builtins.objects.ints.PInt;
108109
import com.oracle.graal.python.builtins.objects.list.PList;
109110
import com.oracle.graal.python.builtins.objects.method.PMethod;
@@ -1875,6 +1876,12 @@ public String doIt(PMethod method) {
18751876
return NodeUtil.printTreeToString(fun.getCallTarget().getRootNode());
18761877
}
18771878

1879+
@Specialization
1880+
@TruffleBoundary
1881+
public String doIt(PGenerator gen) {
1882+
return NodeUtil.printTreeToString(gen.getCallTarget().getRootNode());
1883+
}
1884+
18781885
@Specialization
18791886
@TruffleBoundary
18801887
public String doIt(PCode code) {

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,9 +181,13 @@ public double doPI(PInt value) {
181181
}
182182

183183
@Override
184-
@TruffleBoundary
185184
public double count(double value) {
186185
checkMathDomainError(value < 0);
186+
return op(value);
187+
}
188+
189+
@TruffleBoundary
190+
private static double op(double value) {
187191
return Math.sqrt(value);
188192
}
189193
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/method/ClassmethodBuiltins.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
import com.oracle.truffle.api.dsl.GenerateNodeFactory;
6666
import com.oracle.truffle.api.dsl.ImportStatic;
6767
import com.oracle.truffle.api.dsl.NodeFactory;
68+
import com.oracle.truffle.api.dsl.ReportPolymorphism;
6869
import com.oracle.truffle.api.dsl.Specialization;
6970
import com.oracle.truffle.api.frame.VirtualFrame;
7071
import com.oracle.truffle.api.profiles.BranchProfile;
@@ -106,6 +107,7 @@ private Object doGet(PDecoratedMethod self, Object type, BranchProfile uninitial
106107
}
107108

108109
@ImportStatic(PGuards.class)
110+
@ReportPolymorphism
109111
abstract static class MakeMethodNode extends PNodeWithContext {
110112
abstract Object execute(Object self, Object func);
111113

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,5 +40,7 @@
4040
*/
4141
package com.oracle.graal.python.builtins.objects.type;
4242

43-
public interface LazyPythonClass {
43+
import com.oracle.truffle.api.interop.TruffleObject;
44+
45+
public interface LazyPythonClass extends TruffleObject {
4446
}

0 commit comments

Comments
 (0)