150
150
import com .oracle .truffle .api .dsl .GenerateInline ;
151
151
import com .oracle .truffle .api .dsl .GenerateUncached ;
152
152
import com .oracle .truffle .api .dsl .ImportStatic ;
153
+ import com .oracle .truffle .api .dsl .InlineSupport .InlineTarget ;
154
+ import com .oracle .truffle .api .dsl .InlineSupport .RequiredField ;
155
+ import com .oracle .truffle .api .dsl .InlineSupport .StateField ;
153
156
import com .oracle .truffle .api .dsl .NeverDefault ;
154
157
import com .oracle .truffle .api .dsl .Specialization ;
155
158
import com .oracle .truffle .api .exception .AbstractTruffleException ;
@@ -2141,6 +2144,52 @@ private ReadIndexedArgumentNode ensureReadArgNode() {
2141
2144
}
2142
2145
}
2143
2146
2147
+ /**
2148
+ * An inlined node-like object for keeping track of eager native allocation state bit. Should be
2149
+ * {@code @Cached} and passed into
2150
+ * {@link CreateArgsTupleNode#execute(Node, PythonLanguage, Object[], EagerTupleState)}. Then
2151
+ * the {@link #report(Node, PTuple)} method should be called with the tuple after the native
2152
+ * call returns.
2153
+ */
2154
+ public static final class EagerTupleState {
2155
+ private final StateField state ;
2156
+
2157
+ private static final EagerTupleState UNCACHED = new EagerTupleState ();
2158
+
2159
+ private EagerTupleState () {
2160
+ this .state = null ;
2161
+ }
2162
+
2163
+ private EagerTupleState (InlineTarget target ) {
2164
+ this .state = target .getState (0 , 1 );
2165
+ }
2166
+
2167
+ public boolean isEager (Node inliningTarget ) {
2168
+ if (state == null ) {
2169
+ return false ;
2170
+ }
2171
+ return state .get (inliningTarget ) != 0 ;
2172
+ }
2173
+
2174
+ public void report (Node inliningTarget , PTuple tuple ) {
2175
+ if (state != null ) {
2176
+ if (!isEager (inliningTarget ) && tuple .getSequenceStorage () instanceof NativeSequenceStorage ) {
2177
+ CompilerDirectives .transferToInterpreterAndInvalidate ();
2178
+ state .set (inliningTarget , 1 );
2179
+ }
2180
+ }
2181
+ }
2182
+
2183
+ public static EagerTupleState inline (
2184
+ @ RequiredField (value = StateField .class , bits = 1 ) InlineTarget target ) {
2185
+ return new EagerTupleState (target );
2186
+ }
2187
+
2188
+ public static EagerTupleState getUncached () {
2189
+ return UNCACHED ;
2190
+ }
2191
+ }
2192
+
2144
2193
/**
2145
2194
* We need to inflate all primitives in order to avoid memory leaks. Explanation: Primitives
2146
2195
* would currently be wrapped into a PrimitiveNativeWrapper. If any of those will receive a
@@ -2154,6 +2203,10 @@ private ReadIndexedArgumentNode ensureReadArgNode() {
2154
2203
public abstract static class CreateArgsTupleNode extends Node {
2155
2204
public abstract PTuple execute (PythonLanguage language , Object [] args , boolean eagerNative );
2156
2205
2206
+ public final PTuple execute (Node inliningTarget , PythonLanguage language , Object [] args , EagerTupleState state ) {
2207
+ return execute (language , args , state .isEager (inliningTarget ));
2208
+ }
2209
+
2157
2210
@ Specialization (guards = {"args.length == cachedLen" , "cachedLen <= 8" , "!eagerNative" }, limit = "1" )
2158
2211
@ ExplodeLoop (kind = LoopExplosionKind .FULL_UNROLL )
2159
2212
static PTuple doCachedLen (PythonLanguage language , Object [] args , @ SuppressWarnings ("unused" ) boolean eagerNative ,
0 commit comments