changeset 9896:5945a36ccba4

Merge
author Christos Kotselidis <christos.kotselidis@oracle.com>
date Wed, 05 Jun 2013 15:11:58 +0200
parents ab85c49630e2 (current diff) 7779b1d5ba37 (diff)
children 65e23a65de9d
files graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRegisterConfig.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java make/build-graal.xml
diffstat 142 files changed, 1411 insertions(+), 933 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Wed Jun 05 14:49:34 2013 +0200
+++ b/.hgignore	Wed Jun 05 15:11:58 2013 +0200
@@ -72,3 +72,5 @@
 *.jar.*
 eclipse-build.xml
 rebuild-launch.out
+coverage
+jacoco.exec
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ForeignCallLinkage.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ForeignCallLinkage.java	Wed Jun 05 15:11:58 2013 +0200
@@ -55,4 +55,11 @@
      *         this target
      */
     boolean destroysRegisters();
+
+    /**
+     * Determines if this is call to a function that does not deoptimize, and therefore also does
+     * not lock, GC or throw exceptions. That is, the thread's execution state during the call is
+     * never inspected by another thread.
+     */
+    boolean canDeoptimize();
 }
--- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaMethod.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaMethod.java	Wed Jun 05 15:11:58 2013 +0200
@@ -252,7 +252,8 @@
         ResolvedJavaMethod method1 = runtime.lookupJavaMethod(getClass().getDeclaredMethod("methodWithAnnotatedParameters", HashMap.class, Class.class));
         ResolvedJavaMethod method2 = runtime.lookupJavaMethod(getClass().getDeclaredMethod("nullPointerExceptionOnFirstLine", Object.class, String.class));
         assertEquals(0, method1.getMaxStackSize());
