changeset 18386:656331a61829

Truffle: add support for setting a couple of compiler options for individual execution contexts.
author Chris Seaton <chris.seaton@oracle.com>
date Sun, 16 Nov 2014 15:44:38 -0800
parents ea0fbb571466
children 3e5ed05b7e50
files graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/CompilationPolicy.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/CompilationProfile.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/CounterAndTimeBasedCompilationPolicy.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/CounterBasedCompilationPolicy.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/DefaultInliningPolicy.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalCompilerOptions.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/InterpreterOnlyCompilationPolicy.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleInlining.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleInliningPolicy.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerOptions.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/ExecutionContext.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleRuntime.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultCompilerOptions.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultTruffleRuntime.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/RootNode.java
diffstat 17 files changed, 262 insertions(+), 25 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/CompilationPolicy.java	Thu Nov 13 11:12:25 2014 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/CompilationPolicy.java	Sun Nov 16 15:44:38 2014 -0800
@@ -22,9 +22,11 @@
  */
 package com.oracle.graal.truffle;
 
+import com.oracle.truffle.api.*;
+
 public interface CompilationPolicy {
 
-    boolean shouldCompile(CompilationProfile profile);
+    boolean shouldCompile(CompilationProfile profile, CompilerOptions options);
 
     void recordCompilationFailure(Throwable t);
 }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/CompilationProfile.java	Thu Nov 13 11:12:25 2014 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/CompilationProfile.java	Sun Nov 16 15:44:38 2014 -0800
@@ -44,8 +44,8 @@
     private long timestamp;
 
     public CompilationProfile() {
-        this.compilationCallThreshold = TruffleMinInvokeThreshold.getValue();
-        this.compilationCallAndLoopThreshold = TruffleCompilationThreshold.getValue();
+        compilationCallThreshold = TruffleMinInvokeThreshold.getValue();
+        compilationCallAndLoopThreshold = TruffleCompilationThreshold.getValue();
     }
 
     @Override
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/CounterAndTimeBasedCompilationPolicy.java	Thu Nov 13 11:12:25 2014 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/CounterAndTimeBasedCompilationPolicy.java	Sun Nov 16 15:44:38 2014 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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
@@ -24,13 +24,19 @@
 
 import static com.oracle.graal.truffle.TruffleCompilerOptions.*;
 
