Skip to content

Commit 348dd26

Browse files
committed
[GR-16603] Attribute access optimizations for multi and single context
PullRequest: graalpython/573
2 parents 298ee69 + 36b7be4 commit 348dd26

27 files changed

+586
-327
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1497,7 +1497,7 @@ Object doObjectCachedInstanceShape(@SuppressWarnings("unused") PythonManagedClas
14971497
if (varargs.length > 0 || kwargs.length > 0) {
14981498
// TODO: tfel: this should throw an error only if init isn't overridden
14991499
}
1500-
return factory().createPythonObject(cachedInstanceShape);
1500+
return factory().createPythonObject(self, cachedInstanceShape);
15011501
}
15021502

15031503
@Specialization(guards = "!self.needsNativeAllocation()", replaces = "doObjectCachedInstanceShape")

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

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@
109109
import com.oracle.graal.python.builtins.objects.method.PMethod;
110110
import com.oracle.graal.python.builtins.objects.module.PythonModule;
111111
import com.oracle.graal.python.builtins.objects.object.PythonObject;
112+
import com.oracle.graal.python.builtins.objects.object.PythonObjectLibrary;
112113
import com.oracle.graal.python.builtins.objects.set.PFrozenSet;
113114
import com.oracle.graal.python.builtins.objects.str.PString;
114115
import com.oracle.graal.python.builtins.objects.tuple.PTuple;
@@ -188,6 +189,8 @@
188189
import com.oracle.truffle.api.frame.FrameDescriptor;
189190
import com.oracle.truffle.api.frame.FrameSlot;
190191
import com.oracle.truffle.api.frame.VirtualFrame;
192+
import com.oracle.truffle.api.interop.UnsupportedMessageException;
193+
import com.oracle.truffle.api.library.CachedLibrary;
191194
import com.oracle.truffle.api.nodes.ExplodeLoop;
192195
import com.oracle.truffle.api.nodes.Node;
193196
import com.oracle.truffle.api.nodes.NodeUtil;
@@ -652,12 +655,17 @@ private static void setCustomLocals(Object[] args, Object locals) {
652655
PArguments.setCustomLocals(args, locals);
653656
}
654657

