65
65
import static com .oracle .graal .python .nodes .SpecialAttributeNames .__SLOTS__ ;
66
66
import static com .oracle .graal .python .nodes .SpecialAttributeNames .__WEAKREF__ ;
67
67
import static com .oracle .graal .python .nodes .SpecialMethodNames .MRO ;
68
- import static com .oracle .graal .python .nodes .SpecialMethodNames .__GETATTRIBUTE__ ;
69
68
import static com .oracle .graal .python .nodes .SpecialMethodNames .__NEW__ ;
70
69
71
70
import java .util .ArrayList ;
94
93
import com .oracle .graal .python .builtins .objects .common .HashingStorage ;
95
94
import com .oracle .graal .python .builtins .objects .common .HashingStorageLibrary ;
96
95
import com .oracle .graal .python .builtins .objects .common .HashingStorageLibrary .HashingStorageIterator ;
97
- import com .oracle .graal .python .builtins .objects .common .PHashingCollection ;
98
96
import com .oracle .graal .python .builtins .objects .common .SequenceNodes .GetObjectArrayNode ;
99
97
import com .oracle .graal .python .builtins .objects .common .SequenceNodesFactory .GetObjectArrayNodeGen ;
100
98
import com .oracle .graal .python .builtins .objects .common .SequenceStorageNodes ;
101
99
import com .oracle .graal .python .builtins .objects .common .SequenceStorageNodes .GetInternalObjectArrayNode ;
102
100
import com .oracle .graal .python .builtins .objects .dict .PDict ;
103
101
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 ;
105
103
import com .oracle .graal .python .builtins .objects .object .PythonObjectLibrary ;
106
104
import com .oracle .graal .python .builtins .objects .tuple .PTuple ;
107
105
import com .oracle .graal .python .builtins .objects .type .TypeNodesFactory .GetBaseClassNodeGen ;
124
122
import com .oracle .graal .python .nodes .attributes .LookupAttributeInMRONode ;
125
123
import com .oracle .graal .python .nodes .attributes .ReadAttributeFromObjectNode ;
126
124
import com .oracle .graal .python .nodes .attributes .WriteAttributeToObjectNode ;
127
- import com .oracle .graal .python .nodes .call .special .CallBinaryMethodNode ;
128
125
import com .oracle .graal .python .nodes .call .special .CallUnaryMethodNode ;
129
- import com .oracle .graal .python .nodes .call .special .LookupSpecialMethodNode ;
130
126
import com .oracle .graal .python .nodes .classes .IsSubtypeNode ;
131
127
import com .oracle .graal .python .nodes .object .GetClassNode ;
132
128
import com .oracle .graal .python .nodes .object .IsBuiltinClassProfile ;
133
129
import com .oracle .graal .python .nodes .truffle .PythonTypes ;
130
+ import com .oracle .graal .python .nodes .util .CastToJavaIntExactNode ;
134
131
import com .oracle .graal .python .nodes .util .CastToJavaStringNode ;
135
132
import com .oracle .graal .python .runtime .PythonContext ;
136
133
import com .oracle .graal .python .runtime .PythonOptions ;
@@ -836,12 +833,11 @@ public abstract static class CheckCompatibleForAssigmentNode extends PNodeWithCo
836
833
@ Child private GetBaseClassNode getBaseClassNode ;
837
834
@ Child private LookupAttributeInMRONode lookupSlotsNode ;
838
835
@ Child private LookupAttributeInMRONode lookupNewNode ;
839
- @ Child private HashingStorageLibrary hashingStorageLib ;
840
- @ Child private PythonObjectLibrary objectLibrary ;
841
836
@ Child private PyObjectSizeNode sizeNode ;
842
837
@ Child private GetObjectArrayNode getObjectArrayNode ;
843
838
@ Child private PRaiseNode raiseNode ;
844
839
@ Child private GetNameNode getTypeNameNode ;
840
+ @ Child private ReadAttributeFromObjectNode readAttr ;
845
841
846
842
public abstract boolean execute (VirtualFrame frame , Object oldBase , Object newBase );
847
843
@@ -880,10 +876,7 @@ private boolean compatibleForAssignment(VirtualFrame frame, Object oldB, Object
880
876
oldParent = getBaseClassNode ().execute (oldBase );
881
877
}
882
878
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 ));
887
880
}
888
881
889
882
/**
@@ -901,7 +894,7 @@ private boolean compatibleWithBase(VirtualFrame frame, Object child, Object pare
901
894
}
902
895
903
896
// instead of child->tp_dictoffset == parent->tp_dictoffset
904
- if (hasDict ( frame , child ) != hasDict ( frame , parent )) {
897
+ if (instancesHaveDict ( child ) != instancesHaveDict ( parent )) {
905
898
return false ;
906
899
}
907
900
@@ -914,28 +907,24 @@ private boolean compatibleWithBase(VirtualFrame frame, Object child, Object pare
914
907
}
915
908
916
909
// 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 );
919
912
if (childSlots == null && parentSlots == null ) {
920
913
return true ;
921
914
}
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 ) {
926
916
return false ;
927
917
}
928
-
929
- return true ;
918
+ return compareSlots (frame , parent , child , parentSlots , childSlots );
930
919
}
931
920
932
921
private boolean sameSlotsAdded (VirtualFrame frame , Object a , Object b ) {
933
922
// !(a->tp_flags & Py_TPFLAGS_HEAPTYPE) || !(b->tp_flags & Py_TPFLAGS_HEAPTYPE))
934
923
if (a instanceof PythonBuiltinClass || b instanceof PythonBuiltinClass ) {
935
924
return false ;
936
925
}
937
- Object aSlots = getSlotsFromDict ( frame , a );
938
- Object bSlots = getSlotsFromDict ( frame , b );
926
+ Object aSlots = getSlotsFromType ( a );
927
+ Object bSlots = getSlotsFromType ( b );
939
928
return compareSlots (frame , a , b , aSlots , bSlots );
940
929
}
941
930
@@ -974,20 +963,9 @@ private String getTypeName(Object clazz) {
974
963
return getTypeNameNode .execute (clazz );
975
964
}
976
965
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 ;
991
969
}
992
970
993
971
private GetObjectArrayNode getObjectArrayNode () {
@@ -998,12 +976,12 @@ private GetObjectArrayNode getObjectArrayNode() {
998
976
return getObjectArrayNode ;
999
977
}
1000
978
1001
- private PythonObjectLibrary getObjectLibrary () {
1002
- if (objectLibrary == null ) {
979
+ private ReadAttributeFromObjectNode getReadAttr () {
980
+ if (readAttr == null ) {
1003
981
CompilerDirectives .transferToInterpreterAndInvalidate ();
1004
- objectLibrary = insert (PythonObjectLibrary . getFactory (). createDispatched ( 4 ));
982
+ readAttr = insert (ReadAttributeFromObjectNode . createForceType ( ));
1005
983
}
1006
- return objectLibrary ;
984
+ return readAttr ;
1007
985
}
1008
986
1009
987
private PyObjectSizeNode getSizeNode () {
@@ -1014,14 +992,6 @@ private PyObjectSizeNode getSizeNode() {
1014
992
return sizeNode ;
1015
993
}
1016
994
1017
- private HashingStorageLibrary getHashingStorageLibrary () {
1018
- if (hashingStorageLib == null ) {
1019
- CompilerDirectives .transferToInterpreterAndInvalidate ();
1020
- hashingStorageLib = insert (HashingStorageLibrary .getFactory ().createDispatched (4 ));
1021
- }
1022
- return hashingStorageLib ;
1023
- }
1024
-
1025
995
private LookupAttributeInMRONode getLookupSlots () {
1026
996
if (lookupSlotsNode == null ) {
1027
997
CompilerDirectives .transferToInterpreterAndInvalidate ();
@@ -1086,38 +1056,31 @@ static GetSolidBaseNode getUncached() {
1086
1056
@ Specialization
1087
1057
protected Object getSolid (Object type ,
1088
1058
@ 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 ,
1094
1060
@ Cached GetInternalObjectArrayNode getArrayNode ,
1095
1061
@ Cached BranchProfile typeIsNotBase ,
1096
1062
@ Cached BranchProfile hasBase ,
1097
1063
@ 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 ,
1099
1065
hasNoBase , 0 );
1100
1066
}
1101
1067
1102
1068
@ TruffleBoundary
1103
1069
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 );
1108
1072
}
1109
1073
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 ) {
1113
1076
CompilerAsserts .partialEvaluationConstant (depth );
1114
1077
Object base = getBaseClassNode .execute (type );
1115
1078
if (base != null ) {
1116
1079
hasBase .enter ();
1117
1080
if (depth > 3 ) {
1118
1081
base = solidBaseTB (base , getBaseClassNode , context , getArrayNode , depth );
1119
1082
} 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 ,
1121
1084
hasNoBase , depth + 1 );
1122
1085
}
1123
1086
} else {
@@ -1130,27 +1093,24 @@ protected Object solidBase(Object type, GetBaseClassNode getBaseClassNode, Pytho
1130
1093
}
1131
1094
typeIsNotBase .enter ();
1132
1095
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 )) {
1136
1099
return type ;
1137
1100
} else {
1138
1101
return base ;
1139
1102
}
1140
1103
}
1141
1104
1142
1105
@ 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 ) {
1144
1107
if (typeSlots == null && baseSlots != null && length (((PSequence ) baseSlots ).getSequenceStorage (), getArrayNode ) != 0 ||
1145
1108
baseSlots == null && typeSlots != null && length (((PSequence ) typeSlots ).getSequenceStorage (), getArrayNode ) != 0 ) {
1146
1109
return true ;
1147
1110
}
1148
1111
Object typeNewMethod = LookupAttributeInMRONode .lookup (type , __NEW__ , GetMroStorageNode .getUncached (), ReadAttributeFromObjectNode .getUncached (), true );
1149
1112
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 ;
1154
1114
}
1155
1115
1156
1116
@ TruffleBoundary
@@ -1168,22 +1128,9 @@ private static int length(SequenceStorage storage, GetInternalObjectArrayNode ge
1168
1128
return result ;
1169
1129
}
1170
1130
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 ;
1187
1134
}
1188
1135
}
1189
1136
@@ -1697,4 +1644,18 @@ private static long getBuiltinTypeItemsize(PythonBuiltinClassType cls) {
1697
1644
}
1698
1645
}
1699
1646
}
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
+ }
1700
1661
}
0 commit comments