150150import com .oracle .truffle .api .dsl .GenerateInline ;
151151import com .oracle .truffle .api .dsl .GenerateUncached ;
152152import 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 ;
153156import com .oracle .truffle .api .dsl .NeverDefault ;
154157import com .oracle .truffle .api .dsl .Specialization ;
155158import com .oracle .truffle .api .exception .AbstractTruffleException ;
@@ -2141,6 +2144,52 @@ private ReadIndexedArgumentNode ensureReadArgNode() {
21412144 }
21422145 }
21432146
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+
21442193 /**
21452194 * We need to inflate all primitives in order to avoid memory leaks. Explanation: Primitives
21462195 * would currently be wrapped into a PrimitiveNativeWrapper. If any of those will receive a
@@ -2154,6 +2203,10 @@ private ReadIndexedArgumentNode ensureReadArgNode() {
21542203 public abstract static class CreateArgsTupleNode extends Node {
21552204 public abstract PTuple execute (PythonLanguage language , Object [] args , boolean eagerNative );
21562205
2206+ public final PTuple execute (Node inliningTarget , PythonLanguage language , Object [] args , EagerTupleState state ) {
2207+ return execute (language , args , state .isEager (inliningTarget ));
2208+ }
2209+
21572210 @ Specialization (guards = {"args.length == cachedLen" , "cachedLen <= 8" , "!eagerNative" }, limit = "1" )
21582211 @ ExplodeLoop (kind = LoopExplosionKind .FULL_UNROLL )
21592212 static PTuple doCachedLen (PythonLanguage language , Object [] args , @ SuppressWarnings ("unused" ) boolean eagerNative ,
0 commit comments