+import com.oracle.truffle.api.*;
+
 public class CounterAndTimeBasedCompilationPolicy extends CounterBasedCompilationPolicy {
 
-    private static final long threshold = TruffleTimeThreshold.getValue() * 1_000_000L;
+    @Override
+    public boolean shouldCompile(CompilationProfile profile, CompilerOptions options) {
+        if (super.shouldCompile(profile, options)) {
+            long threshold = TruffleTimeThreshold.getValue() * 1_000_000L;
 
-    @Override
-    public boolean shouldCompile(CompilationProfile profile) {
-        if (super.shouldCompile(profile)) {
+            if (options instanceof GraalCompilerOptions) {
+                threshold = Math.max(threshold, ((GraalCompilerOptions) options).getMinTimeThreshold());
+            }
+
             long time = profile.getTimestamp();
             if (time == 0) {
                 throw new AssertionError();
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/CounterBasedCompilationPolicy.java	Thu Nov 13 11:12:25 2014 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/CounterBasedCompilationPolicy.java	Sun Nov 16 15:44:38 2014 -0800
@@ -22,15 +22,19 @@
  */
 package com.oracle.graal.truffle;
 
+import com.oracle.truffle.api.*;
+
 public class CounterBasedCompilationPolicy implements CompilationPolicy {
 
     private boolean compilationFailed;
 
-    public boolean shouldCompile(CompilationProfile profile) {
+    @Override
+    public boolean shouldCompile(CompilationProfile profile, CompilerOptions options) {
         return !compilationFailed && profile.getInterpreterCallCount() >= profile.getCompilationCallThreshold() &&
                         profile.getInterpreterCallAndLoopCount() >= profile.getCompilationCallAndLoopThreshold();
     }
 
+    @Override
     public void recordCompilationFailure(Throwable t) {
         compilationFailed = true;
     }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/DefaultInliningPolicy.java	Thu Nov 13 11:12:25 2014 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/DefaultInliningPolicy.java	Sun Nov 16 15:44:38 2014 -0800
@@ -24,23 +24,33 @@
 
 import static com.oracle.graal.truffle.TruffleCompilerOptions.*;
 
+import com.oracle.truffle.api.*;
+
 public class DefaultInliningPolicy implements TruffleInliningPolicy {
 
     private static final String REASON_RECURSION = "recursion";
     private static final String REASON_MAXIMUM_NODE_COUNT = "deepNodeCount * callSites  > " + TruffleInliningMaxCallerSize.getValue();
     private static final String REASON_MAXIMUM_TOTAL_NODE_COUNT = "totalNodeCount > " + TruffleInliningMaxCallerSize.getValue();
 
+    @Override
     public double calculateScore(TruffleInliningProfile profile) {
         return profile.getFrequency() / profile.getDeepNodeCount();
     }
 
-    public boolean isAllowed(TruffleInliningProfile profile, int currentNodeCount) {
+    @Override
+    public boolean isAllowed(TruffleInliningProfile profile, int currentNodeCount, CompilerOptions options) {
         if (profile.isRecursiveCall()) {
             profile.setFailedReason(REASON_RECURSION);
             return false;
         }
 
-        if (currentNodeCount + profile.getDeepNodeCount() > TruffleInliningMaxCallerSize.getValue()) {
+        int inliningMaxCallerSize = TruffleInliningMaxCallerSize.getValue();
+
+        if (options instanceof GraalCompilerOptions) {
+            inliningMaxCallerSize = Math.max(inliningMaxCallerSize, ((GraalCompilerOptions) options).getMinInliningMaxCallerSize());
+        }
+
+        if (currentNodeCount + profile.getDeepNodeCount() > inliningMaxCallerSize) {
             profile.setFailedReason(REASON_MAXIMUM_TOTAL_NODE_COUNT);
             return false;
         }
@@ -50,7 +60,7 @@
         }
 
         int cappedCallSites = Math.min(Math.max(profile.getCallSites(), 1), 10);
-        if (profile.getDeepNodeCount() * cappedCallSites > TruffleInliningMaxCallerSize.getValue()) {
+        if (profile.getDeepNodeCount() * cappedCallSites > inliningMaxCallerSize) {
             profile.setFailedReason(REASON_MAXIMUM_NODE_COUNT);
             return false;
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalCompilerOptions.java	Sun Nov 16 15:44:38 2014 -0800
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2014, 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 com.oracle.truffle.api.impl.*;
+
+public class GraalCompilerOptions extends DefaultCompilerOptions {
+
+    private int minTimeThreshold = 0;
+    private int minInliningMaxCallerSize = 0;
+
+    @Override
+    public boolean supportsOption(String name) {
+        switch (name) {
+            case "MinTimeThreshold":
+                return true;
+            case "MinInliningMaxCallerSize":
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    @Override
+    public void setOption(String name, Object value) {
+        switch (name) {
+            case "MinTimeThreshold":
+                minTimeThreshold = getInteger(name, value);
+                break;
+            case "MinInliningMaxCallerSize":
+                minInliningMaxCallerSize = getInteger(name, value);
+                break;
+            default:
+                super.setOption(name, value);
+                break;
+        }
+    }
+
+    private static int getInteger(String name, Object value) {
+        if (value instanceof Integer) {
+            return (int) value;
+        } else {
+            throw new UnsupportedOperationException(String.format("Option %s expected an int value", name));
+        }
+    }
+
+    public int getMinTimeThreshold() {
+        return minTimeThreshold;
+    }
+
+    public int getMinInliningMaxCallerSize() {
+        return minInliningMaxCallerSize;
+    }
+
+}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java	Thu Nov 13 11:12:25 2014 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java	Sun Nov 16 15:44:38 2014 -0800
@@ -113,6 +113,11 @@
     }
 
     @Override
+    public CompilerOptions createCompilerOptions() {
+        return new GraalCompilerOptions();
+    }
+
+    @Override
     public Assumption createAssumption() {
         return createAssumption(null);
     }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/InterpreterOnlyCompilationPolicy.java	Thu Nov 13 11:12:25 2014 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/InterpreterOnlyCompilationPolicy.java	Sun Nov 16 15:44:38 2014 -0800
@@ -22,12 +22,16 @@
  */
 package com.oracle.graal.truffle;
 
+import com.oracle.truffle.api.*;
+
 public class InterpreterOnlyCompilationPolicy implements CompilationPolicy {
 
-    public boolean shouldCompile(CompilationProfile profile) {
+    @Override
+    public boolean shouldCompile(CompilationProfile profile, CompilerOptions options) {
         return false;
     }
 
+    @Override
     public void recordCompilationFailure(Throwable t) {
     }
 
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java	Thu Nov 13 11:12:25 2014 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java	Sun Nov 16 15:44:38 2014 -0800
@@ -37,6 +37,7 @@
 import com.oracle.truffle.api.*;
 import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
 import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.api.impl.*;
 import com.oracle.truffle.api.nodes.*;
 import com.oracle.truffle.api.nodes.Node;
 import com.oracle.truffle.api.utilities.*;
@@ -300,12 +301,12 @@
 
     private void interpreterCall() {
         CompilerAsserts.neverPartOfCompilation();
-        if (this.isValid()) {
+        if (isValid()) {
             // Stubs were deoptimized => reinstall.
             this.runtime.reinstallStubs();
         } else {
             compilationProfile.reportInterpreterCall();
-            if (compilationPolicy.shouldCompile(compilationProfile)) {
+            if (compilationPolicy.shouldCompile(compilationProfile, getCompilerOptions())) {
                 compile();
             }
         }
@@ -479,4 +480,14 @@
         }
     }
 
+    private CompilerOptions getCompilerOptions() {
+        final ExecutionContext context = rootNode.getExecutionContext();
+
+        if (context == null) {
+            return DefaultCompilerOptions.INSTANCE;
+        }
+
+        return context.getCompilerOptions();
+    }
+
 }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleInlining.java	Thu Nov 13 11:12:25 2014 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleInlining.java	Sun Nov 16 15:44:38 2014 -0800
@@ -33,18 +33,19 @@
 
     private final List<TruffleInliningDecision> callSites;
 
-    TruffleInlining(List<TruffleInliningDecision> callSites) {
+    protected TruffleInlining(List<TruffleInliningDecision> callSites) {
         this.callSites = callSites;
     }
 
     public TruffleInlining(OptimizedCallTarget sourceTarget, TruffleInliningPolicy policy) {
-        this(createDecisions(sourceTarget, policy));
+        this(createDecisions(sourceTarget, policy, sourceTarget.getRootNode().getCompilerOptions()));
+
     }
 
-    private static List<TruffleInliningDecision> createDecisions(OptimizedCallTarget sourceTarget, TruffleInliningPolicy policy) {
+    private static List<TruffleInliningDecision> createDecisions(OptimizedCallTarget sourceTarget, TruffleInliningPolicy policy, CompilerOptions options) {
         int nodeCount = sourceTarget.countNonTrivialNodes(false);
         List<TruffleInliningDecision> exploredCallSites = exploreCallSites(new ArrayList<>(Arrays.asList(sourceTarget)), nodeCount, policy);
-        return decideInlining(exploredCallSites, policy, nodeCount);
+        return decideInlining(exploredCallSites, policy, nodeCount, options);
     }
 
     private static List<TruffleInliningDecision> exploreCallSites(List<OptimizedCallTarget> stack, int callStackNodeCount, TruffleInliningPolicy policy) {
@@ -72,11 +73,12 @@
         if (!recursive && callStack.size() < 15) {
             /*
              * We make a preliminary optimistic inlining decision with best possible characteristics
-             * to avoid the exploration of unnecessary pathes in the inlining tree.
+             * to avoid the exploration of unnecessary paths in the inlining tree.
              */
-            if (policy.isAllowed(new TruffleInliningProfile(callNode, nodeCount, nodeCount, frequency, recursive), callStackNodeCount)) {
+            final CompilerOptions options = callNode.getRootNode().getCompilerOptions();
+            if (policy.isAllowed(new TruffleInliningProfile(callNode, nodeCount, nodeCount, frequency, recursive), callStackNodeCount, options)) {
                 List<TruffleInliningDecision> exploredCallSites = exploreCallSites(callStack, callStackNodeCount + nodeCount, policy);
-                childCallSites = decideInlining(exploredCallSites, policy, nodeCount);
+                childCallSites = decideInlining(exploredCallSites, policy, nodeCount, options);
                 for (TruffleInliningDecision childCallSite : childCallSites) {
                     if (childCallSite.isInline()) {
                         deepNodeCount += childCallSite.getProfile().getDeepNodeCount();
@@ -107,13 +109,13 @@
         return false;
     }
 
-    private static List<TruffleInliningDecision> decideInlining(List<TruffleInliningDecision> callSites, TruffleInliningPolicy policy, int nodeCount) {
+    private static List<TruffleInliningDecision> decideInlining(List<TruffleInliningDecision> callSites, TruffleInliningPolicy policy, int nodeCount, CompilerOptions options) {
         int deepNodeCount = nodeCount;
         int index = 0;
         for (TruffleInliningDecision callSite : callSites.stream().sorted().collect(Collectors.toList())) {
             TruffleInliningProfile profile = callSite.getProfile();
             profile.setQueryIndex(index++);
-            if (policy.isAllowed(profile, deepNodeCount)) {
+            if (policy.isAllowed(profile, deepNodeCount, options)) {
                 callSite.setInline(true);
                 deepNodeCount += profile.getDeepNodeCount();
             }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleInliningPolicy.java	Thu Nov 13 11:12:25 2014 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleInliningPolicy.java	Sun Nov 16 15:44:38 2014 -0800
@@ -22,9 +22,11 @@
  */
 package com.oracle.graal.truffle;
 
+import com.oracle.truffle.api.*;
+
 public interface TruffleInliningPolicy {
 
-    boolean isAllowed(TruffleInliningProfile profile, int currentNodeCount);
+    boolean isAllowed(TruffleInliningProfile profile, int currentNodeCount, CompilerOptions options);
 
     double calculateScore(TruffleInliningProfile profile);
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerOptions.java	Sun Nov 16 15:44:38 2014 -0800
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2014, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.truffle.api;
+
+import com.oracle.truffle.api.nodes.*;
+
+/**
+ * Allows options to be set to control the compilation of a specific {@link RootNode}, without
+ * creating a dependency on the specific compiler used. Options can be tested for support before
+ * setting.
+ */
+public interface CompilerOptions {
+
+    boolean supportsOption(String name);
+
+    void setOption(String name, Object value);
+
+}
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/ExecutionContext.java	Thu Nov 13 11:12:25 2014 +0100
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/ExecutionContext.java	Sun Nov 16 15:44:38 2014 -0800
@@ -26,6 +26,7 @@
 
 import java.util.*;
 
+import com.oracle.truffle.api.impl.*;
 import com.oracle.truffle.api.instrument.*;
 import com.oracle.truffle.api.instrument.impl.*;
 import com.oracle.truffle.api.source.*;
@@ -165,4 +166,11 @@
      */
     protected abstract void setSourceCallback(SourceCallback sourceCallback);
 
+    /**
+     * Get compiler options specific to this <code>ExecutionContext</code>.
+     */
+    public CompilerOptions getCompilerOptions() {
+        return DefaultCompilerOptions.INSTANCE;
+    }
+
 }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleRuntime.java	Thu Nov 13 11:12:25 2014 +0100
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleRuntime.java	Sun Nov 16 15:44:38 2014 -0800
@@ -112,6 +112,14 @@
     MaterializedFrame createMaterializedFrame(Object[] arguments, FrameDescriptor frameDescriptor);
 
     /**
+     * Creates an object which allows you to test for support of and set options specific for this
+     * runtime.
+     *
+     * @return the newly created compiler options object
+     */
+    CompilerOptions createCompilerOptions();
+
+    /**
      * Accesses the current stack, i.e., the contents of the {@link Frame}s and the associated
      * {@link CallTarget}s. Iteration starts at the caller frame, i.e., it does not include the
      * current frame.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultCompilerOptions.java	Sun Nov 16 15:44:38 2014 -0800
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2014, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.truffle.api.impl;
+
+import com.oracle.truffle.api.*;
+
+public class DefaultCompilerOptions implements CompilerOptions {
+
+    public static DefaultCompilerOptions INSTANCE = new DefaultCompilerOptions();
+
+    public boolean supportsOption(String name) {
+        return false;
+    }
+
+    public void setOption(String name, Object value) {
+        throw new UnsupportedOperationException(String.format("Option %s is not supported by this runtime"));
+    }
+
+}
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultTruffleRuntime.java	Thu Nov 13 11:12:25 2014 +0100
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultTruffleRuntime.java	Sun Nov 16 15:44:38 2014 -0800
@@ -85,6 +85,11 @@
     }
 
     @Override
+    public CompilerOptions createCompilerOptions() {
+        return new DefaultCompilerOptions();
+    }
+
+    @Override
     public Assumption createAssumption() {
         return createAssumption(null);
     }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/RootNode.java	Thu Nov 13 11:12:25 2014 +0100
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/RootNode.java	Sun Nov 16 15:44:38 2014 -0800
@@ -27,6 +27,7 @@
 import com.oracle.truffle.api.*;
 import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
 import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.api.impl.*;
 import com.oracle.truffle.api.source.*;
 
 /**
@@ -126,4 +127,17 @@
         return null;
     }
 
+    /**
+     * Get compiler options specific to this <code>RootNode</code>.
+     */
+    public CompilerOptions getCompilerOptions() {
+        final ExecutionContext context = getExecutionContext();
+
+        if (context == null) {
+            return DefaultCompilerOptions.INSTANCE;
+        } else {
+            return context.getCompilerOptions();
+        }
+    }
+
 }