-        assertEquals(3, method2.getMaxStackSize());
+        // some versions of javac produce bytecode with a stacksize of 2 for this method
+        assertTrue(3 == method2.getMaxStackSize() || 2 == method2.getMaxStackSize());
     }
 
     private Method findTestMethod(Method apiMethod) {
--- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java	Wed Jun 05 15:11:58 2013 +0200
@@ -59,18 +59,13 @@
 import com.oracle.graal.lir.amd64.AMD64ControlFlow.SequentialSwitchOp;
 import com.oracle.graal.lir.amd64.AMD64ControlFlow.SwitchRangesOp;
 import com.oracle.graal.lir.amd64.AMD64ControlFlow.TableSwitchOp;
-import com.oracle.graal.lir.amd64.AMD64Move.CompareAndSwapOp;
 import com.oracle.graal.lir.amd64.AMD64Move.LeaOp;
-import com.oracle.graal.lir.amd64.AMD64Move.LoadOp;
 import com.oracle.graal.lir.amd64.AMD64Move.MembarOp;
 import com.oracle.graal.lir.amd64.AMD64Move.MoveFromRegOp;
 import com.oracle.graal.lir.amd64.AMD64Move.MoveToRegOp;
 import com.oracle.graal.lir.amd64.AMD64Move.StackLeaOp;
-import com.oracle.graal.lir.amd64.AMD64Move.StoreConstantOp;
-import com.oracle.graal.lir.amd64.AMD64Move.StoreOp;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
-import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.phases.util.*;
 
 /**
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java	Wed Jun 05 15:11:58 2013 +0200
@@ -23,6 +23,7 @@
 package com.oracle.graal.compiler.test;
 
 import static com.oracle.graal.api.code.CodeUtil.*;
+import static com.oracle.graal.phases.GraalOptions.*;
 
 import java.lang.reflect.*;
 import java.util.*;
@@ -420,7 +421,7 @@
         InstalledCode installedCode = Debug.scope("Compiling", new Object[]{runtime, new DebugDumpScope(String.valueOf(id), true)}, new Callable<InstalledCode>() {
 
             public InstalledCode call() throws Exception {
-                final boolean printCompilation = GraalOptions.PrintCompilation && !TTY.isSuppressed();
+                final boolean printCompilation = PrintCompilation.getValue() && !TTY.isSuppressed();
                 if (printCompilation) {
                     TTY.println(String.format("@%-6d Graal %-70s %-45s %-50s ...", id, method.getDeclaringClass().getName(), method.getName(), method.getSignature()));
                 }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/AllocatorTest.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/AllocatorTest.java	Wed Jun 05 15:11:58 2013 +0200
@@ -23,6 +23,7 @@
 package com.oracle.graal.compiler.test.backend;
 
 import static com.oracle.graal.api.code.CodeUtil.*;
+import static com.oracle.graal.phases.GraalOptions.*;
 
 import java.util.*;
 import java.util.concurrent.*;
@@ -112,7 +113,7 @@
 
     private RegisterStats getRegisterStats(final StructuredGraph graph) {
         final PhasePlan phasePlan = getDefaultPhasePlan();
-        final Assumptions assumptions = new Assumptions(GraalOptions.OptAssumptions);
+        final Assumptions assumptions = new Assumptions(OptAssumptions.getValue());
 
         final LIR lir = Debug.scope("FrontEnd", new Callable<LIR>() {
 
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/IterativeInliningTest.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/IterativeInliningTest.java	Wed Jun 05 15:11:58 2013 +0200
@@ -22,6 +22,7 @@
  */
 package com.oracle.graal.compiler.test.ea;
 
+import static com.oracle.graal.phases.GraalOptions.*;
 import static org.junit.Assert.*;
 
 import java.util.concurrent.*;
@@ -100,7 +101,7 @@
 
     private void processMethod(final String snippet) {
         graph = parse(snippet);
-        GraalOptions.OptEarlyReadElimination = true;
+        OptEarlyReadElimination.setValue(true);
         HighTierContext context = new HighTierContext(runtime(), new Assumptions(false), replacements);
         new IterativeInliningPhase(replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL, false).apply(graph, context);
     }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java	Wed Jun 05 15:11:58 2013 +0200
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.compiler;
 
+import static com.oracle.graal.phases.GraalOptions.*;
+
 import java.util.*;
 import java.util.concurrent.*;
 
@@ -56,6 +58,8 @@
     // @formatter:off
     @Option(help = "")
     public static final OptionValue<Boolean> VerifyUsageWithEquals = new OptionValue<>(true);
+    @Option(help = "Enable inlining")
+    public static final OptionValue<Boolean> Inline = new OptionValue<>(true);
     // @formatter:on
 
     /**
@@ -75,7 +79,7 @@
         Debug.scope("GraalCompiler", new Object[]{graph, runtime}, new Runnable() {
 
             public void run() {
-                final Assumptions assumptions = new Assumptions(GraalOptions.OptAssumptions);
+                final Assumptions assumptions = new Assumptions(OptAssumptions.getValue());
                 final LIR lir = Debug.scope("FrontEnd", new Callable<LIR>() {
 
                     public LIR call() {
@@ -136,20 +140,20 @@
             new VerifyUsageWithEquals(runtime, Register.class).apply(graph);
         }
 
-        if (GraalOptions.OptCanonicalizer) {
+        if (OptCanonicalizer.getValue()) {
             new CanonicalizerPhase.Instance(runtime, assumptions).apply(graph);
         }
 
         HighTierContext highTierContext = new HighTierContext(runtime, assumptions, replacements);
 
-        if (GraalOptions.Inline && !plan.isPhaseDisabled(InliningPhase.class)) {
-            if (GraalOptions.IterativeInlining) {
-                new IterativeInliningPhase(replacements, cache, plan, optimisticOpts, GraalOptions.OptEarlyReadElimination).apply(graph, highTierContext);
+        if (Inline.getValue() && !plan.isPhaseDisabled(InliningPhase.class)) {
+            if (IterativeInlining.getValue()) {
+                new IterativeInliningPhase(replacements, cache, plan, optimisticOpts, OptEarlyReadElimination.getValue()).apply(graph, highTierContext);
             } else {
                 new InliningPhase(runtime, null, replacements, assumptions, cache, plan, optimisticOpts).apply(graph);
                 new DeadCodeEliminationPhase().apply(graph);
 
-                if (GraalOptions.ConditionalElimination && GraalOptions.OptCanonicalizer) {
+                if (ConditionalElimination.getValue() && OptCanonicalizer.getValue()) {
                     new CanonicalizerPhase.Instance(runtime, assumptions).apply(graph);
                     new IterativeConditionalEliminationPhase().apply(graph, highTierContext);
                 }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugConfig.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugConfig.java	Wed Jun 05 15:11:58 2013 +0200
@@ -56,6 +56,16 @@
     public static final OptionValue<Boolean> SummarizePerPhase = new OptionValue<>(false);
     @Option(help = "Send Graal IR to dump handlers on error")
     public static final OptionValue<Boolean> DumpOnError = new OptionValue<>(false);
+    @Option(help = "Enable expensive assertions")
+    public static final OptionValue<Boolean> DetailedAsserts = new OptionValue<Boolean>(false) {
+        @Override
+        protected Boolean initialValue() {
+            boolean enabled = value;
+            // turn detailed assertions on when the general assertions are on (misusing the assert keyword for this)
+            assert (enabled = true) == true;
+            return enabled;
+        }
+    };
     // @formatter:on
 
     private final DebugFilter logFilter;
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/Interval.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/Interval.java	Wed Jun 05 15:11:58 2013 +0200
@@ -22,6 +22,10 @@
  */
 package com.oracle.graal.compiler.alloc;
 
+import static com.oracle.graal.api.code.ValueUtil.*;
+import static com.oracle.graal.compiler.GraalDebugConfig.*;
+import static com.oracle.graal.lir.LIRValueUtil.*;
+
 import java.util.*;
 
 import com.oracle.graal.api.code.*;
@@ -29,12 +33,8 @@
 import com.oracle.graal.debug.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.lir.*;
-import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.util.*;
 
-import static com.oracle.graal.api.code.ValueUtil.*;
-import static com.oracle.graal.lir.LIRValueUtil.*;
-
 /**
  * Represents an interval in the {@linkplain LinearScan linear scan register allocator}.
  */
@@ -922,7 +922,7 @@
 
         // do not add use positions for precolored intervals because they are never used
         if (registerPriority != RegisterPriority.None && isVariable(operand)) {
-            if (GraalOptions.DetailedAsserts) {
+            if (DetailedAsserts.getValue()) {
                 for (int i = 0; i < usePosList.size(); i++) {
                     assert pos <= usePosList.usePos(i) : "already added a use-position with lower position";
                     if (i > 0) {
@@ -1026,7 +1026,7 @@
         // split list of use positions
         result.usePosList = usePosList.splitAt(splitPos);
 
-        if (GraalOptions.DetailedAsserts) {
+        if (DetailedAsserts.getValue()) {
             for (int i = 0; i < usePosList.size(); i++) {
                 assert usePosList.usePos(i) < splitPos;
             }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/IntervalWalker.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/IntervalWalker.java	Wed Jun 05 15:11:58 2013 +0200
@@ -22,11 +22,12 @@
  */
 package com.oracle.graal.compiler.alloc;
 
+import static com.oracle.graal.phases.GraalOptions.*;
+
 import com.oracle.graal.compiler.alloc.Interval.RegisterBinding;
 import com.oracle.graal.compiler.alloc.Interval.RegisterBindingLists;
 import com.oracle.graal.compiler.alloc.Interval.State;
 import com.oracle.graal.debug.*;
-import com.oracle.graal.phases.*;
 
 /**
  */
@@ -208,7 +209,7 @@
             boolean isActive = currentInterval.from() <= toOpId;
             int opId = isActive ? currentInterval.from() : toOpId;
 
-            if (GraalOptions.TraceLinearScanLevel >= 2 && !TTY.isSuppressed()) {
+            if (TraceLinearScanLevel.getValue() >= 2 && !TTY.isSuppressed()) {
                 if (currentPosition < opId) {
                     TTY.println();
                     TTY.println("walkTo(%d) *", opId);
@@ -239,7 +240,7 @@
     private void intervalMoved(Interval interval, State from, State to) {
         // intervalMoved() is called whenever an interval moves from one interval list to another.
         // In the implementation of this method it is prohibited to move the interval to any list.
-        if (GraalOptions.TraceLinearScanLevel >= 4 && !TTY.isSuppressed()) {
+        if (TraceLinearScanLevel.getValue() >= 4 && !TTY.isSuppressed()) {
             TTY.print(from.toString() + " to " + to.toString());
             TTY.fillTo(23);
             TTY.out().println(interval.logString(allocator));
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java	Wed Jun 05 15:11:58 2013 +0200
@@ -24,7 +24,9 @@
 
 import static com.oracle.graal.api.code.CodeUtil.*;
 import static com.oracle.graal.api.code.ValueUtil.*;
+import static com.oracle.graal.compiler.GraalDebugConfig.*;
 import static com.oracle.graal.lir.LIRValueUtil.*;
+import static com.oracle.graal.phases.GraalOptions.*;
 
 import java.util.*;
 
@@ -501,7 +503,7 @@
 
     // called once before assignment of register numbers
     void eliminateSpillMoves() {
-        if (GraalOptions.TraceLinearScanLevel >= 3) {
+        if (TraceLinearScanLevel.getValue() >= 3) {
             TTY.println(" Eliminating unnecessary spill moves");
         }
 
@@ -509,7 +511,7 @@
         // the list is sorted by Interval.spillDefinitionPos
         Interval interval;
         interval = createUnhandledLists(mustStoreAtDefinition, null).first;
-        if (GraalOptions.DetailedAsserts) {
+        if (DetailedAsserts.getValue()) {
             checkIntervals(interval);
         }
 
@@ -535,7 +537,7 @@
                     if (!isRegister(curInterval.location()) && curInterval.alwaysInMemory()) {
                         // move target is a stack slot that is always correct, so eliminate
                         // instruction
-                        if (GraalOptions.TraceLinearScanLevel >= 4) {
+                        if (TraceLinearScanLevel.getValue() >= 4) {
                             TTY.println("eliminating move from interval %d to %d", operandNumber(move.getInput()), operandNumber(move.getResult()));
                         }
                         instructions.set(j, null); // null-instructions are deleted by assignRegNum
@@ -561,7 +563,7 @@
 
                         insertionBuffer.append(j + 1, ir.spillMoveFactory.createMove(toLocation, fromLocation));
 
-                        if (GraalOptions.TraceLinearScanLevel >= 4) {
+                        if (TraceLinearScanLevel.getValue() >= 4) {
                             StackSlot slot = interval.spillSlot();
                             TTY.println("inserting move after definition of interval %d to stack slot %s at opId %d", interval.operandNumber, slot, opId);
                         }
@@ -593,7 +595,7 @@
             assert temp.spillDefinitionPos() >= temp.from() : "invalid order";
             assert temp.spillDefinitionPos() <= temp.from() + 2 : "only intervals defined once at their start-pos can be optimized";
 
-            if (GraalOptions.TraceLinearScanLevel >= 4) {
+            if (TraceLinearScanLevel.getValue() >= 4) {
                 TTY.println("interval %d (from %d to %d) must be stored at %d", temp.operandNumber, temp.from(), temp.to(), temp.spillDefinitionPos());
             }
 
@@ -658,7 +660,7 @@
         assert index == numInstructions : "must match";
         assert (index << 1) == opId : "must match: " + (index << 1);
 
-        if (GraalOptions.DetailedAsserts) {
+        if (DetailedAsserts.getValue()) {
             for (int i = 0; i < variables.size(); i++) {
                 assert variables.get(i) != null && variables.get(i).index == i;
             }
@@ -696,7 +698,7 @@
                             int operandNum = operandNumber(operand);
                             if (!liveKill.get(operandNum)) {
                                 liveGen.set(operandNum);
-                                if (GraalOptions.TraceLinearScanLevel >= 4) {
+                                if (TraceLinearScanLevel.getValue() >= 4) {
                                     TTY.println("  Setting liveGen for operand %d at instruction %d", operandNum, op.id());
                                 }
                             }
@@ -705,7 +707,7 @@
                             }
                         }
 
-                        if (GraalOptions.DetailedAsserts) {
+                        if (DetailedAsserts.getValue()) {
                             verifyInput(block, liveKill, operand);
                         }
                         return operand;
@@ -718,7 +720,7 @@
                         int operandNum = operandNumber(operand);
                         if (!liveKill.get(operandNum)) {
                             liveGen.set(operandNum);
-                            if (GraalOptions.TraceLinearScanLevel >= 4) {
+                            if (TraceLinearScanLevel.getValue() >= 4) {
                                 TTY.println("  Setting liveGen for LIR opId %d, operand %d because of state for %s", op.id(), operandNum, op);
                             }
                         }
@@ -737,7 +739,7 @@
                             }
                         }
 
-                        if (GraalOptions.DetailedAsserts) {
+                        if (DetailedAsserts.getValue()) {
                             // fixed intervals are never live at block boundaries, so
                             // they need not be processed in live sets
                             // process them only in debug mode so that this can be checked
@@ -761,7 +763,7 @@
             blockData.get(block).liveIn = new BitSet(liveSize);
             blockData.get(block).liveOut = new BitSet(liveSize);
 
-            if (GraalOptions.TraceLinearScanLevel >= 4) {
+            if (TraceLinearScanLevel.getValue() >= 4) {
                 TTY.println("liveGen  B%d %s", block.getId(), blockData.get(block).liveGen);
                 TTY.println("liveKill B%d %s", block.getId(), blockData.get(block).liveKill);
             }
@@ -850,7 +852,7 @@
                     liveIn.or(blockData.get(block).liveGen);
                 }
 
-                if (GraalOptions.TraceLinearScanLevel >= 4) {
+                if (TraceLinearScanLevel.getValue() >= 4) {
                     traceLiveness(changeOccurredInBlock, iterationCount, block);
                 }
             }
@@ -861,7 +863,7 @@
             }
         } while (changeOccurred);
 
-        if (GraalOptions.DetailedAsserts) {
+        if (DetailedAsserts.getValue()) {
             verifyLiveness();
         }
 
@@ -869,7 +871,7 @@
         Block startBlock = ir.cfg.getStartBlock();
         BitSet liveInArgs = new BitSet(blockData.get(startBlock).liveIn.size());
         if (!blockData.get(startBlock).liveIn.equals(liveInArgs)) {
-            if (GraalOptions.DetailedAsserts) {
+            if (DetailedAsserts.getValue()) {
                 reportFailure(numBlocks);
             }
 
@@ -970,7 +972,7 @@
         if (!isProcessed(operand)) {
             return;
         }
-        if (GraalOptions.TraceLinearScanLevel >= 2 && kind == null) {
+        if (TraceLinearScanLevel.getValue() >= 2 && kind == null) {
             TTY.println(" use %s from %d to %d (%s)", operand, from, to, registerPriority.name());
         }
 
@@ -989,7 +991,7 @@
         if (!isProcessed(operand)) {
             return;
         }
-        if (GraalOptions.TraceLinearScanLevel >= 2) {
+        if (TraceLinearScanLevel.getValue() >= 2) {
             TTY.println(" temp %s tempPos %d (%s)", operand, tempPos, RegisterPriority.MustHaveRegister.name());
         }
 
@@ -1010,7 +1012,7 @@
         if (!isProcessed(operand)) {
             return;
         }
-        if (GraalOptions.TraceLinearScanLevel >= 2) {
+        if (TraceLinearScanLevel.getValue() >= 2) {
             TTY.println(" def %s defPos %d (%s)", operand, defPos, registerPriority.name());
         }
 
@@ -1031,7 +1033,7 @@
             // also add register priority for dead intervals
             interval.addRange(defPos, defPos + 1);
             interval.addUsePos(defPos, registerPriority);
-            if (GraalOptions.TraceLinearScanLevel >= 2) {
+            if (TraceLinearScanLevel.getValue() >= 2) {
                 TTY.println("Warning: def of operand %s at %d occurs without use", operand, defPos);
             }
         }
@@ -1087,12 +1089,12 @@
             MoveOp move = (MoveOp) op;
             if (optimizeMethodArgument(move.getInput())) {
                 StackSlot slot = asStackSlot(move.getInput());
-                if (GraalOptions.DetailedAsserts) {
+                if (DetailedAsserts.getValue()) {
                     assert op.id() > 0 : "invalid id";
                     assert blockForId(op.id()).getPredecessorCount() == 0 : "move from stack must be in first block";
                     assert isVariable(move.getResult()) : "result of move must be a variable";
 
-                    if (GraalOptions.TraceLinearScanLevel >= 4) {
+                    if (TraceLinearScanLevel.getValue() >= 4) {
                         TTY.println("found move from stack slot %s to %s", slot, move.getResult());
                     }
                 }
@@ -1122,7 +1124,7 @@
                             from.setLocationHint(to);
                         }
 
-                        if (GraalOptions.TraceLinearScanLevel >= 4) {
+                        if (TraceLinearScanLevel.getValue() >= 4) {
                             TTY.println("operation at opId %d: added hint from interval %d to %d", op.id(), from.operandNumber, to.operandNumber);
                         }
                         return registerHint;
@@ -1155,7 +1157,7 @@
             for (int operandNum = live.nextSetBit(0); operandNum >= 0; operandNum = live.nextSetBit(operandNum + 1)) {
                 assert live.get(operandNum) : "should not stop here otherwise";
                 AllocatableValue operand = operandFor(operandNum);
-                if (GraalOptions.TraceLinearScanLevel >= 2) {
+                if (TraceLinearScanLevel.getValue() >= 2) {
                     TTY.println("live in %s to %d", operand, blockTo + 2);
                 }
 
@@ -1185,7 +1187,7 @@
                             addTemp(r.asValue(), opId, RegisterPriority.None, Kind.Illegal);
                         }
                     }
-                    if (GraalOptions.TraceLinearScanLevel >= 4) {
+                    if (TraceLinearScanLevel.getValue() >= 4) {
                         TTY.println("operation destroys all caller-save registers");
                     }
                 }
@@ -1436,7 +1438,7 @@
         Interval result = interval.getSplitChildAtOpId(opId, mode, this);
 
         if (result != null) {
-            if (GraalOptions.TraceLinearScanLevel >= 4) {
+            if (TraceLinearScanLevel.getValue() >= 4) {
                 TTY.println("Split child at pos " + opId + " of interval " + interval.toString() + " is " + result.toString());
             }
             return result;
@@ -1490,7 +1492,7 @@
 
     void resolveFindInsertPos(Block fromBlock, Block toBlock, MoveResolver moveResolver) {
         if (fromBlock.getSuccessorCount() <= 1) {
-            if (GraalOptions.TraceLinearScanLevel >= 4) {
+            if (TraceLinearScanLevel.getValue() >= 4) {
                 TTY.println("inserting moves at end of fromBlock B%d", fromBlock.getId());
             }
 
@@ -1504,11 +1506,11 @@
             }
 
         } else {
-            if (GraalOptions.TraceLinearScanLevel >= 4) {
+            if (TraceLinearScanLevel.getValue() >= 4) {
                 TTY.println("inserting moves at beginning of toBlock B%d", toBlock.getId());
             }
 
-            if (GraalOptions.DetailedAsserts) {
+            if (DetailedAsserts.getValue()) {
                 assert ir.lir(fromBlock).get(0) instanceof StandardOp.LabelOp : "block does not start with a label";
 
                 // because the number of predecessor edges matches the number of
@@ -1549,7 +1551,7 @@
 
                     // prevent optimization of two consecutive blocks
                     if (!blockCompleted.get(pred.getLinearScanNumber()) && !blockCompleted.get(sux.getLinearScanNumber())) {
-                        if (GraalOptions.TraceLinearScanLevel >= 3) {
+                        if (TraceLinearScanLevel.getValue() >= 3) {
                             TTY.println(" optimizing empty block B%d (pred: B%d, sux: B%d)", block.getId(), pred.getId(), sux.getId());
                         }
                         blockCompleted.set(block.getLinearScanNumber());
@@ -1576,7 +1578,7 @@
                     // check for duplicate edges between the same blocks (can happen with switch
                     // blocks)
                     if (!alreadyResolved.get(toBlock.getLinearScanNumber())) {
-                        if (GraalOptions.TraceLinearScanLevel >= 3) {
+                        if (GraalOptions.TraceLinearScanLevel.getValue() >= 3) {
                             TTY.println(" processing edge between B%d and B%d", fromBlock.getId(), toBlock.getId());
                         }
                         alreadyResolved.set(toBlock.getLinearScanNumber());
@@ -1614,7 +1616,7 @@
         assert interval != null : "interval must exist";
 
         if (opId != -1) {
-            if (GraalOptions.DetailedAsserts) {
+            if (DetailedAsserts.getValue()) {
                 Block block = blockForId(opId);
                 if (block.getSuccessorCount() <= 1 && opId == getLastLirInstructionId(block)) {
                     // check if spill moves could have been appended at the end of this block, but
@@ -1655,7 +1657,7 @@
     }
 
     void computeOopMap(IntervalWalker iw, LIRInstruction op, BitSet registerRefMap, BitSet frameRefMap) {
-        if (GraalOptions.TraceLinearScanLevel >= 3) {
+        if (TraceLinearScanLevel.getValue() >= 3) {
             TTY.println("creating oop map at opId %d", op.id());
         }
 
@@ -1839,14 +1841,14 @@
 
                 sortIntervalsAfterAllocation();
 
-                if (GraalOptions.DetailedAsserts) {
+                if (DetailedAsserts.getValue()) {
                     verify();
                 }
 
                 eliminateSpillMoves();
                 assignLocations();
 
-                if (GraalOptions.DetailedAsserts) {
+                if (DetailedAsserts.getValue()) {
                     verifyIntervals();
                 }
             }
@@ -1864,7 +1866,7 @@
     }
 
     void printIntervals(String label) {
-        if (GraalOptions.TraceLinearScanLevel >= 1) {
+        if (TraceLinearScanLevel.getValue() >= 1) {
             int i;
             TTY.println();
             TTY.println(label);
@@ -1894,27 +1896,27 @@
 
     boolean verify() {
         // (check that all intervals have a correct register and that no registers are overwritten)
-        if (GraalOptions.TraceLinearScanLevel >= 2) {
+        if (TraceLinearScanLevel.getValue() >= 2) {
             TTY.println(" verifying intervals *");
         }
         verifyIntervals();
 
-        if (GraalOptions.TraceLinearScanLevel >= 2) {
+        if (TraceLinearScanLevel.getValue() >= 2) {
             TTY.println(" verifying that no oops are in fixed intervals *");
         }
         // verifyNoOopsInFixedIntervals();
 
-        if (GraalOptions.TraceLinearScanLevel >= 2) {
+        if (TraceLinearScanLevel.getValue() >= 2) {
             TTY.println(" verifying that unpinned constants are not alive across block boundaries");
         }
         verifyConstants();
 
-        if (GraalOptions.TraceLinearScanLevel >= 2) {
+        if (TraceLinearScanLevel.getValue() >= 2) {
             TTY.println(" verifying register allocation *");
         }
         verifyRegisters();
 
-        if (GraalOptions.TraceLinearScanLevel >= 2) {
+        if (TraceLinearScanLevel.getValue() >= 2) {
             TTY.println(" no errors found *");
         }
 
@@ -1986,7 +1988,7 @@
                 Value l1 = i1.location();
                 Value l2 = i2.location();
                 if (i1.intersects(i2) && (l1.equals(l2))) {
-                    if (GraalOptions.DetailedAsserts) {
+                    if (DetailedAsserts.getValue()) {
                         TTY.println("Intervals %d and %d overlap and have the same register assigned", i1.operandNumber, i2.operandNumber);
                         TTY.println(i1.logString(this));
                         TTY.println(i2.logString(this));
@@ -2066,7 +2068,7 @@
 
             // visit all operands where the liveAtEdge bit is set
             for (int operandNum = liveAtEdge.nextSetBit(0); operandNum >= 0; operandNum = liveAtEdge.nextSetBit(operandNum + 1)) {
-                if (GraalOptions.TraceLinearScanLevel >= 4) {
+                if (TraceLinearScanLevel.getValue() >= 4) {
                     TTY.println("checking interval %d of block B%d", operandNum, block.getId());
                 }
                 Value operand = operandFor(operandNum);
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScanWalker.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScanWalker.java	Wed Jun 05 15:11:58 2013 +0200
@@ -25,6 +25,7 @@
 import static com.oracle.graal.api.code.CodeUtil.*;
 import static com.oracle.graal.api.code.ValueUtil.*;
 import static com.oracle.graal.lir.LIRValueUtil.*;
+import static com.oracle.graal.phases.GraalOptions.*;
 
 import java.util.*;
 
@@ -38,7 +39,6 @@
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.StandardOp.MoveOp;
 import com.oracle.graal.nodes.cfg.*;
-import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.util.*;
 
 /**
@@ -297,7 +297,7 @@
         int optimalSplitPos = -1;
         if (minSplitPos == maxSplitPos) {
             // trivial case, no optimization of split position possible
-            if (GraalOptions.TraceLinearScanLevel >= 4) {
+            if (TraceLinearScanLevel.getValue() >= 4) {
                 TTY.println("      min-pos and max-pos are equal, no optimization possible");
             }
             optimalSplitPos = minSplitPos;
@@ -321,7 +321,7 @@
             assert minBlock.getLinearScanNumber() <= maxBlock.getLinearScanNumber() : "invalid order";
             if (minBlock == maxBlock) {
                 // split position cannot be moved to block boundary : so split as late as possible
-                if (GraalOptions.TraceLinearScanLevel >= 4) {
+                if (TraceLinearScanLevel.getValue() >= 4) {
                     TTY.println("      cannot move split pos to block boundary because minPos and maxPos are in same block");
                 }
                 optimalSplitPos = maxSplitPos;
@@ -333,14 +333,14 @@
                     // as mustHaveRegister) with a hole before each definition. When the register is
                     // needed
                     // for the second definition : an earlier reloading is unnecessary.
-                    if (GraalOptions.TraceLinearScanLevel >= 4) {
+                    if (TraceLinearScanLevel.getValue() >= 4) {
                         TTY.println("      interval has hole just before maxSplitPos, so splitting at maxSplitPos");
                     }
                     optimalSplitPos = maxSplitPos;
 
                 } else {
                     // seach optimal block boundary between minSplitPos and maxSplitPos
-                    if (GraalOptions.TraceLinearScanLevel >= 4) {
+                    if (TraceLinearScanLevel.getValue() >= 4) {
                         TTY.println("      moving split pos to optimal block boundary between block B%d and B%d", minBlock.getId(), maxBlock.getId());
                     }
 
@@ -349,7 +349,7 @@
                         // max-position :
                         // then split before this loop
                         int loopEndPos = interval.nextUsageExact(RegisterPriority.LiveAtLoopEnd, allocator.getLastLirInstructionId(minBlock) + 2);
-                        if (GraalOptions.TraceLinearScanLevel >= 4) {
+                        if (TraceLinearScanLevel.getValue() >= 4) {
                             TTY.println("      loop optimization: loop end found at pos %d", loopEndPos);
                         }
 
@@ -364,7 +364,7 @@
                             // of the interval (normally, only mustHaveRegister causes a reloading)
                             Block loopBlock = allocator.blockForId(loopEndPos);
 
-                            if (GraalOptions.TraceLinearScanLevel >= 4) {
+                            if (TraceLinearScanLevel.getValue() >= 4) {
                                 TTY.println("      interval is used in loop that ends in block B%d, so trying to move maxBlock back from B%d to B%d", loopBlock.getId(), maxBlock.getId(),
                                                 loopBlock.getId());
                             }
@@ -373,11 +373,11 @@
                             optimalSplitPos = findOptimalSplitPos(minBlock, loopBlock, allocator.getLastLirInstructionId(loopBlock) + 2);
                             if (optimalSplitPos == allocator.getLastLirInstructionId(loopBlock) + 2) {
                                 optimalSplitPos = -1;
-                                if (GraalOptions.TraceLinearScanLevel >= 4) {
+                                if (TraceLinearScanLevel.getValue() >= 4) {
                                     TTY.println("      loop optimization not necessary");
                                 }
                             } else {
-                                if (GraalOptions.TraceLinearScanLevel >= 4) {
+                                if (TraceLinearScanLevel.getValue() >= 4) {
                                     TTY.println("      loop optimization successful");
                                 }
                             }
@@ -391,7 +391,7 @@
                 }
             }
         }
-        if (GraalOptions.TraceLinearScanLevel >= 4) {
+        if (TraceLinearScanLevel.getValue() >= 4) {
             TTY.println("      optimal split position: %d", optimalSplitPos);
         }
 
@@ -403,13 +403,13 @@
     // 1) the left part has already a location assigned
     // 2) the right part is sorted into to the unhandled-list
     void splitBeforeUsage(Interval interval, int minSplitPos, int maxSplitPos) {
-        if (GraalOptions.TraceLinearScanLevel >= 2) {
+        if (TraceLinearScanLevel.getValue() >= 2) {
             TTY.println("----- splitting interval: ");
         }
-        if (GraalOptions.TraceLinearScanLevel >= 4) {
+        if (TraceLinearScanLevel.getValue() >= 4) {
             TTY.println(interval.logString(allocator));
         }
-        if (GraalOptions.TraceLinearScanLevel >= 2) {
+        if (TraceLinearScanLevel.getValue() >= 2) {
             TTY.println("      between %d and %d", minSplitPos, maxSplitPos);
         }
 
@@ -427,7 +427,7 @@
         if (optimalSplitPos == interval.to() && interval.nextUsage(RegisterPriority.MustHaveRegister, minSplitPos) == Integer.MAX_VALUE) {
             // the split position would be just before the end of the interval
             // . no split at all necessary
-            if (GraalOptions.TraceLinearScanLevel >= 4) {
+            if (TraceLinearScanLevel.getValue() >= 4) {
                 TTY.println("      no split necessary because optimal split position is at end of interval");
             }
             return;
@@ -442,7 +442,7 @@
             optimalSplitPos = (optimalSplitPos - 1) | 1;
         }
 
-        if (GraalOptions.TraceLinearScanLevel >= 4) {
+        if (TraceLinearScanLevel.getValue() >= 4) {
             TTY.println("      splitting at position %d", optimalSplitPos);
         }
         assert allocator.isBlockBegin(optimalSplitPos) || (optimalSplitPos % 2 == 1) : "split pos must be odd when not on block boundary";
@@ -455,10 +455,10 @@
         assert splitPart.from() >= currentInterval.currentFrom() : "cannot append new interval before current walk position";
         unhandledLists.addToListSortedByStartAndUsePositions(RegisterBinding.Any, splitPart);
 
-        if (GraalOptions.TraceLinearScanLevel >= 2) {
+        if (TraceLinearScanLevel.getValue() >= 2) {
             TTY.println("      split interval in two parts (insertMoveWhenActivated: %b)", moveNecessary);
         }
-        if (GraalOptions.TraceLinearScanLevel >= 2) {
+        if (TraceLinearScanLevel.getValue() >= 2) {
             TTY.print("      ");
             TTY.println(interval.logString(allocator));
             TTY.print("      ");
@@ -476,7 +476,7 @@
         int maxSplitPos = currentPosition;
         int minSplitPos = Math.max(interval.previousUsage(RegisterPriority.ShouldHaveRegister, maxSplitPos) + 1, interval.from());
 
-        if (GraalOptions.TraceLinearScanLevel >= 2) {
+        if (TraceLinearScanLevel.getValue() >= 2) {
             TTY.print("----- splitting and spilling interval: ");
             TTY.println(interval.logString(allocator));
             TTY.println("      between %d and %d", minSplitPos, maxSplitPos);
@@ -490,7 +490,7 @@
 
         if (minSplitPos == interval.from()) {
             // the whole interval is never used, so spill it entirely to memory
-            if (GraalOptions.TraceLinearScanLevel >= 2) {
+            if (TraceLinearScanLevel.getValue() >= 2) {
                 TTY.println("      spilling entire interval because split pos is at beginning of interval");
                 TTY.println("      use positions: " + interval.usePosList().size());
             }
@@ -509,7 +509,7 @@
                 if (isRegister(parent.location())) {
                     if (parent.firstUsage(RegisterPriority.ShouldHaveRegister) == Integer.MAX_VALUE) {
                         // parent is never used, so kick it out of its assigned register
-                        if (GraalOptions.TraceLinearScanLevel >= 4) {
+                        if (TraceLinearScanLevel.getValue() >= 4) {
                             TTY.println("      kicking out interval %d out of its register because it is never used", parent.operandNumber);
                         }
                         allocator.assignSpillSlot(parent);
@@ -534,7 +534,7 @@
                 optimalSplitPos = (optimalSplitPos - 1) | 1;
             }
 
-            if (GraalOptions.TraceLinearScanLevel >= 4) {
+            if (TraceLinearScanLevel.getValue() >= 4) {
                 TTY.println("      splitting at position %d", optimalSplitPos);
             }
             assert allocator.isBlockBegin(optimalSplitPos) || (optimalSplitPos % 2 == 1) : "split pos must be odd when not on block boundary";
@@ -545,7 +545,7 @@
             allocator.changeSpillState(spilledPart, optimalSplitPos);
 
             if (!allocator.isBlockBegin(optimalSplitPos)) {
-                if (GraalOptions.TraceLinearScanLevel >= 4) {
+                if (TraceLinearScanLevel.getValue() >= 4) {
                     TTY.println("      inserting move from interval %d to %d", interval.operandNumber, spilledPart.operandNumber);
                 }
                 insertMove(optimalSplitPos, interval, spilledPart);
@@ -555,7 +555,7 @@
             assert spilledPart.currentSplitChild() == interval : "overwriting wrong currentSplitChild";
             spilledPart.makeCurrentSplitChild();
 
-            if (GraalOptions.TraceLinearScanLevel >= 2) {
+            if (TraceLinearScanLevel.getValue() >= 2) {
                 TTY.println("      split interval in two parts");
                 TTY.print("      ");
                 TTY.println(interval.logString(allocator));
@@ -604,7 +604,7 @@
     }
 
     boolean allocFreeRegister(Interval interval) {
-        if (GraalOptions.TraceLinearScanLevel >= 2) {
+        if (TraceLinearScanLevel.getValue() >= 2) {
             TTY.println("trying to find free register for " + interval.logString(allocator));
         }
 
@@ -620,7 +620,7 @@
         // (either as a fixed register or a normal allocated register in the past)
         // only intervals overlapping with cur are processed, non-overlapping invervals can be
         // ignored safely
-        if (GraalOptions.TraceLinearScanLevel >= 4) {
+        if (TraceLinearScanLevel.getValue() >= 4) {
             TTY.println("      state of registers:");
             for (Register register : availableRegs) {
                 int i = register.number;
@@ -632,7 +632,7 @@
         Interval locationHint = interval.locationHint(true);
         if (locationHint != null && locationHint.location() != null && isRegister(locationHint.location())) {
             hint = asRegister(locationHint.location());
-            if (GraalOptions.TraceLinearScanLevel >= 4) {
+            if (TraceLinearScanLevel.getValue() >= 4) {
                 TTY.println("      hint register %d from interval %s", hint.number, locationHint.logString(allocator));
             }
         }
@@ -676,7 +676,7 @@
 
         splitPos = usePos[reg.number];
         interval.assignLocation(reg.asValue(interval.kind()));
-        if (GraalOptions.TraceLinearScanLevel >= 2) {
+        if (TraceLinearScanLevel.getValue() >= 2) {
             TTY.println("selected register %d", reg.number);
         }
 
@@ -702,7 +702,7 @@
 
     // Split an Interval and spill it to memory so that cur can be placed in a register
     void allocLockedRegister(Interval interval) {
-        if (GraalOptions.TraceLinearScanLevel >= 2) {
+        if (TraceLinearScanLevel.getValue() >= 2) {
             TTY.println("need to split and spill to get register for " + interval.logString(allocator));
         }
 
@@ -715,7 +715,7 @@
         spillCollectActiveAny();
         spillCollectInactiveAny(interval);
 
-        if (GraalOptions.TraceLinearScanLevel >= 4) {
+        if (TraceLinearScanLevel.getValue() >= 4) {
             TTY.println("      state of registers:");
             for (Register reg : availableRegs) {
                 int i = reg.number;
@@ -748,7 +748,7 @@
 
         if (reg == null || usePos[reg.number] <= firstUsage) {
             // the first use of cur is later than the spilling position -> spill cur
-            if (GraalOptions.TraceLinearScanLevel >= 4) {
+            if (TraceLinearScanLevel.getValue() >= 4) {
                 TTY.println("able to spill current interval. firstUsage(register): %d, usePos: %d", firstUsage, reg == null ? 0 : usePos[reg.number]);
             }
 
@@ -767,7 +767,7 @@
 
         int splitPos = blockPos[reg.number];
 
-        if (GraalOptions.TraceLinearScanLevel >= 4) {
+        if (TraceLinearScanLevel.getValue() >= 4) {
             TTY.println("decided to use register %d", reg.number);
         }
         assert splitPos > 0 : "invalid splitPos";
@@ -796,7 +796,7 @@
             if (isOdd(pos)) {
                 // the current instruction is a call that blocks all registers
                 if (pos < allocator.maxOpId() && allocator.hasCall(pos + 1) && interval.to() > pos + 1) {
-                    if (GraalOptions.TraceLinearScanLevel >= 4) {
+                    if (TraceLinearScanLevel.getValue() >= 4) {
                         TTY.println("      free register cannot be available because all registers blocked by following call");
                     }
 
@@ -888,11 +888,11 @@
         Interval interval = currentInterval;
         boolean result = true;
 
-        if (GraalOptions.TraceLinearScanLevel >= 2) {
+        if (TraceLinearScanLevel.getValue() >= 2) {
             TTY.println("+++++ activating interval " + interval.logString(allocator));
         }
 
-        if (GraalOptions.TraceLinearScanLevel >= 4) {
+        if (TraceLinearScanLevel.getValue() >= 4) {
             TTY.println("      splitParent: %s, insertMoveWhenActivated: %b", interval.splitParent().operandNumber, interval.insertMoveWhenActivated());
         }
 
@@ -901,7 +901,7 @@
             // activating an interval that has a stack slot assigned . split it at first use
             // position
             // used for method parameters
-            if (GraalOptions.TraceLinearScanLevel >= 4) {
+            if (TraceLinearScanLevel.getValue() >= 4) {
                 TTY.println("      interval has spill slot assigned (method parameter) . split it before first use");
             }
             splitStackInterval(interval);
@@ -911,7 +911,7 @@
             if (interval.location() == null) {
                 // interval has not assigned register . normal allocation
                 // (this is the normal case for most intervals)
-                if (GraalOptions.TraceLinearScanLevel >= 4) {
+                if (TraceLinearScanLevel.getValue() >= 4) {
                     TTY.println("      normal allocation of register");
                 }
 
@@ -937,7 +937,7 @@
             assert interval.isSplitChild();
             assert interval.currentSplitChild() != null;
             assert !interval.currentSplitChild().operand.equals(operand) : "cannot insert move between same interval";
-            if (GraalOptions.TraceLinearScanLevel >= 4) {
+            if (TraceLinearScanLevel.getValue() >= 4) {
                 TTY.println("Inserting move from interval %d to %d because insertMoveWhenActivated is set", interval.currentSplitChild().operandNumber, interval.operandNumber);
             }
 
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/MoveResolver.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/MoveResolver.java	Wed Jun 05 15:11:58 2013 +0200
@@ -23,6 +23,7 @@
 package com.oracle.graal.compiler.alloc;
 
 import static com.oracle.graal.api.code.ValueUtil.*;
+import static com.oracle.graal.phases.GraalOptions.*;
 
 import java.util.*;
 
@@ -30,7 +31,6 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.lir.*;
-import com.oracle.graal.phases.*;
 
 /**
  */
@@ -201,7 +201,7 @@
 
         insertionBuffer.append(insertIdx, allocator.ir.spillMoveFactory.createMove(toOpr, fromOpr));
 
-        if (GraalOptions.TraceLinearScanLevel >= 4) {
+        if (TraceLinearScanLevel.getValue() >= 4) {
             TTY.println("MoveResolver: inserted move from %d (%s) to %d (%s)", fromInterval.operandNumber, fromInterval.location(), toInterval.operandNumber, toInterval.location());
         }
     }
@@ -213,7 +213,7 @@
         AllocatableValue toOpr = toInterval.operand;
         insertionBuffer.append(insertIdx, allocator.ir.spillMoveFactory.createMove(toOpr, fromOpr));
 
-        if (GraalOptions.TraceLinearScanLevel >= 4) {
+        if (TraceLinearScanLevel.getValue() >= 4) {
             TTY.print("MoveResolver: inserted move from constant %s to %d (%s)", fromOpr, toInterval.operandNumber, toInterval.location());
         }
     }
@@ -285,7 +285,7 @@
                 }
                 spillInterval.assignLocation(spillSlot);
 
-                if (GraalOptions.TraceLinearScanLevel >= 4) {
+                if (TraceLinearScanLevel.getValue() >= 4) {
                     TTY.println("created new Interval %s for spilling", spillInterval.operand);
                 }
 
@@ -327,7 +327,7 @@
     }
 
     void addMapping(Interval fromInterval, Interval toInterval) {
-        if (GraalOptions.TraceLinearScanLevel >= 4) {
+        if (TraceLinearScanLevel.getValue() >= 4) {
             TTY.println("MoveResolver: adding mapping from interval %d (%s) to interval %d (%s)", fromInterval.operandNumber, fromInterval.location(), toInterval.operandNumber, toInterval.location());
         }
 
@@ -339,7 +339,7 @@
     }
 
     void addMapping(Value fromOpr, Interval toInterval) {
-        if (GraalOptions.TraceLinearScanLevel >= 4) {
+        if (TraceLinearScanLevel.getValue() >= 4) {
             TTY.println("MoveResolver: adding mapping from %s to %d (%s)", fromOpr, toInterval.operandNumber, toInterval.location());
         }
         assert isConstant(fromOpr) : "only for constants";
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/RegisterVerifier.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/RegisterVerifier.java	Wed Jun 05 15:11:58 2013 +0200
@@ -23,6 +23,7 @@
 package com.oracle.graal.compiler.alloc;
 
 import static com.oracle.graal.api.code.ValueUtil.*;
+import static com.oracle.graal.phases.GraalOptions.*;
 
 import java.util.*;
 
@@ -33,7 +34,6 @@
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.LIRInstruction.*;
 import com.oracle.graal.nodes.cfg.*;
-import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.util.*;
 
 /**
@@ -92,7 +92,7 @@
     }
 
     private void processBlock(Block block) {
-        if (GraalOptions.TraceLinearScanLevel >= 2) {
+        if (TraceLinearScanLevel.getValue() >= 2) {
             TTY.println();
             TTY.println("processBlock B%d", block.getId());
         }
@@ -100,7 +100,7 @@
         // must copy state because it is modified
         Interval[] inputState = copy(stateForBlock(block));
 
-        if (GraalOptions.TraceLinearScanLevel >= 4) {
+        if (TraceLinearScanLevel.getValue() >= 4) {
             TTY.println("Input-State of intervals:");
             TTY.print("    ");
             for (int i = 0; i < stateSize(); i++) {
@@ -142,7 +142,7 @@
                         savedStateCorrect = false;
                         savedState[i] = null;
 
-                        if (GraalOptions.TraceLinearScanLevel >= 4) {
+                        if (TraceLinearScanLevel.getValue() >= 4) {
                             TTY.println("processSuccessor B%d: invalidating slot %d", block.getId(), i);
                         }
                     }
@@ -151,12 +151,12 @@
 
             if (savedStateCorrect) {
                 // already processed block with correct inputState
-                if (GraalOptions.TraceLinearScanLevel >= 2) {
+                if (TraceLinearScanLevel.getValue() >= 2) {
                     TTY.println("processSuccessor B%d: previous visit already correct", block.getId());
                 }
             } else {
                 // must re-visit this block
-                if (GraalOptions.TraceLinearScanLevel >= 2) {
+                if (TraceLinearScanLevel.getValue() >= 2) {
                     TTY.println("processSuccessor B%d: must re-visit because input state changed", block.getId());
                 }
                 addToWorkList(block);
@@ -164,7 +164,7 @@
 
         } else {
             // block was not processed before, so set initial inputState
-            if (GraalOptions.TraceLinearScanLevel >= 2) {
+            if (TraceLinearScanLevel.getValue() >= 2) {
                 TTY.println("processSuccessor B%d: initial visit", block.getId());
             }
 
@@ -182,11 +182,11 @@
             Register reg = asRegister(location);
             int regNum = reg.number;
             if (interval != null) {
-                if (GraalOptions.TraceLinearScanLevel >= 4) {
+                if (TraceLinearScanLevel.getValue() >= 4) {
                     TTY.println("        %s = %s", reg, interval.operand);
                 }
             } else if (inputState[regNum] != null) {
-                if (GraalOptions.TraceLinearScanLevel >= 4) {
+                if (TraceLinearScanLevel.getValue() >= 4) {
                     TTY.println("        %s = null", reg);
                 }
             }
@@ -209,7 +209,7 @@
         for (int i = 0; i < ops.size(); i++) {
             final LIRInstruction op = ops.get(i);
 
-            if (GraalOptions.TraceLinearScanLevel >= 4) {
+            if (TraceLinearScanLevel.getValue() >= 4) {
                 TTY.println(op.toStringWithIdPrefix());
             }
 
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java	Wed Jun 05 15:11:58 2013 +0200
@@ -26,6 +26,7 @@
 import static com.oracle.graal.api.code.ValueUtil.*;
 import static com.oracle.graal.api.meta.Value.*;
 import static com.oracle.graal.lir.LIRValueUtil.*;
+import static com.oracle.graal.phases.GraalOptions.*;
 
 import java.util.*;
 import java.util.Map.Entry;
@@ -46,7 +47,6 @@
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.virtual.*;
-import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.util.*;
 
 /**
@@ -259,7 +259,7 @@
     }
 
     public void append(LIRInstruction op) {
-        if (GraalOptions.PrintIRWithLIR && !TTY.isSuppressed()) {
+        if (PrintIRWithLIR.getValue() && !TTY.isSuppressed()) {
             if (currentInstruction != null && lastInstructionPrinted != currentInstruction) {
                 lastInstructionPrinted = currentInstruction;
                 InstructionPrinter ip = new InstructionPrinter(TTY.out());
@@ -273,7 +273,7 @@
     }
 
     public void doBlock(Block block) {
-        if (GraalOptions.PrintIRWithLIR) {
+        if (PrintIRWithLIR.getValue()) {
             TTY.print(block.toString());
         }
 
@@ -284,7 +284,7 @@
 
         append(new LabelOp(new Label(), block.isAligned()));
 
-        if (GraalOptions.TraceLIRGeneratorLevel >= 1) {
+        if (TraceLIRGeneratorLevel.getValue() >= 1) {
             TTY.println("BEGIN Generating LIR for block B" + block.getId());
         }
 
@@ -315,12 +315,12 @@
                     }
                 }
             }
-            if (GraalOptions.TraceLIRGeneratorLevel >= 2) {
+            if (TraceLIRGeneratorLevel.getValue() >= 2) {
                 if (fs == null) {
                     TTY.println("STATE RESET");
                 } else {
                     TTY.println("STATE CHANGE (singlePred)");
-                    if (GraalOptions.TraceLIRGeneratorLevel >= 3) {
+                    if (TraceLIRGeneratorLevel.getValue() >= 3) {
                         TTY.println(fs.toString(Node.Verbosity.Debugger));
                     }
                 }
@@ -331,7 +331,7 @@
         List<ScheduledNode> nodes = lir.nodesFor(block);
         for (int i = 0; i < nodes.size(); i++) {
             Node instr = nodes.get(i);
-            if (GraalOptions.TraceLIRGeneratorLevel >= 3) {
+            if (TraceLIRGeneratorLevel.getValue() >= 3) {
                 TTY.println("LIRGen for " + instr);
             }
             FrameState stateAfter = null;
@@ -358,9 +358,9 @@
             if (stateAfter != null) {
                 lastState = stateAfter;
                 assert checkStateReady(lastState);
-                if (GraalOptions.TraceLIRGeneratorLevel >= 2) {
+                if (TraceLIRGeneratorLevel.getValue() >= 2) {
                     TTY.println("STATE CHANGE");
-                    if (GraalOptions.TraceLIRGeneratorLevel >= 3) {
+                    if (TraceLIRGeneratorLevel.getValue() >= 3) {
                         TTY.println(stateAfter.toString(Node.Verbosity.Debugger));
                     }
                 }
@@ -373,7 +373,7 @@
             emitJump(getLIRBlock((FixedNode) successors.first()));
         }
 
-        if (GraalOptions.TraceLIRGeneratorLevel >= 1) {
+        if (TraceLIRGeneratorLevel.getValue() >= 1) {
             TTY.println("END Generating LIR for block B" + block.getId());
         }
 
@@ -384,7 +384,7 @@
         blockLastState.put(block, lastState);
         currentBlock = null;
 
-        if (GraalOptions.PrintIRWithLIR) {
+        if (PrintIRWithLIR.getValue()) {
             TTY.println();
         }
     }
@@ -414,7 +414,7 @@
     }
 
     private void doRoot(ValueNode instr) {
-        if (GraalOptions.TraceLIRGeneratorLevel >= 2) {
+        if (TraceLIRGeneratorLevel.getValue() >= 2) {
             TTY.println("Emitting LIR for instruction " + instr);
         }
         currentInstruction = instr;
@@ -484,7 +484,7 @@
     }
 
     private void moveToPhi(MergeNode merge, AbstractEndNode pred) {
-        if (GraalOptions.TraceLIRGeneratorLevel >= 1) {
+        if (TraceLIRGeneratorLevel.getValue() >= 1) {
             TTY.println("MOVE TO PHI from " + pred + " to " + merge);
         }
         PhiResolver resolver = new PhiResolver(this);
@@ -660,7 +660,7 @@
 
     @Override
     public Variable emitForeignCall(ForeignCallLinkage linkage, DeoptimizingNode info, Value... args) {
-        LIRFrameState state = info != null ? state(info) : null;
+        LIRFrameState state = !linkage.canDeoptimize() ? null : stateFor(info.getDeoptimizationState(), info.getDeoptimizationReason());
 
         // move the arguments into the correct location
         CallingConvention linkageCc = linkage.getCallingConvention();
@@ -707,7 +707,7 @@
                 int switchRangeCount = switchRangeCount(x);
                 if (switchRangeCount == 0) {
                     emitJump(getLIRBlock(x.defaultSuccessor()));
-                } else if (switchRangeCount >= GraalOptions.MinimumJumpTableSize && keyCount / (double) valueRange >= GraalOptions.MinTableSwitchDensity) {
+                } else if (switchRangeCount >= MinimumJumpTableSize.getValue() && keyCount / (double) valueRange >= MinTableSwitchDensity.getValue()) {
                     int minValue = x.keyAt(0).asInt();
                     assert valueRange < Integer.MAX_VALUE;
                     LabelRef[] targets = new LabelRef[(int) valueRange];
@@ -718,7 +718,7 @@
                         targets[x.keyAt(i).asInt() - minValue] = getLIRBlock(x.keySuccessor(i));
                     }
                     emitTableSwitch(minValue, defaultTarget, targets, value);
-                } else if (keyCount / switchRangeCount >= GraalOptions.RangeTestsSwitchDensity) {
+                } else if (keyCount / switchRangeCount >= RangeTestsSwitchDensity.getValue()) {
                     emitSwitchRanges(x, switchRangeCount, value, defaultTarget);
                 } else {
                     emitSequentialSwitch(x, value, defaultTarget);
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java	Wed Jun 05 15:11:58 2013 +0200
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.compiler.phases;
 
+import static com.oracle.graal.phases.GraalOptions.*;
+
 import com.oracle.graal.loop.phases.*;
 import com.oracle.graal.nodes.spi.Lowerable.LoweringType;
 import com.oracle.graal.phases.*;
@@ -32,35 +34,35 @@
 public class HighTier extends PhaseSuite<HighTierContext> {
 
     public HighTier() {
-        if (GraalOptions.FullUnroll) {
+        if (FullUnroll.getValue()) {
             addPhase(new LoopFullUnrollPhase());
         }
 
-        if (GraalOptions.OptTailDuplication) {
+        if (OptTailDuplication.getValue()) {
             addPhase(new TailDuplicationPhase());
         }
 
-        if (GraalOptions.PartialEscapeAnalysis) {
-            addPhase(new PartialEscapeAnalysisPhase(true, GraalOptions.OptEarlyReadElimination));
+        if (PartialEscapeAnalysis.getValue()) {
+            addPhase(new PartialEscapeAnalysisPhase(true, OptEarlyReadElimination.getValue()));
         }
 
-        if (GraalOptions.OptConvertDeoptsToGuards) {
+        if (OptConvertDeoptsToGuards.getValue()) {
             addPhase(new ConvertDeoptimizeToGuardPhase());
         }
 
         addPhase(new LockEliminationPhase());
 
-        if (GraalOptions.OptLoopTransform) {
+        if (OptLoopTransform.getValue()) {
             addPhase(new LoopTransformHighPhase());
             addPhase(new LoopTransformLowPhase());
         }
         addPhase(new RemoveValueProxyPhase());
 
-        if (GraalOptions.CullFrameStates) {
+        if (CullFrameStates.getValue()) {
             addPhase(new CullFrameStatesPhase());
         }
 
-        if (GraalOptions.OptCanonicalizer) {
+        if (OptCanonicalizer.getValue()) {
             addPhase(new CanonicalizerPhase());
         }
 
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/MidTier.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/MidTier.java	Wed Jun 05 15:11:58 2013 +0200
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.compiler.phases;
 
+import static com.oracle.graal.phases.GraalOptions.*;
+
 import com.oracle.graal.loop.phases.*;
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.common.*;
@@ -30,40 +32,40 @@
 public class MidTier extends PhaseSuite<MidTierContext> {
 
     public MidTier() {
-        if (GraalOptions.OptPushThroughPi) {
+        if (OptPushThroughPi.getValue()) {
             addPhase(new PushThroughPiPhase());
-            if (GraalOptions.OptCanonicalizer) {
+            if (OptCanonicalizer.getValue()) {
                 addPhase(new CanonicalizerPhase());
             }
         }
 
-        if (GraalOptions.OptFloatingReads) {
+        if (OptFloatingReads.getValue()) {
             IncrementalCanonicalizerPhase<MidTierContext> canonicalizer = new IncrementalCanonicalizerPhase<>();
             canonicalizer.addPhase(new FloatingReadPhase());
             addPhase(canonicalizer);
-            if (GraalOptions.OptReadElimination) {
+            if (OptReadElimination.getValue()) {
                 addPhase(new ReadEliminationPhase());
             }
         }
         addPhase(new RemoveValueProxyPhase());
 
-        if (GraalOptions.OptCanonicalizer) {
+        if (OptCanonicalizer.getValue()) {
             addPhase(new CanonicalizerPhase());
         }
 
-        if (GraalOptions.OptEliminatePartiallyRedundantGuards) {
+        if (OptEliminatePartiallyRedundantGuards.getValue()) {
             addPhase(new EliminatePartiallyRedundantGuardsPhase(false, true));
         }
 
-        if (GraalOptions.ConditionalElimination && GraalOptions.OptCanonicalizer) {
+        if (ConditionalElimination.getValue() && OptCanonicalizer.getValue()) {
             addPhase(new IterativeConditionalEliminationPhase());
         }
 
-        if (GraalOptions.OptEliminatePartiallyRedundantGuards) {
+        if (OptEliminatePartiallyRedundantGuards.getValue()) {
             addPhase(new EliminatePartiallyRedundantGuardsPhase(true, true));
         }
 
-        if (GraalOptions.OptCanonicalizer) {
+        if (OptCanonicalizer.getValue()) {
             addPhase(new CanonicalizerPhase());
         }
 
@@ -73,7 +75,7 @@
 
         addPhase(new GuardLoweringPhase());
 
-        if (GraalOptions.OptCanonicalizer) {
+        if (OptCanonicalizer.getValue()) {
             addPhase(new CanonicalizerPhase());
         }
     }
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64DeoptimizeOp.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64DeoptimizeOp.java	Wed Jun 05 15:11:58 2013 +0200
@@ -30,7 +30,6 @@
 import com.oracle.graal.asm.amd64.*;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.LIRInstruction.Opcode;
 import com.oracle.graal.lir.amd64.*;
 import com.oracle.graal.lir.asm.*;
 
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java	Wed Jun 05 15:11:58 2013 +0200
@@ -50,7 +50,6 @@
 import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.cfg.*;
-import com.oracle.graal.phases.*;
 
 /**
  * HotSpot AMD64 specific backend.
@@ -75,7 +74,7 @@
      *            the current frame
      */
     protected static void emitStackOverflowCheck(TargetMethodAssembler tasm, boolean afterFrameInit) {
-        if (GraalOptions.StackShadowPages > 0) {
+        if (StackShadowPages.getValue() > 0) {
 
             AMD64MacroAssembler asm = (AMD64MacroAssembler) tasm.asm;
             int frameSize = tasm.frameMap.frameSize();
@@ -83,7 +82,7 @@
                 int lastFramePage = frameSize / unsafe.pageSize();
                 // emit multiple stack bangs for methods with frames larger than a page
                 for (int i = 0; i <= lastFramePage; i++) {
-                    int disp = (i + GraalOptions.StackShadowPages) * unsafe.pageSize();
+                    int disp = (i + StackShadowPages.getValue()) * unsafe.pageSize();
                     if (afterFrameInit) {
                         disp -= frameSize;
                     }
@@ -112,7 +111,7 @@
                 emitStackOverflowCheck(tasm, false);
             }
             asm.decrementq(rsp, frameSize);
-            if (GraalOptions.ZapStackOnMethodEntry) {
+            if (ZapStackOnMethodEntry.getValue()) {
                 final int intSize = 4;
                 for (int i = 0; i < frameSize / intSize; ++i) {
                     asm.movl(new AMD64Address(rsp, i * intSize), 0xC1C1C1C1);
@@ -158,7 +157,7 @@
         AMD64HotSpotLIRGenerator gen = (AMD64HotSpotLIRGenerator) lirGen;
         FrameMap frameMap = gen.frameMap;
         LIR lir = gen.lir;
-        boolean omitFrame = CanOmitFrame && !frameMap.frameNeedsAllocating() && !lir.hasArgInCallerFrame();
+        boolean omitFrame = CanOmitFrame.getValue() && !frameMap.frameNeedsAllocating() && !lir.hasArgInCallerFrame();
 
         Stub stub = gen.getStub();
         AbstractAssembler masm = createAssembler(frameMap);
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCRuntimeCallEpilogueOp.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCRuntimeCallEpilogueOp.java	Wed Jun 05 15:11:58 2013 +0200
@@ -27,7 +27,7 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.asm.amd64.*;
 import com.oracle.graal.hotspot.*;
-import com.oracle.graal.lir.LIRInstruction.Opcode;
+import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.amd64.*;
 import com.oracle.graal.lir.asm.*;
 
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCRuntimeCallPrologueOp.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCRuntimeCallPrologueOp.java	Wed Jun 05 15:11:58 2013 +0200
@@ -27,11 +27,11 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.asm.amd64.*;
-import com.oracle.graal.lir.LIRInstruction.Opcode;
+import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.amd64.*;
 import com.oracle.graal.lir.asm.*;
 
-@Opcode("CRUNTIME_CALL_PROLOGUE")
+@Opcode
 final class AMD64HotSpotCRuntimeCallPrologueOp extends AMD64LIRInstruction {
 
     @Override
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotDeoptimizeCallerOp.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotDeoptimizeCallerOp.java	Wed Jun 05 15:11:58 2013 +0200
@@ -29,7 +29,7 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.amd64.*;
 import com.oracle.graal.hotspot.*;
-import com.oracle.graal.lir.LIRInstruction.Opcode;
+import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.amd64.*;
 import com.oracle.graal.lir.asm.*;
 
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotJumpToExceptionHandlerInCallerOp.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotJumpToExceptionHandlerInCallerOp.java	Wed Jun 05 15:11:58 2013 +0200
@@ -31,7 +31,7 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.amd64.*;
 import com.oracle.graal.asm.amd64.AMD64Assembler.ConditionFlag;
-import com.oracle.graal.lir.LIRInstruction.Opcode;
+import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
 
 /**
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Wed Jun 05 15:11:58 2013 +0200
@@ -220,8 +220,7 @@
     @Override
     public Variable emitForeignCall(ForeignCallLinkage linkage, DeoptimizingNode info, Value... args) {
         Stub stub = getStub();
-        HotSpotForeignCallLinkage hsLinkage = (HotSpotForeignCallLinkage) linkage;
-        boolean destroysRegisters = hsLinkage.destroysRegisters();
+        boolean destroysRegisters = linkage.destroysRegisters();
 
         AMD64SaveRegistersOp save = null;
         StackSlot[] savedRegisterLocations = null;
@@ -243,7 +242,7 @@
 
         Variable result;
 
-        if (!hsLinkage.isLeaf()) {
+        if (linkage.canDeoptimize()) {
             assert info != null;
             append(new AMD64HotSpotCRuntimeCallPrologueOp());
             result = super.emitForeignCall(linkage, info, args);
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotPatchReturnAddressOp.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotPatchReturnAddressOp.java	Wed Jun 05 15:11:58 2013 +0200
@@ -28,7 +28,7 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.amd64.*;
-import com.oracle.graal.lir.LIRInstruction.Opcode;
+import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.amd64.*;
 import com.oracle.graal.lir.asm.*;
 
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRegisterConfig.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRegisterConfig.java	Wed Jun 05 15:11:58 2013 +0200
@@ -23,6 +23,7 @@
 package com.oracle.graal.hotspot.amd64;
 
 import static com.oracle.graal.amd64.AMD64.*;
+import static com.oracle.graal.phases.GraalOptions.*;
 
 import java.util.*;
 
@@ -32,7 +33,6 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.*;
-import com.oracle.graal.phases.*;
 
 public class AMD64HotSpotRegisterConfig implements RegisterConfig {
 
@@ -104,8 +104,8 @@
         }
        // @formatter:on
 
-        if (GraalOptions.RegisterPressure != null) {
-            String[] names = GraalOptions.RegisterPressure.split(",");
+        if (RegisterPressure.getValue() != null) {
+            String[] names = RegisterPressure.getValue().split(",");
             Register[] regs = new Register[names.length];
             for (int i = 0; i < names.length; i++) {
                 regs[i] = findRegister(names[i], registers);
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotReturnOp.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotReturnOp.java	Wed Jun 05 15:11:58 2013 +0200
@@ -26,7 +26,7 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.amd64.*;
-import com.oracle.graal.lir.LIRInstruction.Opcode;
+import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
 
 /**
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotUnwindOp.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotUnwindOp.java	Wed Jun 05 15:11:58 2013 +0200
@@ -31,7 +31,7 @@
 import com.oracle.graal.asm.amd64.*;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.stubs.*;
-import com.oracle.graal.lir.LIRInstruction.Opcode;
+import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.amd64.*;
 import com.oracle.graal.lir.asm.*;
 
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotspotDirectStaticCallOp.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotspotDirectStaticCallOp.java	Wed Jun 05 15:11:58 2013 +0200
@@ -27,7 +27,6 @@
 import com.oracle.graal.asm.amd64.*;
 import com.oracle.graal.hotspot.bridge.*;
 import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.LIRInstruction.Opcode;
 import com.oracle.graal.lir.amd64.*;
 import com.oracle.graal.lir.amd64.AMD64Call.DirectCallOp;
 import com.oracle.graal.lir.asm.*;
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotspotDirectVirtualCallOp.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotspotDirectVirtualCallOp.java	Wed Jun 05 15:11:58 2013 +0200
@@ -29,7 +29,6 @@
 import com.oracle.graal.asm.amd64.*;
 import com.oracle.graal.hotspot.bridge.*;
 import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.LIRInstruction.Opcode;
 import com.oracle.graal.lir.amd64.*;
 import com.oracle.graal.lir.amd64.AMD64Call.DirectCallOp;
 import com.oracle.graal.lir.asm.*;
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64IndirectCallOp.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64IndirectCallOp.java	Wed Jun 05 15:11:58 2013 +0200
@@ -31,7 +31,6 @@
 import com.oracle.graal.asm.amd64.*;
 import com.oracle.graal.hotspot.bridge.*;
 import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.LIRInstruction.Opcode;
 import com.oracle.graal.lir.amd64.*;
 import com.oracle.graal.lir.amd64.AMD64Call.IndirectCallOp;
 import com.oracle.graal.lir.asm.*;
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64SafepointOp.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64SafepointOp.java	Wed Jun 05 15:11:58 2013 +0200
@@ -32,7 +32,6 @@
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.bridge.*;
 import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.LIRInstruction.Opcode;
 import com.oracle.graal.lir.amd64.*;
 import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.nodes.spi.*;
@@ -59,7 +58,7 @@
     @Override
     public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler asm) {
         int pos = asm.codeBuffer.position();
-        int offset = SafepointPollOffset % unsafe.pageSize();
+        int offset = SafepointPollOffset.getValue() % unsafe.pageSize();
         RegisterValue scratch = (RegisterValue) temp;
         if (config.isPollingPageFar) {
             asm.movq(scratch.getRegister(), config.safepointPollingAddress + offset);
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64TailcallOp.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64TailcallOp.java	Wed Jun 05 15:11:58 2013 +0200
@@ -27,7 +27,7 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.amd64.*;
-import com.oracle.graal.lir.LIRInstruction.Opcode;
+import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.amd64.*;
 import com.oracle.graal.lir.asm.*;
 
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java	Wed Jun 05 15:11:58 2013 +0200
@@ -77,7 +77,7 @@
         SPARCHotSpotLIRGenerator gen = (SPARCHotSpotLIRGenerator) lirGen;
         FrameMap frameMap = gen.frameMap;
         LIR lir = gen.lir;
-        boolean omitFrame = CanOmitFrame && !frameMap.frameNeedsAllocating() && !lir.hasArgInCallerFrame();
+        boolean omitFrame = CanOmitFrame.getValue() && !frameMap.frameNeedsAllocating() && !lir.hasArgInCallerFrame();
 
         Stub stub = gen.getStub();
         AbstractAssembler masm = createAssembler(frameMap);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java	Wed Jun 05 15:11:58 2013 +0200
@@ -24,6 +24,7 @@
 
 import static com.oracle.graal.api.code.CodeUtil.*;
 import static com.oracle.graal.nodes.StructuredGraph.*;
+import static com.oracle.graal.phases.GraalOptions.*;
 
 import java.lang.reflect.*;
 import java.util.concurrent.*;
@@ -114,7 +115,7 @@
                 return;
             }
             inProgress = true;
-            if (GraalOptions.DynamicCompilePriority) {
+            if (DynamicCompilePriority.getValue()) {
                 int threadPriority = priority < SlowQueueCutoff.getValue() ? Thread.NORM_PRIORITY : Thread.MIN_PRIORITY;
                 if (Thread.currentThread().getPriority() != threadPriority) {
                     Thread.currentThread().setPriority(threadPriority);
@@ -139,17 +140,17 @@
     public void runCompilation() {
         CompilationStatistics stats = CompilationStatistics.create(method, entryBCI != StructuredGraph.INVOCATION_ENTRY_BCI);
         try (TimerCloseable a = CompilationTime.start()) {
-            final boolean printCompilation = GraalOptions.PrintCompilation && !TTY.isSuppressed();
+            final boolean printCompilation = PrintCompilation.getValue() && !TTY.isSuppressed();
             if (printCompilation) {
                 TTY.println(String.format("%-6d Graal %-70s %-45s %-50s %s...", id, method.getDeclaringClass().getName(), method.getName(), method.getSignature(),
                                 entryBCI == StructuredGraph.INVOCATION_ENTRY_BCI ? "" : "(OSR@" + entryBCI + ") "));
             }
-            if (GraalOptions.HotSpotPrintCompilation) {
+            if (HotSpotPrintCompilation.getValue()) {
                 printCompilation();
             }
 
             CompilationResult result = null;
-            TTY.Filter filter = new TTY.Filter(GraalOptions.PrintFilter, method);
+            TTY.Filter filter = new TTY.Filter(PrintFilter.getValue(), method);
             long start = System.currentTimeMillis();
             try {
                 result = Debug.scope("Compiling", new DebugDumpScope(String.valueOf(id), true), new Callable<CompilationResult>() {
@@ -182,19 +183,19 @@
             installMethod(result);
         } catch (BailoutException bailout) {
             Debug.metric("Bailouts").increment();
-            if (GraalOptions.ExitVMOnBailout) {
+            if (ExitVMOnBailout.getValue()) {
                 TTY.cachedOut.println(MetaUtil.format("Bailout in %H.%n(%p)", method));
                 bailout.printStackTrace(TTY.cachedOut);
                 System.exit(-1);
-            } else if (GraalOptions.PrintBailout) {
+            } else if (PrintBailout.getValue()) {
                 TTY.cachedOut.println(MetaUtil.format("Bailout in %H.%n(%p)", method));
                 bailout.printStackTrace(TTY.cachedOut);
             }
         } catch (Throwable t) {
-            if (GraalOptions.PrintStackTraceOnException || GraalOptions.ExitVMOnException) {
+            if (PrintStackTraceOnException.getValue() || ExitVMOnException.getValue()) {
                 t.printStackTrace(TTY.cachedOut);
             }
-            if (GraalOptions.ExitVMOnException) {
+            if (ExitVMOnException.getValue()) {
                 System.exit(-1);
             }
         }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompileTheWorld.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompileTheWorld.java	Wed Jun 05 15:11:58 2013 +0200
@@ -23,6 +23,7 @@
 package com.oracle.graal.hotspot;
 
 import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
+import static com.oracle.graal.phases.GraalOptions.*;
 
 import java.io.File;
 import java.lang.reflect.Constructor;
@@ -75,7 +76,7 @@
      * {@link GraalOptions#CompileTheWorldStopAt}.
      */
     public CompileTheWorld() {
-        this(GraalOptions.CompileTheWorld, GraalOptions.CompileTheWorldStartAt, GraalOptions.CompileTheWorldStopAt);
+        this(CompileTheWorld.getValue(), CompileTheWorldStartAt.getValue(), CompileTheWorldStopAt.getValue());
     }
 
     /**
@@ -91,7 +92,7 @@
         this.stopAt = stopAt;
 
         // We don't want the VM to exit when a method fails to compile.
-        GraalOptions.ExitVMOnException = false;
+        ExitVMOnException.setValue(false);
     }
 
     /**
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotForeignCallLinkage.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotForeignCallLinkage.java	Wed Jun 05 15:11:58 2013 +0200
@@ -107,7 +107,7 @@
      * @param effect specifies if the call destroys or preserves all registers (apart from
      *            temporaries which are always destroyed)
      * @param ccType calling convention type
-     * @param transition specifies if this is a {@linkplain #isLeaf() leaf} call
+     * @param transition specifies if this is a {@linkplain #canDeoptimize() leaf} call
      * @param reexecutable specifies if the call can be re-executed without (meaningful) side
      *            effects. Deoptimization will not return to a point before a call that cannot be
      *            re-executed.
@@ -235,11 +235,8 @@
         return effect == DESTROYS_REGISTERS;
     }
 
-    /**
-     * Determines if this is call to a function that does not lock, GC or throw exceptions. That is,
-     * the thread's execution state during the call is never inspected by another thread.
-     */
-    public boolean isLeaf() {
-        return transition == Transition.LEAF;
+    @Override
+    public boolean canDeoptimize() {
+        return transition != Transition.LEAF;
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java	Wed Jun 05 15:11:58 2013 +0200
@@ -23,6 +23,7 @@
 package com.oracle.graal.hotspot;
 
 import static com.oracle.graal.graph.UnsafeAccess.*;
+//import static com.oracle.graal.phases.GraalOptions.*;
 
 import java.lang.reflect.*;
 import java.util.*;
@@ -35,6 +36,7 @@
 import com.oracle.graal.hotspot.logging.*;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.options.*;
 import com.oracle.graal.phases.*;
 
 /**
@@ -84,9 +86,14 @@
         runtime.compilerToVm = toVM;
     }
 
+    // @formatter:off
+    @Option(help = "The runtime configuration to use")
+    private static final OptionValue<String> GraalRuntime = new OptionValue<>("basic");
+    // @formatter:on
+
     protected static HotSpotGraalRuntimeFactory findFactory(String architecture) {
         for (HotSpotGraalRuntimeFactory factory : ServiceLoader.loadInstalled(HotSpotGraalRuntimeFactory.class)) {
-            if (factory.getArchitecture().equals(architecture) && factory.getName().equals(GraalOptions.GraalRuntime)) {
+            if (factory.getArchitecture().equals(architecture) && factory.getName().equals(GraalRuntime.getValue())) {
                 return factory;
             }
         }
@@ -123,9 +130,9 @@
         return unsafe.getInt(object, offset);
     }
 
-    protected/* final */CompilerToVM  compilerToVm;
+    protected/* final */CompilerToVM compilerToVm;
     protected/* final */CompilerToGPU compilerToGpu;
-    protected/* final */VMToCompiler  vmToCompiler;
+    protected/* final */VMToCompiler vmToCompiler;
 
     protected final HotSpotRuntime runtime;
     protected final TargetDescription target;
@@ -138,13 +145,13 @@
     private final HotSpotBackend backend;
 
     protected HotSpotGraalRuntime() {
-        CompilerToVM  toVM  = new CompilerToVMImpl();
+        CompilerToVM toVM = new CompilerToVMImpl();
         CompilerToGPU toGPU = new CompilerToGPUImpl();
 
         // initialize VmToCompiler
         VMToCompiler toCompiler = new VMToCompilerImpl(this);
 
-        compilerToVm  = toVM;
+        compilerToVm = toVM;
         compilerToGpu = toGPU;
         vmToCompiler = toCompiler;
         config = new HotSpotVMConfig();
@@ -153,16 +160,16 @@
 
         // Set some global options:
         if (config.compileTheWorld) {
-            GraalOptions.CompileTheWorld = CompileTheWorld.SUN_BOOT_CLASS_PATH;
+            GraalOptions.CompileTheWorld.setValue(CompileTheWorld.SUN_BOOT_CLASS_PATH);
         }
         if (config.compileTheWorldStartAt != 1) {
-            GraalOptions.CompileTheWorldStartAt = config.compileTheWorldStartAt;
+            GraalOptions.CompileTheWorldStartAt.setValue(config.compileTheWorldStartAt);
         }
         if (config.compileTheWorldStopAt != Integer.MAX_VALUE) {
-            GraalOptions.CompileTheWorldStopAt = config.compileTheWorldStopAt;
+            GraalOptions.CompileTheWorldStopAt.setValue(config.compileTheWorldStopAt);
         }
-        GraalOptions.HotSpotPrintCompilation = config.printCompilation;
-        GraalOptions.HotSpotPrintInlining = config.printInlining;
+        GraalOptions.HotSpotPrintCompilation.setValue(config.printCompilation);
+        GraalOptions.HotSpotPrintInlining.setValue(config.printInlining);
 
         if (Boolean.valueOf(System.getProperty("graal.printconfig"))) {
             printConfig(config);
@@ -180,8 +187,8 @@
         replacements = new HotSpotReplacementsImpl(runtime, assumptions, runtime.getGraalRuntime().getTarget());
 
         backend = createBackend();
-        GraalOptions.StackShadowPages = config.stackShadowPages;
-        if (GraalOptions.CacheGraphs) {
+        GraalOptions.StackShadowPages.setValue(config.stackShadowPages);
+        if (GraalOptions.CacheGraphs.getValue()) {
             cache = new HotSpotGraphCache();
         }
     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotOptions.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotOptions.java	Wed Jun 05 15:11:58 2013 +0200
@@ -23,12 +23,10 @@
 
 package com.oracle.graal.hotspot;
 
-import java.lang.reflect.*;
 import java.util.*;
 
 import com.oracle.graal.hotspot.logging.*;
 import com.oracle.graal.options.*;
-import com.oracle.graal.phases.*;
 
 public class HotSpotOptions {
 
@@ -37,8 +35,10 @@
     static {
         ServiceLoader<OptionProvider> sl = ServiceLoader.loadInstalled(OptionProvider.class);
         for (OptionProvider provider : sl) {
-            String name = provider.getName();
-            options.put(name, provider);
+            if (provider.getClass().getName().startsWith("com.oracle.graal")) {
+                String name = provider.getName();
+                options.put(name, provider);
+            }
         }
     }
 
@@ -74,7 +74,8 @@
 
         OptionProvider optionProvider = options.get(fieldName);
         if (optionProvider == null) {
-            return setOptionLegacy(option, fieldName, value, valueString);
+            Logger.info("Could not find option " + fieldName + " (use -G:+PrintFlags to see Graal options)");
+            return false;
         }
 
         Class<?> optionType = optionProvider.getType();
@@ -117,66 +118,6 @@
         return true;
     }
 
-    private static boolean setOptionLegacy(String option, String fieldName, Object v, String valueString) {
-        Object value = v;
-        Field f;
-        try {
-            f = GraalOptions.class.getDeclaredField(fieldName);
-            Class<?> fType = f.getType();
-
-            if (value == null) {
-                if (fType == Boolean.TYPE) {
-                    Logger.info("Value for boolean option '" + fieldName + "' must use '-G:+" + fieldName + "' or '-G:-" + fieldName + "' format");
-                    return false;
-                }
-
-                if (valueString == null) {
-                    Logger.info("Value for option '" + fieldName + "' must use '-G:" + fieldName + "=<value>' format");
-                    return false;
-                }
-
-                if (fType == Float.TYPE) {
-                    value = Float.parseFloat(valueString);
-                } else if (fType == Double.TYPE) {
-                    value = Double.parseDouble(valueString);
-                } else if (fType == Integer.TYPE) {
-                    value = Integer.parseInt(valueString);
-                } else if (fType == String.class) {
-                    value = valueString;
-                }
-            } else {
-                if (fType != Boolean.TYPE) {
-                    Logger.info("Value for option '" + fieldName + "' must use '-G:" + fieldName + "=<value>' format");
-                    return false;
-                }
-            }
-
-            if (value != null) {
-                f.setAccessible(true);
-                f.set(null, value);
-                // Logger.info("Set option " + fieldName + " to " + value);
-            } else {
-                Logger.info("Wrong value \"" + valueString + "\" for option " + fieldName);
-                return false;
-            }
-        } catch (SecurityException e) {
-            Logger.info("Security exception when setting option " + option);
-            return false;
-        } catch (NoSuchFieldException e) {
-            Logger.info("Could not find option " + fieldName + " (use -G:+PrintFlags to see Graal options)");
-            return false;
-        } catch (IllegalArgumentException e) {
-            Logger.info("Illegal value for option " + option);
-            return false;
-        } catch (IllegalAccessException e) {
-            Logger.info("Illegal access exception when setting option " + option);
-            return false;
-        }
-
-        return true;
-
-    }
-
     private static void printFlags() {
         Logger.info("[Graal flags]");
         SortedMap<String, OptionProvider> sortedOptions = new TreeMap<>(options);
@@ -187,28 +128,6 @@
             Logger.info(String.format("%9s %-40s = %-14s %s", opt.getType().getSimpleName(), e.getKey(), value, opt.getHelp()));
         }
 
-        printFlagsLegacy();
-
         System.exit(0);
     }
-
-    protected static void printFlagsLegacy() {
-        Field[] flags = GraalOptions.class.getDeclaredFields();
-        Arrays.sort(flags, new Comparator<Field>() {
-
-            public int compare(Field o1, Field o2) {
-                return o1.getName().compareTo(o2.getName());
-            }
-        });
-        for (Field f : flags) {
-            if (Modifier.isPublic(f.getModifiers()) && Modifier.isStatic(f.getModifiers())) {
-                f.setAccessible(true);
-                try {
-                    Object value = f.get(null);
-                    Logger.info(String.format("%9s %-40s = %s", f.getType().getSimpleName(), f.getName(), value));
-                } catch (Exception e) {
-                }
-            }
-        }
-    }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java	Wed Jun 05 15:11:58 2013 +0200
@@ -28,6 +28,7 @@
 import static com.oracle.graal.hotspot.CompilationTask.*;
 import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
 import static com.oracle.graal.java.GraphBuilderPhase.*;
+import static com.oracle.graal.phases.GraalOptions.*;
 
 import java.io.*;
 import java.lang.reflect.*;
@@ -75,7 +76,7 @@
     private static final OptionValue<Integer> TimedBootstrap = new OptionValue<>(-1);
 
     @Option(help = "Number of compilation threads to use")
-    private static final OptionValue<Integer> Threads = new OptionValue<Integer>(1) {
+    private static final OptionValue<Integer> Threads = new OptionValue<Integer>() {
 
         @Override
         public Integer initialValue() {
@@ -181,7 +182,7 @@
         // Install intrinsics.
         final HotSpotRuntime runtime = graalRuntime.getCapability(HotSpotRuntime.class);
         final Replacements replacements = graalRuntime.getCapability(Replacements.class);
-        if (GraalOptions.Intrinsify) {
+        if (Intrinsify.getValue()) {
             Debug.scope("RegisterReplacements", new Object[]{new DebugDumpScope("RegisterReplacements")}, new Runnable() {
 
                 @Override
@@ -191,7 +192,7 @@
                         provider.registerReplacements(runtime, replacements, runtime.getTarget());
                     }
                     runtime.registerReplacements(replacements);
-                    if (GraalOptions.BootstrapReplacements) {
+                    if (BootstrapReplacements.getValue()) {
                         for (ResolvedJavaMethod method : replacements.getAllReplacements()) {
                             replacements.getMacroSubstitution(method);
                             replacements.getMethodSubstitution(method);
@@ -421,7 +422,7 @@
         System.gc();
         phaseTransition("bootstrap2");
 
-        if (GraalOptions.CompileTheWorld != null) {
+        if (CompileTheWorld.getValue() != null) {
             new CompileTheWorld().compile();
             System.exit(0);
         }
@@ -768,7 +769,7 @@
             phasePlan.addPhase(PhasePosition.AFTER_PARSING, new OnStackReplacementPhase());
         }
         phasePlan.addPhase(PhasePosition.LOW_LEVEL, new WriteBarrierAdditionPhase());
-        if (GraalOptions.VerifyPhases) {
+        if (VerifyPhases.getValue()) {
             phasePlan.addPhase(PhasePosition.LOW_LEVEL, new WriteBarrierVerificationPhase());
 
         }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphCache.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphCache.java	Wed Jun 05 15:11:58 2013 +0200
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.hotspot.meta;
 
+import static com.oracle.graal.phases.GraalOptions.*;
+
 import java.io.*;
 import java.lang.ref.*;
 import java.util.*;
@@ -30,7 +32,6 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.phases.*;
 
 /**
  * This class implements the graph caching system for the HotSpot platform.
@@ -73,12 +74,12 @@
         private static final long serialVersionUID = -3973307040793397840L;
 
         public LRUCache() {
-            super(GraalOptions.GraphCacheSize * 2, 0.75f, false);
+            super(GraphCacheSize.getValue() * 2, 0.75f, false);
         }
 
         @Override
         protected boolean removeEldestEntry(Entry<Long, WeakReference<ResolvedJavaMethod>> eldest) {
-            if (size() > GraalOptions.GraphCacheSize) {
+            if (size() > GraphCacheSize.getValue()) {
                 ResolvedJavaMethod method = eldest.getValue().get();
                 if (method != null) {
                     StructuredGraph cachedGraph = (StructuredGraph) method.getCompilerStorage().get(HotSpotGraphCache.this);
@@ -96,7 +97,7 @@
     private final Map<Long, WeakReference<ResolvedJavaMethod>> cachedGraphIds = Collections.synchronizedMap(new LRUCache());
 
     public HotSpotGraphCache() {
-        if (GraalOptions.PrintGraphCache) {
+        if (PrintGraphCache.getValue()) {
             Runtime.getRuntime().addShutdownHook(new Thread() {
 
                 @Override
@@ -115,7 +116,7 @@
     public StructuredGraph get(ResolvedJavaMethod method) {
         StructuredGraph result = (StructuredGraph) method.getCompilerStorage().get(this);
 
-        if (GraalOptions.PrintGraphCache) {
+        if (PrintGraphCache.getValue()) {
             if (result == null) {
                 missCounter++;
             } else {
@@ -131,7 +132,7 @@
         cachedGraphIds.put(graph.graphId(), new WeakReference<>(graph.method()));
         graph.method().getCompilerStorage().put(this, graph);
 
-        if (GraalOptions.PrintGraphCache) {
+        if (PrintGraphCache.getValue()) {
             putCounter++;
         }
     }
@@ -161,12 +162,12 @@
                 StructuredGraph cachedGraph = (StructuredGraph) method.getCompilerStorage().get(this);
                 if (cachedGraph != null && cachedGraph.graphId() == graphId) {
                     method.getCompilerStorage().remove(this);
-                    if (GraalOptions.PrintGraphCache) {
+                    if (PrintGraphCache.getValue()) {
                         removeHitCounter++;
                     }
                 }
             }
-            if (GraalOptions.PrintGraphCache) {
+            if (PrintGraphCache.getValue()) {
                 removeCounter++;
             }
         }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodData.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodData.java	Wed Jun 05 15:11:58 2013 +0200
@@ -24,6 +24,7 @@
 
 import static com.oracle.graal.graph.UnsafeAccess.*;
 import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
+import static com.oracle.graal.phases.GraalOptions.*;
 
 import java.util.*;
 
@@ -32,7 +33,6 @@
 import com.oracle.graal.api.meta.JavaTypeProfile.ProfiledType;
 import com.oracle.graal.api.meta.ProfilingInfo.TriState;
 import com.oracle.graal.hotspot.*;
-import com.oracle.graal.phases.*;
 
 /**
  * Access to a HotSpot MethodData structure (defined in methodData.hpp).
@@ -376,7 +376,7 @@
         protected abstract long getTypesNotRecordedExecutionCount(HotSpotMethodData data, int position);
 
         private static JavaTypeProfile createTypeProfile(TriState nullSeen, ResolvedJavaType[] types, long[] counts, long totalCount, int entries) {
-            if (entries <= 0 || totalCount < GraalOptions.MatureExecutionsTypeProfile) {
+            if (entries <= 0 || totalCount < MatureExecutionsTypeProfile.getValue()) {
                 return null;
             }
 
@@ -484,7 +484,7 @@
         }
 
         private static JavaMethodProfile createMethodProfile(ResolvedJavaMethod[] methods, long[] counts, long totalCount, int entries) {
-            if (entries <= 0 || totalCount < GraalOptions.MatureExecutionsTypeProfile) {
+            if (entries <= 0 || totalCount < MatureExecutionsTypeProfile.getValue()) {
                 return null;
             }
 
@@ -540,7 +540,7 @@
             long notTakenCount = data.readUnsignedInt(position, NOT_TAKEN_COUNT_OFFSET);
             long total = takenCount + notTakenCount;
 
-            if (total < GraalOptions.MatureExecutionsBranch) {
+            if (total < MatureExecutionsBranch.getValue()) {
                 return -1;
             } else {
                 return takenCount / (double) total;
@@ -607,7 +607,7 @@
                 result[i - 1] = count;
             }
 
-            if (totalCount < GraalOptions.MatureExecutionsPerSwitchCase * length) {
+            if (totalCount < MatureExecutionsPerSwitchCase.getValue() * length) {
                 return null;
             } else {
                 for (int i = 0; i < length; i++) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java	Wed Jun 05 15:11:58 2013 +0200
@@ -31,7 +31,7 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.hotspot.*;
-import com.oracle.graal.phases.*;
+import com.oracle.graal.options.*;
 import com.oracle.graal.replacements.*;
 
 /**
@@ -83,7 +83,7 @@
             assert Modifier.isStatic(flags);
             if (constant == null) {
                 if (holder.isInitialized() && !holder.getName().equals(SystemClassName)) {
-                    if (Modifier.isFinal(getModifiers()) || assumeStaticFieldsFinal(holder.mirror())) {
+                    if (Modifier.isFinal(getModifiers())) {
                         constant = readValue(receiver);
                     }
                 }
@@ -119,11 +119,10 @@
         }
     }
 
-    private static boolean assumeStaticFieldsFinal(Class<?> clazz) {
-        return clazz == GraalOptions.class;
-    }
-
     private static boolean assumeNonStaticFinalFieldsAsFinal(Class<?> clazz) {
+        if (clazz == OptionValue.class) {
+            return true;
+        }
         return clazz == SnippetCounter.class;
     }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java	Wed Jun 05 15:11:58 2013 +0200
@@ -25,6 +25,7 @@
 import static com.oracle.graal.api.meta.MetaUtil.*;
 import static com.oracle.graal.graph.UnsafeAccess.*;
 import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
+import static com.oracle.graal.phases.GraalOptions.*;
 
 import java.lang.annotation.*;
 import java.lang.reflect.*;
@@ -37,7 +38,6 @@
 import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.debug.*;
-import com.oracle.graal.phases.*;
 
 /**
  * Implementation of {@link JavaMethod} for resolved HotSpot methods.
@@ -276,7 +276,7 @@
     public ProfilingInfo getProfilingInfo() {
         ProfilingInfo info;
 
-        if (GraalOptions.UseProfilingInformation && methodData == null) {
+        if (UseProfilingInformation.getValue() && methodData == null) {
             long metaspaceMethodData = unsafeReadWord(metaspaceMethod + graalRuntime().getConfig().methodDataOffset);
             if (metaspaceMethodData != 0) {
                 methodData = new HotSpotMethodData(metaspaceMethodData);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Wed Jun 05 15:11:58 2013 +0200
@@ -50,6 +50,7 @@
 import static com.oracle.graal.hotspot.stubs.UnwindExceptionToCallerStub.*;
 import static com.oracle.graal.java.GraphBuilderPhase.RuntimeCalls.*;
 import static com.oracle.graal.nodes.java.RegisterFinalizerNode.*;
+import static com.oracle.graal.phases.GraalOptions.*;
 import static com.oracle.graal.replacements.Log.*;
 import static com.oracle.graal.replacements.MathSubstitutionsX86.*;
 
@@ -82,9 +83,9 @@
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind;
 import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.spi.Lowerable.LoweringType;
 import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.nodes.virtual.*;
-import com.oracle.graal.phases.*;
 import com.oracle.graal.printer.*;
 import com.oracle.graal.replacements.*;
 import com.oracle.graal.word.*;
@@ -294,26 +295,26 @@
         linkForeignCall(r, VM_ERROR, c.vmErrorAddress, PREPEND_THREAD, REEXECUTABLE, NO_LOCATIONS);
         linkForeignCall(r, OSR_MIGRATION_END, c.osrMigrationEndAddress, DONT_PREPEND_THREAD, NOT_REEXECUTABLE, NO_LOCATIONS);
 
-        if (GraalOptions.IntrinsifyObjectMethods) {
+        if (IntrinsifyObjectMethods.getValue()) {
             r.registerSubstitutions(ObjectSubstitutions.class);
         }
-        if (GraalOptions.IntrinsifySystemMethods) {
+        if (IntrinsifySystemMethods.getValue()) {
             r.registerSubstitutions(SystemSubstitutions.class);
         }
-        if (GraalOptions.IntrinsifyThreadMethods) {
+        if (IntrinsifyThreadMethods.getValue()) {
             r.registerSubstitutions(ThreadSubstitutions.class);
         }
-        if (GraalOptions.IntrinsifyUnsafeMethods) {
+        if (IntrinsifyUnsafeMethods.getValue()) {
             r.registerSubstitutions(UnsafeSubstitutions.class);
         }
-        if (GraalOptions.IntrinsifyClassMethods) {
+        if (IntrinsifyClassMethods.getValue()) {
             r.registerSubstitutions(ClassSubstitutions.class);
         }
-        if (GraalOptions.IntrinsifyAESMethods) {
+        if (IntrinsifyAESMethods.getValue()) {
             r.registerSubstitutions(AESCryptSubstitutions.class);
             r.registerSubstitutions(CipherBlockChainingSubstitutions.class);
         }
-        if (GraalOptions.IntrinsifyReflectionMethods) {
+        if (IntrinsifyReflectionMethods.getValue()) {
             r.registerSubstitutions(ReflectionSubstitutions.class);
         }
 
@@ -492,7 +493,7 @@
                 JavaType[] signature = MetaUtil.signatureToTypes(callTarget.targetMethod().getSignature(), callTarget.isStatic() ? null : callTarget.targetMethod().getDeclaringClass());
 
                 LoweredCallTargetNode loweredCallTarget = null;
-                if (callTarget.invokeKind() == InvokeKind.Virtual && GraalOptions.InlineVTableStubs && (GraalOptions.AlwaysInlineVTableStubs || invoke.isPolymorphic())) {
+                if (callTarget.invokeKind() == InvokeKind.Virtual && InlineVTableStubs.getValue() && (AlwaysInlineVTableStubs.getValue() || invoke.isPolymorphic())) {
 
                     HotSpotResolvedJavaMethod hsMethod = (HotSpotResolvedJavaMethod) callTarget.targetMethod();
                     if (!hsMethod.getDeclaringClass().isInterface()) {
@@ -638,108 +639,115 @@
             graph.replaceFixed(loadMethodNode, metaspaceMethod);
         } else if (n instanceof FixedGuardNode) {
             FixedGuardNode node = (FixedGuardNode) n;
-            ValueAnchorNode newAnchor = graph.add(new ValueAnchorNode(tool.createGuard(node.condition(), node.getReason(), node.getAction(), node.isNegated()).asNode()));
+            GuardingNode guard = tool.createGuard(node.condition(), node.getReason(), node.getAction(), node.isNegated());
+            ValueAnchorNode newAnchor = graph.add(new ValueAnchorNode(guard.asNode()));
+            node.replaceAtUsages(guard.asNode());
             graph.replaceFixedWithFixed(node, newAnchor);
         } else if (n instanceof CommitAllocationNode) {
-            CommitAllocationNode commit = (CommitAllocationNode) n;
+            if (tool.getLoweringType() == LoweringType.AFTER_GUARDS) {
+                CommitAllocationNode commit = (CommitAllocationNode) n;
 
-            ValueNode[] allocations = new ValueNode[commit.getVirtualObjects().size()];
-            for (int objIndex = 0; objIndex < commit.getVirtualObjects().size(); objIndex++) {
-                VirtualObjectNode virtual = commit.getVirtualObjects().get(objIndex);
-                int entryCount = virtual.entryCount();
+                ValueNode[] allocations = new ValueNode[commit.getVirtualObjects().size()];
+                for (int objIndex = 0; objIndex < commit.getVirtualObjects().size(); objIndex++) {
+                    VirtualObjectNode virtual = commit.getVirtualObjects().get(objIndex);
+                    int entryCount = virtual.entryCount();
 
-                FixedWithNextNode newObject;
-                if (virtual instanceof VirtualInstanceNode) {
-                    newObject = graph.add(new NewInstanceNode(virtual.type(), true));
-                } else {
-                    ResolvedJavaType element = ((VirtualArrayNode) virtual).componentType();
-                    newObject = graph.add(new NewArrayNode(element, ConstantNode.forInt(entryCount, graph), true));
+                    FixedWithNextNode newObject;
+                    if (virtual instanceof VirtualInstanceNode) {
+                        newObject = graph.add(new NewInstanceNode(virtual.type(), true));
+                    } else {
+                        ResolvedJavaType element = ((VirtualArrayNode) virtual).componentType();
+                        newObject = graph.add(new NewArrayNode(element, ConstantNode.forInt(entryCount, graph), true));
+                    }
+                    graph.addBeforeFixed(commit, newObject);
+                    allocations[objIndex] = newObject;
                 }
-                graph.addBeforeFixed(commit, newObject);
-                allocations[objIndex] = newObject;
-            }
-            int valuePos = 0;
-            for (int objIndex = 0; objIndex < commit.getVirtualObjects().size(); objIndex++) {
-                VirtualObjectNode virtual = commit.getVirtualObjects().get(objIndex);
-                int entryCount = virtual.entryCount();
+                int valuePos = 0;
+                for (int objIndex = 0; objIndex < commit.getVirtualObjects().size(); objIndex++) {
+                    VirtualObjectNode virtual = commit.getVirtualObjects().get(objIndex);
+                    int entryCount = virtual.entryCount();
 
-                ValueNode newObject = allocations[objIndex];
-                if (virtual instanceof VirtualInstanceNode) {
-                    VirtualInstanceNode instance = (VirtualInstanceNode) virtual;
-                    for (int i = 0; i < entryCount; i++) {
-                        ValueNode value = commit.getValues().get(valuePos++);
-                        if (value instanceof VirtualObjectNode) {
-                            value = allocations[commit.getVirtualObjects().indexOf(value)];
-                        }
-                        if (!(value.isConstant() && value.asConstant().isDefaultForKind())) {
-                            WriteNode write = new WriteNode(newObject, value, createFieldLocation(graph, (HotSpotResolvedJavaField) instance.field(i)), WriteBarrierType.NONE,
-                                            instance.field(i).getKind() == Kind.Object);
+                    ValueNode newObject = allocations[objIndex];
+                    if (virtual instanceof VirtualInstanceNode) {
+                        VirtualInstanceNode instance = (VirtualInstanceNode) virtual;
+                        for (int i = 0; i < entryCount; i++) {
+                            ValueNode value = commit.getValues().get(valuePos++);
+                            if (value instanceof VirtualObjectNode) {
+                                value = allocations[commit.getVirtualObjects().indexOf(value)];
+                            }
+                            if (!(value.isConstant() && value.asConstant().isDefaultForKind())) {
+                                WriteNode write = new WriteNode(newObject, value, createFieldLocation(graph, (HotSpotResolvedJavaField) instance.field(i)), WriteBarrierType.NONE,
+                                                instance.field(i).getKind() == Kind.Object);
 
-                            graph.addBeforeFixed(commit, graph.add(write));
+                                graph.addBeforeFixed(commit, graph.add(write));
+                            }
                         }
-                    }
-                } else {
-                    VirtualArrayNode array = (VirtualArrayNode) virtual;
-                    ResolvedJavaType element = array.componentType();
-                    for (int i = 0; i < entryCount; i++) {
-                        ValueNode value = commit.getValues().get(valuePos++);
-                        if (value instanceof VirtualObjectNode) {
-                            int indexOf = commit.getVirtualObjects().indexOf(value);
-                            assert indexOf != -1 : commit + " " + value;
-                            value = allocations[indexOf];
-                        }
-                        if (!(value.isConstant() && value.asConstant().isDefaultForKind())) {
-                            WriteNode write = new WriteNode(newObject, value, createArrayLocation(graph, element.getKind(), ConstantNode.forInt(i, graph)), WriteBarrierType.NONE,
-                                            value.kind() == Kind.Object);
-                            graph.addBeforeFixed(commit, graph.add(write));
+
+                    } else {
+                        VirtualArrayNode array = (VirtualArrayNode) virtual;
+                        ResolvedJavaType element = array.componentType();
+                        for (int i = 0; i < entryCount; i++) {
+                            ValueNode value = commit.getValues().get(valuePos++);
+                            if (value instanceof VirtualObjectNode) {
+                                int indexOf = commit.getVirtualObjects().indexOf(value);
+                                assert indexOf != -1 : commit + " " + value;
+                                value = allocations[indexOf];
+                            }
+                            if (!(value.isConstant() && value.asConstant().isDefaultForKind())) {
+                                WriteNode write = new WriteNode(newObject, value, createArrayLocation(graph, element.getKind(), ConstantNode.forInt(i, graph)), WriteBarrierType.NONE,
+                                                value.kind() == Kind.Object);
+                                graph.addBeforeFixed(commit, graph.add(write));
+                            }
                         }
                     }
                 }
-            }
-            for (int objIndex = 0; objIndex < commit.getVirtualObjects().size(); objIndex++) {
-                FixedValueAnchorNode anchor = graph.add(new FixedValueAnchorNode(allocations[objIndex]));
-                allocations[objIndex] = anchor;
-                graph.addBeforeFixed(commit, anchor);
+                for (int objIndex = 0; objIndex < commit.getVirtualObjects().size(); objIndex++) {
+                    FixedValueAnchorNode anchor = graph.add(new FixedValueAnchorNode(allocations[objIndex]));
+                    allocations[objIndex] = anchor;
+                    graph.addBeforeFixed(commit, anchor);
+                }
+                for (int objIndex = 0; objIndex < commit.getVirtualObjects().size(); objIndex++) {
+                    for (int lockDepth : commit.getLocks().get(objIndex)) {
+                        MonitorEnterNode enter = graph.add(new MonitorEnterNode(allocations[objIndex], lockDepth));
+                        graph.addBeforeFixed(commit, enter);
+                    }
+                }
+                for (Node usage : commit.usages().snapshot()) {
+                    AllocatedObjectNode addObject = (AllocatedObjectNode) usage;
+                    int index = commit.getVirtualObjects().indexOf(addObject.getVirtualObject());
+                    graph.replaceFloating(addObject, allocations[index]);
+                }
+                graph.removeFixed(commit);
             }
-            for (int objIndex = 0; objIndex < commit.getVirtualObjects().size(); objIndex++) {
-                for (int lockDepth : commit.getLocks().get(objIndex)) {
-                    MonitorEnterNode enter = graph.add(new MonitorEnterNode(allocations[objIndex], lockDepth));
-                    graph.addBeforeFixed(commit, enter);
-                }
-            }
-            for (Node usage : commit.usages().snapshot()) {
-                AllocatedObjectNode addObject = (AllocatedObjectNode) usage;
-                int index = commit.getVirtualObjects().indexOf(addObject.getVirtualObject());
-                graph.replaceFloating(addObject, allocations[index]);
-            }
-            graph.removeFixed(commit);
         } else if (n instanceof CheckCastNode) {
             checkcastSnippets.lower((CheckCastNode) n, tool);
         } else if (n instanceof OSRStartNode) {
-            OSRStartNode osrStart = (OSRStartNode) n;
-            StartNode newStart = graph.add(new StartNode());
-            LocalNode buffer = graph.unique(new LocalNode(0, StampFactory.forKind(wordKind())));
-            ForeignCallNode migrationEnd = graph.add(new ForeignCallNode(this, OSR_MIGRATION_END, buffer));
-            migrationEnd.setStateAfter(osrStart.stateAfter());
+            if (tool.getLoweringType() == LoweringType.AFTER_GUARDS) {
+                OSRStartNode osrStart = (OSRStartNode) n;
+                StartNode newStart = graph.add(new StartNode());
+                LocalNode buffer = graph.unique(new LocalNode(0, StampFactory.forKind(wordKind())));
+                ForeignCallNode migrationEnd = graph.add(new ForeignCallNode(this, OSR_MIGRATION_END, buffer));
+                migrationEnd.setStateAfter(osrStart.stateAfter());
 
-            newStart.setNext(migrationEnd);
-            FixedNode next = osrStart.next();
-            osrStart.setNext(null);
-            migrationEnd.setNext(next);
-            graph.setStart(newStart);
+                newStart.setNext(migrationEnd);
+                FixedNode next = osrStart.next();
+                osrStart.setNext(null);
+                migrationEnd.setNext(next);
+                graph.setStart(newStart);
 
-            // mirroring the calculations in c1_GraphBuilder.cpp (setup_osr_entry_block)
-            int localsOffset = (graph.method().getMaxLocals() - 1) * 8;
-            for (OSRLocalNode osrLocal : graph.getNodes(OSRLocalNode.class)) {
-                int size = FrameStateBuilder.stackSlots(osrLocal.kind());
-                int offset = localsOffset - (osrLocal.index() + size - 1) * 8;
-                IndexedLocationNode location = IndexedLocationNode.create(ANY_LOCATION, osrLocal.kind(), offset, ConstantNode.forLong(0, graph), graph, 1);
-                ReadNode load = graph.add(new ReadNode(buffer, location, osrLocal.stamp(), WriteBarrierType.NONE, false));
-                osrLocal.replaceAndDelete(load);
-                graph.addBeforeFixed(migrationEnd, load);
+                // mirroring the calculations in c1_GraphBuilder.cpp (setup_osr_entry_block)
+                int localsOffset = (graph.method().getMaxLocals() - 1) * 8;
+                for (OSRLocalNode osrLocal : graph.getNodes(OSRLocalNode.class)) {
+                    int size = FrameStateBuilder.stackSlots(osrLocal.kind());
+                    int offset = localsOffset - (osrLocal.index() + size - 1) * 8;
+                    IndexedLocationNode location = IndexedLocationNode.create(ANY_LOCATION, osrLocal.kind(), offset, ConstantNode.forLong(0, graph), graph, 1);
+                    ReadNode load = graph.add(new ReadNode(buffer, location, osrLocal.stamp(), WriteBarrierType.NONE, false));
+                    osrLocal.replaceAndDelete(load);
+                    graph.addBeforeFixed(migrationEnd, load);
+                }
+                osrStart.replaceAtUsages(newStart);
+                osrStart.safeDelete();
             }
-            osrStart.replaceAtUsages(newStart);
-            osrStart.safeDelete();
         } else if (n instanceof CheckCastDynamicNode) {
             checkcastSnippets.lower((CheckCastDynamicNode) n);
         } else if (n instanceof InstanceOfNode) {
@@ -747,19 +755,29 @@
         } else if (n instanceof InstanceOfDynamicNode) {
             instanceofSnippets.lower((InstanceOfDynamicNode) n, tool);
         } else if (n instanceof NewInstanceNode) {
-            newObjectSnippets.lower((NewInstanceNode) n);
+            if (tool.getLoweringType() == LoweringType.AFTER_GUARDS) {
+                newObjectSnippets.lower((NewInstanceNode) n);
+            }
         } else if (n instanceof NewArrayNode) {
-            newObjectSnippets.lower((NewArrayNode) n);
+            if (tool.getLoweringType() == LoweringType.AFTER_GUARDS) {
+                newObjectSnippets.lower((NewArrayNode) n);
+            }
         } else if (n instanceof MonitorEnterNode) {
-            monitorSnippets.lower((MonitorEnterNode) n, tool);
+            if (tool.getLoweringType() == LoweringType.AFTER_GUARDS) {
+                monitorSnippets.lower((MonitorEnterNode) n, tool);
+            }
         } else if (n instanceof MonitorExitNode) {
-            monitorSnippets.lower((MonitorExitNode) n, tool);
+            if (tool.getLoweringType() == LoweringType.AFTER_GUARDS) {
+                monitorSnippets.lower((MonitorExitNode) n, tool);
+            }
         } else if (n instanceof SerialWriteBarrier) {
             writeBarrierSnippets.lower((SerialWriteBarrier) n, tool);
         } else if (n instanceof SerialArrayRangeWriteBarrier) {
             writeBarrierSnippets.lower((SerialArrayRangeWriteBarrier) n, tool);
         } else if (n instanceof NewMultiArrayNode) {
-            newObjectSnippets.lower((NewMultiArrayNode) n);
+            if (tool.getLoweringType() == LoweringType.AFTER_GUARDS) {
+                newObjectSnippets.lower((NewMultiArrayNode) n);
+            }
         } else if (n instanceof LoadExceptionObjectNode) {
             exceptionObjectSnippets.lower((LoadExceptionObjectNode) n);
         } else if (n instanceof IntegerDivNode || n instanceof IntegerRemNode || n instanceof UnsignedDivNode || n instanceof UnsignedRemNode) {
@@ -1018,7 +1036,7 @@
     }
 
     public boolean canDeoptimize(ForeignCallDescriptor descriptor) {
-        return !foreignCalls.get(descriptor).isLeaf();
+        return foreignCalls.get(descriptor).canDeoptimize();
     }
 
     public LocationIdentity[] getKilledLocations(ForeignCallDescriptor descriptor) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/StubForeignCallNode.java	Wed Jun 05 15:11:58 2013 +0200
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2011, 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.hotspot.nodes;
+
+import com.oracle.graal.api.code.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
+
+/**
+ * Node for a {@linkplain ForeignCallDescriptor foreign} call from within a stub.
+ */
+@NodeInfo(nameTemplate = "StubForeignCall#{p#descriptor/s}")
+public class StubForeignCallNode extends FixedWithNextNode implements DeoptimizingNode, LIRLowerable, MemoryCheckpoint {
+
+    @Input private final NodeInputList<ValueNode> arguments;
+    private final MetaAccessProvider runtime;
+    @Input private FrameState deoptState;
+
+    private final ForeignCallDescriptor descriptor;
+
+    public StubForeignCallNode(MetaAccessProvider runtime, ForeignCallDescriptor descriptor, ValueNode... arguments) {
+        super(StampFactory.forKind(Kind.fromJavaClass(descriptor.getResultType())));
+        this.arguments = new NodeInputList<>(this, arguments);
+        this.descriptor = descriptor;
+        this.runtime = runtime;
+    }
+
+    public ForeignCallDescriptor getDescriptor() {
+        return descriptor;
+    }
+
+    @Override
+    public LocationIdentity[] getLocationIdentities() {
+        return runtime.getKilledLocations(descriptor);
+    }
+
+    protected Value[] operands(LIRGeneratorTool gen) {
+        Value[] operands = new Value[arguments.size()];
+        for (int i = 0; i < operands.length; i++) {
+            operands[i] = gen.operand(arguments.get(i));
+        }
+        return operands;
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        assert graph().start() instanceof StubStartNode;
+        ForeignCallLinkage linkage = gen.getRuntime().lookupForeignCall(descriptor);
+        Value[] operands = operands(gen);
+        Value result = gen.emitForeignCall(linkage, this, operands);
+        if (result != null) {
+            gen.setResult(this, result);
+        }
+    }
+
+    @Override
+    public String toString(Verbosity verbosity) {
+        if (verbosity == Verbosity.Name) {
+            return super.toString(verbosity) + "#" + descriptor;
+        }
+        return super.toString(verbosity);
+    }
+
+    @Override
+    public boolean canDeoptimize() {
+        return false;
+    }
+
+    @Override
+    public FrameState getDeoptimizationState() {
+        return null;
+    }
+
+    @Override
+    public void setDeoptimizationState(FrameState state) {
+    }
+
+    @Override
+    public DeoptimizationReason getDeoptimizationReason() {
+        return null;
+    }
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyNode.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyNode.java	Wed Jun 05 15:11:58 2013 +0200
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.hotspot.replacements;
 
+import static com.oracle.graal.phases.GraalOptions.*;
+
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.graph.Node.IterableNodeType;
@@ -29,7 +31,6 @@
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.virtual.*;
-import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.common.*;
 import com.oracle.graal.phases.tiers.*;
 import com.oracle.graal.replacements.nodes.*;
@@ -90,7 +91,7 @@
 
     @Override
     protected StructuredGraph getSnippetGraph(LoweringTool tool) {
-        if (!GraalOptions.IntrinsifyArrayCopy) {
+        if (!IntrinsifyArrayCopy.getValue()) {
             return null;
         }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopySnippets.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopySnippets.java	Wed Jun 05 15:11:58 2013 +0200
@@ -24,6 +24,7 @@
 
 import static com.oracle.graal.api.meta.LocationIdentity.*;
 import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*;
+import static com.oracle.graal.phases.GraalOptions.*;
 import static com.oracle.graal.replacements.nodes.BranchProbabilityNode.*;
 
 import java.lang.reflect.*;
@@ -314,12 +315,12 @@
         }
     }
 
-    private static final SnippetCounter.Group checkCounters = GraalOptions.SnippetCounters ? new SnippetCounter.Group("System.arraycopy checkInputs") : null;
+    private static final SnippetCounter.Group checkCounters = SnippetCounters.getValue() ? new SnippetCounter.Group("System.arraycopy checkInputs") : null;
     private static final SnippetCounter checkSuccessCounter = new SnippetCounter(checkCounters, "checkSuccess", "checkSuccess");
     private static final SnippetCounter checkNPECounter = new SnippetCounter(checkCounters, "checkNPE", "checkNPE");
     private static final SnippetCounter checkAIOOBECounter = new SnippetCounter(checkCounters, "checkAIOOBE", "checkAIOOBE");
 
-    private static final SnippetCounter.Group counters = GraalOptions.SnippetCounters ? new SnippetCounter.Group("System.arraycopy") : null;
+    private static final SnippetCounter.Group counters = SnippetCounters.getValue() ? new SnippetCounter.Group("System.arraycopy") : null;
     private static final SnippetCounter byteCounter = new SnippetCounter(counters, "byte[]", "arraycopy for byte[] arrays");
     private static final SnippetCounter charCounter = new SnippetCounter(counters, "char[]", "arraycopy for char[] arrays");
     private static final SnippetCounter shortCounter = new SnippetCounter(counters, "short[]", "arraycopy for short[] arrays");
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CallSiteSubstitutions.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CallSiteSubstitutions.java	Wed Jun 05 15:11:58 2013 +0200
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.hotspot.replacements;
 
+import static com.oracle.graal.phases.GraalOptions.*;
+
 import java.lang.invoke.*;
 
 import com.oracle.graal.api.code.*;
@@ -29,14 +31,13 @@
 import com.oracle.graal.api.replacements.*;
 import com.oracle.graal.api.runtime.*;
 import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.phases.*;
 
 @ServiceProvider(ReplacementsProvider.class)
 public class CallSiteSubstitutions implements ReplacementsProvider {
 
     @Override
     public void registerReplacements(MetaAccessProvider runtime, Replacements replacements, TargetDescription target) {
-        if (GraalOptions.IntrinsifyCallSiteTarget) {
+        if (IntrinsifyCallSiteTarget.getValue()) {
             replacements.registerSubstitutions(ConstantCallSiteSubstitutions.class);
             replacements.registerSubstitutions(MutableCallSiteSubstitutions.class);
             replacements.registerSubstitutions(VolatileCallSiteSubstitutions.class);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CheckCastSnippets.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CheckCastSnippets.java	Wed Jun 05 15:11:58 2013 +0200
@@ -27,6 +27,7 @@
 import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*;
 import static com.oracle.graal.hotspot.replacements.TypeCheckSnippetUtils.*;
 import static com.oracle.graal.nodes.extended.UnsafeCastNode.*;
+import static com.oracle.graal.phases.GraalOptions.*;
 import static com.oracle.graal.replacements.SnippetTemplate.*;
 import static com.oracle.graal.replacements.nodes.BranchProbabilityNode.*;
 
@@ -39,7 +40,6 @@
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
-import com.oracle.graal.phases.*;
 import com.oracle.graal.replacements.*;
 import com.oracle.graal.replacements.Snippet.ConstantParameter;
 import com.oracle.graal.replacements.Snippet.VarargsParameter;
@@ -168,7 +168,7 @@
             StructuredGraph graph = checkcast.graph();
             ValueNode object = checkcast.object();
             HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) checkcast.type();
-            TypeCheckHints hintInfo = new TypeCheckHints(checkcast.type(), checkcast.profile(), tool.assumptions(), GraalOptions.CheckcastMinHintHitProbability, GraalOptions.CheckcastMaxHints);
+            TypeCheckHints hintInfo = new TypeCheckHints(checkcast.type(), checkcast.profile(), tool.assumptions(), CheckcastMinHintHitProbability.getValue(), CheckcastMaxHints.getValue());
             ValueNode hub = ConstantNode.forConstant(type.klass(), runtime, checkcast.graph());
 
             Arguments args;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotNmethodIntrinsics.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotNmethodIntrinsics.java	Wed Jun 05 15:11:58 2013 +0200
@@ -22,18 +22,19 @@
  */
 package com.oracle.graal.hotspot.replacements;
 
+import static com.oracle.graal.phases.GraalOptions.*;
+
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.runtime.*;
 import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.phases.*;
 
 @ServiceProvider(ReplacementsProvider.class)
 public class HotSpotNmethodIntrinsics implements ReplacementsProvider {
 
     @Override
     public void registerReplacements(MetaAccessProvider runtime, Replacements replacements, TargetDescription target) {
-        if (GraalOptions.IntrinsifyInstalledCodeMethods) {
+        if (IntrinsifyInstalledCodeMethods.getValue()) {
             replacements.registerSubstitutions(HotSpotNmethodSubstitutions.class);
         }
     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java	Wed Jun 05 15:11:58 2013 +0200
@@ -443,6 +443,13 @@
         return loadHubIntrinsic(object, getWordKind());
     }
 
+    /**
+     * Loads the hub from a object.
+     */
+    public static Word loadHubNoNullcheck(Object object) {
+        return loadWordFromObject(object, hubOffset());
+    }
+
     public static Object verifyOop(Object object) {
         if (verifyOops()) {
             verifyOopStub(VERIFY_OOP, object);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java	Wed Jun 05 15:11:58 2013 +0200
@@ -24,6 +24,7 @@
 
 import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*;
 import static com.oracle.graal.hotspot.replacements.TypeCheckSnippetUtils.*;
+import static com.oracle.graal.phases.GraalOptions.*;
 import static com.oracle.graal.replacements.nodes.BranchProbabilityNode.*;
 
 import com.oracle.graal.api.code.*;
@@ -34,7 +35,6 @@
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
-import com.oracle.graal.phases.*;
 import com.oracle.graal.replacements.*;
 import com.oracle.graal.replacements.Snippet.ConstantParameter;
 import com.oracle.graal.replacements.Snippet.VarargsParameter;
@@ -150,7 +150,7 @@
             if (replacer.instanceOf instanceof InstanceOfNode) {
                 InstanceOfNode instanceOf = (InstanceOfNode) replacer.instanceOf;
                 ValueNode object = instanceOf.object();
-                TypeCheckHints hintInfo = new TypeCheckHints(instanceOf.type(), instanceOf.profile(), tool.assumptions(), GraalOptions.InstanceOfMinHintHitProbability, GraalOptions.InstanceOfMaxHints);
+                TypeCheckHints hintInfo = new TypeCheckHints(instanceOf.type(), instanceOf.profile(), tool.assumptions(), InstanceOfMinHintHitProbability.getValue(), InstanceOfMaxHints.getValue());
                 final HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) instanceOf.type();
                 ConstantNode hub = ConstantNode.forConstant(type.klass(), runtime, instanceOf.graph());
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java	Wed Jun 05 15:11:58 2013 +0200
@@ -107,7 +107,7 @@
             } else {
                 // The bias pattern is present in the object's mark word. Need to check
                 // whether the bias owner and the epoch are both still current.
-                Word hub = loadHub(object);
+                Word hub = loadHubNoNullcheck(object);
                 final Word prototypeMarkWord = hub.readWord(prototypeMarkWordOffset(), PROTOTYPE_MARK_WORD_LOCATION);
                 final Word thread = thread();
                 final Word tmp = prototypeMarkWord.or(thread).xor(mark).and(~ageMaskInPlace());
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java	Wed Jun 05 15:11:58 2013 +0200
@@ -27,6 +27,7 @@
 import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*;
 import static com.oracle.graal.nodes.extended.UnsafeArrayCastNode.*;
 import static com.oracle.graal.nodes.extended.UnsafeCastNode.*;
+import static com.oracle.graal.phases.GraalOptions.*;
 import static com.oracle.graal.replacements.SnippetTemplate.*;
 import static com.oracle.graal.replacements.nodes.BranchProbabilityNode.*;
 import static com.oracle.graal.replacements.nodes.ExplodeLoopNode.*;
@@ -40,7 +41,6 @@
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
-import com.oracle.graal.phases.*;
 import com.oracle.graal.replacements.*;
 import com.oracle.graal.replacements.Snippet.ConstantParameter;
 import com.oracle.graal.replacements.Snippet.VarargsParameter;
@@ -278,12 +278,12 @@
         }
     }
 
-    private static final SnippetCounter.Group countersNew = GraalOptions.SnippetCounters ? new SnippetCounter.Group("NewInstance") : null;
+    private static final SnippetCounter.Group countersNew = SnippetCounters.getValue() ? new SnippetCounter.Group("NewInstance") : null;
     private static final SnippetCounter new_seqInit = new SnippetCounter(countersNew, "tlabSeqInit", "TLAB alloc with unrolled zeroing");
     private static final SnippetCounter new_loopInit = new SnippetCounter(countersNew, "tlabLoopInit", "TLAB alloc with zeroing in a loop");
     private static final SnippetCounter new_stub = new SnippetCounter(countersNew, "stub", "alloc and zeroing via stub");
 
-    private static final SnippetCounter.Group countersNewArray = GraalOptions.SnippetCounters ? new SnippetCounter.Group("NewArray") : null;
+    private static final SnippetCounter.Group countersNewArray = SnippetCounters.getValue() ? new SnippetCounter.Group("NewArray") : null;
     private static final SnippetCounter newarray_loopInit = new SnippetCounter(countersNewArray, "tlabLoopInit", "TLAB alloc with zeroing in a loop");
     private static final SnippetCounter newarray_stub = new SnippetCounter(countersNewArray, "stub", "alloc and zeroing via stub");
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneNode.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneNode.java	Wed Jun 05 15:11:58 2013 +0200
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.hotspot.replacements;
 
+import static com.oracle.graal.phases.GraalOptions.*;
+
 import java.lang.reflect.*;
 
 import com.oracle.graal.api.code.*;
@@ -31,7 +33,6 @@
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.nodes.virtual.*;
-import com.oracle.graal.phases.*;
 import com.oracle.graal.replacements.nodes.*;
 
 public class ObjectCloneNode extends MacroNode implements VirtualizableAllocation, ArrayLengthProvider {
@@ -51,7 +52,7 @@
 
     @Override
     protected StructuredGraph getSnippetGraph(LoweringTool tool) {
-        if (!GraalOptions.IntrinsifyObjectClone) {
+        if (!IntrinsifyObjectClone.getValue()) {
             return null;
         }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneSnippets.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneSnippets.java	Wed Jun 05 15:11:58 2013 +0200
@@ -24,6 +24,7 @@
 
 import static com.oracle.graal.api.meta.LocationIdentity.*;
 import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*;
+import static com.oracle.graal.phases.GraalOptions.*;
 import static com.oracle.graal.replacements.nodes.BranchProbabilityNode.*;
 
 import java.lang.reflect.*;
@@ -33,7 +34,6 @@
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.java.*;
-import com.oracle.graal.phases.*;
 import com.oracle.graal.replacements.*;
 import com.oracle.graal.word.*;
 
@@ -117,12 +117,12 @@
         }
     }
 
-    private static final SnippetCounter.Group cloneCounters = GraalOptions.SnippetCounters ? new SnippetCounter.Group("Object.clone") : null;
+    private static final SnippetCounter.Group cloneCounters = SnippetCounters.getValue() ? new SnippetCounter.Group("Object.clone") : null;
     private static final SnippetCounter instanceCloneCounter = new SnippetCounter(cloneCounters, "instanceClone", "clone snippet for instances");
     private static final SnippetCounter arrayCloneCounter = new SnippetCounter(cloneCounters, "arrayClone", "clone snippet for arrays");
     private static final SnippetCounter genericCloneCounter = new SnippetCounter(cloneCounters, "genericClone", "clone snippet for arrays and instances");
 
-    private static final SnippetCounter.Group genericCloneCounters = GraalOptions.SnippetCounters ? new SnippetCounter.Group("Object.clone generic snippet") : null;
+    private static final SnippetCounter.Group genericCloneCounters = SnippetCounters.getValue() ? new SnippetCounter.Group("Object.clone generic snippet") : null;
     private static final SnippetCounter genericInstanceCloneCounter = new SnippetCounter(genericCloneCounters, "genericInstanceClone", "generic clone implementation took instance path");
     private static final SnippetCounter genericArrayCloneCounter = new SnippetCounter(genericCloneCounters, "genericArrayClone", "generic clone implementation took array path");
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ReflectionGetCallerClassNode.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ReflectionGetCallerClassNode.java	Wed Jun 05 15:11:58 2013 +0200
@@ -22,12 +22,13 @@
  */
 package com.oracle.graal.hotspot.replacements;
 
+import static com.oracle.graal.phases.GraalOptions.*;
+
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.phases.*;
 import com.oracle.graal.replacements.nodes.*;
 
 public class ReflectionGetCallerClassNode extends MacroNode implements Canonicalizable, Lowerable {
@@ -64,7 +65,7 @@
      * @return ConstantNode of the caller class, or null
      */
     private ConstantNode getCallerClassNode(MetaAccessProvider runtime) {
-        if (!GraalOptions.IntrinsifyReflectionMethods) {
+        if (!IntrinsifyReflectionMethods.getValue()) {
             return null;
         }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/TypeCheckSnippetUtils.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/TypeCheckSnippetUtils.java	Wed Jun 05 15:11:58 2013 +0200
@@ -23,6 +23,7 @@
 package com.oracle.graal.hotspot.replacements;
 
 import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*;
+import static com.oracle.graal.phases.GraalOptions.*;
 import static com.oracle.graal.replacements.nodes.BranchProbabilityNode.*;
 
 import java.util.*;
@@ -32,7 +33,6 @@
 import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.nodes.*;
-import com.oracle.graal.phases.*;
 import com.oracle.graal.replacements.*;
 import com.oracle.graal.word.*;
 
@@ -145,7 +145,7 @@
         return metaspaceArray.readWord(metaspaceArrayBaseOffset() + index * wordSize(), LocationIdentity.FINAL_LOCATION);
     }
 
-    private static final SnippetCounter.Group counters = GraalOptions.SnippetCounters ? new SnippetCounter.Group("TypeCheck") : null;
+    private static final SnippetCounter.Group counters = SnippetCounters.getValue() ? new SnippetCounter.Group("TypeCheck") : null;
     static final SnippetCounter hintsHit = new SnippetCounter(counters, "hintsHit", "hit a hint type");
     static final SnippetCounter exactHit = new SnippetCounter(counters, "exactHit", "exact type test succeeded");
     static final SnippetCounter exactMiss = new SnippetCounter(counters, "exactMiss", "exact type test failed");
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ExceptionHandlerStub.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ExceptionHandlerStub.java	Wed Jun 05 15:11:58 2013 +0200
@@ -34,7 +34,7 @@
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.bridge.*;
 import com.oracle.graal.hotspot.meta.*;
-import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.hotspot.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.replacements.*;
 import com.oracle.graal.replacements.Snippet.Fold;
@@ -127,6 +127,6 @@
 
     public static final ForeignCallDescriptor EXCEPTION_HANDLER_FOR_PC = descriptorFor(ExceptionHandlerStub.class, "exceptionHandlerForPc");
 
-    @NodeIntrinsic(value = ForeignCallNode.class, setStampFromReturnType = true)
+    @NodeIntrinsic(value = StubForeignCallNode.class, setStampFromReturnType = true)
     public static native Word exceptionHandlerForPc(@ConstantNodeParameter ForeignCallDescriptor exceptionHandlerForPc, Word thread);
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ForeignCallStub.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ForeignCallStub.java	Wed Jun 05 15:11:58 2013 +0200
@@ -24,9 +24,9 @@
 
 import static com.oracle.graal.api.code.CallingConvention.Type.*;
 import static com.oracle.graal.api.meta.MetaUtil.*;
-import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
 import static com.oracle.graal.hotspot.HotSpotForeignCallLinkage.RegisterEffect.*;
 import static com.oracle.graal.hotspot.HotSpotForeignCallLinkage.Transition.*;
+import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
 
 import java.lang.reflect.*;
 
@@ -40,7 +40,6 @@
 import com.oracle.graal.hotspot.replacements.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
-import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind;
 import com.oracle.graal.nodes.spi.*;
@@ -283,14 +282,14 @@
         return invoke;
     }
 
-    private ForeignCallNode createTargetCall(GraphBuilder builder, LocalNode[] locals, ReadRegisterNode thread) {
+    private StubForeignCallNode createTargetCall(GraphBuilder builder, LocalNode[] locals, ReadRegisterNode thread) {
         if (prependThread) {
             ValueNode[] targetArguments = new ValueNode[1 + locals.length];
             targetArguments[0] = thread;
             System.arraycopy(locals, 0, targetArguments, 1, locals.length);
-            return builder.append(new ForeignCallNode(runtime, target.getDescriptor(), targetArguments));
+            return builder.append(new StubForeignCallNode(runtime, target.getDescriptor(), targetArguments));
         } else {
-            return builder.append(new ForeignCallNode(runtime, target.getDescriptor(), locals));
+            return builder.append(new StubForeignCallNode(runtime, target.getDescriptor(), locals));
         }
     }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewArrayStub.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewArrayStub.java	Wed Jun 05 15:11:58 2013 +0200
@@ -36,7 +36,6 @@
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.nodes.*;
 import com.oracle.graal.hotspot.replacements.*;
-import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.replacements.*;
 import com.oracle.graal.replacements.Snippet.ConstantParameter;
@@ -122,6 +121,6 @@
 
     public static final ForeignCallDescriptor NEW_ARRAY_C = descriptorFor(NewArrayStub.class, "newArrayC");
 
-    @NodeIntrinsic(ForeignCallNode.class)
+    @NodeIntrinsic(StubForeignCallNode.class)
     public static native void newArrayC(@ConstantNodeParameter ForeignCallDescriptor newArrayC, Word thread, Word hub, int length);
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewInstanceStub.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewInstanceStub.java	Wed Jun 05 15:11:58 2013 +0200
@@ -37,7 +37,6 @@
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.nodes.*;
 import com.oracle.graal.hotspot.replacements.*;
-import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.replacements.*;
 import com.oracle.graal.replacements.Snippet.ConstantParameter;
@@ -242,6 +241,6 @@
 
     public static final ForeignCallDescriptor NEW_INSTANCE_C = descriptorFor(NewInstanceStub.class, "newInstanceC");
 
-    @NodeIntrinsic(ForeignCallNode.class)
+    @NodeIntrinsic(StubForeignCallNode.class)
     public static native void newInstanceC(@ConstantNodeParameter ForeignCallDescriptor newInstanceC, Word thread, Word hub);
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/StubUtil.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/StubUtil.java	Wed Jun 05 15:11:58 2013 +0200
@@ -35,7 +35,6 @@
 import com.oracle.graal.graph.Node.ConstantNodeParameter;
 import com.oracle.graal.graph.Node.NodeIntrinsic;
 import com.oracle.graal.hotspot.nodes.*;
-import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.replacements.*;
 import com.oracle.graal.replacements.Snippet.Fold;
 import com.oracle.graal.word.*;
@@ -50,15 +49,15 @@
     public static final ForeignCallDescriptor VM_MESSAGE_C = descriptorFor(StubUtil.class, "vmMessageC");
 
     /**
-     * Looks for a {@link ForeignCallNode} node intrinsic named {@code name} in {@code stubClass}
-     * and returns a {@link ForeignCallDescriptor} based on its signature and the value of
-     * {@code hasSideEffect}.
+     * Looks for a {@link StubForeignCallNode} node intrinsic named {@code name} in
+     * {@code stubClass} and returns a {@link ForeignCallDescriptor} based on its signature and the
+     * value of {@code hasSideEffect}.
      */
     public static ForeignCallDescriptor descriptorFor(Class<?> stubClass, String name) {
         Method found = null;
         for (Method method : stubClass.getDeclaredMethods()) {
             if (Modifier.isStatic(method.getModifiers()) && method.getAnnotation(NodeIntrinsic.class) != null && method.getName().equals(name)) {
-                if (method.getAnnotation(NodeIntrinsic.class).value() == ForeignCallNode.class) {
+                if (method.getAnnotation(NodeIntrinsic.class).value() == StubForeignCallNode.class) {
                     assert found == null : "found more than one foreign call named " + name + " in " + stubClass;
                     assert method.getParameterTypes().length != 0 && method.getParameterTypes()[0] == ForeignCallDescriptor.class : "first parameter of foreign call '" + name + "' in " + stubClass +
                                     " must be of type " + ForeignCallDescriptor.class.getSimpleName();
@@ -81,7 +80,7 @@
         }
     }
 
-    @NodeIntrinsic(ForeignCallNode.class)
+    @NodeIntrinsic(StubForeignCallNode.class)
     private static native void vmMessageC(@ConstantNodeParameter ForeignCallDescriptor stubPrintfC, boolean vmError, Word format, long v1, long v2, long v3);
 
     /**
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/UnwindExceptionToCallerStub.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/UnwindExceptionToCallerStub.java	Wed Jun 05 15:11:58 2013 +0200
@@ -34,8 +34,8 @@
 import com.oracle.graal.graph.Node.NodeIntrinsic;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.hotspot.nodes.*;
 import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.replacements.*;
 import com.oracle.graal.replacements.Snippet.Fold;
@@ -99,6 +99,6 @@
 
     public static final ForeignCallDescriptor EXCEPTION_HANDLER_FOR_RETURN_ADDRESS = descriptorFor(UnwindExceptionToCallerStub.class, "exceptionHandlerForReturnAddress");
 
-    @NodeIntrinsic(value = ForeignCallNode.class, setStampFromReturnType = true)
+    @NodeIntrinsic(value = StubForeignCallNode.class, setStampFromReturnType = true)
     public static native Word exceptionHandlerForReturnAddress(@ConstantNodeParameter ForeignCallDescriptor exceptionHandlerForReturnAddress, Word thread, Word returnAddress);
 }
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/BciBlockMapping.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/BciBlockMapping.java	Wed Jun 05 15:11:58 2013 +0200
@@ -23,6 +23,7 @@
 package com.oracle.graal.java;
 
 import static com.oracle.graal.bytecode.Bytecodes.*;
+import static com.oracle.graal.phases.GraalOptions.*;
 
 import java.util.*;
 
@@ -31,7 +32,6 @@
 import com.oracle.graal.bytecode.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.nodes.*;
-import com.oracle.graal.phases.*;
 
 /**
  * Builds a mapping between bytecodes and basic blocks and builds a conservative control flow graph
@@ -187,7 +187,7 @@
         makeExceptionEntries();
         iterateOverBytecodes();
         if (hasJsrBytecodes) {
-            if (!GraalOptions.SupportJsrBytecodes) {
+            if (!SupportJsrBytecodes.getValue()) {
                 throw new JsrNotSupportedBailout("jsr/ret parsing disabled");
             }
             createJsrAlternatives(blockMap[0]);
@@ -209,7 +209,7 @@
         if (Debug.isLogEnabled()) {
             this.log("Before LivenessAnalysis");
         }
-        if (GraalOptions.OptLivenessAnalysis) {
+        if (OptLivenessAnalysis.getValue()) {
             Debug.scope("LivenessAnalysis", new Runnable() {
 
                 @Override
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Wed Jun 05 15:11:58 2013 +0200
@@ -27,6 +27,7 @@
 import static com.oracle.graal.api.meta.DeoptimizationReason.*;
 import static com.oracle.graal.bytecode.Bytecodes.*;
 import static com.oracle.graal.java.GraphBuilderPhase.RuntimeCalls.*;
+import static com.oracle.graal.phases.GraalOptions.*;
 import static java.lang.reflect.Modifier.*;
 
 import java.lang.reflect.*;
@@ -158,7 +159,7 @@
         methodSynchronizedObject = null;
         this.currentGraph = graph;
         this.frameState = new FrameStateBuilder(method, graph, graphBuilderConfig.eagerResolving());
-        TTY.Filter filter = new TTY.Filter(GraalOptions.PrintFilter, method);
+        TTY.Filter filter = new TTY.Filter(PrintFilter.getValue(), method);
         try {
             build();
         } finally {
@@ -182,7 +183,7 @@
     }
 
     private void build() {
-        if (GraalOptions.PrintProfilingInformation) {
+        if (PrintProfilingInformation.getValue()) {
             TTY.println("Profiling info for " + method);
             TTY.println(MetaUtil.indent(MetaUtil.profileToString(profilingInfo, method, CodeUtil.NEW_LINE), "  "));
         }
@@ -921,7 +922,7 @@
         append(new IfNode(currentGraph.unique(new IsNullNode(receiver)), trueSucc, falseSucc, 0.1));
         lastInstr = falseSucc;
 
-        if (GraalOptions.OmitHotExceptionStacktrace) {
+        if (OmitHotExceptionStacktrace.getValue()) {
             ValueNode exception = ConstantNode.forObject(cachedNullPointerException, runtime, currentGraph);
             trueSucc.setNext(handleException(exception, bci()));
         } else {
@@ -945,7 +946,7 @@
         append(new IfNode(currentGraph.unique(new IntegerBelowThanNode(index, length)), trueSucc, falseSucc, 0.9));
         lastInstr = trueSucc;
 
-        if (GraalOptions.OmitHotExceptionStacktrace) {
+        if (OmitHotExceptionStacktrace.getValue()) {
             ValueNode exception = ConstantNode.forObject(cachedArrayIndexOutOfBoundsException, runtime, currentGraph);
             falseSucc.setNext(handleException(exception, bci()));
         } else {
@@ -1023,7 +1024,7 @@
         if (target instanceof ResolvedJavaMethod) {
             ResolvedJavaMethod resolvedTarget = (ResolvedJavaMethod) target;
             ResolvedJavaType holder = resolvedTarget.getDeclaringClass();
-            if (!holder.isInitialized() && GraalOptions.ResolveClassBeforeStaticInvoke) {
+            if (!holder.isInitialized() && ResolveClassBeforeStaticInvoke.getValue()) {
                 handleUnresolvedInvoke(target, InvokeKind.Static);
             } else {
                 ValueNode[] args = frameState.popArguments(resolvedTarget.getSignature().getParameterSlots(false), resolvedTarget.getSignature().getParameterCount(false));
@@ -1123,7 +1124,7 @@
 
     private void appendInvoke(InvokeKind invokeKind, ResolvedJavaMethod targetMethod, ValueNode[] args) {
         Kind resultType = targetMethod.getSignature().getReturnKind();
-        if (GraalOptions.DeoptALot) {
+        if (DeoptALot.getValue()) {
             append(new DeoptimizeNode(DeoptimizationAction.None, RuntimeConstraint));
             frameState.pushReturn(resultType, ConstantNode.defaultForKind(resultType, currentGraph));
             return;
@@ -1766,7 +1767,7 @@
     }
 
     private void traceState() {
-        if (GraalOptions.TraceBytecodeParserLevel >= TRACELEVEL_STATE && Debug.isLogEnabled()) {
+        if (TraceBytecodeParserLevel.getValue() >= TRACELEVEL_STATE && Debug.isLogEnabled()) {
             Debug.log(String.format("|   state [nr locals = %d, stack depth = %d, method = %s]", frameState.localsSize(), frameState.stackSize(), method));
             for (int i = 0; i < frameState.localsSize(); ++i) {
                 ValueNode value = frameState.localAt(i);
@@ -1996,7 +1997,7 @@
     }
 
     private void traceInstruction(int bci, int opcode, boolean blockStart) {
-        if (GraalOptions.TraceBytecodeParserLevel >= TRACELEVEL_INSTRUCTIONS && Debug.isLogEnabled()) {
+        if (TraceBytecodeParserLevel.getValue() >= TRACELEVEL_INSTRUCTIONS && Debug.isLogEnabled()) {
             StringBuilder sb = new StringBuilder(40);
             sb.append(blockStart ? '+' : '|');
             if (bci < 10) {
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64BitManipulationOp.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64BitManipulationOp.java	Wed Jun 05 15:11:58 2013 +0200
@@ -25,6 +25,7 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.amd64.*;
+import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
 
 public class AMD64BitManipulationOp extends AMD64LIRInstruction {
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64BreakpointOp.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64BreakpointOp.java	Wed Jun 05 15:11:58 2013 +0200
@@ -26,7 +26,7 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.amd64.*;
-import com.oracle.graal.lir.LIRInstruction.Opcode;
+import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
 
 /**
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ByteSwapOp.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ByteSwapOp.java	Wed Jun 05 15:11:58 2013 +0200
@@ -25,7 +25,7 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.amd64.*;
-import com.oracle.graal.lir.LIRInstruction.Opcode;
+import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
 
 @Opcode("BSWAP")
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Call.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Call.java	Wed Jun 05 15:11:58 2013 +0200
@@ -29,7 +29,6 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.amd64.*;
 import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.LIRInstruction.Opcode;
 import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.nodes.spi.*;
 
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Compare.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Compare.java	Wed Jun 05 15:11:58 2013 +0200
@@ -28,6 +28,7 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.amd64.*;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
 
 // @formatter:off
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ControlFlow.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ControlFlow.java	Wed Jun 05 15:11:58 2013 +0200
@@ -35,7 +35,6 @@
 import com.oracle.graal.asm.amd64.AMD64Assembler.ConditionFlag;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.LIRInstruction.Opcode;
 import com.oracle.graal.lir.StandardOp.FallThroughOp;
 import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.nodes.calc.*;
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64MathIntrinsicOp.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64MathIntrinsicOp.java	Wed Jun 05 15:11:58 2013 +0200
@@ -27,6 +27,7 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.amd64.*;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
 
 // @formatter:off
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java	Wed Jun 05 15:11:58 2013 +0200
@@ -35,7 +35,6 @@
 import com.oracle.graal.asm.amd64.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.LIRInstruction.Opcode;
 import com.oracle.graal.lir.StandardOp.MoveOp;
 import com.oracle.graal.lir.asm.*;
 
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64RestoreRegistersOp.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64RestoreRegistersOp.java	Wed Jun 05 15:11:58 2013 +0200
@@ -26,7 +26,7 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.asm.amd64.*;
-import com.oracle.graal.lir.LIRInstruction.Opcode;
+import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
 
 /**
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64SaveRegistersOp.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64SaveRegistersOp.java	Wed Jun 05 15:11:58 2013 +0200
@@ -29,7 +29,6 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.asm.amd64.*;
 import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.LIRInstruction.Opcode;
 import com.oracle.graal.lir.asm.*;
 
 /**
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ZapRegistersOp.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ZapRegistersOp.java	Wed Jun 05 15:11:58 2013 +0200
@@ -30,7 +30,6 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.amd64.*;
 import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.LIRInstruction.Opcode;
 import com.oracle.graal.lir.asm.*;
 
 /**
--- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXBitManipulationOp.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXBitManipulationOp.java	Wed Jun 05 15:11:58 2013 +0200
@@ -26,6 +26,7 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.ptx.*;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
 
 public class PTXBitManipulationOp extends PTXLIRInstruction {
--- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXCompare.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXCompare.java	Wed Jun 05 15:11:58 2013 +0200
@@ -29,6 +29,7 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.ptx.*;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.nodes.calc.*;
 
--- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXMove.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXMove.java	Wed Jun 05 15:11:58 2013 +0200
@@ -30,7 +30,6 @@
 import com.oracle.graal.asm.ptx.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.LIRInstruction.Opcode;
 import com.oracle.graal.lir.StandardOp.MoveOp;
 import com.oracle.graal.lir.asm.*;
 
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java	Wed Jun 05 15:11:58 2013 +0200
@@ -56,7 +56,7 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.sparc.SPARCAssembler;
 import com.oracle.graal.graph.GraalInternalError;
-import com.oracle.graal.lir.LIRFrameState;
+import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.TargetMethodAssembler;
 
 //@formatter:off
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBitManipulationOp.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBitManipulationOp.java	Wed Jun 05 15:11:58 2013 +0200
@@ -30,6 +30,7 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.sparc.*;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.sparc.SPARC;
 
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBreakpointOp.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBreakpointOp.java	Wed Jun 05 15:11:58 2013 +0200
@@ -25,9 +25,9 @@
 import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
 
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.asm.sparc.SPARCAssembler;
+import com.oracle.graal.asm.sparc.*;
 import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Trap;
-import com.oracle.graal.lir.LIRInstruction.*;
+import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
 
 /**
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCByteSwapOp.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCByteSwapOp.java	Wed Jun 05 15:11:58 2013 +0200
@@ -24,7 +24,7 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.sparc.*;
-import com.oracle.graal.lir.LIRInstruction.Opcode;
+import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
 
 @Opcode("BSWAP")
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCCompare.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCCompare.java	Wed Jun 05 15:11:58 2013 +0200
@@ -30,6 +30,7 @@
 import com.oracle.graal.asm.sparc.SPARCAssembler;
 import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Cmp;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
 
 //@formatter:off
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java	Wed Jun 05 15:11:58 2013 +0200
@@ -25,22 +25,21 @@
 import static com.oracle.graal.api.code.ValueUtil.*;
 import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
 
+import com.oracle.graal.api.code.CompilationResult.JumpTable;
 import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.code.CompilationResult.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.*;
 import com.oracle.graal.asm.sparc.*;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Bpe;
 import com.oracle.graal.asm.sparc.SPARCAssembler.CC;
 import com.oracle.graal.asm.sparc.SPARCAssembler.ConditionFlag;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Bpe;
 import com.oracle.graal.asm.sparc.SPARCAssembler.Subcc;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.LIRInstruction.*;
-import com.oracle.graal.lir.StandardOp.*;
+import com.oracle.graal.lir.StandardOp.FallThroughOp;
 import com.oracle.graal.lir.asm.*;
-import com.oracle.graal.nodes.calc.Condition;
-import com.oracle.graal.sparc.SPARC;
+import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.sparc.*;
 
 public class SPARCControlFlow {
 
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMathIntrinsicOp.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMathIntrinsicOp.java	Wed Jun 05 15:11:58 2013 +0200
@@ -28,6 +28,7 @@
 import com.oracle.graal.asm.sparc.SPARCAssembler;
 import com.oracle.graal.asm.sparc.SPARCAssembler.Fsqrtd;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
 
 public class SPARCMathIntrinsicOp extends SPARCLIRInstruction {
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java	Wed Jun 05 15:11:58 2013 +0200
@@ -27,8 +27,7 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.asm.sparc.SPARCAddress;
-import com.oracle.graal.asm.sparc.SPARCAssembler;
+import com.oracle.graal.asm.sparc.*;
 import com.oracle.graal.asm.sparc.SPARCAssembler.Lddf;
 import com.oracle.graal.asm.sparc.SPARCAssembler.Ldf;
 import com.oracle.graal.asm.sparc.SPARCAssembler.Ldsb;
@@ -37,20 +36,19 @@
 import com.oracle.graal.asm.sparc.SPARCAssembler.Lduw;
 import com.oracle.graal.asm.sparc.SPARCAssembler.Ldx;
 import com.oracle.graal.asm.sparc.SPARCAssembler.Membar;
+import com.oracle.graal.asm.sparc.SPARCAssembler.NullCheck;
 import com.oracle.graal.asm.sparc.SPARCAssembler.Or;
 import com.oracle.graal.asm.sparc.SPARCAssembler.Stb;
 import com.oracle.graal.asm.sparc.SPARCAssembler.Sth;
 import com.oracle.graal.asm.sparc.SPARCAssembler.Stw;
 import com.oracle.graal.asm.sparc.SPARCAssembler.Stx;
-import com.oracle.graal.asm.sparc.SPARCAssembler.NullCheck;
 import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Setuw;
 import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Setx;
-import com.oracle.graal.graph.GraalInternalError;
+import com.oracle.graal.graph.*;
 import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.LIRInstruction.*;
 import com.oracle.graal.lir.StandardOp.MoveOp;
-import com.oracle.graal.lir.asm.TargetMethodAssembler;
-import com.oracle.graal.sparc.SPARC;
+import com.oracle.graal.lir.asm.*;
+import com.oracle.graal.sparc.*;
 
 public class SPARCMove {
 
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/InfopointOp.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/InfopointOp.java	Wed Jun 05 15:11:58 2013 +0200
@@ -22,8 +22,6 @@
  */
 package com.oracle.graal.lir;
 
-import static com.oracle.graal.lir.LIRInstruction.Opcode;
-
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.lir.asm.*;
 
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstruction.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstruction.java	Wed Jun 05 15:11:58 2013 +0200
@@ -144,13 +144,6 @@
     public static @interface State {
     }
 
-    @Retention(RetentionPolicy.RUNTIME)
-    @Target({ElementType.TYPE, ElementType.FIELD})
-    public static @interface Opcode {
-
-        String value() default "";
-    }
-
     /**
      * Flags for an operand.
      */
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstructionClass.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstructionClass.java	Wed Jun 05 15:11:58 2013 +0200
@@ -174,8 +174,8 @@
 
         @Override
         protected void scan(Class<?> clazz) {
-            if (clazz.getAnnotation(LIRInstruction.Opcode.class) != null) {
-                opcodeConstant = clazz.getAnnotation(LIRInstruction.Opcode.class).value();
+            if (clazz.getAnnotation(Opcode.class) != null) {
+                opcodeConstant = clazz.getAnnotation(Opcode.class).value();
             }
             opcodeOffset = -1;
 
@@ -199,7 +199,7 @@
                 super.scanField(field, type, offset);
             }
 
-            if (field.getAnnotation(LIRInstruction.Opcode.class) != null) {
+            if (field.getAnnotation(Opcode.class) != null) {
                 assert opcodeConstant == null && opcodeOffset == -1 : "Can have only one Opcode definition: " + field.getType();
                 opcodeOffset = offset;
             }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/Opcode.java	Wed Jun 05 15:11:58 2013 +0200
@@ -0,0 +1,40 @@
+/*
+ * 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.lir;
+
+import java.lang.annotation.*;
+
+/**
+ * Denotes an opcode name for an annotated {@link LIRInstruction}.
+ * <p>
+ * Note: Unlike the other LIR related annotations declared as inner classes of
+ * {@link LIRInstruction}, this annotation is in a top level file to work around a <a
+ * href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=409824">bug</a> in Eclipse causing spurious
+ * warnings about unused imports.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.TYPE, ElementType.FIELD})
+public @interface Opcode {
+
+    String value() default "";
+}
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopPolicies.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopPolicies.java	Wed Jun 05 15:11:58 2013 +0200
@@ -22,12 +22,13 @@
  */
 package com.oracle.graal.loop;
 
+import static com.oracle.graal.phases.GraalOptions.*;
+
 import com.oracle.graal.debug.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.cfg.*;
 import com.oracle.graal.nodes.util.*;
-import com.oracle.graal.phases.*;
 
 public abstract class LoopPolicies {
 
@@ -39,7 +40,7 @@
     public static boolean shouldPeel(LoopEx loop, NodesToDoubles probabilities) {
         LoopBeginNode loopBegin = loop.loopBegin();
         double entryProbability = probabilities.get(loopBegin.forwardEnd());
-        return entryProbability > GraalOptions.MinimumPeelProbability && loop.size() + loopBegin.graph().getNodeCount() < GraalOptions.MaximumDesiredSize;
+        return entryProbability > MinimumPeelProbability.getValue() && loop.size() + loopBegin.graph().getNodeCount() < MaximumDesiredSize.getValue();
     }
 
     public static boolean shouldFullUnroll(LoopEx loop) {
@@ -48,14 +49,14 @@
         }
         CountedLoopInfo counted = loop.counted();
         long exactTrips = counted.constantMaxTripCount();
-        int maxNodes = (counted.isExactTripCount() && counted.isConstantExactTripCount()) ? GraalOptions.ExactFullUnrollMaxNodes : GraalOptions.FullUnrollMaxNodes;
-        maxNodes = Math.min(maxNodes, GraalOptions.MaximumDesiredSize - loop.loopBegin().graph().getNodeCount());
+        int maxNodes = (counted.isExactTripCount() && counted.isConstantExactTripCount()) ? ExactFullUnrollMaxNodes.getValue() : FullUnrollMaxNodes.getValue();
+        maxNodes = Math.min(maxNodes, MaximumDesiredSize.getValue() - loop.loopBegin().graph().getNodeCount());
         int size = Math.max(1, loop.size() - 1 - loop.loopBegin().phis().count());
         return size * exactTrips <= maxNodes;
     }
 
     public static boolean shouldTryUnswitch(LoopEx loop) {
-        return loop.loopBegin().unswitches() <= GraalOptions.LoopMaxUnswitch;
+        return loop.loopBegin().unswitches() <= LoopMaxUnswitch.getValue();
     }
 
     public static boolean shouldUnswitch(LoopEx loop, ControlSplitNode controlSplit) {
@@ -77,7 +78,7 @@
         }
         int netDiff = loopTotal - (inBranchTotal);
         double uncertainty = 1 - maxProbability;
-        int maxDiff = GraalOptions.LoopUnswitchMaxIncrease + (int) (GraalOptions.LoopUnswitchUncertaintyBoost * loop.loopBegin().loopFrequency() * uncertainty);
+        int maxDiff = LoopUnswitchMaxIncrease.getValue() + (int) (LoopUnswitchUncertaintyBoost.getValue() * loop.loopBegin().loopFrequency() * uncertainty);
         Debug.log("shouldUnswitch(%s, %s) : delta=%d, max=%d, %.2f%% inside of branches", loop, controlSplit, netDiff, maxDiff, (double) (inBranchTotal) / loopTotal * 100);
         return netDiff <= maxDiff;
     }
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopTransformations.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopTransformations.java	Wed Jun 05 15:11:58 2013 +0200
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.loop;
 
+import static com.oracle.graal.phases.GraalOptions.*;
+
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
@@ -29,12 +31,11 @@
 import com.oracle.graal.graph.NodeClass.Position;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.extended.*;
-import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.common.*;
 
 public abstract class LoopTransformations {
 
-    private static final int UNROLL_LIMIT = GraalOptions.FullUnrollMaxNodes * 2;
+    private static final int UNROLL_LIMIT = FullUnrollMaxNodes.getValue() * 2;
 
     private LoopTransformations() {
         // does not need to be instantiated
@@ -61,7 +62,7 @@
             int mark = graph.getMark();
             peel(loop);
             new CanonicalizerPhase.Instance(runtime, assumptions, mark, null).apply(graph);
-            if (iterations++ > UNROLL_LIMIT || graph.getNodeCount() > GraalOptions.MaximumDesiredSize * 3) {
+            if (iterations++ > UNROLL_LIMIT || graph.getNodeCount() > MaximumDesiredSize.getValue() * 3) {
                 throw new BailoutException("FullUnroll : Graph seems to grow out of proportion");
             }
         }
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopSafepointEliminationPhase.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopSafepointEliminationPhase.java	Wed Jun 05 15:11:58 2013 +0200
@@ -39,9 +39,15 @@
             loops.detectedCountedLoops();
             for (LoopEx loop : loops.countedLoops()) {
                 if (loop.lirLoop().children.isEmpty() && loop.counted().getKind() == Kind.Int) {
-                    loop.counted().createOverFlowGuard();
+                    boolean hasSafepoint = false;
                     for (LoopEndNode loopEnd : loop.loopBegin().loopEnds()) {
-                        loopEnd.disableSafepoint();
+                        hasSafepoint |= loopEnd.canSafepoint();
+                    }
+                    if (hasSafepoint) {
+                        loop.counted().createOverFlowGuard();
+                        for (LoopEndNode loopEnd : loop.loopBegin().loopEnds()) {
+                            loopEnd.disableSafepoint();
+                        }
                     }
                 }
             }
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopTransformHighPhase.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopTransformHighPhase.java	Wed Jun 05 15:11:58 2013 +0200
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.loop.phases;
 
+import static com.oracle.graal.phases.GraalOptions.*;
+
 import com.oracle.graal.debug.*;
 import com.oracle.graal.loop.*;
 import com.oracle.graal.nodes.*;
@@ -34,7 +36,7 @@
     @Override
     protected void run(StructuredGraph graph) {
         if (graph.hasLoops()) {
-            if (GraalOptions.LoopPeeling) {
+            if (LoopPeeling.getValue()) {
                 NodesToDoubles probabilities = new ComputeProbabilityClosure(graph).apply();
                 LoopsData data = new LoopsData(graph);
                 for (LoopEx loop : data.outterFirst()) {
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopTransformLowPhase.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopTransformLowPhase.java	Wed Jun 05 15:11:58 2013 +0200
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.loop.phases;
 
+import static com.oracle.graal.phases.GraalOptions.*;
+
 import com.oracle.graal.debug.*;
 import com.oracle.graal.graph.NodeClass.NodeClassIterator;
 import com.oracle.graal.loop.*;
@@ -35,7 +37,7 @@
     @Override
     protected void run(StructuredGraph graph) {
         if (graph.hasLoops()) {
-            if (GraalOptions.ReassociateInvariants) {
+            if (ReassociateInvariants.getValue()) {
                 final LoopsData dataReassociate = new LoopsData(graph);
                 Debug.scope("ReassociateInvariants", new Runnable() {
 
@@ -47,7 +49,7 @@
                     }
                 });
             }
-            if (GraalOptions.LoopUnswitch) {
+            if (LoopUnswitch.getValue()) {
                 boolean unswitched;
                 do {
                     unswitched = false;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java	Wed Jun 05 15:11:58 2013 +0200
@@ -25,12 +25,13 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.nodes.util.*;
 
 @NodeInfo(nameTemplate = "FixedGuard(!={p#negated}) {p#reason/s}")
-public final class FixedGuardNode extends FixedWithNextNode implements Simplifiable, Lowerable, Node.IterableNodeType, Negatable {
+public final class FixedGuardNode extends FixedWithNextNode implements Simplifiable, Lowerable, Node.IterableNodeType, Negatable, GuardingNode {
 
     @Input private LogicNode condition;
     private final DeoptimizationReason reason;
@@ -51,7 +52,7 @@
     }
 
     public FixedGuardNode(LogicNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action, boolean negated) {
-        super(StampFactory.forVoid());
+        super(StampFactory.dependency());
         this.action = action;
         this.negated = negated;
         this.condition = condition;
@@ -84,6 +85,7 @@
         if (condition instanceof LogicConstantNode) {
             LogicConstantNode c = (LogicConstantNode) condition;
             if (c.getValue() != negated) {
+                this.replaceAtUsages(BeginNode.prevBegin(this));
                 graph().removeFixed(this);
             } else {
                 FixedNode next = this.next();
@@ -121,4 +123,9 @@
         negated = !negated;
         return this;
     }
+
+    @Override
+    public FixedGuardNode asNode() {
+        return this;
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ForeignCallNode.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ForeignCallNode.java	Wed Jun 05 15:11:58 2013 +0200
@@ -91,7 +91,7 @@
     public FrameState getDeoptimizationState() {
         if (deoptState != null) {
             return deoptState;
-        } else if (stateAfter() != null) {
+        } else if (stateAfter() != null && canDeoptimize()) {
             FrameState stateDuring = stateAfter();
             if ((stateDuring.stackSize() > 0 && stateDuring.stackAt(stateDuring.stackSize() - 1) == this) || (stateDuring.stackSize() > 1 && stateDuring.stackAt(stateDuring.stackSize() - 2) == this)) {
                 stateDuring = stateDuring.duplicateModified(stateDuring.bci, stateDuring.rethrowException(), this.kind());
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/OSRStartNode.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/OSRStartNode.java	Wed Jun 05 15:11:58 2013 +0200
@@ -30,9 +30,7 @@
 
     @Override
     public void lower(LoweringTool tool, LoweringType loweringType) {
-        if (loweringType == LoweringType.AFTER_GUARDS) {
-            tool.getRuntime().lower(this, tool);
-        }
+        tool.getRuntime().lower(this, tool);
     }
 
     public NodeIterable<OSRLocalNode> getOSRLocals() {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java	Wed Jun 05 15:11:58 2013 +0200
@@ -27,11 +27,12 @@
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
+import com.oracle.graal.nodes.virtual.*;
 
 /**
  * Reads an {@linkplain AccessNode accessed} value.
  */
-public final class ReadNode extends FloatableAccessNode implements Node.IterableNodeType, LIRLowerable, Canonicalizable, PiPushable {
+public final class ReadNode extends FloatableAccessNode implements Node.IterableNodeType, LIRLowerable, Canonicalizable, PiPushable, Virtualizable {
 
     public ReadNode(ValueNode object, ValueNode location, Stamp stamp, WriteBarrierType barrierType, boolean compress) {
         super(object, location, stamp, barrierType, compress);
@@ -128,6 +129,21 @@
         return false;
     }
 
+    @Override
+    public void virtualize(VirtualizerTool tool) {
+        if (location() instanceof ConstantLocationNode) {
+            ConstantLocationNode constantLocation = (ConstantLocationNode) location();
+            State state = tool.getObjectState(object());
+            if (state != null && state.getState() == EscapeState.Virtual) {
+                VirtualObjectNode virtual = state.getVirtualObject();
+                int entryIndex = virtual.entryIndexForOffset(constantLocation.getDisplacement());
+                if (entryIndex != -1 && virtual.entryKind(entryIndex) == constantLocation.getValueKind()) {
+                    tool.replaceWith(state.getEntry(entryIndex));
+                }
+            }
+        }
+    }
+
     /**
      * Reads a value from memory.
      * 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeLoadNode.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeLoadNode.java	Wed Jun 05 15:11:58 2013 +0200
@@ -83,8 +83,8 @@
                                                                   // UnsafeAccess only have an
                                                                   // object base
                 ObjectStamp receiverStamp = object().objectStamp();
-                if (receiverStamp.nonNull()) {
-                    ResolvedJavaType receiverType = receiverStamp.type();
+                ResolvedJavaType receiverType = receiverStamp.type();
+                if (receiverStamp.nonNull() && receiverType != null) {
                     ResolvedJavaField field = receiverType.findInstanceFieldWithOffset(displacement());
                     if (field != null) {
                         return this.graph().add(new LoadFieldNode(object(), field));
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ValueAnchorNode.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ValueAnchorNode.java	Wed Jun 05 15:11:58 2013 +0200
@@ -61,6 +61,10 @@
         }
     }
 
+    public void removeAnchoredNode(ValueNode value) {
+        this.anchored.remove(value);
+    }
+
     @Override
     public ValueNode canonical(CanonicalizerTool tool) {
         if (permanent) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java	Wed Jun 05 15:11:58 2013 +0200
@@ -28,11 +28,12 @@
 import com.oracle.graal.nodes.extended.LocationNode.Location;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
+import com.oracle.graal.nodes.virtual.*;
 
 /**
  * Writes a given {@linkplain #value() value} a {@linkplain AccessNode memory location}.
  */
-public final class WriteNode extends AccessNode implements StateSplit, LIRLowerable, MemoryCheckpoint, Node.IterableNodeType {
+public final class WriteNode extends AccessNode implements StateSplit, LIRLowerable, MemoryCheckpoint, Node.IterableNodeType, Virtualizable {
 
     @Input private ValueNode value;
     @Input(notDataflow = true) private FrameState stateAfter;
@@ -75,4 +76,20 @@
     public LocationIdentity[] getLocationIdentities() {
         return new LocationIdentity[]{location().getLocationIdentity()};
     }
+
+    @Override
+    public void virtualize(VirtualizerTool tool) {
+        if (location() instanceof ConstantLocationNode) {
+            ConstantLocationNode constantLocation = (ConstantLocationNode) location();
+            State state = tool.getObjectState(object());
+            if (state != null && state.getState() == EscapeState.Virtual) {
+                VirtualObjectNode virtual = state.getVirtualObject();
+                int entryIndex = virtual.entryIndexForOffset(constantLocation.getDisplacement());
+                if (entryIndex != -1 && virtual.entryKind(entryIndex) == constantLocation.getValueKind()) {
+                    tool.setVirtualEntry(state, entryIndex, value());
+                    tool.delete();
+                }
+            }
+        }
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewArrayNode.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewArrayNode.java	Wed Jun 05 15:11:58 2013 +0200
@@ -100,9 +100,7 @@
 
     @Override
     public void lower(LoweringTool tool, LoweringType loweringType) {
-        if (loweringType == LoweringType.AFTER_GUARDS) {
-            tool.getRuntime().lower(this, tool);
-        }
+        tool.getRuntime().lower(this, tool);
     }
 
     @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewInstanceNode.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewInstanceNode.java	Wed Jun 05 15:11:58 2013 +0200
@@ -78,9 +78,7 @@
 
     @Override
     public void lower(LoweringTool tool, LoweringType loweringType) {
-        if (loweringType == LoweringType.AFTER_GUARDS) {
-            tool.getRuntime().lower(this, tool);
-        }
+        tool.getRuntime().lower(this, tool);
     }
 
     @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewMultiArrayNode.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewMultiArrayNode.java	Wed Jun 05 15:11:58 2013 +0200
@@ -63,9 +63,7 @@
 
     @Override
     public void lower(LoweringTool tool, LoweringType loweringType) {
-        if (loweringType == LoweringType.AFTER_GUARDS) {
-            tool.getRuntime().lower(this, tool);
-        }
+        tool.getRuntime().lower(this, tool);
     }
 
     public ResolvedJavaType type() {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LoweringTool.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LoweringTool.java	Wed Jun 05 15:11:58 2013 +0200
@@ -28,11 +28,14 @@
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.cfg.*;
 import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.nodes.spi.Lowerable.LoweringType;
 
 public interface LoweringTool {
 
     GraalCodeCacheProvider getRuntime();
 
+    LoweringType getLoweringType();
+
     Replacements getReplacements();
 
     GuardingNode createNullCheckGuard(GuardedNode guardedNode, ValueNode object);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/CommitAllocationNode.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/CommitAllocationNode.java	Wed Jun 05 15:11:58 2013 +0200
@@ -66,9 +66,7 @@
 
     @Override
     public void lower(LoweringTool tool, LoweringType loweringType) {
-        if (loweringType == LoweringType.AFTER_GUARDS) {
-            tool.getRuntime().lower(this, tool);
-        }
+        tool.getRuntime().lower(this, tool);
     }
 
     @Override
--- a/graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionProcessor.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionProcessor.java	Wed Jun 05 15:11:58 2013 +0200
@@ -106,7 +106,10 @@
         Element enclosing = element.getEnclosingElement();
         String declaringClass = "";
         String separator = "";
+        List<Element> originatingElementsList = new ArrayList<>();
+        originatingElementsList.add(field);
         while (enclosing != null) {
+            originatingElementsList.add(enclosing);
             if (enclosing.getKind() == ElementKind.CLASS || enclosing.getKind() == ElementKind.INTERFACE) {
                 if (enclosing.getModifiers().contains(Modifier.PRIVATE)) {
                     String msg = String.format("Option field cannot be declared in a private %s %s", enclosing.getKind().name().toLowerCase(), enclosing);
@@ -123,9 +126,10 @@
         }
 
         String providerClassName = declaringClass.replace('.', '_') + "_" + fieldName;
+        Element[] originatingElements = originatingElementsList.toArray(new Element[originatingElementsList.size()]);
 
         Filer filer = processingEnv.getFiler();
-        try (PrintWriter out = createSourceFile(element, pkg, providerClassName, filer)) {
+        try (PrintWriter out = createSourceFile(pkg, providerClassName, filer, originatingElements)) {
 
             out.println("/*");
             out.println(" * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.");
@@ -185,24 +189,24 @@
         }
 
         try {
-            createProviderFile(field, pkg, providerClassName);
+            createProviderFile(pkg, providerClassName, originatingElements);
         } catch (IOException e) {
             processingEnv.getMessager().printMessage(Kind.ERROR, e.getMessage(), field);
         }
     }
 
-    private void createProviderFile(Element field, String pkg, String providerClassName) throws IOException {
+    private void createProviderFile(String pkg, String providerClassName, Element... originatingElements) throws IOException {
         String filename = "META-INF/providers/" + pkg + "." + providerClassName;
-        FileObject file = processingEnv.getFiler().createResource(StandardLocation.CLASS_OUTPUT, "", filename, field);
+        FileObject file = processingEnv.getFiler().createResource(StandardLocation.CLASS_OUTPUT, "", filename, originatingElements);
         PrintWriter writer = new PrintWriter(new OutputStreamWriter(file.openOutputStream(), "UTF-8"));
         writer.println(OptionProvider.class.getName());
         writer.close();
     }
 
-    protected PrintWriter createSourceFile(Element element, String pkg, String relativeName, Filer filer) {
+    protected PrintWriter createSourceFile(String pkg, String relativeName, Filer filer, Element... originatingElements) {
         try {
             // Ensure Unix line endings to comply with Graal code style guide checked by Checkstyle
-            JavaFileObject sourceFile = filer.createSourceFile(pkg + "." + relativeName, element);
+            JavaFileObject sourceFile = filer.createSourceFile(pkg + "." + relativeName, originatingElements);
             return new PrintWriter(sourceFile.openWriter()) {
 
                 @Override
--- a/graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionValue.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionValue.java	Wed Jun 05 15:11:58 2013 +0200
@@ -39,13 +39,7 @@
     protected T value;
 
     /**
-     * Guards whether {@link #initialValue()} should be called to give a subclass an opportunity to
-     * provide a context-sensitive initial value for this option.
-     */
-    protected boolean initialValueCalled;
-
-    /**
-     * Create an option.
+     * Creates an option value.
      * 
      * @param value the initial/default value of the option
      */
@@ -53,17 +47,30 @@
         this.value = value;
     }
 
+    private static final Object UNINITIALIZED = "UNINITIALIZED";
+
+    /**
+     * Creates an uninitialized option value for a subclass that initializes itself
+     * {@link #initialValue() lazily}.
+     */
+    @SuppressWarnings("unchecked")
+    protected OptionValue() {
+        this.value = (T) UNINITIALIZED;
+    }
+
+    /**
+     * Lazy initialization of value.
+     */
     protected T initialValue() {
-        return value;
+        throw new InternalError("Uninitialized option value must override initialValue()");
     }
 
     /**
      * Gets the value of this option.
      */
     public final T getValue() {
-        if (!initialValueCalled) {
+        if (value == UNINITIALIZED) {
             value = initialValue();
-            initialValueCalled = true;
         }
         return value;
     }
@@ -74,6 +81,5 @@
     @SuppressWarnings("unchecked")
     public final void setValue(Object v) {
         this.value = (T) v;
-        this.initialValueCalled = true;
     }
 }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FrameStateAssignmentPhase.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FrameStateAssignmentPhase.java	Wed Jun 05 15:11:58 2013 +0200
@@ -41,6 +41,7 @@
             if (node instanceof DeoptimizingNode) {
                 DeoptimizingNode deopt = (DeoptimizingNode) node;
                 if (deopt.canDeoptimize() && deopt.getDeoptimizationState() == null) {
+                    GraalInternalError.guarantee(currentState != null, "no FrameState at DeoptimizingNode %s", deopt);
                     deopt.setDeoptimizationState(currentState);
                 }
             }
@@ -58,10 +59,7 @@
 
         @Override
         protected FrameState merge(MergeNode merge, List<FrameState> states) {
-            if (merge.stateAfter() != null) {
-                return merge.stateAfter();
-            }
-            return singleFrameState(merge, states);
+            return merge.stateAfter() != null ? merge.stateAfter() : singleFrameState(merge, states);
         }
 
         @Override
@@ -73,7 +71,6 @@
         protected Map<LoopExitNode, FrameState> processLoop(LoopBeginNode loop, FrameState initialState) {
             return ReentrantNodeIterator.processLoop(this, loop, initialState).exitStates;
         }
-
     }
 
     @Override
@@ -93,33 +90,12 @@
     }
 
     private static FrameState singleFrameState(@SuppressWarnings("unused") MergeNode merge, List<FrameState> states) {
-        if (states.size() == 0) {
-            return null;
-        }
-        FrameState firstState = states.get(0);
-        FrameState singleState = firstState;
-        if (singleState == null) {
-            return null;
-        }
-        int singleBci = singleState.bci;
+        FrameState singleState = states.get(0);
         for (int i = 1; i < states.size(); ++i) {
-            FrameState cur = states.get(i);
-            if (cur == null) {
+            if (states.get(i) != singleState) {
                 return null;
             }
-
-            if (cur != singleState) {
-                singleState = null;
-            }
-
-            if (cur.bci != singleBci) {
-                singleBci = FrameState.INVALID_FRAMESTATE_BCI;
-            }
-
         }
-        if (singleState != null) {
-            return singleState;
-        }
-        return null;
+        return singleState;
     }
 }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GuardLoweringPhase.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GuardLoweringPhase.java	Wed Jun 05 15:11:58 2013 +0200
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.phases.common;
 
+import static com.oracle.graal.phases.GraalOptions.*;
+
 import java.util.*;
 import java.util.Map.Entry;
 
@@ -220,7 +222,7 @@
 
     private static void processBlock(Block block, SchedulePhase schedule, int implicitNullCheckLimit) {
         List<ScheduledNode> nodes = schedule.nodesFor(block);
-        if (GraalOptions.OptImplicitNullChecks && implicitNullCheckLimit > 0) {
+        if (OptImplicitNullChecks.getValue() && implicitNullCheckLimit > 0) {
             new UseImplicitNullChecks(implicitNullCheckLimit).processNodes(nodes, block.getBeginNode());
         }
         new LowerGuards(block).processNodes(nodes, block.getBeginNode());
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java	Wed Jun 05 15:11:58 2013 +0200
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.phases.common;
 
+import static com.oracle.graal.phases.GraalOptions.*;
+
 import java.util.*;
 import java.util.concurrent.*;
 
@@ -33,6 +35,7 @@
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.nodes.util.*;
+import com.oracle.graal.options.*;
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.PhasePlan.PhasePosition;
 import com.oracle.graal.phases.common.CanonicalizerPhase.CustomCanonicalizer;
@@ -43,6 +46,11 @@
 
 public class InliningPhase extends Phase {
 
+    // @formatter:off
+    @Option(help = "Unconditionally inline intrinsics")
+    public static final OptionValue<Boolean> AlwaysInlineIntrinsics = new OptionValue<>(false);
+    // @formatter:on
+
     private final PhasePlan plan;
     private final MetaAccessProvider runtime;
     private final Assumptions compilationAssumptions;
@@ -182,7 +190,7 @@
             metricInliningRuns.increment();
             Debug.dump(callerGraph, "after %s", callee);
 
-            if (GraalOptions.OptCanonicalizer) {
+            if (OptCanonicalizer.getValue()) {
                 int markBeforeCanonicalization = callerGraph.getMark();
                 new CanonicalizerPhase.Instance(runtime, callerAssumptions, invokeUsages, markBeforeInlining, customCanonicalizer).apply(callerGraph);
 
@@ -268,7 +276,7 @@
                     // probability to check the inlining
                 }
 
-                if (GraalOptions.OptCanonicalizer) {
+                if (OptCanonicalizer.getValue()) {
                     new CanonicalizerPhase.Instance(runtime, assumptions).apply(newGraph);
                 }
 
@@ -278,7 +286,7 @@
     }
 
     private StructuredGraph getCachedGraph(ResolvedJavaMethod method) {
-        if (GraalOptions.CacheGraphs && cache != null) {
+        if (CacheGraphs.getValue() && cache != null) {
             StructuredGraph cachedGraph = cache.get(method);
             if (cachedGraph != null) {
                 return cachedGraph;
@@ -295,14 +303,14 @@
 
         new DeadCodeEliminationPhase().apply(newGraph);
 
-        if (GraalOptions.OptCanonicalizer) {
+        if (OptCanonicalizer.getValue()) {
             new CanonicalizerPhase.Instance(runtime, assumptions).apply(newGraph);
         }
 
-        if (GraalOptions.CullFrameStates) {
+        if (CullFrameStates.getValue()) {
             new CullFrameStatesPhase().apply(newGraph);
         }
-        if (GraalOptions.CacheGraphs && cache != null) {
+        if (CacheGraphs.getValue() && cache != null) {
             cache.put(newGraph.copy());
         }
         return newGraph;
@@ -328,7 +336,7 @@
         }
 
         protected double computeMaximumSize(double relevance, int configuredMaximum) {
-            double inlineRatio = Math.min(GraalOptions.RelevanceCapForInlining, relevance);
+            double inlineRatio = Math.min(RelevanceCapForInlining.getValue(), relevance);
             return configuredMaximum * inlineRatio;
         }
 
@@ -340,7 +348,7 @@
         }
 
         protected boolean isIntrinsic(InlineInfo info) {
-            if (GraalOptions.AlwaysInlineIntrinsics) {
+            if (AlwaysInlineIntrinsics.getValue()) {
                 return onlyIntrinsics(info);
             } else {
                 return onlyForcedIntrinsics(info);
@@ -410,7 +418,7 @@
         }
 
         public boolean continueInlining(StructuredGraph currentGraph) {
-            if (currentGraph.getNodeCount() >= GraalOptions.MaximumDesiredSize) {
+            if (currentGraph.getNodeCount() >= MaximumDesiredSize.getValue()) {
                 InliningUtil.logInliningDecision("inlining is cut off by MaximumDesiredSize");
                 metricInliningStoppedByMaxDesiredSize.increment();
                 return false;
@@ -427,7 +435,7 @@
             double inliningBonus = getInliningBonus(info);
 
             int lowLevelGraphSize = previousLowLevelGraphSize(info);
-            if (GraalOptions.SmallCompiledLowLevelGraphSize > 0 && lowLevelGraphSize > GraalOptions.SmallCompiledLowLevelGraphSize * inliningBonus) {
+            if (SmallCompiledLowLevelGraphSize.getValue() > 0 && lowLevelGraphSize > SmallCompiledLowLevelGraphSize.getValue() * inliningBonus) {
                 return InliningUtil.logNotInlinedMethod(info, inliningDepth, "too large previous low-level graph: %d", lowLevelGraphSize);
             }
 
@@ -439,16 +447,16 @@
              */
 
             int nodes = determineNodeCount(info);
-            if (nodes < GraalOptions.TrivialInliningSize * inliningBonus) {
+            if (nodes < TrivialInliningSize.getValue() * inliningBonus) {
                 return InliningUtil.logInlinedMethod(info, inliningDepth, fullyProcessed, "trivial (nodes=%d)", nodes);
             }
 
             double invokes = determineInvokeProbability(info);
-            if (GraalOptions.LimitInlinedInvokes > 0 && fullyProcessed && invokes > GraalOptions.LimitInlinedInvokes * inliningBonus) {
+            if (LimitInlinedInvokes.getValue() > 0 && fullyProcessed && invokes > LimitInlinedInvokes.getValue() * inliningBonus) {
                 return InliningUtil.logNotInlinedMethod(info, inliningDepth, "invoke probability is too high (%f)", invokes);
             }
 
-            double maximumNodes = computeMaximumSize(relevance, (int) (GraalOptions.MaximumInliningSize * inliningBonus));
+            double maximumNodes = computeMaximumSize(relevance, (int) (MaximumInliningSize.getValue() * inliningBonus));
             if (nodes < maximumNodes) {
                 return InliningUtil.logInlinedMethod(info, inliningDepth, fullyProcessed, "relevance-based (relevance=%f, nodes=%d)", relevance, nodes);
             }
@@ -784,7 +792,7 @@
         }
 
         public double invokeRelevance(Invoke invoke) {
-            return Math.min(GraalOptions.CapInheritedRelevance, relevance) * nodeRelevance.get(invoke.asNode());
+            return Math.min(CapInheritedRelevance.getValue(), relevance) * nodeRelevance.get(invoke.asNode());
         }
     }
 
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java	Wed Jun 05 15:11:58 2013 +0200
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.phases.common;
 
+import static com.oracle.graal.phases.GraalOptions.*;
+
 import java.lang.reflect.*;
 import java.util.*;
 import java.util.concurrent.*;
@@ -98,7 +100,7 @@
      * Print a HotSpot-style inlining message to the console.
      */
     private static void printInlining(final ResolvedJavaMethod method, final Invoke invoke, final int inliningDepth, final boolean success, final String msg, final Object... args) {
-        if (GraalOptions.HotSpotPrintInlining) {
+        if (HotSpotPrintInlining.getValue()) {
             final int mod = method.getModifiers();
             // 1234567
             TTY.print("        ");     // print timestamp
@@ -668,7 +670,7 @@
                 replacementNodes.add(null);
             }
 
-            if (GraalOptions.OptTailDuplication) {
+            if (OptTailDuplication.getValue()) {
                 /*
                  * We might want to perform tail duplication at the merge after a type switch, if
                  * there are invokes that would benefit from the improvement in type information.
@@ -1154,7 +1156,7 @@
                 ArrayList<ResolvedJavaMethod> newConcreteMethods = new ArrayList<>();
                 ArrayList<Double> newConcreteMethodsProbabilities = new ArrayList<>();
                 for (int i = 0; i < concreteMethods.size(); ++i) {
-                    if (concreteMethodsProbabilities.get(i) >= GraalOptions.MegamorphicInliningMinMethodProbability) {
+                    if (concreteMethodsProbabilities.get(i) >= GraalOptions.MegamorphicInliningMinMethodProbability.getValue()) {
                         newConcreteMethods.add(concreteMethods.get(i));
                         newConcreteMethodsProbabilities.add(concreteMethodsProbabilities.get(i));
                     }
@@ -1227,7 +1229,7 @@
     private static boolean checkTargetConditions(InliningData data, Replacements replacements, Invoke invoke, ResolvedJavaMethod method, OptimisticOptimizations optimisticOpts) {
         if (method == null) {
             return logNotInlinedMethodAndReturnFalse(invoke, data.inliningDepth(), method, "the method is not resolved");
-        } else if (Modifier.isNative(method.getModifiers()) && (!GraalOptions.Intrinsify || !InliningUtil.canIntrinsify(replacements, method))) {
+        } else if (Modifier.isNative(method.getModifiers()) && (!GraalOptions.Intrinsify.getValue() || !InliningUtil.canIntrinsify(replacements, method))) {
             return logNotInlinedMethodAndReturnFalse(invoke, data.inliningDepth(), method, "it is a non-intrinsic native method");
         } else if (Modifier.isAbstract(method.getModifiers())) {
             return logNotInlinedMethodAndReturnFalse(invoke, data.inliningDepth(), method, "it is an abstract method");
@@ -1235,7 +1237,7 @@
             return logNotInlinedMethodAndReturnFalse(invoke, data.inliningDepth(), method, "the method's class is not initialized");
         } else if (!method.canBeInlined()) {
             return logNotInlinedMethodAndReturnFalse(invoke, data.inliningDepth(), method, "it is marked non-inlinable");
-        } else if (data.countRecursiveInlining(method) > GraalOptions.MaximumRecursiveInlining) {
+        } else if (data.countRecursiveInlining(method) > MaximumRecursiveInlining.getValue()) {
             return logNotInlinedMethodAndReturnFalse(invoke, data.inliningDepth(), method, "it exceeds the maximum recursive inlining depth");
         } else if (new OptimisticOptimizations(method).lessOptimisticThan(optimisticOpts)) {
             return logNotInlinedMethodAndReturnFalse(invoke, data.inliningDepth(), method, "the callee uses less optimistic optimizations than caller");
@@ -1269,6 +1271,10 @@
 
         FrameState stateAfter = invoke.stateAfter();
         assert stateAfter == null || stateAfter.isAlive();
+        GuardingNode receiverNullCheckNode = null;
+        if (receiverNullCheck) {
+            receiverNullCheckNode = receiverNullCheck(invoke);
+        }
 
         IdentityHashMap<Node, Node> replacements = new IdentityHashMap<>();
         ArrayList<Node> nodes = new ArrayList<>();
@@ -1280,7 +1286,18 @@
             if (node == entryPointNode || node == entryPointNode.stateAfter()) {
                 // Do nothing.
             } else if (node instanceof LocalNode) {
-                replacements.put(node, parameters.get(((LocalNode) node).index()));
+                int localIndex = ((LocalNode) node).index();
+                ValueNode parameter = parameters.get(localIndex);
+                if (receiverNullCheckNode != null && localIndex == 0) {
+                    Stamp piStamp = parameter.stamp();
+                    if (piStamp instanceof ObjectStamp) {
+                        piStamp = piStamp.join(StampFactory.objectNonNull());
+                    }
+                    PiNode piReceiver = graph.add(new PiNode(parameter, piStamp));
+                    piReceiver.setGuard(receiverNullCheckNode);
+                    parameter = piReceiver;
+                }
+                replacements.put(node, parameter);
             } else {
                 nodes.add(node);
                 if (node instanceof ReturnNode) {
@@ -1300,9 +1317,6 @@
 
         Map<Node, Node> duplicates = graph.addDuplicates(nodes, replacements);
         FixedNode firstCFGNodeDuplicate = (FixedNode) duplicates.get(firstCFGNode);
-        if (receiverNullCheck) {
-            receiverNullCheck(invoke);
-        }
         invoke.asNode().replaceAtPredecessor(firstCFGNodeDuplicate);
 
         FrameState stateAtExceptionEdge = null;
@@ -1408,15 +1422,17 @@
         return true;
     }
 
-    public static void receiverNullCheck(Invoke invoke) {
+    public static GuardingNode receiverNullCheck(Invoke invoke) {
         MethodCallTargetNode callTarget = (MethodCallTargetNode) invoke.callTarget();
         StructuredGraph graph = callTarget.graph();
         NodeInputList<ValueNode> parameters = callTarget.arguments();
         ValueNode firstParam = parameters.size() <= 0 ? null : parameters.get(0);
         if (!callTarget.isStatic() && firstParam.kind() == Kind.Object && !firstParam.objectStamp().nonNull()) {
-            graph.addBeforeFixed(invoke.asNode(),
-                            graph.add(new FixedGuardNode(graph.unique(new IsNullNode(firstParam)), DeoptimizationReason.NullCheckException, DeoptimizationAction.InvalidateReprofile, true)));
+            FixedGuardNode guard = graph.add(new FixedGuardNode(graph.unique(new IsNullNode(firstParam)), DeoptimizationReason.NullCheckException, DeoptimizationAction.InvalidateReprofile, true));
+            graph.addBeforeFixed(invoke.asNode(), guard);
+            return guard;
         }
+        return null;
     }
 
     public static boolean canIntrinsify(Replacements replacements, ResolvedJavaMethod target) {
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InsertStateAfterPlaceholderPhase.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InsertStateAfterPlaceholderPhase.java	Wed Jun 05 15:11:58 2013 +0200
@@ -48,6 +48,9 @@
 
         @Override
         public ValueNode canonical(CanonicalizerTool tool) {
+            if (!usages().isEmpty()) {
+                return this;
+            }
             if (stateAfter() == null) {
                 return null;
             }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java	Wed Jun 05 15:11:58 2013 +0200
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.phases.common;
 
+import static com.oracle.graal.phases.GraalOptions.*;
+
 import java.util.*;
 
 import com.oracle.graal.api.code.*;
@@ -69,6 +71,11 @@
         }
 
         @Override
+        public LoweringType getLoweringType() {
+            return loweringType;
+        }
+
+        @Override
         public GuardingNode createNullCheckGuard(GuardedNode guardedNode, ValueNode object) {
             if (object.objectStamp().nonNull()) {
                 // Short cut creation of null check guard if the object is known to be non-null.
@@ -95,7 +102,7 @@
             if (loweringType == LoweringType.AFTER_GUARDS) {
                 throw new GraalInternalError("Cannot create guards in after-guard lowering");
             }
-            if (GraalOptions.OptEliminateGuards) {
+            if (OptEliminateGuards.getValue()) {
                 for (Node usage : condition.usages()) {
                     if (!activeGuards.isNew(usage) && activeGuards.isMarked(usage) && ((GuardNode) usage).negated() == negated) {
                         return (GuardNode) usage;
@@ -103,7 +110,7 @@
                 }
             }
             GuardNode newGuard = guardAnchor.asNode().graph().unique(new GuardNode(condition, guardAnchor, deoptReason, action, negated));
-            if (GraalOptions.OptEliminateGuards) {
+            if (OptEliminateGuards.getValue()) {
                 activeGuards.grow();
                 activeGuards.mark(newGuard);
             }
@@ -203,7 +210,7 @@
                 }
             }
 
-            if (parentAnchor == null && GraalOptions.OptEliminateGuards) {
+            if (parentAnchor == null && OptEliminateGuards.getValue()) {
                 for (GuardNode guard : anchor.asNode().usages().filter(GuardNode.class)) {
                     activeGuards.clear(guard);
                 }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/SafepointInsertionPhase.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/SafepointInsertionPhase.java	Wed Jun 05 15:11:58 2013 +0200
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.phases.common;
 
+import static com.oracle.graal.phases.GraalOptions.*;
+
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.phases.*;
@@ -33,7 +35,7 @@
 
     @Override
     protected void run(StructuredGraph graph) {
-        if (GraalOptions.GenLoopSafepoints) {
+        if (GenLoopSafepoints.getValue()) {
             for (LoopEndNode loopEndNode : graph.getNodes(LoopEndNode.class)) {
                 if (!loopEndNode.canSafepoint()) {
                     continue;
@@ -43,8 +45,8 @@
             }
         }
 
-        if (GraalOptions.GenSafepoints) {
-            if (!GraalOptions.OptEliminateSafepoints || graph.getNodes(MethodCallTargetNode.class).isNotEmpty()) {
+        if (GenSafepoints.getValue()) {
+            if (!OptEliminateSafepoints.getValue() || graph.getNodes(MethodCallTargetNode.class).isNotEmpty()) {
                 for (ReturnNode returnNode : graph.getNodes(ReturnNode.class)) {
                     SafepointNode safepoint = graph.add(new SafepointNode());
                     graph.addBeforeFixed(returnNode, safepoint);
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/TailDuplicationPhase.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/TailDuplicationPhase.java	Wed Jun 05 15:11:58 2013 +0200
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.phases.common;
 
+import static com.oracle.graal.phases.GraalOptions.*;
+
 import java.util.*;
 
 import com.oracle.graal.debug.*;
@@ -80,7 +82,7 @@
     public static final TailDuplicationDecision DEFAULT_DECISION = new TailDuplicationDecision() {
 
         public boolean doTransform(MergeNode merge, int fixedNodeCount) {
-            if (fixedNodeCount < GraalOptions.TailDuplicationTrivialSize) {
+            if (fixedNodeCount < TailDuplicationTrivialSize.getValue()) {
                 return true;
             }
             HashSet<PhiNode> improvements = new HashSet<>();
@@ -136,7 +138,7 @@
         // A snapshot is taken here, so that new MergeNode instances aren't considered for tail
         // duplication.
         for (MergeNode merge : graph.getNodes(MergeNode.class).snapshot()) {
-            if (!(merge instanceof LoopBeginNode) && nodeProbabilities.get(merge) >= GraalOptions.TailDuplicationProbability) {
+            if (!(merge instanceof LoopBeginNode) && nodeProbabilities.get(merge) >= TailDuplicationProbability.getValue()) {
                 tailDuplicate(merge, DEFAULT_DECISION, null, phaseContext);
             }
         }
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java	Wed Jun 05 15:11:58 2013 +0200
@@ -22,215 +22,328 @@
  */
 package com.oracle.graal.phases;
 
+import com.oracle.graal.options.*;
+
 /**
  * This class encapsulates options that control the behavior of the Graal compiler.
- * 
- * (thomaswue) WARNING: Fields of this class are treated as final by Graal.
  */
 // @formatter:off
 public final class GraalOptions {
 
-    // Checkstyle: stop
-    private static final boolean ____ = false;
-    // Checkstyle: resume
-
-    public static String  CompilerConfiguration              = "basic";
-    public static String  GraalRuntime                       = "basic";
+    @Option(help = "Enable use of compiler intrinsics")
+    public static final OptionValue<Boolean> Intrinsify = new OptionValue<>(true);
+    @Option(help = "Enable inlining of monomorphic calls")
+    static final OptionValue<Boolean> InlineMonomorphicCalls = new OptionValue<>(true);
+    @Option(help = "Enable inlining of polymorphic calls")
+    static final OptionValue<Boolean> InlinePolymorphicCalls = new OptionValue<>(true);
+    @Option(help = "Enable inlining of megamorphic calls")
+    static final OptionValue<Boolean> InlineMegamorphicCalls = new OptionValue<>(true);
+    @Option(help = "")
+    public static final OptionValue<Double> MegamorphicInliningMinMethodProbability = new OptionValue<>(0.33D);
+    @Option(help = "")
+    public static final OptionValue<Integer> MaximumDesiredSize = new OptionValue<>(5000);
+    @Option(help = "")
+    public static final OptionValue<Integer> MaximumRecursiveInlining = new OptionValue<>(1);
 
     // inlining settings
-    public static boolean Inline                             = true;
-    public static boolean AlwaysInlineIntrinsics             = ____;
-    public static boolean Intrinsify                         = true;
-           static boolean InlineMonomorphicCalls             = true;
-           static boolean InlinePolymorphicCalls             = true;
-           static boolean InlineMegamorphicCalls             = true;
-    public static double  MegamorphicInliningMinMethodProbability = 0.33;
-    public static int     MaximumDesiredSize                 = 5000;
-    public static int     MaximumRecursiveInlining           = 1;
-    public static float   BoostInliningForEscapeAnalysis     = 2f;
-    public static float   RelevanceCapForInlining            = 1f;
-    public static float   CapInheritedRelevance              = 1f;
-    public static boolean IterativeInlining                  = ____;
+    @Option(help = "")
+    public static final OptionValue<Float> BoostInliningForEscapeAnalysis = new OptionValue<>(2f);
+    @Option(help = "")
+    public static final OptionValue<Float> RelevanceCapForInlining = new OptionValue<>(1f);
+    @Option(help = "")
+    public static final OptionValue<Float> CapInheritedRelevance = new OptionValue<>(1f);
+    @Option(help = "")
+    public static final OptionValue<Boolean> IterativeInlining = new OptionValue<>(false);
 
-    public static int     TrivialInliningSize                = 10;
-    public static int     MaximumInliningSize                = 300;
-    public static int     SmallCompiledLowLevelGraphSize     = 300;
-    public static double  LimitInlinedInvokes                = 5.0;
+    @Option(help = "")
+    public static final OptionValue<Integer> TrivialInliningSize = new OptionValue<>(10);
+    @Option(help = "")
+    public static final OptionValue<Integer> MaximumInliningSize = new OptionValue<>(300);
+    @Option(help = "")
+    public static final OptionValue<Integer> SmallCompiledLowLevelGraphSize = new OptionValue<>(300);
+    @Option(help = "")
+    public static final OptionValue<Double> LimitInlinedInvokes = new OptionValue<>(5.0);
 
     // escape analysis settings
-    public static boolean PartialEscapeAnalysis              = true;
-    public static boolean EscapeAnalysisHistogram            = ____;
-    public static int     EscapeAnalysisIterations           = 2;
-    public static String  EscapeAnalyzeOnly                  = null;
-    public static int     MaximumEscapeAnalysisArrayLength   = 32;
-    public static boolean PEAInliningHints                   = ____;
+    @Option(help = "")
+    public static final OptionValue<Boolean> PartialEscapeAnalysis = new OptionValue<>(true);
+    @Option(help = "")
+    public static final OptionValue<Boolean> EscapeAnalysisHistogram = new OptionValue<>(false);
+    @Option(help = "")
+    public static final OptionValue<Integer> EscapeAnalysisIterations = new OptionValue<>(2);
+    @Option(help = "")
+    public static final OptionValue<String> EscapeAnalyzeOnly = new OptionValue<>(null);
+    @Option(help = "")
+    public static final OptionValue<Integer> MaximumEscapeAnalysisArrayLength = new OptionValue<>(32);
+    @Option(help = "")
+    public static final OptionValue<Boolean> PEAInliningHints = new OptionValue<>(false);
 
-    public static double  TailDuplicationProbability         = 0.5;
-    public static int     TailDuplicationTrivialSize         = 1;
+    @Option(help = "")
+    public static final OptionValue<Double> TailDuplicationProbability = new OptionValue<>(0.5);
+    @Option(help = "")
+    public static final OptionValue<Integer> TailDuplicationTrivialSize = new OptionValue<>(1);
 
     // profiling information
-    public static int     DeoptsToDisableOptimisticOptimization = 40;
-    public static int     MatureExecutionsBranch             = 1;
-    public static int     MatureExecutionsPerSwitchCase      = 1;
-    public static int     MatureExecutionsTypeProfile        = 1;
+    @Option(help = "")
+    public static final OptionValue<Integer> DeoptsToDisableOptimisticOptimization = new OptionValue<>(40);
+    @Option(help = "")
+    public static final OptionValue<Integer> MatureExecutionsBranch = new OptionValue<>(1);
+    @Option(help = "")
+    public static final OptionValue<Integer> MatureExecutionsPerSwitchCase = new OptionValue<>(1);
+    @Option(help = "")
+    public static final OptionValue<Integer> MatureExecutionsTypeProfile = new OptionValue<>(1);
 
     // comilation queue
-    public static boolean DynamicCompilePriority             = ____;
-    public static String  CompileTheWorld                    = null;
-    public static int     CompileTheWorldStartAt             = 1;
-    public static int     CompileTheWorldStopAt              = Integer.MAX_VALUE;
+    @Option(help = "")
+    public static final OptionValue<Boolean> DynamicCompilePriority = new OptionValue<>(false);
+    @Option(help = "")
+    public static final OptionValue<String> CompileTheWorld = new OptionValue<>(null);
+    @Option(help = "")
+    public static final OptionValue<Integer> CompileTheWorldStartAt = new OptionValue<>(1);
+    @Option(help = "")
+    public static final OptionValue<Integer> CompileTheWorldStopAt = new OptionValue<>(Integer.MAX_VALUE);
 
     // graph caching
-    public static boolean CacheGraphs                        = true;
-    public static int     GraphCacheSize                     = 1000;
-    public static boolean PrintGraphCache                    = ____;
+    @Option(help = "")
+    public static final OptionValue<Boolean> CacheGraphs = new OptionValue<>(true);
+    @Option(help = "")
+    public static final OptionValue<Integer> GraphCacheSize = new OptionValue<>(1000);
+    @Option(help = "")
+    public static final OptionValue<Boolean> PrintGraphCache = new OptionValue<>(false);
 
     //loop transform settings TODO (gd) tune
-    public static boolean LoopPeeling                        = true;
-    public static boolean ReassociateInvariants              = true;
-    public static boolean FullUnroll                         = true;
-    public static boolean LoopUnswitch                       = true;
-    public static int     FullUnrollMaxNodes                 = 300;
-    public static int     ExactFullUnrollMaxNodes            = 1200;
-    public static float   MinimumPeelProbability             = 0.35f;
-    public static int     LoopMaxUnswitch                    = 3;
-    public static int     LoopUnswitchMaxIncrease            = 50;
-    public static int     LoopUnswitchUncertaintyBoost       = 5;
-    public static boolean UseLoopLimitChecks                 = true;
+    @Option(help = "")
+    public static final OptionValue<Boolean> LoopPeeling = new OptionValue<>(true);
+    @Option(help = "")
+    public static final OptionValue<Boolean> ReassociateInvariants = new OptionValue<>(true);
+    @Option(help = "")
+    public static final OptionValue<Boolean> FullUnroll = new OptionValue<>(true);
+    @Option(help = "")
+    public static final OptionValue<Boolean> LoopUnswitch = new OptionValue<>(true);
+    @Option(help = "")
+    public static final OptionValue<Integer> FullUnrollMaxNodes = new OptionValue<>(300);
+    @Option(help = "")
+    public static final OptionValue<Integer> ExactFullUnrollMaxNodes = new OptionValue<>(1200);
+    @Option(help = "")
+    public static final OptionValue<Float> MinimumPeelProbability = new OptionValue<>(0.35f);
+    @Option(help = "")
+    public static final OptionValue<Integer> LoopMaxUnswitch = new OptionValue<>(3);
+    @Option(help = "")
+    public static final OptionValue<Integer> LoopUnswitchMaxIncrease = new OptionValue<>(50);
+    @Option(help = "")
+    public static final OptionValue<Integer> LoopUnswitchUncertaintyBoost = new OptionValue<>(5);
+    @Option(help = "")
+    public static final OptionValue<Boolean> UseLoopLimitChecks = new OptionValue<>(true);
 
     // debugging settings
-    public static boolean ZapStackOnMethodEntry              = ____;
-    public static boolean DeoptALot                          = ____;
-    public static boolean VerifyPhases                       = false;
+    @Option(help = "")
+    public static final OptionValue<Boolean> ZapStackOnMethodEntry = new OptionValue<>(false);
+    @Option(help = "")
+    public static final OptionValue<Boolean> DeoptALot = new OptionValue<>(false);
+    @Option(help = "")
+    public static final OptionValue<Boolean> VerifyPhases = new OptionValue<>(false);
 
-    public static String  PrintFilter                        = null;
+    @Option(help = "")
+    public static final OptionValue<String> PrintFilter = new OptionValue<>(null);
 
     // Debug settings:
-    public static boolean BootstrapReplacements              = ____;
+    @Option(help = "")
+    public static final OptionValue<Boolean> BootstrapReplacements = new OptionValue<>(false);
 
     // Ideal graph visualizer output settings
-    public static boolean PrintBinaryGraphs                  = true;
-    public static boolean PrintCFG                           = ____;
-    public static boolean PrintIdealGraphFile                = ____;
-    public static String  PrintIdealGraphAddress             = "127.0.0.1";
-    public static int     PrintIdealGraphPort                = 4444;
-    public static int     PrintBinaryGraphPort               = 4445;
+    @Option(help = "")
+    public static final OptionValue<Boolean> PrintBinaryGraphs = new OptionValue<>(true);
+    @Option(help = "")
+    public static final OptionValue<Boolean> PrintCFG = new OptionValue<>(false);
+    @Option(help = "")
+    public static final OptionValue<Boolean> PrintIdealGraphFile = new OptionValue<>(false);
+    @Option(help = "")
+    public static final OptionValue<String> PrintIdealGraphAddress = new OptionValue<>("127.0.0.1");
+    @Option(help = "")
+    public static final OptionValue<Integer> PrintIdealGraphPort = new OptionValue<>(4444);
+    @Option(help = "")
+    public static final OptionValue<Integer> PrintBinaryGraphPort = new OptionValue<>(4445);
 
     // Other printing settings
-    public static boolean PrintCompilation                   = ____;
-    public static boolean PrintProfilingInformation          = ____;
-    public static boolean PrintIRWithLIR                     = ____;
-    public static boolean PrintCodeBytes                     = ____;
-    public static boolean PrintBailout                       = ____;
-    public static int     TraceLinearScanLevel               = 0;
-    public static int     TraceLIRGeneratorLevel             = 0;
-    public static boolean TraceEscapeAnalysis                = ____;
-    public static int     TraceBytecodeParserLevel           = 0;
-    public static boolean ExitVMOnBailout                    = ____;
-    public static boolean ExitVMOnException                  = true;
-    public static boolean PrintStackTraceOnException         = false;
+    @Option(help = "")
+    public static final OptionValue<Boolean> PrintCompilation = new OptionValue<>(false);
+    @Option(help = "")
+    public static final OptionValue<Boolean> PrintProfilingInformation = new OptionValue<>(false);
+    @Option(help = "")
+    public static final OptionValue<Boolean> PrintIRWithLIR = new OptionValue<>(false);
+    @Option(help = "")
+    public static final OptionValue<Boolean> PrintCodeBytes = new OptionValue<>(false);
+    @Option(help = "")
+    public static final OptionValue<Boolean> PrintBailout = new OptionValue<>(false);
+    @Option(help = "")
+    public static final OptionValue<Integer> TraceLinearScanLevel = new OptionValue<>(0);
+    @Option(help = "")
+    public static final OptionValue<Integer> TraceLIRGeneratorLevel = new OptionValue<>(0);
+    @Option(help = "")
+    public static final OptionValue<Boolean> TraceEscapeAnalysis = new OptionValue<>(false);
+    @Option(help = "")
+    public static final OptionValue<Integer> TraceBytecodeParserLevel = new OptionValue<>(0);
+    @Option(help = "")
+    public static final OptionValue<Boolean> ExitVMOnBailout = new OptionValue<>(false);
+    @Option(help = "")
+    public static final OptionValue<Boolean> ExitVMOnException = new OptionValue<>(true);
+    @Option(help = "")
+    public static final OptionValue<Boolean> PrintStackTraceOnException = new OptionValue<>(false);
 
     // HotSpot command line options
-    public static boolean HotSpotPrintCompilation            = ____;
-    public static boolean HotSpotPrintInlining               = ____;
+    @Option(help = "")
+    public static final OptionValue<Boolean> HotSpotPrintCompilation = new OptionValue<>(false);
+    @Option(help = "")
+    public static final OptionValue<Boolean> HotSpotPrintInlining = new OptionValue<>(false);
 
     // Register allocator debugging
-    public static String  RegisterPressure                   = null;
+    @Option(help = "")
+    public static final OptionValue<String> RegisterPressure = new OptionValue<>(null);
 
     // Code generator settings
-    public static boolean ConditionalElimination             = true;
-    public static boolean CullFrameStates                    = ____;
-    public static boolean UseProfilingInformation            = true;
-           static boolean RemoveNeverExecutedCode            = true;
-           static boolean UseExceptionProbability            = true;
-           static boolean UseExceptionProbabilityForOperations = true;
-    public static boolean OmitHotExceptionStacktrace         = ____;
-    public static boolean GenSafepoints                      = true;
-    public static boolean GenLoopSafepoints                  = true;
-           static boolean UseTypeCheckHints                  = true;
-    public static boolean InlineVTableStubs                  = true;
-    public static boolean AlwaysInlineVTableStubs            = ____;
-    public static boolean GenAssertionCode                   = ____;
-    public static boolean AlignCallsForPatching              = true;
-    public static boolean ResolveClassBeforeStaticInvoke     = ____;
-    public static boolean CanOmitFrame                       = true;
-    public static int     SafepointPollOffset                = 256;
+    @Option(help = "")
+    public static final OptionValue<Boolean> ConditionalElimination = new OptionValue<>(true);
+    @Option(help = "")
+    public static final OptionValue<Boolean> CullFrameStates = new OptionValue<>(false);
+    @Option(help = "")
+    public static final OptionValue<Boolean> UseProfilingInformation = new OptionValue<>(true);
+    @Option(help = "")
+           static final OptionValue<Boolean> RemoveNeverExecutedCode = new OptionValue<>(true);
+           @Option(help = "")
+           static final OptionValue<Boolean> UseExceptionProbability = new OptionValue<>(true);
+           @Option(help = "")
+           static final OptionValue<Boolean> UseExceptionProbabilityForOperations = new OptionValue<>(true);
+           @Option(help = "")
+    public static final OptionValue<Boolean> OmitHotExceptionStacktrace = new OptionValue<>(false);
+    @Option(help = "")
+    public static final OptionValue<Boolean> GenSafepoints = new OptionValue<>(true);
+    @Option(help = "")
+    public static final OptionValue<Boolean> GenLoopSafepoints = new OptionValue<>(true);
+    @Option(help = "")
+           static final OptionValue<Boolean> UseTypeCheckHints = new OptionValue<>(true);
+           @Option(help = "")
+    public static final OptionValue<Boolean> InlineVTableStubs = new OptionValue<>(true);
+    @Option(help = "")
+    public static final OptionValue<Boolean> AlwaysInlineVTableStubs = new OptionValue<>(false);
+    @Option(help = "")
+    public static final OptionValue<Boolean> GenAssertionCode = new OptionValue<>(false);
+    @Option(help = "")
+    public static final OptionValue<Boolean> AlignCallsForPatching = new OptionValue<>(true);
+    @Option(help = "")
+    public static final OptionValue<Boolean> ResolveClassBeforeStaticInvoke = new OptionValue<>(false);
+    @Option(help = "")
+    public static final OptionValue<Boolean> CanOmitFrame = new OptionValue<>(true);
+    @Option(help = "")
+    public static final OptionValue<Integer> SafepointPollOffset = new OptionValue<>(256);
 
-    public static boolean MemoryAwareScheduling              = true;
+    @Option(help = "")
+    public static final OptionValue<Boolean> MemoryAwareScheduling = new OptionValue<>(true);
 
     // Translating tableswitch instructions
-    public static int     MinimumJumpTableSize               = 5;
-    public static int     RangeTestsSwitchDensity            = 5;
-    public static double  MinTableSwitchDensity              = 0.5;
-
-    public static boolean DetailedAsserts                    = ____;
+    @Option(help = "")
+    public static final OptionValue<Integer> MinimumJumpTableSize = new OptionValue<>(5);
+    @Option(help = "")
+    public static final OptionValue<Integer> RangeTestsSwitchDensity = new OptionValue<>(5);
+    @Option(help = "")
+    public static final OptionValue<Double> MinTableSwitchDensity = new OptionValue<>(0.5);
 
     // Runtime settings
-    public static int     StackShadowPages                   = 2;
+    @Option(help = "")
+    public static final OptionValue<Integer> StackShadowPages = new OptionValue<>(2);
 
-    public static boolean SupportJsrBytecodes                = true;
+    @Option(help = "")
+    public static final OptionValue<Boolean> SupportJsrBytecodes = new OptionValue<>(true);
 
-    public static boolean OptAssumptions                     = true;
-    public static boolean OptConvertDeoptsToGuards           = true;
-    public static boolean OptReadElimination                 = true;
-    public static boolean OptEarlyReadElimination            = true;
-    public static boolean OptCanonicalizer                   = true;
-    public static boolean OptScheduleOutOfLoops              = true;
-    public static boolean OptEliminateGuards                 = true;
-    public static boolean OptEliminateSafepoints             = true;
-    public static boolean OptImplicitNullChecks              = true;
-    public static boolean OptLivenessAnalysis                = true;
-    public static boolean OptLoopTransform                   = true;
-    public static boolean OptFloatingReads                   = true;
-    public static boolean OptTailDuplication                 = true;
-    public static boolean OptEliminatePartiallyRedundantGuards = true;
-    public static boolean OptFilterProfiledTypes             = true;
-    public static boolean OptDevirtualizeInvokesOptimistically = true;
-    public static boolean OptPushThroughPi                   = true;
+    @Option(help = "")
+    public static final OptionValue<Boolean> OptAssumptions = new OptionValue<>(true);
+    @Option(help = "")
+    public static final OptionValue<Boolean> OptConvertDeoptsToGuards = new OptionValue<>(true);
+    @Option(help = "")
+    public static final OptionValue<Boolean> OptReadElimination = new OptionValue<>(true);
+    @Option(help = "")
+    public static final OptionValue<Boolean> OptEarlyReadElimination = new OptionValue<>(true);
+    @Option(help = "")
+    public static final OptionValue<Boolean> OptCanonicalizer = new OptionValue<>(true);
+    @Option(help = "")
+    public static final OptionValue<Boolean> OptScheduleOutOfLoops = new OptionValue<>(true);
+    @Option(help = "")
+    public static final OptionValue<Boolean> OptEliminateGuards = new OptionValue<>(true);
+    @Option(help = "")
+    public static final OptionValue<Boolean> OptEliminateSafepoints = new OptionValue<>(true);
+    @Option(help = "")
+    public static final OptionValue<Boolean> OptImplicitNullChecks = new OptionValue<>(true);
+    @Option(help = "")
+    public static final OptionValue<Boolean> OptLivenessAnalysis = new OptionValue<>(true);
+    @Option(help = "")
+    public static final OptionValue<Boolean> OptLoopTransform = new OptionValue<>(true);
+    @Option(help = "")
+    public static final OptionValue<Boolean> OptFloatingReads = new OptionValue<>(true);
+    @Option(help = "")
+    public static final OptionValue<Boolean> OptTailDuplication = new OptionValue<>(true);
+    @Option(help = "")
+    public static final OptionValue<Boolean> OptEliminatePartiallyRedundantGuards = new OptionValue<>(true);
+    @Option(help = "")
+    public static final OptionValue<Boolean> OptFilterProfiledTypes = new OptionValue<>(true);
+    @Option(help = "")
+    public static final OptionValue<Boolean> OptDevirtualizeInvokesOptimistically = new OptionValue<>(true);
+    @Option(help = "")
+    public static final OptionValue<Boolean> OptPushThroughPi = new OptionValue<>(true);
 
     // Intrinsification settings
-    public static boolean IntrinsifyObjectClone              = ____;
-    public static boolean IntrinsifyArrayCopy                = true;
-    public static boolean IntrinsifyObjectMethods            = true;
-    public static boolean IntrinsifySystemMethods            = true;
-    public static boolean IntrinsifyClassMethods             = true;
-    public static boolean IntrinsifyThreadMethods            = true;
-    public static boolean IntrinsifyUnsafeMethods            = true;
-    public static boolean IntrinsifyMathMethods              = true;
-    public static boolean IntrinsifyAESMethods               = true;
-    public static boolean IntrinsifyReflectionMethods        = true;
-    public static boolean IntrinsifyInstalledCodeMethods     = true;
-    public static boolean IntrinsifyCallSiteTarget           = true;
+    @Option(help = "")
+    public static final OptionValue<Boolean> IntrinsifyObjectClone = new OptionValue<>(false);
+    @Option(help = "")
+    public static final OptionValue<Boolean> IntrinsifyArrayCopy = new OptionValue<>(true);
+    @Option(help = "")
+    public static final OptionValue<Boolean> IntrinsifyObjectMethods = new OptionValue<>(true);
+    @Option(help = "")
+    public static final OptionValue<Boolean> IntrinsifySystemMethods = new OptionValue<>(true);
+    @Option(help = "")
+    public static final OptionValue<Boolean> IntrinsifyClassMethods = new OptionValue<>(true);
+    @Option(help = "")
+    public static final OptionValue<Boolean> IntrinsifyThreadMethods = new OptionValue<>(true);
+    @Option(help = "")
+    public static final OptionValue<Boolean> IntrinsifyUnsafeMethods = new OptionValue<>(true);
+    @Option(help = "")
+    public static final OptionValue<Boolean> IntrinsifyMathMethods = new OptionValue<>(true);
+    @Option(help = "")
+    public static final OptionValue<Boolean> IntrinsifyAESMethods = new OptionValue<>(true);
+    @Option(help = "")
+    public static final OptionValue<Boolean> IntrinsifyReflectionMethods = new OptionValue<>(true);
+    @Option(help = "")
+    public static final OptionValue<Boolean> IntrinsifyInstalledCodeMethods = new OptionValue<>(true);
+    @Option(help = "")
+    public static final OptionValue<Boolean> IntrinsifyCallSiteTarget = new OptionValue<>(true);
     /**
      * Counts the various paths taken through snippets.
      */
-    public static boolean SnippetCounters = false;
+    @Option(help = "")
+    public static final OptionValue<Boolean> SnippetCounters = new OptionValue<>(false);
 
     /**
      * If the probability that a checkcast will hit one the profiled types (up to {@link #CheckcastMaxHints})
      * is below this value, the checkcast will be compiled without hints.
      */
-    public static double CheckcastMinHintHitProbability = 0.5;
+    @Option(help = "")
+    public static final OptionValue<Double> CheckcastMinHintHitProbability = new OptionValue<>(0.5);
 
     /**
      * The maximum number of hint types that will be used when compiling a checkcast for which
      * profiling information is available. Note that {@link #CheckcastMinHintHitProbability}
      * also influences whether hints are used.
      */
-    public static int CheckcastMaxHints = 2;
+    @Option(help = "")
+    public static final OptionValue<Integer> CheckcastMaxHints = new OptionValue<>(2);
 
     /**
      * @see #CheckcastMinHintHitProbability
      */
-    public static double InstanceOfMinHintHitProbability = 0.5;
+    @Option(help = "")
+    public static final OptionValue<Double> InstanceOfMinHintHitProbability = new OptionValue<>(0.5);
 
     /**
      * @see #CheckcastMaxHints
      */
-    public static int InstanceOfMaxHints = 2;
-
-    static {
-        // turn detailed assertions on when the general assertions are on (misusing the assert keyword for this)
-        assert (DetailedAsserts = true) == true;
-    }
+    @Option(help = "")
+    public static final OptionValue<Integer> InstanceOfMaxHints = new OptionValue<>(2);
 }
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/OptimisticOptimizations.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/OptimisticOptimizations.java	Wed Jun 05 15:11:58 2013 +0200
@@ -79,39 +79,39 @@
     }
 
     public boolean removeNeverExecutedCode() {
-        return GraalOptions.RemoveNeverExecutedCode && enabledOpts.contains(Optimization.RemoveNeverExecutedCode);
+        return GraalOptions.RemoveNeverExecutedCode.getValue() && enabledOpts.contains(Optimization.RemoveNeverExecutedCode);
     }
 
     public boolean useTypeCheckHints() {
-        return GraalOptions.UseTypeCheckHints && enabledOpts.contains(Optimization.UseTypeCheckHints);
+        return GraalOptions.UseTypeCheckHints.getValue() && enabledOpts.contains(Optimization.UseTypeCheckHints);
     }
 
     public boolean inlineMonomorphicCalls() {
-        return GraalOptions.InlineMonomorphicCalls && enabledOpts.contains(Optimization.UseTypeCheckedInlining);
+        return GraalOptions.InlineMonomorphicCalls.getValue() && enabledOpts.contains(Optimization.UseTypeCheckedInlining);
     }
 
     public boolean inlinePolymorphicCalls() {
-        return GraalOptions.InlinePolymorphicCalls && enabledOpts.contains(Optimization.UseTypeCheckedInlining);
+        return GraalOptions.InlinePolymorphicCalls.getValue() && enabledOpts.contains(Optimization.UseTypeCheckedInlining);
     }
 
     public boolean inlineMegamorphicCalls() {
-        return GraalOptions.InlineMegamorphicCalls && enabledOpts.contains(Optimization.UseTypeCheckedInlining);
+        return GraalOptions.InlineMegamorphicCalls.getValue() && enabledOpts.contains(Optimization.UseTypeCheckedInlining);
     }
 
     public boolean devirtualizeInvokes() {
-        return GraalOptions.OptDevirtualizeInvokesOptimistically && enabledOpts.contains(Optimization.UseTypeCheckedInlining);
+        return GraalOptions.OptDevirtualizeInvokesOptimistically.getValue() && enabledOpts.contains(Optimization.UseTypeCheckedInlining);
     }
 
     public boolean useExceptionProbability() {
-        return GraalOptions.UseExceptionProbability && enabledOpts.contains(Optimization.UseExceptionProbability);
+        return GraalOptions.UseExceptionProbability.getValue() && enabledOpts.contains(Optimization.UseExceptionProbability);
     }
 
     public boolean useExceptionProbabilityForOperations() {
-        return GraalOptions.UseExceptionProbabilityForOperations && enabledOpts.contains(Optimization.UseExceptionProbabilityForOperations);
+        return GraalOptions.UseExceptionProbabilityForOperations.getValue() && enabledOpts.contains(Optimization.UseExceptionProbabilityForOperations);
     }
 
     public boolean useLoopLimitChecks() {
-        return GraalOptions.UseLoopLimitChecks && enabledOpts.contains(Optimization.UseLoopLimitChecks);
+        return GraalOptions.UseLoopLimitChecks.getValue() && enabledOpts.contains(Optimization.UseLoopLimitChecks);
     }
 
     public boolean lessOptimisticThan(OptimisticOptimizations other) {
@@ -124,6 +124,6 @@
     }
 
     private static boolean checkDeoptimizations(ProfilingInfo profilingInfo, DeoptimizationReason reason) {
-        return profilingInfo.getDeoptimizationCount(reason) < GraalOptions.DeoptsToDisableOptimisticOptimization;
+        return profilingInfo.getDeoptimizationCount(reason) < GraalOptions.DeoptsToDisableOptimisticOptimization.getValue();
     }
 }
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java	Wed Jun 05 15:11:58 2013 +0200
@@ -23,6 +23,7 @@
 package com.oracle.graal.phases.schedule;
 
 import static com.oracle.graal.api.meta.LocationIdentity.*;
+import static com.oracle.graal.phases.GraalOptions.*;
 
 import java.util.*;
 
@@ -172,7 +173,7 @@
     private final SchedulingStrategy selectedStrategy;
 
     public SchedulePhase() {
-        this(GraalOptions.OptScheduleOutOfLoops ? SchedulingStrategy.LATEST_OUT_OF_LOOPS : SchedulingStrategy.LATEST);
+        this(OptScheduleOutOfLoops.getValue() ? SchedulingStrategy.LATEST_OUT_OF_LOOPS : SchedulingStrategy.LATEST);
     }
 
     public SchedulePhase(SchedulingStrategy strategy) {
@@ -185,7 +186,7 @@
         earliestCache = graph.createNodeMap();
         blockToNodesMap = new BlockMap<>(cfg);
 
-        if (GraalOptions.MemoryAwareScheduling && selectedStrategy != SchedulingStrategy.EARLIEST && graph.getNodes(FloatingReadNode.class).isNotEmpty()) {
+        if (MemoryAwareScheduling.getValue() && selectedStrategy != SchedulingStrategy.EARLIEST && graph.getNodes(FloatingReadNode.class).isNotEmpty()) {
 
             assignBlockToNodes(graph, SchedulingStrategy.EARLIEST);
             sortNodesWithinBlocks(graph, SchedulingStrategy.EARLIEST);
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/Suites.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/Suites.java	Wed Jun 05 15:11:58 2013 +0200
@@ -25,10 +25,16 @@
 import java.util.*;
 
 import com.oracle.graal.graph.*;
+import com.oracle.graal.options.*;
 import com.oracle.graal.phases.*;
 
 public final class Suites {
 
+    // @formatter:off
+    @Option(help = "The compiler configuration to use")
+    private static final OptionValue<String> CompilerConfiguration = new OptionValue<>("basic");
+    // @formatter:on
+
     public static final Suites DEFAULT;
 
     private final PhaseSuite<HighTierContext> highTier;
@@ -69,7 +75,7 @@
     }
 
     public static Suites createDefaultSuites() {
-        return createSuites(GraalOptions.CompilerConfiguration);
+        return createSuites(CompilerConfiguration.getValue());
     }
 
     public static Suites createSuites(String name) {
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/verify/VerifyUsageWithEquals.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/verify/VerifyUsageWithEquals.java	Wed Jun 05 15:11:58 2013 +0200
@@ -73,7 +73,7 @@
         for (ObjectEqualsNode cn : graph.getNodes().filter(ObjectEqualsNode.class)) {
             if (!isEqualsMethod(graph)) {
                 // bail out if we compare an object of type klass with == or != (except null checks)
-                assert !(checkUsage(cn.x(), cn.y()) && checkUsage(cn.y(), cn.x())) : "Verifcation of " + klass.getName() + " usage failed: Comparison " + cn.x() + " and" + cn.y() + " in " +
+                assert !(checkUsage(cn.x(), cn.y()) && checkUsage(cn.y(), cn.x())) : "Verifcation of " + klass.getName() + " usage failed: Comparing " + cn.x() + " and" + cn.y() + " in " +
                                 graph.method() + " must use .equals() for object equality, not '==' or '!='";
             }
         }
--- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/DebugEnvironment.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/DebugEnvironment.java	Wed Jun 05 15:11:58 2013 +0200
@@ -23,13 +23,13 @@
 package com.oracle.graal.printer;
 
 import static com.oracle.graal.compiler.GraalDebugConfig.*;
+import static com.oracle.graal.phases.GraalOptions.*;
 
 import java.io.*;
 import java.util.*;
 
 import com.oracle.graal.compiler.*;
 import com.oracle.graal.debug.*;
-import com.oracle.graal.phases.*;
 
 public class DebugEnvironment {
 
@@ -37,8 +37,8 @@
         Debug.enable();
         List<DebugDumpHandler> dumpHandlers = new ArrayList<>();
         dumpHandlers.add(new GraphPrinterDumpHandler());
-        if (GraalOptions.PrintCFG) {
-            if (GraalOptions.PrintBinaryGraphs) {
+        if (PrintCFG.getValue()) {
+            if (PrintBinaryGraphs.getValue()) {
                 TTY.println("CFG dumping slows down PrintBinaryGraphs: use -G:-PrintCFG to disable it");
             }
             dumpHandlers.add(new CFGPrinterObserver());
--- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/GraphPrinterDumpHandler.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/GraphPrinterDumpHandler.java	Wed Jun 05 15:11:58 2013 +0200
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.printer;
 
+import static com.oracle.graal.phases.GraalOptions.*;
+
 import java.io.*;
 import java.net.*;
 import java.nio.channels.*;
@@ -33,7 +35,6 @@
 import com.oracle.graal.compiler.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.graph.*;
-import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.schedule.*;
 
 /**
@@ -60,7 +61,7 @@
                 return;
             }
             previousInlineContext.clear();
-            if (GraalOptions.PrintIdealGraphFile) {
+            if (PrintIdealGraphFile.getValue()) {
                 initializeFilePrinter();
             } else {
                 initializeNetworkPrinter();
@@ -75,7 +76,7 @@
 
     private void initializeFilePrinter() {
         String ext;
-        if (GraalOptions.PrintBinaryGraphs) {
+        if (PrintBinaryGraphs.getValue()) {
             ext = ".bgv";
         } else {
             ext = ".gv.xml";
@@ -91,7 +92,7 @@
             num = "-" + Integer.toString(++i);
         }
         try {
-            if (GraalOptions.PrintBinaryGraphs) {
+            if (PrintBinaryGraphs.getValue()) {
                 printer = new BinaryGraphPrinter(FileChannel.open(file.toPath(), StandardOpenOption.WRITE, StandardOpenOption.CREATE_NEW));
             } else {
                 printer = new IdealGraphPrinter(new FileOutputStream(file));
@@ -105,10 +106,10 @@
     }
 
     private void initializeNetworkPrinter() {
-        String host = GraalOptions.PrintIdealGraphAddress;
-        int port = GraalOptions.PrintBinaryGraphs ? GraalOptions.PrintBinaryGraphPort : GraalOptions.PrintIdealGraphPort;
+        String host = PrintIdealGraphAddress.getValue();
+        int port = PrintBinaryGraphs.getValue() ? PrintBinaryGraphPort.getValue() : PrintIdealGraphPort.getValue();
         try {
-            if (GraalOptions.PrintBinaryGraphs) {
+            if (PrintBinaryGraphs.getValue()) {
                 printer = new BinaryGraphPrinter(SocketChannel.open(new InetSocketAddress(host, port)));
             } else {
                 IdealGraphPrinter xmlPrinter = new IdealGraphPrinter(new Socket(host, port).getOutputStream());
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/BoxingSnippets.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/BoxingSnippets.java	Wed Jun 05 15:11:58 2013 +0200
@@ -22,6 +22,7 @@
  */
 package com.oracle.graal.replacements;
 
+import static com.oracle.graal.phases.GraalOptions.*;
 import static com.oracle.graal.replacements.SnippetTemplate.*;
 
 import java.lang.reflect.*;
@@ -36,7 +37,6 @@
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
-import com.oracle.graal.phases.*;
 import com.oracle.graal.replacements.Snippet.Fold;
 import com.oracle.graal.replacements.Snippet.SnippetInliningPolicy;
 import com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates;
@@ -237,7 +237,7 @@
         }
     }
 
-    private static final SnippetCounter.Group integerCounters = GraalOptions.SnippetCounters ? new SnippetCounter.Group("Integer intrinsifications") : null;
+    private static final SnippetCounter.Group integerCounters = SnippetCounters.getValue() ? new SnippetCounter.Group("Integer intrinsifications") : null;
     private static final SnippetCounter valueOfCounter = new SnippetCounter(integerCounters, "valueOf", "valueOf intrinsification");
 
 }
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraalMethodSubstitutions.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraalMethodSubstitutions.java	Wed Jun 05 15:11:58 2013 +0200
@@ -22,11 +22,12 @@
  */
 package com.oracle.graal.replacements;
 
+import static com.oracle.graal.phases.GraalOptions.*;
+
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.runtime.*;
 import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.phases.*;
 
 /**
  * Method substitutions that are VM-independent.
@@ -39,7 +40,7 @@
             replacements.registerSubstitutions(clazz);
         }
 
-        if (GraalOptions.Intrinsify) {
+        if (Intrinsify.getValue()) {
             replacements.registerSubstitutions(MathSubstitutionsX86.class);
             replacements.registerSubstitutions(DoubleSubstitutions.class);
             replacements.registerSubstitutions(FloatSubstitutions.class);
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java	Wed Jun 05 15:11:58 2013 +0200
@@ -33,6 +33,7 @@
 import com.oracle.graal.graph.Node.ConstantNodeParameter;
 import com.oracle.graal.graph.Node.NodeIntrinsic;
 import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.PhiNode.PhiType;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.java.*;
@@ -284,34 +285,8 @@
         if (newInstance instanceof ValueNode && (((ValueNode) newInstance).kind() != Kind.Object || ((ValueNode) newInstance).stamp() == StampFactory.forNodeIntrinsic())) {
             StructuredGraph graph = (StructuredGraph) newInstance.graph();
             for (CheckCastNode checkCastNode : newInstance.usages().filter(CheckCastNode.class).snapshot()) {
-                for (ProxyNode vpn : checkCastNode.usages().filter(ProxyNode.class).snapshot()) {
-                    graph.replaceFloating(vpn, checkCastNode);
-                }
                 for (Node checkCastUsage : checkCastNode.usages().snapshot()) {
-                    if (checkCastUsage instanceof ValueAnchorNode) {
-                        ValueAnchorNode valueAnchorNode = (ValueAnchorNode) checkCastUsage;
-                        graph.removeFixed(valueAnchorNode);
-                    } else if (checkCastUsage instanceof UnboxNode) {
-                        UnboxNode unbox = (UnboxNode) checkCastUsage;
-                        unbox.replaceAtUsages(newInstance);
-                        graph.removeFixed(unbox);
-                    } else if (checkCastUsage instanceof MethodCallTargetNode) {
-                        MethodCallTargetNode checkCastCallTarget = (MethodCallTargetNode) checkCastUsage;
-                        assert checkCastCallTarget.targetMethod().getAnnotation(NodeIntrinsic.class) != null : "checkcast at " + sourceLocation(checkCastNode) +
-                                        " not used by an unboxing method or node intrinsic, but by a call at " + sourceLocation(checkCastCallTarget.usages().first()) + " to " +
-                                        checkCastCallTarget.targetMethod();
-                        checkCastUsage.replaceFirstInput(checkCastNode, checkCastNode.object());
-                    } else if (checkCastUsage instanceof FrameState) {
-                        checkCastUsage.replaceFirstInput(checkCastNode, null);
-                    } else if (checkCastUsage instanceof ReturnNode && checkCastNode.object().stamp() == StampFactory.forNodeIntrinsic()) {
-                        checkCastUsage.replaceFirstInput(checkCastNode, checkCastNode.object());
-                    } else if (checkCastUsage instanceof IsNullNode) {
-                        assert checkCastUsage.usages().count() == 1 && checkCastUsage.usages().first().predecessor() == checkCastNode;
-                        graph.replaceFloating((FloatingNode) checkCastUsage, LogicConstantNode.contradiction(graph));
-                    } else {
-                        Debug.dump(graph, "exception");
-                        assert false : sourceLocation(checkCastUsage) + " has unexpected usage " + checkCastUsage + " of checkcast at " + sourceLocation(checkCastNode);
-                    }
+                    checkCheckCastUsage(graph, newInstance, checkCastNode, checkCastUsage);
                 }
                 FixedNode next = checkCastNode.next();
                 checkCastNode.setNext(null);
@@ -320,4 +295,47 @@
             }
         }
     }
+
+    private static void checkCheckCastUsage(StructuredGraph graph, Node intrinsifiedNode, Node input, Node usage) {
+        if (usage instanceof ValueAnchorNode) {
+            ValueAnchorNode valueAnchorNode = (ValueAnchorNode) usage;
+            valueAnchorNode.removeAnchoredNode((ValueNode) input);
+            Debug.log("%s: Removed a ValueAnchor input", Debug.contextSnapshot(JavaMethod.class));
+        } else if (usage instanceof UnboxNode) {
+            UnboxNode unbox = (UnboxNode) usage;
+            unbox.replaceAtUsages(intrinsifiedNode);
+            graph.removeFixed(unbox);
+            Debug.log("%s: Removed an UnboxNode", Debug.contextSnapshot(JavaMethod.class));
+        } else if (usage instanceof MethodCallTargetNode) {
+            MethodCallTargetNode checkCastCallTarget = (MethodCallTargetNode) usage;
+            assert checkCastCallTarget.targetMethod().getAnnotation(NodeIntrinsic.class) != null : "checkcast at " + sourceLocation(input) +
+                            " not used by an unboxing method or node intrinsic, but by a call at " + sourceLocation(checkCastCallTarget.usages().first()) + " to " + checkCastCallTarget.targetMethod();
+            usage.replaceFirstInput(input, intrinsifiedNode);
+            Debug.log("%s: Checkcast used in an other node intrinsic", Debug.contextSnapshot(JavaMethod.class));
+        } else if (usage instanceof FrameState) {
+            usage.replaceFirstInput(input, null);
+            Debug.log("%s: Checkcast used in a FS", Debug.contextSnapshot(JavaMethod.class));
+        } else if (usage instanceof ReturnNode && ((ValueNode) intrinsifiedNode).stamp() == StampFactory.forNodeIntrinsic()) {
+            usage.replaceFirstInput(input, intrinsifiedNode);
+            Debug.log("%s: Checkcast used in a return with forNodeIntrinsic stamp", Debug.contextSnapshot(JavaMethod.class));
+        } else if (usage instanceof IsNullNode) {
+            assert usage.usages().count() == 1 && usage.usages().first().predecessor() == input;
+            graph.replaceFloating((FloatingNode) usage, LogicConstantNode.contradiction(graph));
+            Debug.log("%s: Replaced IsNull with false", Debug.contextSnapshot(JavaMethod.class));
+        } else if (usage instanceof ProxyNode) {
+            ProxyNode proxy = (ProxyNode) usage;
+            assert proxy.type() == PhiType.Value;
+            ProxyNode newProxy = graph.unique(new ProxyNode((ValueNode) intrinsifiedNode, proxy.proxyPoint(), PhiType.Value, proxy.getIdentity()));
+            for (Node proxyUsage : usage.usages().snapshot()) {
+                checkCheckCastUsage(graph, newProxy, proxy, proxyUsage);
+            }
+        } else if (usage instanceof PiNode) {
+            for (Node piUsage : usage.usages().snapshot()) {
+                checkCheckCastUsage(graph, intrinsifiedNode, usage, piUsage);
+            }
+        } else {
+            Debug.dump(graph, "exception");
+            assert false : sourceLocation(usage) + " has unexpected usage " + usage + " of checkcast at " + sourceLocation(input);
+        }
+    }
 }
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java	Wed Jun 05 15:11:58 2013 +0200
@@ -23,6 +23,7 @@
 package com.oracle.graal.replacements;
 
 import static com.oracle.graal.api.meta.MetaUtil.*;
+import static com.oracle.graal.phases.GraalOptions.*;
 
 import java.lang.reflect.*;
 import java.util.*;
@@ -320,7 +321,7 @@
             graphBuilder.apply(graph);
 
             new WordTypeVerificationPhase(runtime, target.wordKind).apply(graph);
-            if (GraalOptions.OptCanonicalizer) {
+            if (OptCanonicalizer.getValue()) {
                 new WordTypeRewriterPhase(runtime, target.wordKind).apply(graph);
                 new CanonicalizerPhase.Instance(runtime, assumptions).apply(graph);
             }
@@ -335,7 +336,7 @@
          * @param callee the graph that was inlined into {@code caller}
          */
         protected void afterInline(StructuredGraph caller, StructuredGraph callee) {
-            if (GraalOptions.OptCanonicalizer) {
+            if (OptCanonicalizer.getValue()) {
                 new WordTypeRewriterPhase(runtime, target.wordKind).apply(caller);
                 new CanonicalizerPhase.Instance(runtime, assumptions).apply(caller);
             }
@@ -350,7 +351,7 @@
             new WordTypeRewriterPhase(runtime, target.wordKind).apply(graph);
 
             new DeadCodeEliminationPhase().apply(graph);
-            if (GraalOptions.OptCanonicalizer) {
+            if (OptCanonicalizer.getValue()) {
                 new CanonicalizerPhase.Instance(runtime, assumptions).apply(graph);
             }
         }
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java	Wed Jun 05 15:11:58 2013 +0200
@@ -34,6 +34,7 @@
 import com.oracle.graal.loop.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
@@ -723,10 +724,14 @@
             } else {
                 returnValue = (ValueNode) duplicates.get(returnNode.result());
             }
-            assert returnValue != null || replacee.usages().isEmpty();
-            replacer.replace(replacee, returnValue);
+            Node returnDuplicate = duplicates.get(returnNode);
+            if (returnValue == null && replacee.usages().isNotEmpty() && replacee instanceof MemoryCheckpoint) {
+                replacer.replace(replacee, (ValueNode) returnDuplicate.predecessor());
+            } else {
+                assert returnValue != null || replacee.usages().isEmpty() : this + " " + returnValue + " " + returnNode + " " + replacee.usages();
+                replacer.replace(replacee, returnValue);
 
-            Node returnDuplicate = duplicates.get(returnNode);
+            }
             if (returnDuplicate.isAlive()) {
                 returnDuplicate.clearInputs();
                 returnDuplicate.replaceAndDelete(next);
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/BlockState.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/BlockState.java	Wed Jun 05 15:11:58 2013 +0200
@@ -30,11 +30,11 @@
 import com.oracle.graal.nodes.spi.Virtualizable.EscapeState;
 import com.oracle.graal.nodes.virtual.*;
 
-class BlockState {
+public class BlockState {
 
-    private final IdentityHashMap<VirtualObjectNode, ObjectState> objectStates = new IdentityHashMap<>();
-    private final IdentityHashMap<ValueNode, VirtualObjectNode> objectAliases;
-    private final IdentityHashMap<ValueNode, ValueNode> scalarAliases;
+    protected final IdentityHashMap<VirtualObjectNode, ObjectState> objectStates = new IdentityHashMap<>();
+    protected final IdentityHashMap<ValueNode, VirtualObjectNode> objectAliases;
+    protected final IdentityHashMap<ValueNode, ValueNode> scalarAliases;
     final HashMap<ReadCacheEntry, ValueNode> readCache;
 
     static class ReadCacheEntry {
@@ -144,6 +144,10 @@
         return new BlockState(this);
     }
 
+    public BlockState cloneEmptyState() {
+        return new BlockState();
+    }
+
     public void materializeBefore(FixedNode fixed, VirtualObjectNode virtual, EscapeState state, GraphEffectList materializeEffects) {
         PartialEscapeClosure.METRIC_MATERIALIZATIONS.increment();
         List<AllocatedObjectNode> objects = new ArrayList<>(2);
@@ -239,39 +243,14 @@
         return objectStates + " " + readCache;
     }
 
-    public BlockState meetAliases(List<? extends BlockState> states) {
-        BlockState newState = new BlockState();
-
-        BlockState firstState = states.get(0);
-        newState.objectAliases.putAll(firstState.objectAliases);
+    public void meetAliases(List<? extends BlockState> states) {
+        objectAliases.putAll(states.get(0).objectAliases);
+        scalarAliases.putAll(states.get(0).scalarAliases);
         for (int i = 1; i < states.size(); i++) {
             BlockState state = states.get(i);
-            Iterator<Map.Entry<ValueNode, VirtualObjectNode>> iter = newState.objectAliases.entrySet().iterator();
-            while (iter.hasNext()) {
-                Map.Entry<ValueNode, VirtualObjectNode> entry = iter.next();
-                if (state.objectAliases.containsKey(entry.getKey())) {
-                    assert state.objectAliases.get(entry.getKey()) == entry.getValue();
-                } else {
-                    iter.remove();
-                }
-            }
+            meetMaps(objectAliases, state.objectAliases);
+            meetMaps(scalarAliases, state.scalarAliases);
         }
-
-        newState.scalarAliases.putAll(firstState.scalarAliases);
-        for (int i = 1; i < states.size(); i++) {
-            BlockState state = states.get(i);
-            Iterator<Map.Entry<ValueNode, ValueNode>> iter = newState.scalarAliases.entrySet().iterator();
-            while (iter.hasNext()) {
-                Map.Entry<ValueNode, ValueNode> entry = iter.next();
-                if (state.scalarAliases.containsKey(entry.getKey())) {
-                    assert state.scalarAliases.get(entry.getKey()) == entry.getValue();
-                } else {
-                    iter.remove();
-                }
-            }
-        }
-
-        return newState;
     }
 
     public Map<ReadCacheEntry, ValueNode> getReadCache() {
@@ -289,14 +268,14 @@
         return objectAliasesEqual && objectStatesEqual && readCacheEqual && scalarAliasesEqual;
     }
 
-    private static <K, V> boolean compareMaps(Map<K, V> left, Map<K, V> right) {
+    protected static <K, V> boolean compareMaps(Map<K, V> left, Map<K, V> right) {
         if (left.size() != right.size()) {
             return false;
         }
         return compareMapsNoSize(left, right);
     }
 
-    private static <K, V> boolean compareMapsNoSize(Map<K, V> left, Map<K, V> right) {
+    protected static <K, V> boolean compareMapsNoSize(Map<K, V> left, Map<K, V> right) {
         if (left == right) {
             return true;
         }
@@ -312,4 +291,16 @@
         return true;
     }
 
+    protected static <U, V> void meetMaps(Map<U, V> target, Map<U, V> source) {
+        Iterator<Map.Entry<U, V>> iter = target.entrySet().iterator();
+        while (iter.hasNext()) {
+            Map.Entry<U, V> entry = iter.next();
+            if (source.containsKey(entry.getKey())) {
+                assert source.get(entry.getKey()) == entry.getValue();
+            } else {
+                iter.remove();
+            }
+        }
+    }
+
 }
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/IterativeInliningPhase.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/IterativeInliningPhase.java	Wed Jun 05 15:11:58 2013 +0200
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.virtual.phases.ea;
 
+import static com.oracle.graal.phases.GraalOptions.*;
+
 import java.util.*;
 import java.util.concurrent.*;
 
@@ -50,7 +52,7 @@
     }
 
     public static final void trace(String format, Object... obj) {
-        if (GraalOptions.TraceEscapeAnalysis) {
+        if (TraceEscapeAnalysis.getValue()) {
             Debug.log(format, obj);
         }
     }
@@ -63,7 +65,7 @@
 
     private void runIterations(final StructuredGraph graph, final boolean simple, final HighTierContext context) {
         Boolean continueIteration = true;
-        for (int iteration = 0; iteration < GraalOptions.EscapeAnalysisIterations && continueIteration; iteration++) {
+        for (int iteration = 0; iteration < EscapeAnalysisIterations.getValue() && continueIteration; iteration++) {
             continueIteration = Debug.scope("iteration " + iteration, new Callable<Boolean>() {
 
                 @Override
@@ -73,7 +75,7 @@
                     boolean eaResult = ea.runAnalysis(graph, context);
                     progress |= eaResult;
 
-                    Map<Invoke, Double> hints = GraalOptions.PEAInliningHints ? PartialEscapeAnalysisPhase.getHints(graph) : null;
+                    Map<Invoke, Double> hints = PEAInliningHints.getValue() ? PartialEscapeAnalysisPhase.getHints(graph) : null;
 
                     InliningPhase inlining = new InliningPhase(context.getRuntime(), hints, replacements, context.getAssumptions(), cache, plan, optimisticOpts);
                     inlining.setMaxMethodsPerInlining(simple ? 1 : Integer.MAX_VALUE);
@@ -82,7 +84,7 @@
 
                     new DeadCodeEliminationPhase().apply(graph);
 
-                    if (GraalOptions.ConditionalElimination && GraalOptions.OptCanonicalizer) {
+                    if (ConditionalElimination.getValue() && OptCanonicalizer.getValue()) {
                         new CanonicalizerPhase().apply(graph, context);
                         new IterativeConditionalEliminationPhase().apply(graph, context);
                     }
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeAnalysisPhase.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeAnalysisPhase.java	Wed Jun 05 15:11:58 2013 +0200
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.virtual.phases.ea;
 
+import static com.oracle.graal.phases.GraalOptions.*;
+
 import java.util.*;
 import java.util.concurrent.*;
 
@@ -39,7 +41,7 @@
 import com.oracle.graal.phases.schedule.*;
 import com.oracle.graal.phases.tiers.*;
 
-public class PartialEscapeAnalysisPhase extends BasePhase<HighTierContext> {
+public class PartialEscapeAnalysisPhase extends BasePhase<PhaseContext> {
 
     public abstract static class Closure<T> extends ReentrantBlockIterator.BlockIteratorClosure<T> {
 
@@ -63,12 +65,12 @@
     }
 
     @Override
-    protected void run(StructuredGraph graph, HighTierContext context) {
+    protected void run(StructuredGraph graph, PhaseContext context) {
         runAnalysis(graph, context);
     }
 
-    public boolean runAnalysis(final StructuredGraph graph, final HighTierContext context) {
-        if (!VirtualUtil.matches(graph, GraalOptions.EscapeAnalyzeOnly)) {
+    public boolean runAnalysis(final StructuredGraph graph, final PhaseContext context) {
+        if (!VirtualUtil.matches(graph, EscapeAnalyzeOnly.getValue())) {
             return false;
         }
 
@@ -87,7 +89,7 @@
 
         boolean continueIteration = true;
         boolean changed = false;
-        for (int iteration = 0; iteration < GraalOptions.EscapeAnalysisIterations && continueIteration; iteration++) {
+        for (int iteration = 0; iteration < EscapeAnalysisIterations.getValue() && continueIteration; iteration++) {
             boolean currentChanged = Debug.scope("iteration " + iteration, new Callable<Boolean>() {
 
                 @Override
@@ -109,7 +111,7 @@
 
                     new DeadCodeEliminationPhase().apply(graph);
 
-                    if (GraalOptions.OptCanonicalizer) {
+                    if (OptCanonicalizer.getValue()) {
                         new CanonicalizerPhase.Instance(context.getRuntime(), context.getAssumptions(), null, customCanonicalizer).apply(graph);
                     }
 
@@ -123,7 +125,7 @@
         return changed;
     }
 
-    protected Closure<?> createAnalysisClosure(final HighTierContext context, SchedulePhase schedule) {
+    protected Closure<?> createAnalysisClosure(PhaseContext context, SchedulePhase schedule) {
         return new PartialEscapeClosure<>(schedule, context.getRuntime(), context.getAssumptions());
     }
 
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java	Wed Jun 05 15:11:58 2013 +0200
@@ -23,6 +23,7 @@
 package com.oracle.graal.virtual.phases.ea;
 
 import static com.oracle.graal.api.meta.LocationIdentity.*;
+import static com.oracle.graal.phases.GraalOptions.*;
 
 import java.util.*;
 
@@ -39,7 +40,6 @@
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.spi.Virtualizable.EscapeState;
 import com.oracle.graal.nodes.virtual.*;
-import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.graph.*;
 import com.oracle.graal.phases.graph.ReentrantBlockIterator.BlockIteratorClosure;
 import com.oracle.graal.phases.graph.ReentrantBlockIterator.LoopInfo;
@@ -48,7 +48,7 @@
 import com.oracle.graal.virtual.phases.ea.BlockState.ReadCacheEntry;
 import com.oracle.graal.virtual.phases.ea.EffectList.Effect;
 
-class PartialEscapeClosure<BlockT extends BlockState> extends PartialEscapeAnalysisPhase.Closure<BlockT> {
+public class PartialEscapeClosure<BlockT extends BlockState> extends PartialEscapeAnalysisPhase.Closure<BlockT> {
 
     public static final DebugMetric METRIC_MATERIALIZATIONS = Debug.metric("Materializations");
     public static final DebugMetric METRIC_MATERIALIZATIONS_PHI = Debug.metric("MaterializationsPhi");
@@ -167,7 +167,7 @@
                 VirtualUtil.trace("%s ", node);
                 deleted = false;
             }
-            if (GraalOptions.OptEarlyReadElimination) {
+            if (OptEarlyReadElimination.getValue()) {
                 if (!deleted && node instanceof MemoryCheckpoint) {
                     METRIC_MEMORYCHECKOINT.increment();
                     MemoryCheckpoint checkpoint = (MemoryCheckpoint) node;
@@ -476,7 +476,8 @@
 
         @SuppressWarnings("unchecked")
         private void merge(List<BlockT> states) {
-            newState = (BlockT) states.get(0).meetAliases(states);
+            newState = (BlockT) states.get(0).cloneEmptyState();
+            newState.meetAliases(states);
 
             /*
              * Iterative processing: Merging the materialized/virtual state of virtual objects can
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualUtil.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualUtil.java	Wed Jun 05 15:11:58 2013 +0200
@@ -22,13 +22,14 @@
  */
 package com.oracle.graal.virtual.phases.ea;
 
+import static com.oracle.graal.phases.GraalOptions.*;
+
 import java.util.*;
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
-import com.oracle.graal.phases.*;
 
 public final class VirtualUtil {
 
@@ -105,7 +106,7 @@
     }
 
     public static void trace(String format, Object... obj) {
-        if (GraalOptions.TraceEscapeAnalysis) {
+        if (TraceEscapeAnalysis.getValue()) {
             Debug.log(format, obj);
         }
     }
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualizerToolImpl.java	Wed Jun 05 14:49:34 2013 +0200
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualizerToolImpl.java	Wed Jun 05 15:11:58 2013 +0200
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.virtual.phases.ea;
 
+import static com.oracle.graal.phases.GraalOptions.*;
+
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
@@ -31,7 +33,6 @@
 import com.oracle.graal.nodes.spi.Virtualizable.State;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.virtual.*;
-import com.oracle.graal.phases.*;
 
 class VirtualizerToolImpl implements VirtualizerTool {
 
@@ -164,7 +165,7 @@
 
     @Override
     public int getMaximumEntryCount() {
-        return GraalOptions.MaximumEscapeAnalysisArrayLength;
+        return MaximumEscapeAnalysisArrayLength.getValue();
     }
 
     @Override
@@ -183,14 +184,14 @@
 
     @Override
     public void addReadCache(ValueNode object, ResolvedJavaField identity, ValueNode value) {
-        if (GraalOptions.OptEarlyReadElimination) {
+        if (OptEarlyReadElimination.getValue()) {
             state.addReadCache(object, identity, value);
         }
     }
 
     @Override
     public ValueNode getReadCache(ValueNode object, ResolvedJavaField identity) {
-        if (GraalOptions.OptEarlyReadElimination) {
+        if (OptEarlyReadElimination.getValue()) {
             return state.getReadCache(object, identity);
         }
         return null;
@@ -198,7 +199,7 @@
 
     @Override
     public void killReadCache(ResolvedJavaField identity) {
-        if (GraalOptions.OptEarlyReadElimination) {
+        if (OptEarlyReadElimination.getValue()) {
             state.killReadCache(identity);
         }
     }
--- a/make/build-graal.xml	Wed Jun 05 14:49:34 2013 +0200
+++ b/make/build-graal.xml	Wed Jun 05 15:11:58 2013 +0200
@@ -39,10 +39,10 @@
       <src path="${src.dir}/com.oracle.graal.debug"/>
       <src path="${src.dir}/com.oracle.graal.api.replacements"/>
       <src path="${src.dir}/com.oracle.graal.nodes"/>
+      <src path="${src.dir}/com.oracle.graal.options"/>
       <src path="${src.dir}/com.oracle.graal.phases"/>
       <src path="${src.dir}/com.oracle.graal.phases.common"/>
       <src path="${src.dir}/com.oracle.graal.virtual"/>
-      <src path="${src.dir}/com.oracle.graal.options"/>
       <src path="${src.dir}/com.oracle.graal.loop"/>
       <src path="${src.dir}/com.oracle.graal.alloc"/>
       <src path="${src.dir}/com.oracle.graal.asm"/>
@@ -82,8 +82,10 @@
         <provider classname="com.oracle.graal.replacements.GraalMethodSubstitutions"/>
       </service>
       <service type="com.oracle.graal.options.OptionProvider">
+        <provider classname="com.oracle.graal.compiler.GraalCompiler_Inline"/>
         <provider classname="com.oracle.graal.compiler.GraalCompiler_VerifyUsageWithEquals"/>
         <provider classname="com.oracle.graal.compiler.GraalDebugConfig_DebugEnabled"/>
+        <provider classname="com.oracle.graal.compiler.GraalDebugConfig_DetailedAsserts"/>
         <provider classname="com.oracle.graal.compiler.GraalDebugConfig_Dump"/>
         <provider classname="com.oracle.graal.compiler.GraalDebugConfig_DumpOnError"/>
         <provider classname="com.oracle.graal.compiler.GraalDebugConfig_Log"/>
@@ -94,6 +96,7 @@
         <provider classname="com.oracle.graal.compiler.GraalDebugConfig_SummarizePerPhase"/>
         <provider classname="com.oracle.graal.compiler.GraalDebugConfig_Time"/>
         <provider classname="com.oracle.graal.hotspot.CompilationTask_SlowQueueCutoff"/>
+        <provider classname="com.oracle.graal.hotspot.HotSpotGraalRuntime_GraalRuntime"/>
         <provider classname="com.oracle.graal.hotspot.bridge.VMToCompilerImpl_BenchmarkDynamicCounters"/>
         <provider classname="com.oracle.graal.hotspot.bridge.VMToCompilerImpl_GenericDynamicCounters"/>
         <provider classname="com.oracle.graal.hotspot.bridge.VMToCompilerImpl_LogFile"/>
@@ -102,6 +105,136 @@
         <provider classname="com.oracle.graal.hotspot.bridge.VMToCompilerImpl_SlowCompileThreads"/>
         <provider classname="com.oracle.graal.hotspot.bridge.VMToCompilerImpl_Threads"/>
         <provider classname="com.oracle.graal.hotspot.bridge.VMToCompilerImpl_TimedBootstrap"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_AlignCallsForPatching"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_AlwaysInlineVTableStubs"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_BoostInliningForEscapeAnalysis"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_BootstrapReplacements"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_CacheGraphs"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_CanOmitFrame"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_CapInheritedRelevance"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_CheckcastMaxHints"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_CheckcastMinHintHitProbability"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_CompileTheWorld"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_CompileTheWorldStartAt"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_CompileTheWorldStopAt"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_ConditionalElimination"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_CullFrameStates"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_DeoptALot"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_DeoptsToDisableOptimisticOptimization"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_DynamicCompilePriority"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_EscapeAnalysisHistogram"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_EscapeAnalysisIterations"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_EscapeAnalyzeOnly"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_ExactFullUnrollMaxNodes"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_ExitVMOnBailout"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_ExitVMOnException"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_FullUnroll"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_FullUnrollMaxNodes"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_GenAssertionCode"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_GenLoopSafepoints"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_GenSafepoints"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_GraphCacheSize"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_HotSpotPrintCompilation"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_HotSpotPrintInlining"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_InlineMegamorphicCalls"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_InlineMonomorphicCalls"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_InlinePolymorphicCalls"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_InlineVTableStubs"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_InstanceOfMaxHints"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_InstanceOfMinHintHitProbability"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_Intrinsify"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_IntrinsifyAESMethods"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_IntrinsifyArrayCopy"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_IntrinsifyCallSiteTarget"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_IntrinsifyClassMethods"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_IntrinsifyInstalledCodeMethods"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_IntrinsifyMathMethods"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_IntrinsifyObjectClone"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_IntrinsifyObjectMethods"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_IntrinsifyReflectionMethods"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_IntrinsifySystemMethods"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_IntrinsifyThreadMethods"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_IntrinsifyUnsafeMethods"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_IterativeInlining"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_LimitInlinedInvokes"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_LoopMaxUnswitch"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_LoopPeeling"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_LoopUnswitch"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_LoopUnswitchMaxIncrease"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_LoopUnswitchUncertaintyBoost"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_MatureExecutionsBranch"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_MatureExecutionsPerSwitchCase"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_MatureExecutionsTypeProfile"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_MaximumDesiredSize"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_MaximumEscapeAnalysisArrayLength"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_MaximumInliningSize"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_MaximumRecursiveInlining"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_MegamorphicInliningMinMethodProbability"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_MemoryAwareScheduling"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_MinTableSwitchDensity"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_MinimumJumpTableSize"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_MinimumPeelProbability"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_OmitHotExceptionStacktrace"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_OptAssumptions"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_OptCanonicalizer"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_OptConvertDeoptsToGuards"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_OptDevirtualizeInvokesOptimistically"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_OptEarlyReadElimination"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_OptEliminateGuards"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_OptEliminatePartiallyRedundantGuards"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_OptEliminateSafepoints"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_OptFilterProfiledTypes"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_OptFloatingReads"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_OptImplicitNullChecks"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_OptLivenessAnalysis"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_OptLoopTransform"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_OptPushThroughPi"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_OptReadElimination"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_OptScheduleOutOfLoops"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_OptTailDuplication"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_PEAInliningHints"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_PartialEscapeAnalysis"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_PrintBailout"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_PrintBinaryGraphPort"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_PrintBinaryGraphs"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_PrintCFG"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_PrintCodeBytes"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_PrintCompilation"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_PrintFilter"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_PrintGraphCache"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_PrintIRWithLIR"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_PrintIdealGraphAddress"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_PrintIdealGraphFile"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_PrintIdealGraphPort"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_PrintProfilingInformation"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_PrintStackTraceOnException"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_RangeTestsSwitchDensity"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_ReassociateInvariants"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_RegisterPressure"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_RelevanceCapForInlining"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_RemoveNeverExecutedCode"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_ResolveClassBeforeStaticInvoke"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_SafepointPollOffset"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_SmallCompiledLowLevelGraphSize"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_SnippetCounters"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_StackShadowPages"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_SupportJsrBytecodes"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_TailDuplicationProbability"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_TailDuplicationTrivialSize"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_TraceBytecodeParserLevel"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_TraceEscapeAnalysis"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_TraceLIRGeneratorLevel"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_TraceLinearScanLevel"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_TrivialInliningSize"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_UseExceptionProbability"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_UseExceptionProbabilityForOperations"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_UseLoopLimitChecks"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_UseProfilingInformation"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_UseTypeCheckHints"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_VerifyPhases"/>
+        <provider classname="com.oracle.graal.phases.GraalOptions_ZapStackOnMethodEntry"/>
+        <provider classname="com.oracle.graal.phases.common.InliningPhase_AlwaysInlineIntrinsics"/>
+        <provider classname="com.oracle.graal.phases.tiers.Suites_CompilerConfiguration"/>
       </service>
       <service type="com.oracle.graal.phases.tiers.CompilerConfiguration">
         <provider classname="com.oracle.graal.compiler.phases.BasicCompilerConfiguration"/>
--- a/mx/projects	Wed Jun 05 14:49:34 2013 +0200
+++ b/mx/projects	Wed Jun 05 15:11:58 2013 +0200
@@ -100,7 +100,7 @@
 project@com.oracle.graal.hotspot@sourceDirs=src
 project@com.oracle.graal.hotspot@dependencies=com.oracle.graal.replacements,com.oracle.graal.printer
 project@com.oracle.graal.hotspot@checkstyle=com.oracle.graal.graph
-project@com.oracle.graal.hotspot@annotationProcessors=com.oracle.graal.replacements.verifier,com.oracle.graal.service.processor,com.oracle.graal.options
+project@com.oracle.graal.hotspot@annotationProcessors=com.oracle.graal.replacements.verifier,com.oracle.graal.service.processor
 project@com.oracle.graal.hotspot@javaCompliance=1.7
 
 # graal.hotspot.amd64
@@ -143,6 +143,7 @@
 project@com.oracle.graal.options@sourceDirs=src
 project@com.oracle.graal.options@checkstyle=com.oracle.graal.graph
 project@com.oracle.graal.options@javaCompliance=1.7
+project@com.oracle.graal.options@annotationProcessorForDependents=true
 
 # graal.graph
 project@com.oracle.graal.graph@subDir=graal
@@ -251,7 +252,7 @@
 # graal.phases
 project@com.oracle.graal.phases@subDir=graal
 project@com.oracle.graal.phases@sourceDirs=src
-project@com.oracle.graal.phases@dependencies=com.oracle.graal.nodes
+project@com.oracle.graal.phases@dependencies=com.oracle.graal.nodes,com.oracle.graal.options
 project@com.oracle.graal.phases@checkstyle=com.oracle.graal.graph
 project@com.oracle.graal.phases@javaCompliance=1.7
 
@@ -279,10 +280,10 @@
 # graal.compiler
 project@com.oracle.graal.compiler@subDir=graal
 project@com.oracle.graal.compiler@sourceDirs=src
-project@com.oracle.graal.compiler@dependencies=com.oracle.graal.api.runtime,com.oracle.graal.virtual,com.oracle.graal.options,com.oracle.graal.loop,com.oracle.graal.alloc,com.oracle.graal.lir
+project@com.oracle.graal.compiler@dependencies=com.oracle.graal.api.runtime,com.oracle.graal.virtual,com.oracle.graal.loop,com.oracle.graal.alloc,com.oracle.graal.lir
 project@com.oracle.graal.compiler@checkstyle=com.oracle.graal.graph
 project@com.oracle.graal.compiler@javaCompliance=1.7
-project@com.oracle.graal.compiler@annotationProcessors=com.oracle.graal.service.processor,com.oracle.graal.options
+project@com.oracle.graal.compiler@annotationProcessors=com.oracle.graal.service.processor
 
 # graal.compiler.amd64
 project@com.oracle.graal.compiler.amd64@subDir=graal
--- a/mxtool/mx.py	Wed Jun 05 14:49:34 2013 +0200
+++ b/mxtool/mx.py	Wed Jun 05 15:11:58 2013 +0200
@@ -146,6 +146,7 @@
 _libs = dict()
 _dists = dict()
 _suites = dict()
+_annotationProcessors = None
 _mainSuite = None
 _opts = None
 _java = None
@@ -219,8 +220,8 @@
         libraries if 'includeLibs' is true, to the 'deps' list.
         """
         childDeps = list(self.deps)
-        if includeAnnotationProcessors and hasattr(self, 'annotationProcessors') and len(self.annotationProcessors) > 0:
-            childDeps = self.annotationProcessors + childDeps
+        if includeAnnotationProcessors and len(self.annotation_processors()) > 0:
+            childDeps = self.annotation_processors() + childDeps
         if self in deps:
             return deps
         for name in childDeps:
@@ -408,6 +409,19 @@
         self._init_packages_and_imports()
         return self._imported_java_packages
 
+    def annotation_processors(self):
+        if not hasattr(self, '_annotationProcessors'):
+            ap = set()
+            if hasattr(self, '_declaredAnnotationProcessors'):
+                ap = set(self._declaredAnnotationProcessors)
+
+            # find dependencies that auto-inject themselves as annotation processors to all dependents                
+            allDeps = self.all_deps([], includeLibs=False, includeSelf=False, includeAnnotationProcessors=False)
+            for p in allDeps:
+                if hasattr(p, 'annotationProcessorForDependents') and p.annotationProcessorForDependents.lower() == 'true':
+                    ap.add(p.name)
+            self._annotationProcessors = list(ap)
+        return self._annotationProcessors
 
 class Library(Dependency):
     def __init__(self, suite, name, path, mustExist, urls, sourcePath, sourceUrls):
@@ -527,7 +541,7 @@
             if not p.native and p.javaCompliance is None:
                 abort('javaCompliance property required for non-native project ' + name)
             if len(ap) > 0:
-                p.annotationProcessors = ap
+                p._declaredAnnotationProcessors = ap
             p.__dict__.update(attrs)
             self.projects.append(p)
 
@@ -731,6 +745,18 @@
     """
     return _projects.values()
 
+def annotation_processors():
+    """
+    Get the list of all loaded projects that define an annotation processor.
+    """
+    global _annotationProcessors
+    if _annotationProcessors is None:
+        ap = set()
+        for p in projects():
+            ap.update(p.annotation_processors())
+        _annotationProcessors = list(ap)
+    return _annotationProcessors
+
 def distribution(name, fatalIfMissing=True):
     """
     Get the distribution for a given name. This will abort if the named distribution does
@@ -1515,8 +1541,9 @@
         if java().debug_port is not None:
             javacArgs += ['-J-Xdebug', '-J-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=' + str(java().debug_port)]
 
-        if hasattr(p, 'annotationProcessors') and len(p.annotationProcessors) > 0:
-            processorPath = classpath(p.annotationProcessors, resolve=True)
+        ap = p.annotation_processors()
+        if len(ap) > 0:
+            processorPath = classpath(ap, resolve=True)
             genDir = p.source_gen_dir();
             if exists(genDir):
                 shutil.rmtree(genDir)
@@ -1672,16 +1699,16 @@
     return 0
 
 def processorjars():
-    projects = set()
     
+    projs = set()
     for p in sorted_deps():
         if _isAnnotationProcessorDependency(p):
-            projects.add(p)
+            projs.add(p)
             
-    if len(projects) <= 0:
+    if len(projs) < 0:
         return
     
-    pnames = [p.name for p in projects]
+    pnames = [p.name for p in projs]
     build(['--projects', ",".join(pnames)])
     archive(pnames)
 
@@ -2172,7 +2199,7 @@
                 os.mkdir(srcDir)
             out.element('classpathentry', {'kind' : 'src', 'path' : src})
 
-        if hasattr(p, 'annotationProcessors') and len(p.annotationProcessors) > 0:
+        if len(p.annotation_processors()) > 0:
             genDir = p.source_gen_dir();
             if not exists(genDir):
                 os.mkdir(genDir)
@@ -2296,22 +2323,22 @@
         eclipseSettingsDir = join(suite.dir, 'mx', 'eclipse-settings')
         if exists(eclipseSettingsDir):
             for name in os.listdir(eclipseSettingsDir):
-                if name == "org.eclipse.jdt.apt.core.prefs" and not (hasattr(p, 'annotationProcessors') and len(p.annotationProcessors) > 0):
+                if name == "org.eclipse.jdt.apt.core.prefs" and not len(p.annotation_processors()) > 0:
                     continue
                 path = join(eclipseSettingsDir, name)
                 if isfile(path):
                     with open(join(eclipseSettingsDir, name)) as f:
                         content = f.read()
                     content = content.replace('${javaCompliance}', str(p.javaCompliance))
-                    if hasattr(p, 'annotationProcessors') and len(p.annotationProcessors) > 0:
+                    if len(p.annotation_processors()) > 0:
                         content = content.replace('org.eclipse.jdt.core.compiler.processAnnotations=disabled', 'org.eclipse.jdt.core.compiler.processAnnotations=enabled')
                     update_file(join(settingsDir, name), content)
         
-        if hasattr(p, 'annotationProcessors') and len(p.annotationProcessors) > 0:
+        if len(p.annotation_processors()) > 0:
             out = XMLDoc()
             out.open('factorypath')
             out.element('factorypathentry', {'kind' : 'PLUGIN', 'id' : 'org.eclipse.jst.ws.annotations.core', 'enabled' : 'true', 'runInBatchMode' : 'false'})
-            for ap in p.annotationProcessors:
+            for ap in p.annotation_processors():
                 apProject = project(ap)
                 for dep in apProject.all_deps([], True):
                     if dep.isLibrary():
@@ -2336,22 +2363,7 @@
     """
     Determines if a given project is part of an annotation processor.
     """
-    processors = set()
-    
-    for otherProject in projects():
-        if hasattr(otherProject, 'annotationProcessors') and len(otherProject.annotationProcessors) > 0:
-            for processorName in otherProject.annotationProcessors:
-                processors.add(project(processorName, fatalIfMissing=True))
-                 
-    if p in processors:
-        return True
-    
-    for otherProject in processors:
-        deps = otherProject.all_deps([], True)
-        if p in deps:
-            return True
-    
-    return False
+    return p in sorted_deps(annotation_processors())
 
 def _genEclipseBuilder(dotProjectDoc, p, name, mxCommand, refresh=True, async=False, logToConsole=False, xmlIndent='\t', xmlStandalone=None):
     launchOut = XMLDoc();
@@ -2446,7 +2458,7 @@
         out.element('explicit-platform', {'explicit-source-supported' : 'true'})
         out.open('source-roots')
         out.element('root', {'id' : 'src.dir'})
-        if hasattr(p, 'annotationProcessors') and len(p.annotationProcessors) > 0:
+        if len(p.annotation_processors()) > 0:
             out.element('root', {'id' : 'src.ap-source-output.dir'})
         out.close('source-roots')
         out.open('test-roots')
@@ -2486,7 +2498,7 @@
         annotationProcessorEnabled = "false"
         annotationProcessorReferences = ""
         annotationProcessorSrcFolder = ""
-        if hasattr(p, 'annotationProcessors') and len(p.annotationProcessors) > 0:
+        if len(p.annotation_processors()) > 0:
             annotationProcessorEnabled = "true"
             annotationProcessorSrcFolder = "src.ap-source-output.dir=${build.generated.sources.dir}/ap-source-output"
 
@@ -2578,8 +2590,8 @@
         
         deps = p.all_deps([], True)
         annotationProcessorOnlyDeps = []
-        if hasattr(p, 'annotationProcessors') and len(p.annotationProcessors) > 0:
-            for ap in p.annotationProcessors:
+        if len(p.annotation_processors()) > 0:
+            for ap in p.annotation_processors():
                 apProject = project(ap)
                 if not apProject in deps:
                     deps.append(apProject)