655-
private void setBuiltinsInGlobals(VirtualFrame frame, PDict globals, HashingCollectionNodes.SetItemNode setBuiltins, PythonModule builtins) {
658+
private void setBuiltinsInGlobals(VirtualFrame frame, PDict globals, HashingCollectionNodes.SetItemNode setBuiltins, PythonModule builtins, PythonObjectLibrary lib) {
656659
if (builtins != null) {
657-
PHashingCollection builtinsDict = builtins.getDict();
660+
PHashingCollection builtinsDict = lib.getDict(builtins);
658661
if (builtinsDict == null) {
659662
builtinsDict = factory().createDictFixedStorage(builtins);
660-
builtins.setDict(builtinsDict);
663+
try {
664+
lib.setDict(builtins, builtinsDict);
665+
} catch (UnsupportedMessageException e) {
666+
CompilerDirectives.transferToInterpreter();
667+
throw new IllegalStateException(e);
668+
}
661669
}
662670
setBuiltins.execute(frame, globals, BuiltinNames.__BUILTINS__, builtinsDict);
663671
} else {
@@ -666,9 +674,9 @@ private void setBuiltinsInGlobals(VirtualFrame frame, PDict globals, HashingColl
666674
}
667675
}
668676

669-
private void setCustomGlobals(VirtualFrame frame, PDict globals, HashingCollectionNodes.SetItemNode setBuiltins, Object[] args) {
677+
private void setCustomGlobals(VirtualFrame frame, PDict globals, HashingCollectionNodes.SetItemNode setBuiltins, Object[] args, PythonObjectLibrary lib) {
670678
PythonModule builtins = getContext().getBuiltins();
671-
setBuiltinsInGlobals(frame, globals, setBuiltins, builtins);
679+
setBuiltinsInGlobals(frame, globals, setBuiltins, builtins, lib);
672680
PArguments.setGlobals(args, globals);
673681
}
674682

@@ -687,10 +695,11 @@ Object execInheritGlobalsInheritLocals(VirtualFrame frame, Object source, @Suppr
687695

688696
@Specialization
689697
Object execCustomGlobalsGlobalLocals(VirtualFrame frame, Object source, PDict globals, @SuppressWarnings("unused") PNone locals,
698+
@CachedLibrary(limit = "1") PythonObjectLibrary lib,
690699
@Cached("create()") HashingCollectionNodes.SetItemNode setBuiltins) {
691700
PCode code = createAndCheckCode(frame, source);
692701
Object[] args = PArguments.create();
693-
setCustomGlobals(frame, globals, setBuiltins, args);
702+
setCustomGlobals(frame, globals, setBuiltins, args, lib);
694703
// here, we don't need to set any locals, since the {Write,Read,Delete}NameNodes will
695704
// fall back (like their CPython counterparts) to writing to the globals. We only need
696705
// to ensure that the `locals()` call still gives us the globals dict
@@ -717,10 +726,11 @@ Object execInheritGlobalsCustomLocals(VirtualFrame frame, Object source, @Suppre
717726

718727
@Specialization(guards = {"isMapping(locals)"})
719728
Object execCustomGlobalsCustomLocals(VirtualFrame frame, Object source, PDict globals, Object locals,
729+
@CachedLibrary(limit = "1") PythonObjectLibrary lib,
720730
@Cached("create()") HashingCollectionNodes.SetItemNode setBuiltins) {
721731
PCode code = createAndCheckCode(frame, source);
722732
Object[] args = PArguments.create();
723-
setCustomGlobals(frame, globals, setBuiltins, args);
733+
setCustomGlobals(frame, globals, setBuiltins, args, lib);
724734
setCustomLocals(args, locals);
725735

726736
return invokeNode.execute(frame, code.getRootCallTarget(), args);
@@ -1927,14 +1937,21 @@ abstract static class GlobalsNode extends PythonBuiltinNode {
19271937
private final ConditionProfile condProfile = ConditionProfile.createBinaryProfile();
19281938

19291939
@Specialization
1930-
public Object globals(VirtualFrame frame) {
1940+
public Object globals(VirtualFrame frame,
1941+
@CachedLibrary(limit = "1") PythonObjectLibrary lib) {
19311942
PFrame callerFrame = readCallerFrameNode.executeWith(frame, 0);
19321943
PythonObject globals = callerFrame.getGlobals();
19331944
if (condProfile.profile(globals instanceof PythonModule)) {
1934-
PHashingCollection dict = globals.getDict();
1945+
PHashingCollection dict = lib.getDict(globals);
19351946
if (dict == null) {
19361947
CompilerDirectives.transferToInterpreter();
1937-
globals.setDict(dict = factory().createDictFixedStorage(globals));
1948+
dict = factory().createDictFixedStorage(globals);
1949+
try {
1950+
lib.setDict(globals, dict);
1951+
} catch (UnsupportedMessageException e) {
1952+
CompilerDirectives.transferToInterpreter();
1953+
throw new IllegalStateException(e);
1954+
}
19381955
}
19391956
return dict;
19401957
} else {

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/PEllipsis.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2018, 2019, 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
@@ -40,8 +40,14 @@
4040
*/
4141
package com.oracle.graal.python.builtins.objects;
4242

43+
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
44+
import com.oracle.graal.python.builtins.objects.object.PythonObjectLibrary;
45+
import com.oracle.graal.python.builtins.objects.type.LazyPythonClass;
4346
import com.oracle.truffle.api.CompilerAsserts;
47+
import com.oracle.truffle.api.library.ExportLibrary;
48+
import com.oracle.truffle.api.library.ExportMessage;
4449

50+
@ExportLibrary(PythonObjectLibrary.class)
4551
public final class PEllipsis extends PythonAbstractObject {
4652

4753
public static final PEllipsis INSTANCE = new PEllipsis();
@@ -59,4 +65,10 @@ public String toString() {
5965
public int compareTo(Object o) {
6066
return this.hashCode() - o.hashCode();
6167
}
68+
69+
@ExportMessage
70+
@SuppressWarnings("static-method")
71+
public LazyPythonClass getLazyPythonClass() {
72+
return PythonBuiltinClassType.PEllipsis;
73+
}
6274
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/PNone.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,16 @@
2525
*/
2626
package com.oracle.graal.python.builtins.objects;
2727

28+
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
29+
import com.oracle.graal.python.builtins.objects.object.PythonObjectLibrary;
30+
import com.oracle.graal.python.builtins.objects.type.LazyPythonClass;
2831
import com.oracle.truffle.api.CompilerAsserts;
2932
import com.oracle.truffle.api.interop.InteropLibrary;
3033
import com.oracle.truffle.api.library.ExportLibrary;
3134
import com.oracle.truffle.api.library.ExportMessage;
3235

3336
@ExportLibrary(InteropLibrary.class)
37+
@ExportLibrary(PythonObjectLibrary.class)
3438
public final class PNone extends PythonAbstractObject {
3539

3640
public static final PNone NONE = new PNone();
@@ -54,4 +58,10 @@ public int compareTo(Object o) {
5458
static boolean isNull(@SuppressWarnings("unused") PNone self) {
5559
return true;
5660
}
61+
62+
@ExportMessage
63+
@SuppressWarnings("static-method")
64+
public LazyPythonClass getLazyPythonClass() {
65+
return PythonBuiltinClassType.PNone;
66+
}
5767
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/PNotImplemented.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2017, 2018, Oracle and/or its affiliates.
2+
* Copyright (c) 2017, 2019, Oracle and/or its affiliates.
33
* Copyright (c) 2013, Regents of the University of California
44
*
55
* All rights reserved.
@@ -25,8 +25,14 @@
2525
*/
2626
package com.oracle.graal.python.builtins.objects;
2727

28+
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
29+
import com.oracle.graal.python.builtins.objects.object.PythonObjectLibrary;
30+
import com.oracle.graal.python.builtins.objects.type.LazyPythonClass;
2831
import com.oracle.truffle.api.CompilerAsserts;
32+
import com.oracle.truffle.api.library.ExportLibrary;
33+
import com.oracle.truffle.api.library.ExportMessage;
2934

35+
@ExportLibrary(PythonObjectLibrary.class)
3036
public final class PNotImplemented extends PythonAbstractObject {
3137

3238
public static final PNotImplemented NOT_IMPLEMENTED = new PNotImplemented();
@@ -43,4 +49,10 @@ public String toString() {
4349
public int compareTo(Object o) {
4450
return this.hashCode() - o.hashCode();
4551
}
52+
53+
@ExportMessage
54+
@SuppressWarnings("static-method")
55+
public LazyPythonClass getLazyPythonClass() {
56+
return PythonBuiltinClassType.PNotImplemented;
57+
}
4658
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cell/PCell.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,17 @@
4040
*/
4141
package com.oracle.graal.python.builtins.objects.cell;
4242

43+
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
4344
import com.oracle.graal.python.builtins.objects.PythonAbstractObject;
45+
import com.oracle.graal.python.builtins.objects.object.PythonObjectLibrary;
46+
import com.oracle.graal.python.builtins.objects.type.LazyPythonClass;
4447
import com.oracle.truffle.api.Assumption;
4548
import com.oracle.truffle.api.CompilerAsserts;
4649
import com.oracle.truffle.api.CompilerDirectives;
50+
import com.oracle.truffle.api.library.ExportLibrary;
51+
import com.oracle.truffle.api.library.ExportMessage;
4752

53+
@ExportLibrary(PythonObjectLibrary.class)
4854
public final class PCell extends PythonAbstractObject {
4955
private final Assumption effectivelyFinal;
5056
private Object ref;
@@ -101,4 +107,10 @@ public int compareTo(Object o) {
101107
CompilerDirectives.transferToInterpreter();
102108
throw new UnsupportedOperationException();
103109
}
110+
111+
@ExportMessage
112+
@SuppressWarnings("static-method")
113+
public LazyPythonClass getLazyPythonClass() {
114+
return PythonBuiltinClassType.PCell;
115+
}
104116
}

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

Lines changed: 0 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,10 @@
4040
*/
4141
package com.oracle.graal.python.builtins.objects.cext;
4242

43-
import static com.oracle.graal.python.builtins.objects.cext.NativeCAPISymbols.FUN_GET_OB_TYPE;
4443
import static com.oracle.graal.python.builtins.objects.cext.NativeCAPISymbols.FUN_NATIVE_LONG_TO_JAVA;
4544
import static com.oracle.graal.python.builtins.objects.cext.NativeCAPISymbols.FUN_NATIVE_TO_JAVA;
4645
import static com.oracle.graal.python.builtins.objects.cext.NativeCAPISymbols.FUN_PTR_COMPARE;
4746
import static com.oracle.graal.python.builtins.objects.cext.NativeCAPISymbols.FUN_PY_FLOAT_AS_DOUBLE;
48-
import static com.oracle.graal.python.builtins.objects.cext.NativeCAPISymbols.FUN_PY_OBJECT_GENERIC_GET_DICT;
4947
import static com.oracle.graal.python.builtins.objects.cext.NativeCAPISymbols.FUN_PY_TRUFFLE_BYTE_ARRAY_TO_NATIVE;
5048
import static com.oracle.graal.python.builtins.objects.cext.NativeCAPISymbols.FUN_PY_TRUFFLE_CSTR_TO_STRING;
5149
import static com.oracle.graal.python.builtins.objects.cext.NativeCAPISymbols.FUN_PY_TRUFFLE_STRING_TO_CSTR;
@@ -66,7 +64,6 @@
6664
import com.oracle.graal.python.builtins.objects.cext.CExtNodesFactory.AsLongNodeGen;
6765
import com.oracle.graal.python.builtins.objects.cext.CExtNodesFactory.CextUpcallNodeGen;
6866
import com.oracle.graal.python.builtins.objects.cext.CExtNodesFactory.DirectUpcallNodeGen;
69-
import com.oracle.graal.python.builtins.objects.cext.CExtNodesFactory.GetNativeClassNodeFactory.GetNativeClassCachedNodeGen;
7067
import com.oracle.graal.python.builtins.objects.cext.CExtNodesFactory.GetTypeMemberNodeGen;
7168
import com.oracle.graal.python.builtins.objects.cext.CExtNodesFactory.IsPointerNodeGen;
7269
import com.oracle.graal.python.builtins.objects.cext.CExtNodesFactory.ObjectUpcallNodeGen;
@@ -873,76 +870,6 @@ public String execute(Object charPtr,
873870
}
874871
}
875872

876-
// -----------------------------------------------------------------------------------------------------------------
877-
public abstract static class GetNativeClassNode extends CExtBaseNode {
878-
public abstract PythonAbstractClass execute(PythonNativeObject object);
879-
880-
abstract static class GetNativeClassCachedNode extends GetNativeClassNode {
881-
@Specialization(guards = "object == cachedObject", limit = "1")
882-
static PythonAbstractClass getNativeClassCachedIdentity(@SuppressWarnings("unused") PythonNativeObject object,
883-
@Exclusive @Cached("object") @SuppressWarnings("unused") PythonNativeObject cachedObject,
884-
@Exclusive @Cached(value = "getNativeClassUncached(cachedObject)", allowUncached = true) PythonAbstractClass cachedClass) {
885-
// TODO: (tfel) is this really something we can do? It's so rare for this class to
886-
// change that it shouldn't be worth the effort, but in native code, anything can
887-
// happen. OTOH, CPython also has caches that can become invalid when someone just
888-
// goes and changes the ob_type of an object.
889-
return cachedClass;
890-
}
891-
892-
@Specialization(guards = "cachedObject.equals(object)", limit = "1", assumptions = "singleContextAssumption()")
893-
static PythonAbstractClass getNativeClassCached(@SuppressWarnings("unused") PythonNativeObject object,
894-
@Exclusive @Cached("object") @SuppressWarnings("unused") PythonNativeObject cachedObject,
895-
@Exclusive @Cached(value = "getNativeClassUncached(cachedObject)", allowUncached = true) PythonAbstractClass cachedClass) {
896-
// TODO same as for 'getNativeClassCachedIdentity'
897-
return cachedClass;
898-
}
899-
900-
@Specialization(replaces = "getNativeClassCached")
901-
static PythonAbstractClass getNativeClass(PythonNativeObject object,
902-
@Exclusive @Cached PCallCapiFunction callGetObTypeNode,
903-
@Exclusive @Cached ToJavaNode toJavaNode) {
904-
// do not convert wrap 'object.object' since that is really the native pointer
905-
// object
906-
return (PythonAbstractClass) toJavaNode.execute(callGetObTypeNode.call(FUN_GET_OB_TYPE, object.getPtr()));
907-
}
908-
909-
protected static PythonAbstractClass getNativeClassUncached(PythonNativeObject object) {
910-
// do not convert wrap 'object.object' since that is really the native pointer
911-
// object
912-
return getNativeClass(object, PCallCapiFunction.getUncached(), ToJavaNode.getUncached());
913-
}
914-
}
915-
916-
private static final class Uncached extends GetNativeClassNode {
917-
private static final Uncached INSTANCE = new Uncached();
918-
919-
@TruffleBoundary
920-
@Override
921-
public PythonAbstractClass execute(PythonNativeObject object) {
922-
return GetNativeClassCachedNode.getNativeClassUncached(object);
923-
}
924-
925-
@Override
926-
public NodeCost getCost() {
927-
return NodeCost.MEGAMORPHIC;
928-
}
929-
930-
@Override
931-
public boolean isAdoptable() {
932-
return false;
933-
}
934-
935-
}
936-
937-
public static GetNativeClassNode create() {
938-
return GetNativeClassCachedNodeGen.create();
939-
}
940-
941-
public static GetNativeClassNode getUncached() {
942-
return Uncached.INSTANCE;
943-
}
944-
}
945-
946873
// -----------------------------------------------------------------------------------------------------------------
947874
@GenerateUncached
948875
public abstract static class SizeofWCharNode extends CExtBaseNode {
@@ -1732,35 +1659,6 @@ void doGeneric(PythonAbstractObject obj, Object ptr,
17321659
}
17331660
}
17341661

1735-
// -----------------------------------------------------------------------------------------------------------------
1736-
@GenerateUncached
1737-
public abstract static class GetObjectDictNode extends CExtBaseNode {
1738-
public abstract Object execute(Object self);
1739-
1740-
@Specialization
1741-
public Object execute(Object self,
1742-
@Exclusive @Cached ToSulongNode toSulong,
1743-
@Exclusive @Cached ToJavaNode toJava,
1744-
@CachedLibrary(limit = "1") InteropLibrary interopLibrary,
1745-
@Exclusive @Cached ImportCAPISymbolNode importCAPISymbolNode) {
1746-
try {
1747-
Object func = importCAPISymbolNode.execute(FUN_PY_OBJECT_GENERIC_GET_DICT);
1748-
return toJava.execute(interopLibrary.execute(func, toSulong.execute(self)));
1749-
} catch (UnsupportedTypeException | ArityException | UnsupportedMessageException e) {
1750-
CompilerDirectives.transferToInterpreter();
1751-
throw new IllegalStateException("could not run our core function to get the dict of a native object", e);
1752-
}
1753-
}
1754-
1755-
public static GetObjectDictNode create() {
1756-
return CExtNodesFactory.GetObjectDictNodeGen.create();
1757-
}
1758-
1759-
public static GetObjectDictNode getUncached() {
1760-
return CExtNodesFactory.GetObjectDictNodeGen.getUncached();
1761-
}
1762-
}
1763-
17641662
@GenerateUncached
17651663
@TypeSystemReference(PythonTypes.class)
17661664
public abstract static class GetTypeMemberNode extends CExtBaseNode {

0 commit comments

Comments
 (0)