43
43
import com .oracle .graal .python .builtins .objects .common .SequenceNodes .GetObjectArrayNode ;
44
44
import com .oracle .graal .python .builtins .objects .common .SequenceStorageNodes ;
45
45
import com .oracle .graal .python .builtins .objects .tuple .PTuple ;
46
+ import com .oracle .graal .python .builtins .objects .type .TypeNodes .IsSameTypeNode ;
46
47
import com .oracle .graal .python .nodes .PNodeWithContext ;
47
48
import com .oracle .graal .python .runtime .PythonOptions ;
48
49
import com .oracle .truffle .api .CompilerDirectives ;
49
50
import com .oracle .truffle .api .dsl .Cached ;
51
+ import com .oracle .truffle .api .dsl .Cached .Shared ;
50
52
import com .oracle .truffle .api .dsl .GenerateUncached ;
51
53
import com .oracle .truffle .api .dsl .ImportStatic ;
52
54
import com .oracle .truffle .api .dsl .Specialization ;
@@ -73,8 +75,10 @@ public final boolean execute(Object derived, Object cls) {
73
75
return execute (null , derived , cls );
74
76
}
75
77
76
- @ Specialization (guards = "derived == cls" )
77
- boolean isSameClass (@ SuppressWarnings ("unused" ) Object derived , @ SuppressWarnings ("unused" ) Object cls ) {
78
+ @ Specialization (guards = "isSameMetaObject(isSameTypeNode, derived, cls)" , limit = "1" )
79
+ @ SuppressWarnings ("unused" )
80
+ static boolean doSameClass (Object derived , Object cls ,
81
+ @ Shared ("isSameType" ) @ Cached IsSameTypeNode isSameTypeNode ) {
78
82
return true ;
79
83
}
80
84
@@ -84,11 +88,12 @@ protected static int[] observedSize() {
84
88
return ary ;
85
89
}
86
90
87
- @ Specialization (guards = {"derived != cls" , "derived == cachedDerived" , "cls == cachedCls" }, limit = "getCallSiteInlineCacheMaxDepth()" )
88
- boolean isSubclass (VirtualFrame frame , @ SuppressWarnings ("unused" ) Object derived , @ SuppressWarnings ("unused" ) Object cls ,
91
+ @ Specialization (guards = {"!isSameMetaObject(isSameTypeNode, derived, cls) " , "derived == cachedDerived" , "cls == cachedCls" }, limit = "getCallSiteInlineCacheMaxDepth()" )
92
+ static boolean doSubclass (VirtualFrame frame , @ SuppressWarnings ("unused" ) Object derived , @ SuppressWarnings ("unused" ) Object cls ,
89
93
@ Cached (value = "observedSize()" , dimensions = 1 ) int [] observedSizeArray ,
90
94
@ Cached ("derived" ) Object cachedDerived ,
91
95
@ Cached ("cls" ) Object cachedCls ,
96
+ @ Cached @ SuppressWarnings ("unused" ) IsSameTypeNode isSameTypeNode ,
92
97
@ Cached SequenceStorageNodes .LenNode lenNode ,
93
98
@ Cached AbstractObjectGetBasesNode getBasesNode ,
94
99
@ Cached AbstractObjectIsSubclassNode isSubclassNode ,
@@ -114,7 +119,7 @@ boolean isSubclass(VirtualFrame frame, @SuppressWarnings("unused") Object derive
114
119
return loopUnexploded (frame , cachedCls , isSubclassNode , basesAry );
115
120
}
116
121
117
- private static final boolean loopUnexploded (VirtualFrame frame , Object cachedCls , AbstractObjectIsSubclassNode isSubclassNode , Object [] basesAry ) {
122
+ private static boolean loopUnexploded (VirtualFrame frame , Object cachedCls , AbstractObjectIsSubclassNode isSubclassNode , Object [] basesAry ) {
118
123
for (Object baseCls : basesAry ) {
119
124
if (isSubclassNode .execute (frame , baseCls , cachedCls )) {
120
125
return true ;
@@ -124,7 +129,7 @@ private static final boolean loopUnexploded(VirtualFrame frame, Object cachedCls
124
129
}
125
130
126
131
@ ExplodeLoop
127
- private static final boolean loopBases (VirtualFrame frame , Object cachedCls , Object [] bases , AbstractObjectIsSubclassNode isSubclassNode ) {
132
+ private static boolean loopBases (VirtualFrame frame , Object cachedCls , Object [] bases , AbstractObjectIsSubclassNode isSubclassNode ) {
128
133
for (int i = 0 ; i < bases .length ; i ++) {
129
134
if (isSubclassNode .execute (frame , bases [i ], cachedCls )) {
130
135
return true ;
@@ -133,13 +138,14 @@ private static final boolean loopBases(VirtualFrame frame, Object cachedCls, Obj
133
138
return false ;
134
139
}
135
140
136
- @ Specialization (replaces = {"isSubclass " , "isSameClass " })
137
- boolean isSubclassGeneric (VirtualFrame frame , Object derived , Object cls ,
141
+ @ Specialization (replaces = {"doSubclass " , "doSameClass " })
142
+ static boolean doGeneric (VirtualFrame frame , Object derived , Object cls ,
138
143
@ Cached SequenceStorageNodes .LenNode lenNode ,
139
144
@ Cached AbstractObjectGetBasesNode getBasesNode ,
140
145
@ Cached AbstractObjectIsSubclassNode isSubclassNode ,
146
+ @ Shared ("isSameType" ) @ Cached IsSameTypeNode isSameTypeNode ,
141
147
@ Cached GetObjectArrayNode getObjectArrayNode ) {
142
- if (derived == cls ) {
148
+ if (isSameMetaObject ( isSameTypeNode , derived , cls ) ) {
143
149
return true ;
144
150
}
145
151
@@ -159,4 +165,12 @@ boolean isSubclassGeneric(VirtualFrame frame, Object derived, Object cls,
159
165
private static boolean isEmpty (PTuple bases , SequenceStorageNodes .LenNode lenNode ) {
160
166
return lenNode .execute (bases .getSequenceStorage ()) == 0 ;
161
167
}
168
+
169
+ /**
170
+ * Tests if the two meta objects {@code derived} and {@code cls} are the same. This differs from
171
+ * {@link IsSameTypeNode} because it will also accept meta objects that are not classes.
172
+ */
173
+ static boolean isSameMetaObject (IsSameTypeNode isSameTypeNode , Object derived , Object cls ) {
174
+ return derived == cls || isSameTypeNode .execute (derived , cls );
175
+ }
162
176
}
0 commit comments