changeset 15214:bf37ce7df3fd

Merge.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Thu, 17 Apr 2014 21:50:14 +0200
parents ff0283a98b7a (diff) f52e47b757b9 (current diff)
children ca250afc78ec
files graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/Condition.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRTypeTool.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/Stamp.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/ComputeImmediateDominator.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/NodeIterators.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/TreeIterators.java
diffstat 16 files changed, 254 insertions(+), 404 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotOptimizedCallTarget.java	Thu Apr 17 19:30:37 2014 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,181 +0,0 @@
-/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.truffle.hotspot;
-
-import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
-import static com.oracle.graal.truffle.TruffleCompilerOptions.*;
-import static com.oracle.graal.truffle.OptimizedCallTargetLog.*;
-
-import java.util.concurrent.*;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.hotspot.meta.*;
-import com.oracle.graal.truffle.*;
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.nodes.*;
-
-/**
- * Call target for running truffle on a standard VM (and not in SubstrateVM).
- */
-public final class HotSpotOptimizedCallTarget extends OptimizedCallTarget {
-
-    protected final TruffleCompiler compiler;
-    private Future<InstalledCode> installedCodeTask;
-    private SpeculationLog speculationLog = new HotSpotSpeculationLog();
-
-    HotSpotOptimizedCallTarget(RootNode rootNode, TruffleCompiler compiler, int invokeCounter, int compilationThreshold, boolean compilationEnabled) {
-        super(rootNode, invokeCounter, compilationThreshold, compilationEnabled, TruffleUseTimeForCompilationDecision.getValue() ? new TimedCompilationPolicy() : new DefaultCompilationPolicy());
-        this.compiler = compiler;
-    }
-
-    @Override
-    public SpeculationLog getSpeculationLog() {
-        return speculationLog;
-    }
-
-    @Override
-    public Object call(Object... args) {
-        return callBoundary(args);
-    }
-
-    @TruffleCallBoundary
-    private Object callBoundary(Object[] args) {
-        if (CompilerDirectives.inInterpreter()) {
-            return compiledCallFallback(args);
-        } else {
-            // We come here from compiled code (i.e., we have been inlined).
-            return executeHelper(args);
-        }
-    }
-
-    private Object compiledCallFallback(Object[] args) {
-        if (isValid()) {
-            reinstallCallMethodShortcut();
-        }
-        return interpreterCall(args);
-    }
-
-    private static void reinstallCallMethodShortcut() {
-        if (TraceTruffleCompilation.getValue()) {
-            OUT.println("[truffle] reinstall OptimizedCallTarget.call code with frame prolog shortcut.");
-        }
-        HotSpotTruffleRuntime.installOptimizedCallTargetCallMethod();
-    }
-
-    @Override
-    public void invalidate() {
-        runtime().getCompilerToVM().invalidateInstalledCode(this);
-    }
-
-    @Override
-    public Object executeVarargs(Object... args) throws InvalidInstalledCodeException {
-        return runtime().getCompilerToVM().executeCompiledMethodVarargs(args, this);
-    }
-
-    @Override
-    protected void invalidate(Node oldNode, Node newNode, CharSequence reason) {
-        if (isValid()) {
-            CompilerAsserts.neverPartOfCompilation();
-            invalidate();
-            compilationProfile.reportInvalidated();
-            logOptimizedInvalidated(this, oldNode, newNode, reason);
-        }
-        cancelInstalledTask(oldNode, newNode, reason);
-    }
-
-    private void cancelInstalledTask(Node oldNode, Node newNode, CharSequence reason) {
-        Future<InstalledCode> task = this.installedCodeTask;
-        if (task != null) {
-            task.cancel(true);
-            logOptimizingUnqueued(this, oldNode, newNode, reason);
-            compilationProfile.reportInvalidated();
-        }
-    }
-
-    private Object interpreterCall(Object[] args) {
-        CompilerAsserts.neverPartOfCompilation();
-        compilationProfile.reportInterpreterCall();
-        if (TruffleCallTargetProfiling.getValue()) {
-            callCount++;
-        }
-
-        if (compilationEnabled && compilationPolicy.shouldCompile(compilationProfile)) {
-            compile();
-            if (isValid()) {
-                try {
-                    return executeVarargs(new Object[]{this, args});
-                } catch (InvalidInstalledCodeException ex) {
-                }
-            }
-        }
-        return executeHelper(args);
-    }
-
-    private boolean isCompiling() {
-        Future<InstalledCode> codeTask = this.installedCodeTask;
-        if (codeTask != null) {
-            if (codeTask.isCancelled() || codeTask.isDone()) {
-                // System.out.println("done or cancelled => set null " + codeTask.isCancelled());
-                return false;
-            }
-            return true;
-        }
-        return false;
-    }
-
-    @Override
-    public void compile() {
-        if (!isCompiling()) {
-            performInlining();
-            logOptimizingQueued(this);
-            this.installedCodeTask = compiler.compile(this);
-            if (!TruffleBackgroundCompilation.getValue()) {
-                receiveInstalledCode();
-            }
-        }
-    }
-
-    @Override
-    public void exceptionWhileCompiling(Throwable t) {
-        compilationEnabled = false;
-        logOptimizingFailed(this, t.getMessage());
-        if (t instanceof BailoutException) {
-            // Bailout => move on.
-        } else {
-            if (TruffleCompilationExceptionsAreFatal.getValue()) {
-                t.printStackTrace(OUT);
-                System.exit(-1);
-            }
-        }
-    }
-
-    private void receiveInstalledCode() {
-        try {
-            // Force task completion.
-            installedCodeTask.get();
-        } catch (InterruptedException | ExecutionException e) {
-            exceptionWhileCompiling(e.getCause());
-        }
-    }
-
-}
--- a/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleReplacements.java	Thu Apr 17 19:30:37 2014 +0200
+++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleReplacements.java	Thu Apr 17 21:50:14 2014 +0200
@@ -28,7 +28,6 @@
 import com.oracle.graal.phases.util.*;
 import com.oracle.graal.runtime.*;
 import com.oracle.graal.truffle.*;
