changeset 22323:096e2c0fd2dc

Cannot pass VirtualFrame into a Runnable. Either invoke the call directly or materialize the frame
author Jaroslav Tulach <jaroslav.tulach@oracle.com>
date Thu, 22 Oct 2015 21:07:03 +0200
parents 7c396c4f46f5
children ad67d348e361
files truffle/com.oracle.truffle.api.vm/src/com/oracle/truffle/api/vm/PolyglotEngine.java truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/Accessor.java
diffstat 2 files changed, 37 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/truffle/com.oracle.truffle.api.vm/src/com/oracle/truffle/api/vm/PolyglotEngine.java	Thu Oct 22 19:59:02 2015 +0200
+++ b/truffle/com.oracle.truffle.api.vm/src/com/oracle/truffle/api/vm/PolyglotEngine.java	Thu Oct 22 21:07:03 2015 +0200
@@ -51,6 +51,7 @@
 import java.util.logging.Logger;
 
 import com.oracle.truffle.api.CallTarget;
+import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.Truffle;
 import com.oracle.truffle.api.TruffleLanguage;
 import com.oracle.truffle.api.TruffleLanguage.Env;
@@ -58,6 +59,7 @@
 import com.oracle.truffle.api.debug.Debugger;
 import com.oracle.truffle.api.debug.ExecutionEvent;
 import com.oracle.truffle.api.debug.SuspendedEvent;
+import com.oracle.truffle.api.frame.MaterializedFrame;
 import com.oracle.truffle.api.frame.VirtualFrame;
 import com.oracle.truffle.api.impl.Accessor;
 import com.oracle.truffle.api.instrument.Instrumenter;
@@ -106,6 +108,12 @@
 @SuppressWarnings("rawtypes")
 public class PolyglotEngine {
     static final boolean JAVA_INTEROP_ENABLED = !Boolean.getBoolean("com.oracle.truffle.aot");
+    private static final Executor DIRECT_EXECUTOR = new Executor() {
+        @Override
+        public void execute(Runnable command) {
+            command.run();
+        }
+    };
 
     static final Logger LOG = Logger.getLogger(PolyglotEngine.class.getName());
     private static final SPIAccessor SPI = new SPIAccessor();
@@ -349,12 +357,7 @@
             if (in == null) {
                 in = System.in;
             }
-            Executor nonNullExecutor = executor != null ? executor : new Executor() {
-                @Override
-                public void execute(Runnable command) {
-                    command.run();
-                }
-            };
+            Executor nonNullExecutor = executor != null ? executor : DIRECT_EXECUTOR;
             return new PolyglotEngine(nonNullExecutor, globals, out, err, in, handlers.toArray(new EventConsumer[0]));
         }
     }
@@ -526,22 +529,37 @@
     }
 
     @SuppressWarnings("try")
-    final Object invokeForeign(final Node foreignNode, final VirtualFrame frame, final TruffleObject receiver) throws IOException {
+    final Object invokeForeign(final Node foreignNode, VirtualFrame frame, final TruffleObject receiver) throws IOException {
         final Object[] res = {null, null};
+        if (executor == DIRECT_EXECUTOR) {
+            try (final Closeable c = SPI.executionStart(PolyglotEngine.this, -1, debugger, null)) {
+                final Object[] args = ForeignAccess.getArguments(frame).toArray();
+                res[0] = ForeignAccess.execute(foreignNode, frame, receiver, args);
+            }
+        } else {
+            invokeForeignOnExecutor(foreignNode, frame, receiver, res);
+        }
+        exceptionCheck(res);
+        if (res[0] instanceof TruffleObject) {
+            return new EngineTruffleObject(this, (TruffleObject) res[0]);
+        } else {
+            return res[0];
+        }
+    }
+
+    @TruffleBoundary
+    private void invokeForeignOnExecutor(final Node foreignNode, VirtualFrame frame, final TruffleObject receiver, final Object[] res) throws IOException {
+        final MaterializedFrame materialized = frame.materialize();
         final CountDownLatch computed = new CountDownLatch(1);
-        final Thread caller = Thread.currentThread();
         executor.execute(new Runnable() {
+            @SuppressWarnings("try")
             @Override
             public void run() {
                 try (final Closeable c = SPI.executionStart(PolyglotEngine.this, -1, debugger, null)) {
-                    final Object[] args = ForeignAccess.getArguments(frame).toArray();
-                    if (caller != Thread.currentThread()) {
-                        RootNode node = SymbolInvokerImpl.createTemporaryRoot(TruffleLanguage.class, foreignNode, receiver, args.length);
-                        final CallTarget target = Truffle.getRuntime().createCallTarget(node);
-                        res[0] = target.call(args);
-                    } else {
-                        res[0] = ForeignAccess.execute(foreignNode, frame, receiver, args);
-                    }
+                    final Object[] args = ForeignAccess.getArguments(materialized).toArray();
+                    RootNode node = SymbolInvokerImpl.createTemporaryRoot(TruffleLanguage.class, foreignNode, receiver, args.length);
+                    final CallTarget target = Truffle.getRuntime().createCallTarget(node);
+                    res[0] = target.call(args);
                 } catch (Exception ex) {
                     res[1] = ex;
                 } finally {
@@ -554,12 +572,6 @@
         } catch (InterruptedException ex) {
             throw new InterruptedIOException(ex.getMessage());
         }
-        exceptionCheck(res);
-        if (res[0] instanceof TruffleObject) {
-            return new EngineTruffleObject(this, (TruffleObject) res[0]);
-        } else {
-            return res[0];
-        }
     }
 
     /**
--- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/Accessor.java	Thu Oct 22 19:59:02 2015 +0200
+++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/Accessor.java	Thu Oct 22 21:07:03 2015 +0200
@@ -33,6 +33,7 @@
 
 import com.oracle.truffle.api.Assumption;
 import com.oracle.truffle.api.CallTarget;
+import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.Truffle;
 import com.oracle.truffle.api.TruffleLanguage;
 import com.oracle.truffle.api.TruffleLanguage.Env;
@@ -267,6 +268,7 @@
     private static Reference<Object> previousVM = new WeakReference<>(null);
     private static Assumption oneVM = Truffle.getRuntime().createAssumption();
 
+    @TruffleBoundary
     @SuppressWarnings("unused")
     protected Closeable executionStart(Object vm, int currentDepth, Debugger debugger, Source s) {
         vm.getClass();
@@ -280,6 +282,7 @@
         }
         CURRENT_VM.set(vm);
         class ContextCloseable implements Closeable {
+            @TruffleBoundary
             @Override
             public void close() throws IOException {
                 CURRENT_VM.set(prev);