|
55 | 55 | import com.oracle.graal.python.nodes.truffle.PythonTypes;
|
56 | 56 | import com.oracle.graal.python.runtime.PythonOptions;
|
57 | 57 | import com.oracle.truffle.api.Assumption;
|
| 58 | +import com.oracle.truffle.api.CompilerAsserts; |
58 | 59 | import com.oracle.truffle.api.RootCallTarget;
|
59 | 60 | import com.oracle.truffle.api.dsl.ImportStatic;
|
60 | 61 | import com.oracle.truffle.api.dsl.NodeFactory;
|
61 | 62 | import com.oracle.truffle.api.dsl.ReportPolymorphism;
|
62 | 63 | import com.oracle.truffle.api.dsl.TypeSystemReference;
|
63 | 64 | import com.oracle.truffle.api.nodes.Node;
|
| 65 | +import com.oracle.truffle.api.nodes.NodeUtil; |
64 | 66 | import com.oracle.truffle.api.nodes.RootNode;
|
65 | 67 |
|
66 | 68 | @TypeSystemReference(PythonTypes.class)
|
67 | 69 | @ImportStatic(PythonOptions.class)
|
68 | 70 | @ReportPolymorphism
|
69 | 71 | abstract class CallSpecialMethodNode extends Node {
|
| 72 | + |
70 | 73 | /**
|
71 | 74 | * Returns a new instanceof the builtin if it's a subclass of the given class, and null
|
72 | 75 | * otherwise.
|
73 | 76 | */
|
74 |
| - private static <T extends PythonBuiltinBaseNode> T getBuiltin(PBuiltinFunction func, Class<T> clazz) { |
| 77 | + private <T extends PythonBuiltinBaseNode> T getBuiltin(PBuiltinFunction func, Class<T> clazz) { |
| 78 | + CompilerAsserts.neverPartOfCompilation(); |
75 | 79 | NodeFactory<? extends PythonBuiltinBaseNode> builtinNodeFactory = func.getBuiltinNodeFactory();
|
76 |
| - if (builtinNodeFactory != null) { |
| 80 | + if (builtinNodeFactory != null && !callerExceedsMaxSize()) { |
77 | 81 | return clazz.isAssignableFrom(builtinNodeFactory.getNodeClass()) ? clazz.cast(func.getBuiltinNodeFactory().createNode()) : null;
|
78 | 82 | } else {
|
79 | 83 | return null;
|
80 | 84 | }
|
81 | 85 | }
|
82 | 86 |
|
| 87 | + private boolean callerExceedsMaxSize() { |
| 88 | + CompilerAsserts.neverPartOfCompilation(); |
| 89 | + int n = NodeUtil.countNodes(getRootNode()); |
| 90 | + // nb: option 'BuiltinsInliningMaxCallerSize' is defined as a compatible option, i.e., ASTs |
| 91 | + // will only we shared between contexts that have the same value for this option. |
| 92 | + int maxSize = PythonOptions.getOption(lookupContextReference(PythonLanguage.class).get(), PythonOptions.BuiltinsInliningMaxCallerSize); |
| 93 | + return n >= maxSize; |
| 94 | + } |
| 95 | + |
83 | 96 | protected Assumption singleContextAssumption() {
|
84 | 97 | return PythonLanguage.getCurrent().singleContextAssumption;
|
85 | 98 | }
|
86 | 99 |
|
87 |
| - protected static PythonUnaryBuiltinNode getUnary(Object func) { |
| 100 | + PythonUnaryBuiltinNode getUnary(Object func) { |
88 | 101 | if (func instanceof PBuiltinFunction) {
|
89 | 102 | return getBuiltin((PBuiltinFunction) func, PythonUnaryBuiltinNode.class);
|
90 | 103 | }
|
91 | 104 | return null;
|
92 | 105 | }
|
93 | 106 |
|
94 |
| - protected static PythonBinaryBuiltinNode getBinary(Object func) { |
| 107 | + PythonBinaryBuiltinNode getBinary(Object func) { |
95 | 108 | if (func instanceof PBuiltinFunction) {
|
96 | 109 | return getBuiltin((PBuiltinFunction) func, PythonBinaryBuiltinNode.class);
|
97 | 110 | }
|
98 | 111 | return null;
|
99 | 112 | }
|
100 | 113 |
|
101 |
| - protected static PythonTernaryBuiltinNode getTernary(Object func) { |
| 114 | + PythonTernaryBuiltinNode getTernary(Object func) { |
102 | 115 | if (func instanceof PBuiltinFunction) {
|
103 | 116 | return getBuiltin((PBuiltinFunction) func, PythonTernaryBuiltinNode.class);
|
104 | 117 | }
|
105 | 118 | return null;
|
106 | 119 | }
|
107 | 120 |
|
108 |
| - protected static PythonQuaternaryBuiltinNode getQuaternary(Object func) { |
| 121 | + PythonQuaternaryBuiltinNode getQuaternary(Object func) { |
109 | 122 | if (func instanceof PBuiltinFunction) {
|
110 | 123 | return getBuiltin((PBuiltinFunction) func, PythonQuaternaryBuiltinNode.class);
|
111 | 124 | }
|
112 | 125 | return null;
|
113 | 126 | }
|
114 | 127 |
|
115 |
| - protected static PythonVarargsBuiltinNode getVarargs(Object func) { |
| 128 | + PythonVarargsBuiltinNode getVarargs(Object func) { |
116 | 129 | if (func instanceof PBuiltinFunction) {
|
117 | 130 | return getBuiltin((PBuiltinFunction) func, PythonVarargsBuiltinNode.class);
|
118 | 131 | }
|
|
0 commit comments