-import com.oracle.graal.truffle.hotspot.substitutions.*;
 
 public final class HotSpotTruffleReplacements extends TruffleReplacements {
 
@@ -41,10 +40,4 @@
         SnippetReflectionProvider snippetReflection = Graal.getRequiredCapability(SnippetReflectionProvider.class);
         return new HotSpotTruffleReplacements(providers, snippetReflection);
     }
-
-    @Override
-    protected void registerTruffleSubstitutions() {
-        super.registerTruffleSubstitutions();
-        registerSubstitutions(HotSpotOptimizedCallTargetSubstitutions.class);
-    }
 }
--- a/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java	Thu Apr 17 19:30:37 2014 +0200
+++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java	Thu Apr 17 21:50:14 2014 +0200
@@ -27,15 +27,19 @@
 import static com.oracle.graal.truffle.TruffleCompilerOptions.*;
 
 import java.util.*;
+import java.util.concurrent.*;
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.code.CallingConvention.Type;
 import com.oracle.graal.api.code.stack.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.runtime.*;
+import com.oracle.graal.compiler.*;
 import com.oracle.graal.compiler.target.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.Debug.Scope;
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.java.*;
 import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.nodes.*;
@@ -44,6 +48,7 @@
 import com.oracle.graal.phases.common.*;
 import com.oracle.graal.phases.tiers.*;
 import com.oracle.graal.phases.util.*;
+import com.oracle.graal.printer.*;
 import com.oracle.graal.runtime.*;
 import com.oracle.graal.truffle.*;
 import com.oracle.truffle.api.*;
@@ -61,11 +66,13 @@
         return new HotSpotTruffleRuntime();
     }
 
-    private TruffleCompiler truffleCompiler;
+    private TruffleCompilerImpl truffleCompiler;
     private Replacements truffleReplacements;
     private StackIntrospection stackIntrospection;
     private ArrayList<String> includes;
     private ArrayList<String> excludes;
+    private Map<OptimizedCallTarget, Future<?>> compilations = new IdentityHashMap<>();
+    private final ThreadPoolExecutor compileQueue;
 
     private final ResolvedJavaMethod[] callNodeMethod;
     private final ResolvedJavaMethod[] callTargetMethod;
