Skip to content

Commit 1348ede

Browse files
committed
Fix: IsSubtypeNode cached on MRO without assumption.
1 parent b751e17 commit 1348ede

File tree

1 file changed

+28
-12
lines changed
  • graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/classes

1 file changed

+28
-12
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/classes/IsSubtypeNode.java

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,12 @@
4141
package com.oracle.graal.python.nodes.classes;
4242

4343
import com.oracle.graal.python.builtins.objects.type.PythonAbstractClass;
44-
import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetMroNode;
44+
import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetMroStorageNode;
4545
import com.oracle.graal.python.builtins.objects.type.TypeNodes.IsSameTypeNode;
4646
import com.oracle.graal.python.nodes.PNodeWithContext;
4747
import com.oracle.graal.python.runtime.PythonOptions;
4848
import com.oracle.graal.python.runtime.exception.PythonErrorType;
49+
import com.oracle.graal.python.runtime.sequence.storage.MroSequenceStorage;
4950
import com.oracle.truffle.api.CompilerDirectives;
5051
import com.oracle.truffle.api.dsl.Cached;
5152
import com.oracle.truffle.api.dsl.Fallback;
@@ -61,7 +62,7 @@ public abstract class IsSubtypeNode extends PNodeWithContext {
6162

6263
@Child private AbstractObjectGetBasesNode getBasesNode = AbstractObjectGetBasesNode.create();
6364
@Child private AbstractObjectIsSubclassNode abstractIsSubclassNode = AbstractObjectIsSubclassNode.create();
64-
@Child private GetMroNode getMroNode;
65+
@Child private GetMroStorageNode getMroNode;
6566
@Child private IsSameTypeNode isSameTypeNode;
6667

6768
private final ConditionProfile exceptionDerivedProfile = ConditionProfile.createBinaryProfile();
@@ -73,24 +74,39 @@ public static IsSubtypeNode create() {
7374

7475
public abstract boolean execute(Object derived, Object cls);
7576

76-
@Specialization(guards = {"derived == cachedDerived", "cls == cachedCls"}, limit = "getVariableArgumentInlineCacheLimit()")
77+
@Specialization(guards = { //
78+
"derived == cachedDerived", //
79+
"cls == cachedCls", //
80+
"mro.length() < 32" //
81+
}, //
82+
limit = "getVariableArgumentInlineCacheLimit()", //
83+
assumptions = "mro.getLookupStableAssumption()")
7784
@ExplodeLoop
7885
boolean isSubtypeOfConstantType(@SuppressWarnings("unused") PythonAbstractClass derived, @SuppressWarnings("unused") PythonAbstractClass cls,
79-
@Cached("derived") PythonAbstractClass cachedDerived,
80-
@Cached("cls") PythonAbstractClass cachedCls) {
81-
for (PythonAbstractClass n : getMro(cachedDerived)) {
86+
@Cached("derived") @SuppressWarnings("unused") PythonAbstractClass cachedDerived,
87+
@Cached("cls") PythonAbstractClass cachedCls,
88+
@Cached("getMro(cachedDerived)") MroSequenceStorage mro) {
89+
for (PythonAbstractClass n : mro.getInternalClassArray()) {
8290
if (isSameType(n, cachedCls)) {
8391
return true;
8492
}
8593
}
8694
return false;
8795
}
8896

89-
@Specialization(guards = {"derived == cachedDerived"}, limit = "getVariableArgumentInlineCacheLimit()", replaces = "isSubtypeOfConstantType")
97+
@Specialization(guards = { //
98+
"derived == cachedDerived", //
99+
"mro.length() < 32" //
100+
}, //
101+
limit = "getVariableArgumentInlineCacheLimit()", //
102+
replaces = "isSubtypeOfConstantType", //
103+
assumptions = "mro.getLookupStableAssumption()" //
104+
)
90105
@ExplodeLoop
91106
boolean isSubtypeOfVariableType(@SuppressWarnings("unused") PythonAbstractClass derived, PythonAbstractClass cls,
92-
@Cached("derived") PythonAbstractClass cachedDerived) {
93-
for (PythonAbstractClass n : getMro(cachedDerived)) {
107+
@Cached("derived") @SuppressWarnings("unused") PythonAbstractClass cachedDerived,
108+
@Cached("getMro(cachedDerived)") MroSequenceStorage mro) {
109+
for (PythonAbstractClass n : mro.getInternalClassArray()) {
94110
if (isSameType(n, cls)) {
95111
return true;
96112
}
@@ -100,7 +116,7 @@ boolean isSubtypeOfVariableType(@SuppressWarnings("unused") PythonAbstractClass
100116

101117
@Specialization(replaces = {"isSubtypeOfConstantType", "isSubtypeOfVariableType"})
102118
boolean issubTypeGeneric(PythonAbstractClass derived, PythonAbstractClass cls) {
103-
for (PythonAbstractClass n : getMro(derived)) {
119+
for (PythonAbstractClass n : getMro(derived).getInternalClassArray()) {
104120
if (isSameType(n, cls)) {
105121
return true;
106122
}
@@ -121,10 +137,10 @@ public boolean isSubclass(Object derived, Object cls) {
121137
return abstractIsSubclassNode.execute(derived, cls);
122138
}
123139

124-
private PythonAbstractClass[] getMro(PythonAbstractClass clazz) {
140+
protected MroSequenceStorage getMro(PythonAbstractClass clazz) {
125141
if (getMroNode == null) {
126142
CompilerDirectives.transferToInterpreterAndInvalidate();
127-
getMroNode = insert(GetMroNode.create());
143+
getMroNode = insert(GetMroStorageNode.create());
128144
}
129145
return getMroNode.execute(clazz);
130146
}

0 commit comments

Comments
 (0)