Mercurial > hg > truffle
changeset 22314:e56d1a618f64
Need to send every invokeForeign into the executor
author | Jaroslav Tulach <jaroslav.tulach@oracle.com> |
---|---|
date | Fri, 16 Oct 2015 18:28:21 +0200 |
parents | 06c5171e44c8 |
children | 518f8ead5d01 |
files | truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/ArrayTruffleObject.java truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/EngineAsynchTest.java truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/EngineTest.java truffle/com.oracle.truffle.api.vm/src/com/oracle/truffle/api/vm/PolyglotEngine.java |
diffstat | 4 files changed, 74 insertions(+), 30 deletions(-) [+] |
line wrap: on
line diff
--- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/ArrayTruffleObject.java Fri Oct 16 11:22:48 2015 +0200 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/ArrayTruffleObject.java Fri Oct 16 18:28:21 2015 +0200 @@ -31,19 +31,26 @@ import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.nodes.RootNode; import java.util.List; +import static org.junit.Assert.assertNotEquals; final class ArrayTruffleObject implements TruffleObject, ForeignAccess.Factory10 { private final ForeignAccess access; private final Object[] values; + private final Thread forbiddenDupl; ArrayTruffleObject(Object[] values) { - this.access = ForeignAccess.create(getClass(), this); + this(values, null); + } + + ArrayTruffleObject(Object[] values, Thread forbiddenDupl) { + this.access = forbiddenDupl == null ? ForeignAccess.create(getClass(), this) : null; this.values = values; + this.forbiddenDupl = forbiddenDupl; } @Override public ForeignAccess getForeignAccess() { - return access; + return access != null ? access : ForeignAccess.create(getClass(), this); } @Override @@ -93,6 +100,9 @@ @Override public CallTarget accessInvoke(int argumentsLength) { + if (argumentsLength == 1) { + return target(new DuplNode()); + } if (argumentsLength == 2) { return target(new InvokeNode()); } @@ -148,4 +158,20 @@ } } } + + private final class DuplNode extends RootNode { + public DuplNode() { + super(TruffleLanguage.class, null, null); + } + + @Override + public Object execute(VirtualFrame frame) { + final List<Object> args = ForeignAccess.getArguments(frame); + if (!"dupl".equals(args.get(0))) { + return null; + } + assertNotEquals("Cannot allocate duplicate on forbidden thread", forbiddenDupl, Thread.currentThread()); + return new ArrayTruffleObject(values); + } + } }
--- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/EngineAsynchTest.java Fri Oct 16 11:22:48 2015 +0200 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/EngineAsynchTest.java Fri Oct 16 18:28:21 2015 +0200 @@ -32,6 +32,11 @@ } @Override + protected Thread forbiddenThread() { + return Thread.currentThread(); + } + + @Override protected PolyglotEngine.Builder createBuilder() { return PolyglotEngine.buildNew().executor(Executors.newSingleThreadExecutor()); }
--- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/EngineTest.java Fri Oct 16 11:22:48 2015 +0200 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/EngineTest.java Fri Oct 16 18:28:21 2015 +0200 @@ -47,7 +47,13 @@ assertNotNull(res); } + protected Thread forbiddenThread() { + return null; + } + private interface AccessArray { + AccessArray dupl(); + List<? extends Number> get(int index); } @@ -55,10 +61,11 @@ public void wrappedAsArray() throws Exception { Object[][] matrix = {{1, 2, 3}}; - PolyglotEngine tvm = createBuilder().globalSymbol("arr", new ArrayTruffleObject(matrix)).build(); + PolyglotEngine tvm = createBuilder().globalSymbol("arr", new ArrayTruffleObject(matrix, forbiddenThread())).build(); PolyglotEngine.Language language1 = tvm.getLanguages().get("application/x-test-import-export-1"); AccessArray access = language1.eval(Source.fromText("return=arr", "get the array")).as(AccessArray.class); assertNotNull("Array converted to list", access); + access = access.dupl(); List<? extends Number> list = access.get(0); assertEquals("Size 3", 3, list.size()); assertEquals(1, list.get(0));
--- a/truffle/com.oracle.truffle.api.vm/src/com/oracle/truffle/api/vm/PolyglotEngine.java Fri Oct 16 11:22:48 2015 +0200 +++ b/truffle/com.oracle.truffle.api.vm/src/com/oracle/truffle/api/vm/PolyglotEngine.java Fri Oct 16 18:28:21 2015 +0200 @@ -51,6 +51,7 @@ import java.util.logging.Logger; import com.oracle.truffle.api.CallTarget; +import com.oracle.truffle.api.Truffle; import com.oracle.truffle.api.TruffleLanguage; import com.oracle.truffle.api.TruffleLanguage.Env; import com.oracle.truffle.api.TruffleLanguage.Registration; @@ -65,6 +66,7 @@ import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.interop.java.JavaInterop; import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.nodes.RootNode; import com.oracle.truffle.api.source.Source; /** @@ -525,14 +527,38 @@ @SuppressWarnings("try") final Object invokeForeign(final Node foreignNode, final VirtualFrame frame, final TruffleObject receiver) throws IOException { - Object res; - try (final Closeable c = SPI.executionStart(PolyglotEngine.this, -1, debugger, null)) { - res = ForeignAccess.execute(foreignNode, frame, receiver, ForeignAccess.getArguments(frame).toArray()); + final Object[] res = {null, null}; + final CountDownLatch computed = new CountDownLatch(1); + final Thread caller = Thread.currentThread(); + executor.execute(new Runnable() { + @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); + } + } catch (Exception ex) { + res[1] = ex; + } finally { + computed.countDown(); + } + } + }); + try { + computed.await(); + } catch (InterruptedException ex) { + throw new InterruptedIOException(ex.getMessage()); } - if (res instanceof TruffleObject) { - return new EngineTruffleObject(this, (TruffleObject) res); + exceptionCheck(res); + if (res[0] instanceof TruffleObject) { + return new EngineTruffleObject(this, (TruffleObject) res[0]); } else { - return res; + return res[0]; } } @@ -730,27 +756,7 @@ return representation.cast(obj); } if (JAVA_INTEROP_ENABLED) { - final Object[] ret = {null, null}; - final CountDownLatch computed = new CountDownLatch(1); - executor.execute(new Runnable() { - @Override - public void run() { - try { - ret[0] = JavaInterop.asJavaObject(representation, (TruffleObject) obj); - } catch (Exception ex) { - ret[1] = ex; - } finally { - computed.countDown(); - } - } - }); - try { - computed.await(); - } catch (InterruptedException ex) { - throw new InterruptedIOException(ex.getMessage()); - } - exceptionCheck(ret); - return representation.cast(ret[0]); + return JavaInterop.asJavaObject(representation, (TruffleObject) obj); } throw new ClassCastException("Value cannot be represented as " + representation.getName()); }