Skip to content

Commit a0eeb6f

Browse files
msimacektimfel
authored andcommitted
Simplify getting __dict__ in TypeNodes
1 parent f5cf850 commit a0eeb6f

File tree

1 file changed

+47
-86
lines changed
  • graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type

1 file changed

+47
-86
lines changed

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

Lines changed: 47 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@
6565
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__SLOTS__;
6666
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__WEAKREF__;
6767
import static com.oracle.graal.python.nodes.SpecialMethodNames.MRO;
68-
import static com.oracle.graal.python.nodes.SpecialMethodNames.__GETATTRIBUTE__;
6968
import static com.oracle.graal.python.nodes.SpecialMethodNames.__NEW__;
7069

7170
import java.util.ArrayList;
@@ -94,14 +93,13 @@
9493
import com.oracle.graal.python.builtins.objects.common.HashingStorage;
9594
import com.oracle.graal.python.builtins.objects.common.HashingStorageLibrary;
9695
import com.oracle.graal.python.builtins.objects.common.HashingStorageLibrary.HashingStorageIterator;
97-
import com.oracle.graal.python.builtins.objects.common.PHashingCollection;
9896
import com.oracle.graal.python.builtins.objects.common.SequenceNodes.GetObjectArrayNode;
9997
import com.oracle.graal.python.builtins.objects.common.SequenceNodesFactory.GetObjectArrayNodeGen;
10098
import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes;
10199
import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes.GetInternalObjectArrayNode;
102100
import com.oracle.graal.python.builtins.objects.dict.PDict;
103101
import com.oracle.graal.python.builtins.objects.function.PFunction;
104-
import com.oracle.graal.python.builtins.objects.mappingproxy.PMappingproxy;
102+
import com.oracle.graal.python.builtins.objects.object.PythonObject;
105103
import com.oracle.graal.python.builtins.objects.object.PythonObjectLibrary;
106104
import com.oracle.graal.python.builtins.objects.tuple.PTuple;
107105
import com.oracle.graal.python.builtins.objects.type.TypeNodesFactory.GetBaseClassNodeGen;
@@ -124,13 +122,12 @@
124122
import com.oracle.graal.python.nodes.attributes.LookupAttributeInMRONode;
125123
import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode;
126124
import com.oracle.graal.python.nodes.attributes.WriteAttributeToObjectNode;
127-
import com.oracle.graal.python.nodes.call.special.CallBinaryMethodNode;
128125
import com.oracle.graal.python.nodes.call.special.CallUnaryMethodNode;
129-
import com.oracle.graal.python.nodes.call.special.LookupSpecialMethodNode;
130126
import com.oracle.graal.python.nodes.classes.IsSubtypeNode;
131127
import com.oracle.graal.python.nodes.object.GetClassNode;
132128
import com.oracle.graal.python.nodes.object.IsBuiltinClassProfile;
133129
import com.oracle.graal.python.nodes.truffle.PythonTypes;
130+
import com.oracle.graal.python.nodes.util.CastToJavaIntExactNode;
134131
import com.oracle.graal.python.nodes.util.CastToJavaStringNode;
135132
import com.oracle.graal.python.runtime.PythonContext;
136133
import com.oracle.graal.python.runtime.PythonOptions;
@@ -836,12 +833,11 @@ public abstract static class CheckCompatibleForAssigmentNode extends PNodeWithCo
836833
@Child private GetBaseClassNode getBaseClassNode;
837834
@Child private LookupAttributeInMRONode lookupSlotsNode;
838835
@Child private LookupAttributeInMRONode lookupNewNode;
839-
@Child private HashingStorageLibrary hashingStorageLib;
840-
@Child private PythonObjectLibrary objectLibrary;
841836
@Child private PyObjectSizeNode sizeNode;
842837
@Child private GetObjectArrayNode getObjectArrayNode;
843838
@Child private PRaiseNode raiseNode;
844839
@Child private GetNameNode getTypeNameNode;
840+
@Child private ReadAttributeFromObjectNode readAttr;
845841

846842
public abstract boolean execute(VirtualFrame frame, Object oldBase, Object newBase);
847843

@@ -880,10 +876,7 @@ private boolean compatibleForAssignment(VirtualFrame frame, Object oldB, Object
880876
oldParent = getBaseClassNode().execute(oldBase);
881877
}
882878

883-
if (newBase != oldBase && (newParent != oldParent || !sameSlotsAdded(frame, newBase, oldBase))) {
884-
return false;
885-
}
886-
return true;
879+
return newBase == oldBase || (newParent == oldParent && sameSlotsAdded(frame, newBase, oldBase));
887880
}
888881