@@ -77,6 +84,20 @@
         callNodeMethod = new ResolvedJavaMethod[]{getGraalProviders().getMetaAccess().lookupJavaMethod(HotSpotFrameInstance.CallNodeFrame.METHOD)};
         callTargetMethod = new ResolvedJavaMethod[]{getGraalProviders().getMetaAccess().lookupJavaMethod(HotSpotFrameInstance.CallTargetFrame.METHOD)};
         anyFrameMethod = new ResolvedJavaMethod[]{callNodeMethod[0], callTargetMethod[0]};
+
+        // Create compilation queue.
+        CompilerThreadFactory factory = new CompilerThreadFactory("TruffleCompilerThread", new CompilerThreadFactory.DebugConfigAccess() {
+            public GraalDebugConfig getDebugConfig() {
+                if (Debug.isEnabled()) {
+                    GraalDebugConfig debugConfig = DebugEnvironment.initialize(TTY.out().out());
+                    debugConfig.dumpHandlers().add(new TruffleTreeDumpHandler());
+                    return debugConfig;
+                } else {
+                    return null;
+                }
+            }
+        });
+        compileQueue = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), factory);
     }
 
     public String getName() {
@@ -84,10 +105,13 @@
     }
 
     public RootCallTarget createCallTarget(RootNode rootNode) {
-        if (truffleCompiler == null) {
-            truffleCompiler = new TruffleCompilerImpl();
+        CompilationPolicy compilationPolicy;
+        if (acceptForCompilation(rootNode)) {
+            compilationPolicy = new CounterBasedCompilationPolicy();
+        } else {
+            compilationPolicy = new InterpreterOnlyCompilationPolicy();
         }
-        return new HotSpotOptimizedCallTarget(rootNode, truffleCompiler, TruffleMinInvokeThreshold.getValue(), TruffleCompilationThreshold.getValue(), acceptForCompilation(rootNode));
+        return new OptimizedCallTarget(rootNode, this, TruffleMinInvokeThreshold.getValue(), TruffleCompilationThreshold.getValue(), compilationPolicy, new HotSpotSpeculationLog());
     }
 
     public DirectCallNode createDirectCallNode(CallTarget target) {
@@ -176,7 +200,7 @@
     public static void installOptimizedCallTargetCallMethod() {
         Providers providers = getGraalProviders();
         MetaAccessProvider metaAccess = providers.getMetaAccess();
-        ResolvedJavaType type = metaAccess.lookupJavaType(HotSpotOptimizedCallTarget.class);
+        ResolvedJavaType type = metaAccess.lookupJavaType(OptimizedCallTarget.class);
         for (ResolvedJavaMethod method : type.getDeclaredMethods()) {
             if (method.getAnnotation(TruffleCallBoundary.class) != null) {
                 CompilationResult compResult = compileMethod(method);
@@ -264,4 +288,52 @@
             return null;
         }
     }
+
+    public void compile(OptimizedCallTarget optimizedCallTarget, boolean mayBeAsynchronous) {
+        if (truffleCompiler == null) {
+            truffleCompiler = new TruffleCompilerImpl();
+        }
+        Runnable r = new Runnable() {
+            @Override
+            public void run() {
+                try (Scope s = Debug.scope("Truffle", new TruffleDebugJavaMethod(optimizedCallTarget))) {
+                    truffleCompiler.compileMethodImpl(optimizedCallTarget);
+                    optimizedCallTarget.compilationFinished(null);
+                } catch (Throwable e) {
+                    optimizedCallTarget.compilationFinished(e);
+                }
+            }
+        };
+        if (mayBeAsynchronous) {
+            Future<?> future = compileQueue.submit(r);
+            this.compilations.put(optimizedCallTarget, future);
+        } else {
+            r.run();
+        }
+    }
+
+    public boolean cancelInstalledTask(OptimizedCallTarget optimizedCallTarget) {
+        Future<?> codeTask = this.compilations.get(optimizedCallTarget);
+        if (codeTask != null && isCompiling(optimizedCallTarget)) {
+            this.compilations.remove(codeTask);
+            return codeTask.cancel(true);
+        }
+        return false;
+    }
+
+    public boolean isCompiling(OptimizedCallTarget optimizedCallTarget) {
+        Future<?> codeTask = this.compilations.get(optimizedCallTarget);
+        if (codeTask != null) {
+            if (codeTask.isCancelled() || codeTask.isDone()) {
+                this.compilations.remove(optimizedCallTarget);
+                return false;
+            }
+            return true;
+        }
+        return false;
+    }
+
+    public void invalidateInstalledCode(OptimizedCallTarget optimizedCallTarget) {
+        HotSpotGraalRuntime.runtime().getCompilerToVM().invalidateInstalledCode(optimizedCallTarget);
+    }
 }
--- a/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/substitutions/HotSpotOptimizedCallTargetSubstitutions.java	Thu Apr 17 19:30:37 2014 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +0,0 @@
-/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.truffle.hotspot.substitutions;
-
-import com.oracle.graal.api.replacements.*;
-import com.oracle.graal.truffle.hotspot.*;
-
-@ClassSubstitution(HotSpotOptimizedCallTarget.class)
-public class HotSpotOptimizedCallTargetSubstitutions {
-
-}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/CompilationPolicy.java	Thu Apr 17 19:30:37 2014 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/CompilationPolicy.java	Thu Apr 17 21:50:14 2014 +0200
@@ -26,4 +26,6 @@
 
     boolean shouldCompile(CompilationProfile profile);
 
+    void recordCompilationFailure(Throwable t);
+
 }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/CompilationProfile.java	Thu Apr 17 19:30:37 2014 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/CompilationProfile.java	Thu Apr 17 21:50:14 2014 +0200
@@ -40,8 +40,6 @@
 
     private long previousTimestamp;
 
-    private final String name;
-
     private int callCount;
     private int callAndLoopCount;
     private int compilationCallThreshold;
@@ -50,13 +48,12 @@
     private final int originalInvokeCounter;
     private final int originalCompilationThreshold;
 
-    public CompilationProfile(final int compilationThreshold, final int initialInvokeCounter, final String name) {
+    public CompilationProfile(final int compilationThreshold, final int initialInvokeCounter) {
         this.previousTimestamp = System.nanoTime();
         this.compilationCallThreshold = initialInvokeCounter;
         this.compilationCallAndLoopThreshold = compilationThreshold;
         this.originalInvokeCounter = initialInvokeCounter;
         this.originalCompilationThreshold = compilationThreshold;
-        this.name = name;
     }
 
     @Override
@@ -86,10 +83,6 @@
         return previousTimestamp;
     }
 
-    public String getName() {
-        return this.name;
-    }
-
     public int getInvalidationCount() {
         return invalidationCount;
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/CounterBasedCompilationPolicy.java	Thu Apr 17 21:50:14 2014 +0200
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.truffle;
+
+public class CounterBasedCompilationPolicy implements CompilationPolicy {
+
+    private boolean compilationFailed;
+
+    public boolean shouldCompile(CompilationProfile profile) {
+        return !compilationFailed && profile.getCallCount() >= profile.getCompilationCallThreshold() && profile.getCallAndLoopCount() >= profile.getCompilationCallAndLoopThreshold();
+    }
+
+    public void recordCompilationFailure(Throwable t) {
+        compilationFailed = true;
+    }
+
+}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/DefaultCompilationPolicy.java	Thu Apr 17 19:30:37 2014 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +0,0 @@
-/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.truffle;
-
-public class DefaultCompilationPolicy implements CompilationPolicy {
-
-    public boolean shouldCompile(CompilationProfile profile) {
-        return profile.getCallCount() >= profile.getCompilationCallThreshold() && profile.getCallAndLoopCount() >= profile.getCompilationCallAndLoopThreshold();
-    }
-
-}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java	Thu Apr 17 19:30:37 2014 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java	Thu Apr 17 21:50:14 2014 +0200
@@ -28,4 +28,12 @@
 public interface GraalTruffleRuntime extends TruffleRuntime {
 
     Replacements getReplacements();
+
+    void compile(OptimizedCallTarget optimizedCallTarget, boolean mayBeAsynchronous);
+
+    boolean cancelInstalledTask(OptimizedCallTarget optimizedCallTarget);
+
+    boolean isCompiling(OptimizedCallTarget optimizedCallTarget);
+
+    void invalidateInstalledCode(OptimizedCallTarget optimizedCallTarget);
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/InterpreterOnlyCompilationPolicy.java	Thu Apr 17 21:50:14 2014 +0200
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.truffle;
+
+public class InterpreterOnlyCompilationPolicy implements CompilationPolicy {
+
+    public boolean shouldCompile(CompilationProfile profile) {
+        return false;
+    }
+
+    public void recordCompilationFailure(Throwable t) {
+    }
+
+}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java	Thu Apr 17 19:30:37 2014 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java	Thu Apr 17 21:50:14 2014 +0200
@@ -38,11 +38,12 @@
 /**
  * Call target that is optimized by Graal upon surpassing a specific invocation threshold.
  */
-public abstract class OptimizedCallTarget extends InstalledCode implements RootCallTarget, LoopCountReceiver, ReplaceObserver {
+public class OptimizedCallTarget extends InstalledCode implements RootCallTarget, LoopCountReceiver, ReplaceObserver {
 
     protected static final PrintStream OUT = TTY.out().out();
 
-    protected boolean compilationEnabled;
+    protected final GraalTruffleRuntime runtime;
+    private SpeculationLog speculationLog;
     protected int callCount;
     protected boolean inliningPerformed;
     protected final CompilationProfile compilationProfile;
@@ -56,18 +57,105 @@
         return rootNode;
     }
 
-    public OptimizedCallTarget(RootNode rootNode, int invokeCounter, int compilationThreshold, boolean compilationEnabled, CompilationPolicy compilationPolicy) {
+    public OptimizedCallTarget(RootNode rootNode, GraalTruffleRuntime runtime, int invokeCounter, int compilationThreshold, CompilationPolicy compilationPolicy, SpeculationLog speculationLog) {
+        this.runtime = runtime;
+        this.speculationLog = speculationLog;
         this.rootNode = rootNode;
         this.rootNode.adoptChildren();
         this.rootNode.setCallTarget(this);
-        this.compilationEnabled = compilationEnabled;
         this.compilationPolicy = compilationPolicy;
-        this.compilationProfile = new CompilationProfile(compilationThreshold, invokeCounter, rootNode.toString());
+        this.compilationProfile = new CompilationProfile(compilationThreshold, invokeCounter);
         if (TruffleCallTargetProfiling.getValue()) {
             registerCallTarget(this);
         }
     }
 
+    public SpeculationLog getSpeculationLog() {
+        return speculationLog;
+    }
+
+    @Override
+    public Object call(Object... args) {
+        return callBoundary(args);
+    }
+
+    @TruffleCallBoundary
+    private Object callBoundary(Object[] args) {
+        if (CompilerDirectives.inInterpreter()) {
+            return compiledCallFallback(args);
+        } else {
+            // We come here from compiled code (i.e., we have been inlined).
+            return executeHelper(args);
+        }
+    }
+
+    private Object compiledCallFallback(Object[] args) {
+        return interpreterCall(args);
+    }
+
+    @Override
+    public void invalidate() {
+        this.runtime.invalidateInstalledCode(this);
+    }
+
+    protected void invalidate(Node oldNode, Node newNode, CharSequence reason) {
+        if (isValid()) {
+            CompilerAsserts.neverPartOfCompilation();
+            invalidate();
+            compilationProfile.reportInvalidated();
+            logOptimizedInvalidated(this, oldNode, newNode, reason);
+        }
+        cancelInstalledTask(oldNode, newNode, reason);
+    }
+
+    private void cancelInstalledTask(Node oldNode, Node newNode, CharSequence reason) {
+        if (this.runtime.cancelInstalledTask(this)) {
+            logOptimizingUnqueued(this, oldNode, newNode, reason);
+            compilationProfile.reportInvalidated();
+        }
+    }
+
+    private Object interpreterCall(Object[] args) {
+        CompilerAsserts.neverPartOfCompilation();
+        compilationProfile.reportInterpreterCall();
+        if (TruffleCallTargetProfiling.getValue()) {
+            callCount++;
+        }
+
+        if (compilationPolicy.shouldCompile(compilationProfile)) {
+            compile();
+            if (isValid()) {
+                return call(args);
+            }
+        }
+        return executeHelper(args);
+    }
+
+    public void compile() {
+        if (!runtime.isCompiling(this)) {
+            performInlining();
+            logOptimizingQueued(this);
+            runtime.compile(this, TruffleBackgroundCompilation.getValue());
+        }
+    }
+
+    public void compilationFinished(Throwable t) {
+        if (t == null) {
+            // Compilation was successful.
+        } else {
+            compilationPolicy.recordCompilationFailure(t);
+            logOptimizingFailed(this, t.getMessage());
+            if (t instanceof BailoutException) {
+                // Bailout => move on.
+            } else {
+                if (TruffleCompilationExceptionsAreFatal.getValue()) {
+                    t.printStackTrace(OUT);
+                    System.exit(-1);
+                }
+            }
+        }
+    }
+
     protected final Object callProxy(VirtualFrame frame) {
         try {
             return getRootNode().execute(frame);
@@ -113,11 +201,6 @@
         return compilationProfile;
     }
 
-    @Override
-    public abstract Object call(Object... args);
-
-    public abstract void compile();
-
     public final Object callInlined(Object[] arguments) {
         if (CompilerDirectives.inInterpreter()) {
             compilationProfile.reportInlinedCall();
@@ -152,8 +235,6 @@
         }
     }
 
-    protected abstract void invalidate(Node oldNode, Node newNode, CharSequence reason);
-
     public final Object executeHelper(Object[] args) {
         VirtualFrame frame = createFrame(getRootNode().getFrameDescriptor(), args);
         return callProxy(frame);
@@ -178,8 +259,6 @@
         invalidate(oldNode, newNode, reason);
     }
 
-    public abstract SpeculationLog getSpeculationLog();
-
     public Map<String, Object> getDebugProperties() {
         Map<String, Object> properties = new LinkedHashMap<>();
         addASTSizeProperty(this, properties);
@@ -187,7 +266,4 @@
         return properties;
 
     }
-
-    public abstract void exceptionWhileCompiling(Throwable e);
-
 }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTargetLog.java	Thu Apr 17 19:30:37 2014 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTargetLog.java	Thu Apr 17 21:50:14 2014 +0200
@@ -267,7 +267,6 @@
 
             int nodeCount = OptimizedCallUtils.countNonTrivialNodes(callTarget, true);
             String comment = callTarget.isValid() ? "" : " int";
-            comment += callTarget.compilationEnabled ? "" : " fail";
             OUT.printf("%-50s | %10d | %15d | %10d | %3d%s\n", callTarget.getRootNode(), callTarget.callCount, nodeCount, nodeCount, callTarget.getCompilationProfile().getInvalidationCount(), comment);
 
             totalCallCount += callTarget.callCount;
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TimedCompilationPolicy.java	Thu Apr 17 19:30:37 2014 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,51 +0,0 @@
-/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.truffle;
-
-import static com.oracle.graal.truffle.TruffleCompilerOptions.*;
-
-import java.io.*;
-
-public class TimedCompilationPolicy extends DefaultCompilationPolicy {
-
-    @Override
-    public boolean shouldCompile(CompilationProfile profile) {
-        if (super.shouldCompile(profile)) {
-            long timestamp = System.nanoTime();
-            long prevTimestamp = profile.getPreviousTimestamp();
-            long timespan = (timestamp - prevTimestamp);
-            if (timespan < (TruffleCompilationDecisionTime.getValue())) {
-                return true;
-            }
-            // TODO shouldCompile should not modify the compilation profile
-            // maybe introduce another method?
-            profile.reportTiminingFailed(timestamp);
-            if (TruffleCompilationDecisionTimePrintFail.getValue()) {
-                PrintStream out = System.out;
-                out.println(profile.getName() + ": timespan  " + (timespan / 1000000) + " ms  larger than threshold");
-            }
-        }
-        return false;
-    }
-
-}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompiler.java	Thu Apr 17 19:30:37 2014 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.truffle;
-
-import java.util.concurrent.*;
-
-import com.oracle.graal.api.code.*;
-
-/**
- * Interface of the Truffle compiler producing an {@link InstalledCode} object from the partial
- * evaluation starting with the AST represented by the given {@link OptimizedCallTarget} node.
- */
-public interface TruffleCompiler {
-
-    Future<InstalledCode> compile(OptimizedCallTarget node);
-}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java	Thu Apr 17 19:30:37 2014 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java	Thu Apr 17 21:50:14 2014 +0200
@@ -27,14 +27,11 @@
 import static com.oracle.graal.truffle.TruffleCompilerOptions.*;
 
 import java.util.*;
-import java.util.concurrent.*;
-
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.code.Assumptions.Assumption;
 import com.oracle.graal.api.code.CallingConvention.Type;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.runtime.*;
-import com.oracle.graal.compiler.*;
 import com.oracle.graal.compiler.target.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.Debug.Scope;
@@ -55,7 +52,7 @@
 /**
  * Implementation of the Truffle compiler using Graal.
  */
-public class TruffleCompilerImpl implements TruffleCompiler {
+public class TruffleCompilerImpl {
 
     private final Providers providers;
     private final Suites suites;
@@ -64,7 +61,6 @@
     private final GraphBuilderConfiguration config;
     private final RuntimeProvider runtime;
     private final TruffleCache truffleCache;
-    private final ThreadPoolExecutor compileQueue;
 
     private static final Class<?>[] SKIPPED_EXCEPTION_CLASSES = new Class[]{UnexpectedResultException.class, SlowPathException.class, ArithmeticException.class};
 
@@ -78,20 +74,6 @@
         this.providers = backend.getProviders().copyWith(truffleReplacements);
         this.suites = backend.getSuites().getDefaultSuites();
 
-        // Create compilation queue.
-        CompilerThreadFactory factory = new CompilerThreadFactory("TruffleCompilerThread", new CompilerThreadFactory.DebugConfigAccess() {
-            public GraalDebugConfig getDebugConfig() {
-                if (Debug.isEnabled()) {
-                    GraalDebugConfig debugConfig = DebugEnvironment.initialize(TTY.out().out());
-                    debugConfig.dumpHandlers().add(new TruffleTreeDumpHandler());
-                    return debugConfig;
-                } else {
-                    return null;
-                }
-            }
-        });
-        compileQueue = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), factory);
-
         ResolvedJavaType[] skippedExceptionTypes = getSkippedExceptionTypes(providers.getMetaAccess());
         GraphBuilderConfiguration eagerConfig = GraphBuilderConfiguration.getEagerDefault();
         eagerConfig.setSkippedExceptionTypes(skippedExceptionTypes);
@@ -115,25 +97,11 @@
         return skippedExceptionTypes;
     }
 
-    public Future<InstalledCode> compile(final OptimizedCallTarget compilable) {
-        return compileQueue.submit(new Callable<InstalledCode>() {
-            @Override
-            public InstalledCode call() {
-                try (Scope s = Debug.scope("Truffle", new TruffleDebugJavaMethod(compilable))) {
-                    return compileMethodImpl(compilable);
-                } catch (Throwable e) {
-                    compilable.exceptionWhileCompiling(e);
-                    return null;
-                }
-            }
-        });
-    }
-
     public static final DebugTimer PartialEvaluationTime = Debug.timer("PartialEvaluationTime");
     public static final DebugTimer CompilationTime = Debug.timer("CompilationTime");
     public static final DebugTimer CodeInstallationTime = Debug.timer("CodeInstallation");
 
-    private InstalledCode compileMethodImpl(final OptimizedCallTarget compilable) {
+    public InstalledCode compileMethodImpl(final OptimizedCallTarget compilable) {
         final StructuredGraph graph;
 
         if (TraceTruffleCompilation.getValue()) {
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java	Thu Apr 17 19:30:37 2014 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java	Thu Apr 17 21:50:14 2014 +0200
@@ -72,8 +72,6 @@
     @Option(help = "Enable asynchronous truffle compilation in background thread")
     public static final OptionValue<Boolean> TruffleBackgroundCompilation = new OptionValue<>(true);
     @Option(help = "")
-    public static final OptionValue<Boolean> TruffleUseTimeForCompilationDecision = new OptionValue<>(false);
-    @Option(help = "")
     public static final OptionValue<Integer> TruffleCompilationDecisionTime = new OptionValue<>(100);
     @Option(help = "")
     public static final OptionValue<Boolean> TruffleCompilationDecisionTimePrintFail = new OptionValue<>(false);