889882
/**
@@ -901,7 +894,7 @@ private boolean compatibleWithBase(VirtualFrame frame, Object child, Object pare
901894
}
902895

903896
// instead of child->tp_dictoffset == parent->tp_dictoffset
904-
if (hasDict(frame, child) != hasDict(frame, parent)) {
897+
if (instancesHaveDict(child) != instancesHaveDict(parent)) {
905898
return false;
906899
}
907900

@@ -914,28 +907,24 @@ private boolean compatibleWithBase(VirtualFrame frame, Object child, Object pare
914907
}
915908

916909
// instead of child->tp_itemsize == parent->tp_itemsize
917-
Object childSlots = getSlotsFromDict(frame, child);
918-
Object parentSlots = getSlotsFromDict(frame, parent);
910+
Object childSlots = getSlotsFromType(child);
911+
Object parentSlots = getSlotsFromType(parent);
919912
if (childSlots == null && parentSlots == null) {
920913
return true;
921914
}
922-
if (childSlots == null && parentSlots != null || childSlots != null && parentSlots == null) {
923-
return false;
924-
}
925-
if (!compareSlots(frame, parent, child, parentSlots, childSlots)) {
915+
if (childSlots == null || parentSlots == null) {
926916
return false;
927917
}
928-
929-
return true;
918+
return compareSlots(frame, parent, child, parentSlots, childSlots);
930919
}
931920

932921
private boolean sameSlotsAdded(VirtualFrame frame, Object a, Object b) {
933922
// !(a->tp_flags & Py_TPFLAGS_HEAPTYPE) || !(b->tp_flags & Py_TPFLAGS_HEAPTYPE))
934923
if (a instanceof PythonBuiltinClass || b instanceof PythonBuiltinClass) {
935924
return false;
936925
}
937-
Object aSlots = getSlotsFromDict(frame, a);
938-
Object bSlots = getSlotsFromDict(frame, b);
926+
Object aSlots = getSlotsFromType(a);
927+
Object bSlots = getSlotsFromType(b);
939928
return compareSlots(frame, a, b, aSlots, bSlots);
940929
}
941930

@@ -974,20 +963,9 @@ private String getTypeName(Object clazz) {
974963
return getTypeNameNode.execute(clazz);
975964
}
976965

977-
private Object getSlotsFromDict(VirtualFrame frame, Object type) {
978-
Object dict = getObjectLibrary().lookupAttribute(type, frame, __DICT__);
979-
if (dict != PNone.NO_VALUE) {
980-
if (dict instanceof PMappingproxy) {
981-
dict = ((PMappingproxy) dict).getMapping();
982-
}
983-
HashingStorage storage = ((PHashingCollection) dict).getDictStorage();
984-
return getHashingStorageLibrary().getItem(storage, __SLOTS__);
985-
}
986-
return null;
987-
}
988-
989-
private boolean hasDict(VirtualFrame frame, Object type) {
990-
return getObjectLibrary().lookupAttribute(type, frame, __DICT__) != PNone.NO_VALUE;
966+
private Object getSlotsFromType(Object type) {
967+
Object slots = getReadAttr().execute(type, __SLOTS__);
968+
return slots != PNone.NO_VALUE ? slots : null;
991969
}
992970

993971
private GetObjectArrayNode getObjectArrayNode() {
@@ -998,12 +976,12 @@ private GetObjectArrayNode getObjectArrayNode() {
998976
return getObjectArrayNode;
999977
}
1000978

1001-
private PythonObjectLibrary getObjectLibrary() {
1002-
if (objectLibrary == null) {
979+
private ReadAttributeFromObjectNode getReadAttr() {
980+
if (readAttr == null) {
1003981
CompilerDirectives.transferToInterpreterAndInvalidate();
1004-
objectLibrary = insert(PythonObjectLibrary.getFactory().createDispatched(4));
982+
readAttr = insert(ReadAttributeFromObjectNode.createForceType());
1005983
}
1006-
return objectLibrary;
984+
return readAttr;
1007985
}
1008986

1009987
private PyObjectSizeNode getSizeNode() {
@@ -1014,14 +992,6 @@ private PyObjectSizeNode getSizeNode() {
1014992
return sizeNode;
1015993
}
1016994

1017-
private HashingStorageLibrary getHashingStorageLibrary() {
1018-
if (hashingStorageLib == null) {
1019-
CompilerDirectives.transferToInterpreterAndInvalidate();
1020-
hashingStorageLib = insert(HashingStorageLibrary.getFactory().createDispatched(4));
1021-
}
1022-
return hashingStorageLib;
1023-
}
1024-
1025995
private LookupAttributeInMRONode getLookupSlots() {
1026996
if (lookupSlotsNode == null) {
1027997
CompilerDirectives.transferToInterpreterAndInvalidate();
@@ -1086,38 +1056,31 @@ static GetSolidBaseNode getUncached() {
10861056
@Specialization
10871057
protected Object getSolid(Object type,
10881058
@Cached GetBaseClassNode getBaseClassNode,
1089-
@Cached LookupSpecialMethodNode.Dynamic lookupGetAttribute,
1090-
@Cached CallBinaryMethodNode callGetAttr,
1091-
@CachedLibrary(limit = "4") HashingStorageLibrary storageLibrary,
1092-
@CachedLibrary(limit = "6") PythonObjectLibrary objectLibrary,
1093-
@Cached GetClassNode getClassNode,
1059+
@Cached("createForceType()") ReadAttributeFromObjectNode readAttr,
10941060
@Cached GetInternalObjectArrayNode getArrayNode,
10951061
@Cached BranchProfile typeIsNotBase,
10961062
@Cached BranchProfile hasBase,
10971063
@Cached BranchProfile hasNoBase) {
1098-
return solidBase(type, getBaseClassNode, PythonContext.get(this), lookupGetAttribute, callGetAttr, storageLibrary, getClassNode, objectLibrary, getArrayNode, typeIsNotBase, hasBase,
1064+
return solidBase(type, getBaseClassNode, PythonContext.get(this), readAttr, getArrayNode, typeIsNotBase, hasBase,
10991065
hasNoBase, 0);
11001066
}
11011067

11021068
@TruffleBoundary
11031069
protected Object solidBaseTB(Object type, GetBaseClassNode getBaseClassNode, PythonContext context, GetInternalObjectArrayNode getArrayNode, int depth) {
1104-
return solidBase(type, getBaseClassNode, context, LookupSpecialMethodNode.Dynamic.getUncached(), CallBinaryMethodNode.getUncached(),
1105-
HashingStorageLibrary.getUncached(), GetClassNode.getUncached(), PythonObjectLibrary.getUncached(), getArrayNode, BranchProfile.getUncached(), BranchProfile.getUncached(),
1106-
BranchProfile.getUncached(),
1107-
depth);
1070+
return solidBase(type, getBaseClassNode, context, ReadAttributeFromObjectNode.getUncachedForceType(), getArrayNode, BranchProfile.getUncached(),
1071+
BranchProfile.getUncached(), BranchProfile.getUncached(), depth);
11081072
}
11091073

1110-
protected Object solidBase(Object type, GetBaseClassNode getBaseClassNode, PythonContext context, LookupSpecialMethodNode.Dynamic lookupGetAttribute,
1111-
CallBinaryMethodNode callGetAttr, HashingStorageLibrary storageLibrary, GetClassNode getClassNode,
1112-
PythonObjectLibrary objectLibrary, GetInternalObjectArrayNode getArrayNode, BranchProfile typeIsNotBase, BranchProfile hasBase, BranchProfile hasNoBase, int depth) {
1074+
protected Object solidBase(Object type, GetBaseClassNode getBaseClassNode, PythonContext context, ReadAttributeFromObjectNode readAttr,
1075+
GetInternalObjectArrayNode getArrayNode, BranchProfile typeIsNotBase, BranchProfile hasBase, BranchProfile hasNoBase, int depth) {
11131076
CompilerAsserts.partialEvaluationConstant(depth);
11141077
Object base = getBaseClassNode.execute(type);
11151078
if (base != null) {
11161079
hasBase.enter();
11171080
if (depth > 3) {
11181081
base = solidBaseTB(base, getBaseClassNode, context, getArrayNode, depth);
11191082
} else {
1120-
base = solidBase(base, getBaseClassNode, context, lookupGetAttribute, callGetAttr, storageLibrary, getClassNode, objectLibrary, getArrayNode, typeIsNotBase, hasBase,
1083+
base = solidBase(base, getBaseClassNode, context, readAttr, getArrayNode, typeIsNotBase, hasBase,
11211084
hasNoBase, depth + 1);
11221085
}
11231086
} else {
@@ -1130,27 +1093,24 @@ protected Object solidBase(Object type, GetBaseClassNode getBaseClassNode, Pytho
11301093
}
11311094
typeIsNotBase.enter();
11321095

1133-
Object typeSlots = getSlotsFromDict(type, lookupGetAttribute, callGetAttr, getClassNode, storageLibrary);
1134-
Object baseSlots = getSlotsFromDict(base, lookupGetAttribute, callGetAttr, getClassNode, storageLibrary);
1135-
if (extraivars(type, base, typeSlots, baseSlots, objectLibrary, getArrayNode)) {
1096+
Object typeSlots = getSlotsFromType(type, readAttr);
1097+
Object baseSlots = getSlotsFromType(base, readAttr);
1098+
if (extraivars(type, base, typeSlots, baseSlots, getArrayNode)) {
11361099
return type;
11371100
} else {
11381101
return base;
11391102
}
11401103
}
11411104

11421105
@TruffleBoundary
1143-
private boolean extraivars(Object type, Object base, Object typeSlots, Object baseSlots, PythonObjectLibrary objectLibrary, GetInternalObjectArrayNode getArrayNode) {
1106+
private boolean extraivars(Object type, Object base, Object typeSlots, Object baseSlots, GetInternalObjectArrayNode getArrayNode) {
11441107
if (typeSlots == null && baseSlots != null && length(((PSequence) baseSlots).getSequenceStorage(), getArrayNode) != 0 ||
11451108
baseSlots == null && typeSlots != null && length(((PSequence) typeSlots).getSequenceStorage(), getArrayNode) != 0) {
11461109
return true;
11471110
}
11481111
Object typeNewMethod = LookupAttributeInMRONode.lookup(type, __NEW__, GetMroStorageNode.getUncached(), ReadAttributeFromObjectNode.getUncached(), true);
11491112
Object baseNewMethod = LookupAttributeInMRONode.lookup(base, __NEW__, GetMroStorageNode.getUncached(), ReadAttributeFromObjectNode.getUncached(), true);
1150-
if (typeNewMethod != baseNewMethod) {
1151-
return true;
1152-
}
1153-
return hasDict(base, objectLibrary) != hasDict(type, objectLibrary);
1113+
return typeNewMethod != baseNewMethod;
11541114
}
11551115

11561116
@TruffleBoundary
@@ -1168,22 +1128,9 @@ private static int length(SequenceStorage storage, GetInternalObjectArrayNode ge
11681128
return result;
11691129
}
11701130

1171-
private static Object getSlotsFromDict(Object type, LookupSpecialMethodNode.Dynamic lookupGetAttribute, CallBinaryMethodNode callGetAttr,
1172-
GetClassNode getClassNode, HashingStorageLibrary lib) {
1173-
Object getAttr = lookupGetAttribute.execute(null, getClassNode.execute(type), __GETATTRIBUTE__, type);
1174-
Object dict = callGetAttr.executeObject(getAttr, type, __DICT__);
1175-
if (dict != PNone.NO_VALUE) {
1176-
if (dict instanceof PMappingproxy) {
1177-
dict = ((PMappingproxy) dict).getMapping();
1178-
}
1179-
HashingStorage storage = ((PHashingCollection) dict).getDictStorage();
1180-
return lib.getItem(storage, __SLOTS__);
1181-
}
1182-
return null;
1183-
}
1184-
1185-
protected boolean hasDict(Object obj, PythonObjectLibrary objectLibrary) {
1186-
return objectLibrary.lookupAttribute(obj, null, __DICT__) != PNone.NO_VALUE;
1131+
private static Object getSlotsFromType(Object type, ReadAttributeFromObjectNode readAttr) {
1132+
Object slots = readAttr.execute(type, __SLOTS__);
1133+
return slots != PNone.NO_VALUE ? slots : null;
11871134
}
11881135
}
11891136

@@ -1697,4 +1644,18 @@ private static long getBuiltinTypeItemsize(PythonBuiltinClassType cls) {
16971644
}
16981645
}
16991646
}
1647+
1648+
// Equivalent of checking type->tp_dictoffset != 0 in CPython
1649+
private static boolean instancesHaveDict(Object type) {
1650+
if (type instanceof PythonBuiltinClassType) {
1651+
return ((PythonBuiltinClassType) type).isBuiltinWithDict();
1652+
}
1653+
if (type instanceof PythonClass) {
1654+
return (((PythonClass) type).getInstanceShape().getFlags() & PythonObject.HAS_SLOTS_BUT_NO_DICT_FLAG) == 0;
1655+
}
1656+
if (type instanceof PythonAbstractNativeObject) {
1657+
return CastToJavaIntExactNode.getUncached().execute(GetTypeMemberNode.getUncached().execute(type, NativeMember.TP_DICTOFFSET)) != 0;
1658+
}
1659+
return true;
1660+
}
17001661
}

0 commit comments

Comments
 (0)