changeset 9948:b4325bc087c4

Merge
author Lukas Stadler <lukas.stadler@jku.at>
date Sat, 08 Jun 2013 15:44:39 +0200
parents f8a4c5011a10 (current diff) 2194b25ff111 (diff)
children 41511d78546a 8efb5a58a799
files graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InlineableElement.java graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java
diffstat 44 files changed, 759 insertions(+), 259 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/DeoptimizationAction.java	Sat Jun 08 15:43:48 2013 +0200
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/DeoptimizationAction.java	Sat Jun 08 15:44:39 2013 +0200
@@ -32,28 +32,39 @@
      * it's highly likely nothing will change the likelihood of the deoptimization happening again.
      * For example, a compiled array allocation where the size is negative.
      */
-    None,
+    None(false),
 
     /**
      * Do not invalidate the machine code, but schedule a recompilation if this deoptimization is
      * triggered too often.
      */
-    RecompileIfTooManyDeopts,
+    RecompileIfTooManyDeopts(true),
 
     /**
      * Invalidate the machine code and reset the profiling information.
      */
-    InvalidateReprofile,
+    InvalidateReprofile(true),
 
     /**
      * Invalidate the machine code and immediately schedule a recompilation. This is typically used
      * when deoptimizing to resolve an unresolved symbol in which case extra profiling is not
      * required to determine that the deoptimization will not re-occur.
      */
-    InvalidateRecompile,
+    InvalidateRecompile(true),
 
     /**
      * Invalidate the machine code and stop compiling the outermost method of this compilation.
      */
-    InvalidateStopCompiling;
+    InvalidateStopCompiling(true);
+
+    private final boolean invalidatesCompilation;
+
+    private DeoptimizationAction(boolean invalidatesCompilation) {
+        this.invalidatesCompilation = invalidatesCompilation;
+    }
+
+    public boolean doesInvalidateCompilation() {
+        return invalidatesCompilation;
+    }
+
 }
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/AbstractJavaProfile.java	Sat Jun 08 15:43:48 2013 +0200
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/AbstractJavaProfile.java	Sat Jun 08 15:44:39 2013 +0200
@@ -25,10 +25,14 @@
 import java.io.*;
 
 /**
- * This profile object represents a certain set of profiling information at a specific BCI. The
- * precision of the supplied values may vary, but a runtime that provides this information should be
- * aware that it will be used to guide performance-critical decisions like speculative inlining,
- * etc.
+ * This object holds probability information for a set of items that were profiled at a specific
+ * BCI. The precision of the supplied values may vary, but a runtime that provides this information
+ * should be aware that it will be used to guide performance-critical decisions like speculative
+ * inlining, etc.
+ * 
+ * @param <T> a subclass of AbstractProfiledItem
+ * @param <U> the class of the items that are profiled at the specific BCI and for which
+ *            probabilities are stored. E.g., a ResolvedJavaType or a ResolvedJavaMethod.
  */
 public abstract class AbstractJavaProfile<T extends AbstractProfiledItem<U>, U> implements Serializable {
 
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/DefaultProfilingInfo.java	Sat Jun 08 15:43:48 2013 +0200
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/DefaultProfilingInfo.java	Sat Jun 08 15:44:39 2013 +0200
@@ -87,6 +87,11 @@
     }
 
     @Override
+    public boolean isMature() {
+        return false;
+    }
+
+    @Override
     public String toString() {
         return "BaseProfilingInfo<" + MetaUtil.profileToString(this, null, "; ") + ">";
     }
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ProfilingInfo.java	Sat Jun 08 15:43:48 2013 +0200
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ProfilingInfo.java	Sat Jun 08 15:44:39 2013 +0200
@@ -112,4 +112,12 @@
      */
     int getDeoptimizationCount(DeoptimizationReason reason);
 
+    /**
+     * Returns true if the profiling information can be assumed as sufficiently accurate.
+     * 
+     * @return true if the profiling information was recorded often enough mature enough, false
+     *         otherwise.
+     */
+    boolean isMature();
+
 }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ProfilingInfoTest.java	Sat Jun 08 15:43:48 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ProfilingInfoTest.java	Sat Jun 08 15:44:39 2013 +0200
@@ -128,7 +128,11 @@
     }
 
     public static Serializable checkCastSnippet(Object obj) {
-        return (Serializable) obj;
+        try {
+            return (Serializable) obj;
+        } catch (ClassCastException e) {
+            return null;
+        }
     }
 
     @Test
@@ -250,19 +254,30 @@
 
     @Test
     public void testNullSeen() {
-        ProfilingInfo info = profile("instanceOfSnippet", 1);
+        testNullSeen("instanceOfSnippet");
+        testNullSeen("checkCastSnippet");
+    }
+
+    private void testNullSeen(String snippet) {
+        ProfilingInfo info = profile(snippet, 1);
         Assert.assertEquals(TriState.FALSE, info.getNullSeen(1));
 
-        continueProfiling("instanceOfSnippet", "ABC");
+        continueProfiling(snippet, "ABC");
         Assert.assertEquals(TriState.FALSE, info.getNullSeen(1));
 
-        continueProfiling("instanceOfSnippet", (Object) null);
+        continueProfiling(snippet, new Object());
+        Assert.assertEquals(TriState.FALSE, info.getNullSeen(1));
+
+        continueProfiling(snippet, (Object) null);
         Assert.assertEquals(TriState.TRUE, info.getNullSeen(1));
 
-        continueProfiling("instanceOfSnippet", 0.0);
+        continueProfiling(snippet, 0.0);
         Assert.assertEquals(TriState.TRUE, info.getNullSeen(1));
 
-        resetProfile("instanceOfSnippet");
+        continueProfiling(snippet, new Object());
+        Assert.assertEquals(TriState.TRUE, info.getNullSeen(1));
+
+        resetProfile(snippet);
         Assert.assertEquals(TriState.FALSE, info.getNullSeen(1));
     }
 
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotGraalRuntime.java	Sat Jun 08 15:43:48 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotGraalRuntime.java	Sat Jun 08 15:44:39 2013 +0200
@@ -25,6 +25,7 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.sparc.*;
 
 /**
  * SPARC specific implementation of {@link HotSpotGraalRuntime}.
@@ -44,10 +45,15 @@
         return graalRuntime();
     }
 
+    protected static Architecture createArchitecture() {
+        return new SPARC();
+    }
+
     @Override
     protected TargetDescription createTarget() {
-        // SPARC: Create target description.
-        throw new InternalError("NYI");
+        final int stackFrameAlignment = 16;
+        final int implicitNullCheckLimit = 4096;
+        return new TargetDescription(createArchitecture(), true, stackFrameAlignment, implicitNullCheckLimit, true);
     }
 
     @Override
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java	Sat Jun 08 15:43:48 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java	Sat Jun 08 15:44:39 2013 +0200
@@ -31,6 +31,7 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.runtime.*;
 import com.oracle.graal.compiler.target.*;
+import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.bridge.*;
 import com.oracle.graal.hotspot.logging.*;
 import com.oracle.graal.hotspot.meta.*;
@@ -87,9 +88,11 @@
         runtime.compilerToVm = toVM;
     }
 
+    private static final String DEFAULT_GRAAL_RUNTIME = "basic";
+
     // @formatter:off
     @Option(help = "The runtime configuration to use")
-    private static final OptionValue<String> GraalRuntime = new OptionValue<>("basic");
+    private static final OptionValue<String> GraalRuntime = new OptionValue<>(DEFAULT_GRAAL_RUNTIME);
     // @formatter:on
 
     protected static HotSpotGraalRuntimeFactory findFactory(String architecture) {
@@ -98,6 +101,11 @@
                 return factory;
             }
         }
+        if (!DEFAULT_GRAAL_RUNTIME.equals(GraalRuntime.getValue())) {
+            // Fail fast if a non-default value for GraalRuntime was specified
+            // and the corresponding factory is not available
+            throw new GraalInternalError("Specified runtime \"%s\" not available for the %s architecture", GraalRuntime.getValue(), architecture);
+        }
         return null;
     }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotOptions.java	Sat Jun 08 15:43:48 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotOptions.java	Sat Jun 08 15:44:39 2013 +0200
@@ -23,16 +23,28 @@
 
 package com.oracle.graal.hotspot;
 
+import static java.nio.file.Files.*;
+
+import java.io.*;
+import java.nio.charset.*;
+import java.nio.file.*;
 import java.util.*;
 
 import com.oracle.graal.hotspot.logging.*;
 import com.oracle.graal.options.*;
 
+/**
+ * Called from {@code graalCompiler.cpp} to parse any Graal specific options. Such options are
+ * (currently) distinguished by a {@code "-G:"} prefix.
+ */
 public class HotSpotOptions {
 
     private static final Map<String, OptionDescriptor> options = new HashMap<>();
 
-    static {
+    /**
+     * Initializes {@link #options} from {@link Options} services.
+     */
+    private static void initializeOptions() {
         ServiceLoader<Options> sl = ServiceLoader.loadInstalled(Options.class);
         for (Options opts : sl) {
             for (OptionDescriptor desc : opts) {
@@ -45,6 +57,38 @@
         }
     }
 
+    /**
+     * Loads default option value overrides from a {@code graal.options} file if it exists. Each
+     * line in this file starts with {@code "#"} and is ignored or must have the format of a Graal
+     * command line option without the leading {@code "-G:"} prefix. These option value are set
+     * prior to processing of any Graal options present on the command line.
+     */
+    private static void loadOptionOverrides() throws InternalError {
+        String javaHome = System.getProperty("java.home");
+        Path graalDotOptions = Paths.get(javaHome, "lib", "graal.options");
+        if (!exists(graalDotOptions)) {
+            graalDotOptions = Paths.get(javaHome, "jre", "lib", "graal.options");
+        }
+        if (exists(graalDotOptions)) {
+            try {
+                for (String line : Files.readAllLines(graalDotOptions, Charset.defaultCharset())) {
+                    if (!line.startsWith("#")) {
+                        if (!setOption(line)) {
+                            throw new InternalError("Invalid option \"" + line + "\" specified in " + graalDotOptions);
+                        }
+                    }
+                }
+            } catch (IOException e) {
+                throw (InternalError) new InternalError().initCause(e);
+            }
+        }
+    }
+
+    static {
+        initializeOptions();
+        loadOptionOverrides();
+    }
+
     // Called from VM code
     public static boolean setOption(String option) {
         if (option.length() == 0) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Sat Jun 08 15:43:48 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Sat Jun 08 15:44:39 2013 +0200
@@ -384,6 +384,8 @@
     public int typeProfileWidth;
     public int methodProfileWidth;
 
+    public int interpreterProfilingThreshold;
+
     public long inlineCacheMissStub;
     public long handleDeoptStub;
     public long uncommonTrapStub;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphCache.java	Sat Jun 08 15:43:48 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphCache.java	Sat Jun 08 15:44:39 2013 +0200
@@ -127,13 +127,15 @@
     }
 
     @Override
-    public void put(StructuredGraph graph) {
+    public void put(StructuredGraph graph, boolean hasMatureProfilingInfo) {
         assert graph.method() != null;
-        cachedGraphIds.put(graph.graphId(), new WeakReference<>(graph.method()));
-        graph.method().getCompilerStorage().put(this, graph);
+        if (hasMatureProfilingInfo) {
+            cachedGraphIds.put(graph.graphId(), new WeakReference<>(graph.method()));
+            graph.method().getCompilerStorage().put(this, graph);
 
-        if (PrintGraphCache.getValue()) {
-            putCounter++;
+            if (PrintGraphCache.getValue()) {
+                putCounter++;
+            }
         }
     }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodData.java	Sat Jun 08 15:43:48 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodData.java	Sat Jun 08 15:44:39 2013 +0200
@@ -24,7 +24,6 @@
 
 import static com.oracle.graal.graph.UnsafeAccess.*;
 import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
-import static com.oracle.graal.phases.GraalOptions.*;
 
 import java.util.*;
 
@@ -376,7 +375,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 < MatureExecutionsTypeProfile.getValue()) {
+            if (entries <= 0 || totalCount <= 0) {
                 return null;
             }
 
@@ -484,7 +483,7 @@
         }
 
         private static JavaMethodProfile createMethodProfile(ResolvedJavaMethod[] methods, long[] counts, long totalCount, int entries) {
-            if (entries <= 0 || totalCount < MatureExecutionsTypeProfile.getValue()) {
+            if (entries <= 0 || totalCount <= 0) {
                 return null;
             }
 
@@ -540,11 +539,7 @@
             long notTakenCount = data.readUnsignedInt(position, NOT_TAKEN_COUNT_OFFSET);
             long total = takenCount + notTakenCount;
 
-            if (total < MatureExecutionsBranch.getValue()) {
-                return -1;
-            } else {
-                return takenCount / (double) total;
-            }
+            return total <= 0 ? -1 : takenCount / (double) total;
         }
 
         @Override
@@ -607,7 +602,7 @@
                 result[i - 1] = count;
             }
 
-            if (totalCount < MatureExecutionsPerSwitchCase.getValue() * length) {
+            if (totalCount <= 0) {
                 return null;
             } else {
                 for (int i = 0; i < length; i++) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotProfilingInfo.java	Sat Jun 08 15:43:48 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotProfilingInfo.java	Sat Jun 08 15:44:39 2013 +0200
@@ -22,32 +22,36 @@
  */
 package com.oracle.graal.hotspot.meta;
 
+import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
+
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.hotspot.*;
+import com.oracle.graal.phases.*;
 
 public final class HotSpotProfilingInfo extends CompilerObject implements ProfilingInfo {
 
     private static final long serialVersionUID = -8307682725047864875L;
     private static final DebugMetric metricInsufficentSpace = Debug.metric("InsufficientSpaceForProfilingData");
 
+    private final HotSpotMethodData methodData;
+    private final HotSpotResolvedJavaMethod method;
+
     private int position;
     private int hintPosition;
     private int hintBCI;
     private HotSpotMethodDataAccessor dataAccessor;
-    private HotSpotMethodData methodData;
-    private final int codeSize;
 
-    public HotSpotProfilingInfo(HotSpotMethodData methodData, int codeSize) {
+    public HotSpotProfilingInfo(HotSpotMethodData methodData, HotSpotResolvedJavaMethod method) {
         this.methodData = methodData;
-        this.codeSize = codeSize;
+        this.method = method;
         hintPosition = 0;
         hintBCI = -1;
     }
 
     @Override
     public int getCodeSize() {
-        return codeSize;
+        return method.getCodeSize();
     }
 
     @Override
@@ -158,6 +162,11 @@
     }
 
     @Override
+    public boolean isMature() {
+        return method.invocationCount() >= graalRuntime().getConfig().interpreterProfilingThreshold + GraalOptions.MatureProfilingInformationThreshold.getValue();
+    }
+
+    @Override
     public String toString() {
         return "HotSpotProfilingInfo<" + MetaUtil.profileToString(this, null, "; ") + ">";
     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java	Sat Jun 08 15:43:48 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java	Sat Jun 08 15:44:39 2013 +0200
@@ -288,7 +288,7 @@
             // case of a deoptimization.
             info = DefaultProfilingInfo.get(TriState.FALSE);
         } else {
-            info = new HotSpotProfilingInfo(methodData, codeSize);
+            info = new HotSpotProfilingInfo(methodData, this);
         }
         return info;
     }
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Sat Jun 08 15:43:48 2013 +0200
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Sat Jun 08 15:44:39 2013 +0200
@@ -919,7 +919,7 @@
         }
         BlockPlaceholderNode trueSucc = currentGraph.add(new BlockPlaceholderNode());
         BlockPlaceholderNode falseSucc = currentGraph.add(new BlockPlaceholderNode());
-        append(new IfNode(currentGraph.unique(new IsNullNode(receiver)), trueSucc, falseSucc, 0.1));
+        append(new IfNode(currentGraph.unique(new IsNullNode(receiver)), trueSucc, falseSucc, 0.01));
         lastInstr = falseSucc;
 
         if (OmitHotExceptionStacktrace.getValue()) {
@@ -943,7 +943,7 @@
     private void emitBoundsCheck(ValueNode index, ValueNode length) {
         BlockPlaceholderNode trueSucc = currentGraph.add(new BlockPlaceholderNode());
         BlockPlaceholderNode falseSucc = currentGraph.add(new BlockPlaceholderNode());
-        append(new IfNode(currentGraph.unique(new IntegerBelowThanNode(index, length)), trueSucc, falseSucc, 0.9));
+        append(new IfNode(currentGraph.unique(new IntegerBelowThanNode(index, length)), trueSucc, falseSucc, 0.99));
         lastInstr = trueSucc;
 
         if (OmitHotExceptionStacktrace.getValue()) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InlineableElement.java	Sat Jun 08 15:43:48 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.nodes;
-
-public interface InlineableElement {
-
-    int getNodeCount();
-
-    Iterable<Invoke> getInvokes();
-}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java	Sat Jun 08 15:43:48 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java	Sat Jun 08 15:44:39 2013 +0200
@@ -35,7 +35,7 @@
  * A graph that contains at least one distinguished node : the {@link #start() start} node. This
  * node is the start of the control flow of the graph.
  */
-public class StructuredGraph extends Graph implements InlineableElement {
+public class StructuredGraph extends Graph {
 
     public static final int INVOCATION_ENTRY_BCI = -1;
     public static final long INVALID_GRAPH_ID = -1;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SwitchNode.java	Sat Jun 08 15:43:48 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SwitchNode.java	Sat Jun 08 15:44:39 2013 +0200
@@ -56,9 +56,12 @@
     }
 
     private boolean assertProbabilities() {
+        double total = 0;
         for (double d : keyProbabilities) {
+            total += d;
             assert d >= 0.0 : "Cannot have negative probabilities in switch node: " + d;
         }
+        assert total > 0.999 && total < 1.001;
         return true;
     }
 
@@ -73,6 +76,32 @@
         return sum;
     }
 
+    public void setProbability(Node successor, double value) {
+        double changeInProbability = 0;
+        int nonZeroProbabilityCases = 0;
+        for (int i = 0; i < keySuccessors.length; i++) {
+            if (successors.get(keySuccessors[i]) == successor) {
+                changeInProbability += keyProbabilities[i] - value;
+                keyProbabilities[i] = value;
+            } else if (keyProbabilities[i] > 0) {
+                nonZeroProbabilityCases++;
+            }
+        }
+
+        if (nonZeroProbabilityCases > 0) {
+            double changePerEntry = changeInProbability / nonZeroProbabilityCases;
+            if (changePerEntry != 0) {
+                for (int i = 0; i < keyProbabilities.length; i++) {
+                    if (keyProbabilities[i] > 0) {
+                        keyProbabilities[i] = keyProbabilities[i] + changePerEntry;
+                    }
+                }
+            }
+        }
+
+        assertProbabilities();
+    }
+
     public ValueNode value() {
         return value;
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/GraphCache.java	Sat Jun 08 15:43:48 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/GraphCache.java	Sat Jun 08 15:44:39 2013 +0200
@@ -27,7 +27,7 @@
 
 public interface GraphCache {
 
-    void put(StructuredGraph graph);
+    void put(StructuredGraph graph, boolean hasMatureProfilingInfo);
 
     StructuredGraph get(ResolvedJavaMethod method);
 
--- a/graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionProcessor.java	Sat Jun 08 15:43:48 2013 +0200
+++ b/graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionProcessor.java	Sat Jun 08 15:44:39 2013 +0200
@@ -159,7 +159,7 @@
                 String help = option.help;
                 String location = pkg + "." + option.declaringClass + "." + option.field.getSimpleName();
                 String comma = i == info.options.size() - 1 ? "" : ",";
-                out.printf("            new %s(\"%s\", %s.class, \"%s\", \"%s\", %s)%s%n", OptionDescriptor.class.getSimpleName(), name, type, help, location, optionValue, comma);
+                out.printf("            new %s(\"%s\", %s.class, \"%s\", \"%s\", %s)%s\n", OptionDescriptor.class.getSimpleName(), name, type, help, location, optionValue, comma);
                 i++;
             }
             out.println("        );");
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java	Sat Jun 08 15:43:48 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java	Sat Jun 08 15:44:39 2013 +0200
@@ -40,7 +40,9 @@
 import com.oracle.graal.phases.PhasePlan.PhasePosition;
 import com.oracle.graal.phases.common.CanonicalizerPhase.CustomCanonicalizer;
 import com.oracle.graal.phases.common.InliningUtil.InlineInfo;
+import com.oracle.graal.phases.common.InliningUtil.Inlineable;
 import com.oracle.graal.phases.common.InliningUtil.InlineableMacroNode;
+import com.oracle.graal.phases.common.InliningUtil.InlineableGraph;
 import com.oracle.graal.phases.common.InliningUtil.InliningPolicy;
 import com.oracle.graal.phases.graph.*;
 
@@ -154,10 +156,10 @@
                 MethodInvocation calleeInvocation = data.pushInvocation(info, parentAssumptions, invokeProbability, invokeRelevance);
 
                 for (int i = 0; i < info.numberOfMethods(); i++) {
-                    InlineableElement elem = getInlineableElement(info.methodAt(i), info.invoke(), calleeInvocation.assumptions());
+                    Inlineable elem = getInlineableElement(info.methodAt(i), info.invoke(), calleeInvocation.assumptions());
                     info.setInlinableElement(i, elem);
-                    if (elem instanceof StructuredGraph) {
-                        data.pushGraph((StructuredGraph) elem, invokeProbability * info.probabilityAt(i), invokeRelevance * info.relevanceAt(i));
+                    if (elem instanceof InlineableGraph) {
+                        data.pushGraph(((InlineableGraph) elem).getGraph(), invokeProbability * info.probabilityAt(i), invokeRelevance * info.relevanceAt(i));
                     } else {
                         assert elem instanceof InlineableMacroNode;
                         data.pushDummyGraph();
@@ -215,12 +217,12 @@
         }
     }
 
-    private InlineableElement getInlineableElement(final ResolvedJavaMethod method, Invoke invoke, Assumptions assumptions) {
+    private Inlineable getInlineableElement(final ResolvedJavaMethod method, Invoke invoke, Assumptions assumptions) {
         Class<? extends FixedWithNextNode> macroNodeClass = InliningUtil.getMacroNodeClass(replacements, method);
         if (macroNodeClass != null) {
             return new InlineableMacroNode(macroNodeClass);
         } else {
-            return buildGraph(method, invoke, assumptions);
+            return new InlineableGraph(buildGraph(method, invoke, assumptions));
         }
     }
 
@@ -296,6 +298,8 @@
     }
 
     private StructuredGraph parseBytecodes(StructuredGraph newGraph, Assumptions assumptions) {
+        boolean hasMatureProfilingInfo = newGraph.method().getProfilingInfo().isMature();
+
         if (plan != null) {
             plan.runPhases(PhasePosition.AFTER_PARSING, newGraph);
         }
@@ -311,7 +315,7 @@
             new CullFrameStatesPhase().apply(newGraph);
         }
         if (CacheGraphs.getValue() && cache != null) {
-            cache.put(newGraph.copy());
+            cache.put(newGraph.copy(), hasMatureProfilingInfo);
         }
         return newGraph;
     }
@@ -387,7 +391,7 @@
         protected static int determineNodeCount(InlineInfo info) {
             int nodes = 0;
             for (int i = 0; i < info.numberOfMethods(); i++) {
-                InlineableElement elem = info.inlineableElementAt(i);
+                Inlineable elem = info.inlineableElementAt(i);
                 if (elem != null) {
                     nodes += elem.getNodeCount();
                 }
@@ -398,10 +402,10 @@
         protected static double determineInvokeProbability(InlineInfo info) {
             double invokeProbability = 0;
             for (int i = 0; i < info.numberOfMethods(); i++) {
-                InlineableElement callee = info.inlineableElementAt(i);
+                Inlineable callee = info.inlineableElementAt(i);
                 Iterable<Invoke> invokes = callee.getInvokes();
                 if (invokes.iterator().hasNext()) {
-                    NodesToDoubles nodeProbabilities = new ComputeProbabilityClosure((StructuredGraph) callee).apply();
+                    NodesToDoubles nodeProbabilities = new ComputeProbabilityClosure(((InlineableGraph) callee).getGraph()).apply();
                     for (Invoke invoke : invokes) {
                         invokeProbability += nodeProbabilities.get(invoke.asNode());
                     }
@@ -433,15 +437,16 @@
             }
 
             double inliningBonus = getInliningBonus(info);
-
+            int nodes = determineNodeCount(info);
             int lowLevelGraphSize = previousLowLevelGraphSize(info);
+
             if (SmallCompiledLowLevelGraphSize.getValue() > 0 && lowLevelGraphSize > SmallCompiledLowLevelGraphSize.getValue() * inliningBonus) {
-                return InliningUtil.logNotInlinedMethod(info, inliningDepth, "too large previous low-level graph: %d", lowLevelGraphSize);
+                return InliningUtil.logNotInlinedMethod(info, inliningDepth, "too large previous low-level graph (low-level-nodes: %d, relevance=%f, probability=%f, bonus=%f, nodes=%d)",
+                                lowLevelGraphSize, relevance, probability, inliningBonus, nodes);
             }
 
-            int nodes = determineNodeCount(info);
             if (nodes < TrivialInliningSize.getValue() * inliningBonus) {
-                return InliningUtil.logInlinedMethod(info, inliningDepth, fullyProcessed, "trivial (nodes=%d)", nodes);
+                return InliningUtil.logInlinedMethod(info, inliningDepth, fullyProcessed, "trivial (relevance=%f, probability=%f, bonus=%f, nodes=%d)", relevance, probability, inliningBonus, nodes);
             }
 
             /*
@@ -452,16 +457,17 @@
              */
             double invokes = determineInvokeProbability(info);
             if (LimitInlinedInvokes.getValue() > 0 && fullyProcessed && invokes > LimitInlinedInvokes.getValue() * inliningBonus) {
-                return InliningUtil.logNotInlinedMethod(info, inliningDepth, "callee invoke probability is too high (%f)", invokes);
+                return InliningUtil.logNotInlinedMethod(info, inliningDepth, "callee invoke probability is too high (invokeP=%f, relevance=%f, probability=%f, bonus=%f, nodes=%d)", invokes,
+                                relevance, probability, inliningBonus, nodes);
             }
 
             double maximumNodes = computeMaximumSize(relevance, (int) (MaximumInliningSize.getValue() * inliningBonus));
             if (nodes <= maximumNodes) {
-                return InliningUtil.logInlinedMethod(info, inliningDepth, fullyProcessed, "relevance-based (relevance=%f, probability=%f, bonus=%f, nodes=%d <= max=%f)", relevance, probability,
+                return InliningUtil.logInlinedMethod(info, inliningDepth, fullyProcessed, "relevance-based (relevance=%f, probability=%f, bonus=%f, nodes=%d <= %f)", relevance, probability,
                                 inliningBonus, nodes, maximumNodes);
             }
 
-            return InliningUtil.logNotInlinedMethod(info, inliningDepth, "relevance-based (relevance=%f, probability=%f, bonus=%f, nodes=%d > max=%f)", relevance, probability, inliningBonus, nodes,
+            return InliningUtil.logNotInlinedMethod(info, inliningDepth, "relevance-based (relevance=%f, probability=%f, bonus=%f, nodes=%d > %f)", relevance, probability, inliningBonus, nodes,
                             maximumNodes);
         }
     }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java	Sat Jun 08 15:43:48 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java	Sat Jun 08 15:44:39 2013 +0200
@@ -66,7 +66,37 @@
         boolean isWorthInlining(InlineInfo info, int inliningDepth, double probability, double relevance, boolean fullyProcessed);
     }
 
-    public static class InlineableMacroNode implements InlineableElement {
+    public interface Inlineable {
+
+        int getNodeCount();
+
+        Iterable<Invoke> getInvokes();
+    }
+
+    public static class InlineableGraph implements Inlineable {
+
+        private final StructuredGraph graph;
+
+        public InlineableGraph(StructuredGraph graph) {
+            this.graph = graph;
+        }
+
+        @Override
+        public int getNodeCount() {
+            return graph.getNodeCount();
+        }
+
+        @Override
+        public Iterable<Invoke> getInvokes() {
+            return graph.getInvokes();
+        }
+
+        public StructuredGraph getGraph() {
+            return graph;
+        }
+    }
+
+    public static class InlineableMacroNode implements Inlineable {
 
         private final Class<? extends FixedWithNextNode> macroNodeClass;
 
@@ -238,13 +268,13 @@
 
         ResolvedJavaMethod methodAt(int index);
 
-        InlineableElement inlineableElementAt(int index);
+        Inlineable inlineableElementAt(int index);
 
         double probabilityAt(int index);
 
         double relevanceAt(int index);
 
-        void setInlinableElement(int index, InlineableElement inlineableElement);
+        void setInlinableElement(int index, Inlineable inlineableElement);
 
         /**
          * Performs the inlining described by this object and returns the node that represents the
@@ -277,10 +307,10 @@
             return invoke;
         }
 
-        protected static void inline(Invoke invoke, ResolvedJavaMethod concrete, InlineableElement inlineable, Assumptions assumptions, boolean receiverNullCheck) {
+        protected static void inline(Invoke invoke, ResolvedJavaMethod concrete, Inlineable inlineable, Assumptions assumptions, boolean receiverNullCheck) {
             StructuredGraph graph = invoke.asNode().graph();
-            if (inlineable instanceof StructuredGraph) {
-                StructuredGraph calleeGraph = (StructuredGraph) inlineable;
+            if (inlineable instanceof InlineableGraph) {
+                StructuredGraph calleeGraph = ((InlineableGraph) inlineable).getGraph();
                 InliningUtil.inline(invoke, calleeGraph, receiverNullCheck);
 
                 graph.getLeafGraphIds().add(calleeGraph.graphId());
@@ -331,7 +361,7 @@
     private static class ExactInlineInfo extends AbstractInlineInfo {
 
         protected final ResolvedJavaMethod concrete;
-        private InlineableElement inlineableElement;
+        private Inlineable inlineableElement;
 
         public ExactInlineInfo(Invoke invoke, ResolvedJavaMethod concrete) {
             super(invoke);
@@ -377,13 +407,13 @@
         }
 
         @Override
-        public InlineableElement inlineableElementAt(int index) {
+        public Inlineable inlineableElementAt(int index) {
             assert index == 0;
             return inlineableElement;
         }
 
         @Override
-        public void setInlinableElement(int index, InlineableElement inlineableElement) {
+        public void setInlinableElement(int index, Inlineable inlineableElement) {
             assert index == 0;
             this.inlineableElement = inlineableElement;
         }
@@ -398,7 +428,7 @@
 
         private final ResolvedJavaMethod concrete;
         private final ResolvedJavaType type;
-        private InlineableElement inlineableElement;
+        private Inlineable inlineableElement;
 
         public TypeGuardInlineInfo(Invoke invoke, ResolvedJavaMethod concrete, ResolvedJavaType type) {
             super(invoke);
@@ -418,7 +448,7 @@
         }
 
         @Override
-        public InlineableElement inlineableElementAt(int index) {
+        public Inlineable inlineableElementAt(int index) {
             assert index == 0;
             return inlineableElement;
         }
@@ -436,7 +466,7 @@
         }
 
         @Override
-        public void setInlinableElement(int index, InlineableElement inlineableElement) {
+        public void setInlinableElement(int index, Inlineable inlineableElement) {
             assert index == 0;
             this.inlineableElement = inlineableElement;
         }
@@ -491,7 +521,7 @@
         private final ArrayList<ProfiledType> ptypes;
         private final ArrayList<Double> concretesProbabilities;
         private final double notRecordedTypeProbability;
-        private final InlineableElement[] inlineableElements;
+        private final Inlineable[] inlineableElements;
 
         public MultiTypeGuardInlineInfo(Invoke invoke, ArrayList<ResolvedJavaMethod> concretes, ArrayList<Double> concretesProbabilities, ArrayList<ProfiledType> ptypes,
                         ArrayList<Integer> typesToConcretes, double notRecordedTypeProbability) {
@@ -504,7 +534,7 @@
             this.ptypes = ptypes;
             this.typesToConcretes = typesToConcretes;
             this.notRecordedTypeProbability = notRecordedTypeProbability;
-            this.inlineableElements = new InlineableElement[concretes.size()];
+            this.inlineableElements = new Inlineable[concretes.size()];
             this.methodProbabilities = computeMethodProbabilities();
             this.maximumMethodProbability = maximumMethodProbability();
             assert maximumMethodProbability > 0;
@@ -540,7 +570,7 @@
         }
 
         @Override
-        public InlineableElement inlineableElementAt(int index) {
+        public Inlineable inlineableElementAt(int index) {
             assert index >= 0 && index < concretes.size();
             return inlineableElements[index];
         }
@@ -556,7 +586,7 @@
         }
 
         @Override
-        public void setInlinableElement(int index, InlineableElement inlineableElement) {
+        public void setInlinableElement(int index, Inlineable inlineableElement) {
             assert index >= 0 && index < concretes.size();
             inlineableElements[index] = inlineableElement;
         }
@@ -907,16 +937,12 @@
         @Override
         public void tryToDevirtualizeInvoke(MetaAccessProvider runtime, Assumptions assumptions) {
             if (hasSingleMethod()) {
-                tryToDevirtualizeSingleMethod(graph(), runtime);
+                devirtualizeWithTypeSwitch(graph(), InvokeKind.Special, concretes.get(0), runtime);
             } else {
                 tryToDevirtualizeMultipleMethods(graph(), runtime);
             }
         }
 
-        private void tryToDevirtualizeSingleMethod(StructuredGraph graph, MetaAccessProvider runtime) {
-            devirtualizeWithTypeSwitch(graph, InvokeKind.Special, concretes.get(0), runtime);
-        }
-
         private void tryToDevirtualizeMultipleMethods(StructuredGraph graph, MetaAccessProvider runtime) {
             MethodCallTargetNode methodCallTarget = (MethodCallTargetNode) invoke.callTarget();
             if (methodCallTarget.invokeKind() == InvokeKind.Interface) {
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java	Sat Jun 08 15:43:48 2013 +0200
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java	Sat Jun 08 15:44:39 2013 +0200
@@ -87,11 +87,7 @@
     @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);
+    public static final OptionValue<Integer> MatureProfilingInformationThreshold = new OptionValue<>(100);
 
     // comilation queue
     @Option(help = "")
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/ComputeProbabilityClosure.java	Sat Jun 08 15:43:48 2013 +0200
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/ComputeProbabilityClosure.java	Sat Jun 08 15:44:39 2013 +0200
@@ -26,6 +26,7 @@
 
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.util.*;
 
 /**
@@ -63,12 +64,104 @@
     }
 
     public NodesToDoubles apply() {
+        adjustControlSplitProbabilities();
         new PropagateProbability(graph.start()).apply();
         computeLoopFactors();
         new PropagateLoopFrequency(graph.start()).apply();
+        assert verifyProbabilities();
         return nodeProbabilities;
     }
 
+    /**
+     * Assume that paths with a DeoptimizeNode at their end are taken infrequently.
+     */
+    private void adjustControlSplitProbabilities() {
+        HashSet<ControlSplitNode> result = new HashSet<>();
+        NodeBitMap visitedNodes = new NodeBitMap(graph);
+        for (DeoptimizeNode n : graph.getNodes(DeoptimizeNode.class)) {
+            if (n.action().doesInvalidateCompilation()) {
+                findParentControlSplitNodes(result, n, visitedNodes);
+            }
+        }
+
+        for (ControlSplitNode n : result) {
+            if (!allSuxVisited(n, visitedNodes)) {
+                modifyProbabilities(n, visitedNodes);
+            }
+        }
+    }
+
+    private static void findParentControlSplitNodes(HashSet<ControlSplitNode> result, DeoptimizeNode n, NodeBitMap visitedNodes) {
+        ArrayDeque<FixedNode> nodes = new ArrayDeque<>();
+        nodes.push(n);
+
+        Node currentNode;
+        do {
+            currentNode = nodes.pop();
+            visitedNodes.mark(currentNode);
+
+            for (Node pred : currentNode.cfgPredecessors()) {
+                FixedNode fixedPred = (FixedNode) pred;
+                if (allSuxVisited(fixedPred, visitedNodes) || fixedPred instanceof InvokeWithExceptionNode) {
+                    nodes.push(fixedPred);
+                } else {
+                    assert fixedPred instanceof ControlSplitNode : "only control splits can have more than one sux";
+                    result.add((ControlSplitNode) fixedPred);
+                }
+            }
+        } while (!nodes.isEmpty());
+    }
+
+    private static void modifyProbabilities(ControlSplitNode node, NodeBitMap visitedNodes) {
+        if (node instanceof IfNode) {
+            IfNode ifNode = (IfNode) node;
+            assert visitedNodes.isMarked(ifNode.falseSuccessor()) ^ visitedNodes.isMarked(ifNode.trueSuccessor());
+
+            if (visitedNodes.isMarked(ifNode.trueSuccessor())) {
+                if (ifNode.probability(ifNode.trueSuccessor()) > 0) {
+                    ifNode.setTrueSuccessorProbability(0);
+                }
+            } else {
+                if (ifNode.probability(ifNode.trueSuccessor()) < 1) {
+                    ifNode.setTrueSuccessorProbability(1);
+                }
+            }
+        } else if (node instanceof SwitchNode) {
+            SwitchNode switchNode = (SwitchNode) node;
+            for (Node sux : switchNode.successors()) {
+                if (visitedNodes.isMarked(sux)) {
+                    switchNode.setProbability(sux, 0);
+                }
+            }
+        } else {
+            GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+    private static boolean allSuxVisited(FixedNode fixedPred, NodeBitMap visitedNodes) {
+        for (Node sux : fixedPred.successors()) {
+            if (!visitedNodes.contains(sux)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private boolean verifyProbabilities() {
+        if (doesNotAlwaysDeopt(graph)) {
+            for (DeoptimizeNode n : graph.getNodes(DeoptimizeNode.class)) {
+                if (n.action().doesInvalidateCompilation() && nodeProbabilities.get(n) > 0.01) {
+                    throw new AssertionError(String.format("%s with reason %s and probability %f in graph %s", n, n.reason(), nodeProbabilities.get(n), graph));
+                }
+            }
+        }
+        return true;
+    }
+
+    private static boolean doesNotAlwaysDeopt(StructuredGraph graph) {
+        return graph.getNodes(ReturnNode.class).iterator().hasNext();
+    }
+
     private void computeLoopFactors() {
         for (LoopInfo info : loopInfos) {
             double frequency = info.loopFrequency(nodeProbabilities);
--- a/make/Makefile	Sat Jun 08 15:43:48 2013 +0200
+++ b/make/Makefile	Sat Jun 08 15:44:39 2013 +0200
@@ -516,6 +516,10 @@
 $(EXPORT_JRE_LIB_DIR)/%.jar: $(SHARED_DIR)/%.jar
 	$(install-file)
 
+# Shared options files
+$(EXPORT_JRE_LIB_DIR)/%.options: $(SHARED_DIR)/%.options
+	$(install-file)
+	
 # Include files (jvmti.h, jvmticmlr.h, jni.h, $(JDK_INCLUDE_SUBDIR)/jni_md.h, jmm.h, jfr.h)
 $(EXPORT_INCLUDE_DIR)/%: $(GEN_DIR)/jvmtifiles/%
 	$(install-file)
--- a/make/build-graal.xml	Sat Jun 08 15:43:48 2013 +0200
+++ b/make/build-graal.xml	Sat Jun 08 15:44:39 2013 +0200
@@ -28,7 +28,7 @@
   <property name="classes.dir" value="${shared.dir}/graal"/>
   <property name="jar.dir" value="${shared.dir}"/>
   <property name="jar.file" value="${jar.dir}/graal.jar"/>
-  <target depends="jar" name="main"/>
+  <target depends="options,jar" name="main"/>
   <target depends="cleanclasses" name="compile">
     <mkdir dir="${classes.dir}"/>
     <javac debug="on" destdir="${classes.dir}" includeantruntime="false">
@@ -101,6 +101,14 @@
   <target name="cleanclasses">
     <delete dir="${classes.dir}"/>
   </target>
+  <target if="graal.options.exists" name="options">
+    <copy todir="${jar.dir}">
+      <filelist dir="${gamma.dir}" files="graal.options"/>
+    </copy>
+  </target>
+  <target name="check-graal-options-exists">
+    <available file="${gamma.dir}/graal.options" property="graal.options.exists"/>
+  </target>
   <target depends="cleanclasses" name="clean">
     <delete file="${jar.file}"/>
   </target>
--- a/make/solaris/makefiles/buildtree.make	Sat Jun 08 15:43:48 2013 +0200
+++ b/make/solaris/makefiles/buildtree.make	Sat Jun 08 15:44:39 2013 +0200
@@ -229,7 +229,9 @@
 	echo "$(call gamma-path,altsrc,os/$(OS_FAMILY)/vm) \\"; \
 	echo "$(call gamma-path,commonsrc,os/$(OS_FAMILY)/vm) \\"; \
 	echo "$(call gamma-path,altsrc,os/posix/vm) \\"; \
-	echo "$(call gamma-path,commonsrc,os/posix/vm)"; \
+	echo "$(call gamma-path,commonsrc,os/posix/vm) \\"; \
+	echo "$(call gamma-path,altsrc,gpu/ptx) \\"; \
+	echo "$(call gamma-path,commonsrc,gpu/ptx)"; \
 	echo; \
 	echo "Src_Dirs_I = \\"; \
 	echo "$(call gamma-path,altsrc,share/vm/prims) \\"; \
@@ -244,8 +246,9 @@
 	echo "$(call gamma-path,commonsrc,os_cpu/$(OS_FAMILY)_$(ARCH)/vm) \\"; \
 	echo "$(call gamma-path,altsrc,os/$(OS_FAMILY)/vm) \\"; \
 	echo "$(call gamma-path,commonsrc,os/$(OS_FAMILY)/vm) \\"; \
-	echo "$(call gamma-path,altsrc,os/posix/vm) \\"; \
-	echo "$(call gamma-path,commonsrc,os/posix/vm)"; \
+	echo "$(call gamma-path,commonsrc,os/posix/vm) \\"; \
+	echo "$(call gamma-path,altsrc,gpu) \\"; \
+	echo "$(call gamma-path,commonsrc,gpu)"; \
 	[ -n "$(CFLAGS_BROWSE)" ] && \
 	    echo && echo "CFLAGS_BROWSE = $(CFLAGS_BROWSE)"; \
 	[ -n "$(ENABLE_FULL_DEBUG_SYMBOLS)" ] && \
--- a/make/solaris/makefiles/vm.make	Sat Jun 08 15:43:48 2013 +0200
+++ b/make/solaris/makefiles/vm.make	Sat Jun 08 15:44:39 2013 +0200
@@ -194,7 +194,9 @@
 COMPILER2_PATHS +=  $(GENERATED)/adfiles
 
 GRAAL_PATHS += $(call altsrc,$(HS_COMMON_SRC)/share/vm/graal)
+GRAAL_PATHS += $(call altsrc,$(HS_COMMON_SRC)/gpu/ptx)
 GRAAL_PATHS += $(HS_COMMON_SRC)/share/vm/graal
+GRAAL_PATHS += $(HS_COMMON_SRC)/gpu/ptx
 
 # Include dirs per type.
 Src_Dirs/CORE      := $(CORE_PATHS)
--- a/mx/commands.py	Sat Jun 08 15:43:48 2013 +0200
+++ b/mx/commands.py	Sat Jun 08 15:44:39 2013 +0200
@@ -232,6 +232,8 @@
     machine = platform.uname()[4]
     if machine in ['amd64', 'AMD64', 'x86_64', 'i86pc']:
         return 'amd64'
+    if machine in ['sun4v']:
+        return 'sparc'
     if machine == 'i386' and mx.get_os() == 'darwin':
         try:
             # Support for Snow Leopard and earlier version of MacOSX
@@ -343,6 +345,7 @@
 
 def _installGraalJarInJdks(graalDist):
     graalJar = graalDist.path
+    graalOptions = join(_graal_home, 'graal.options')
     jdks = join(_graal_home, 'jdk' + str(mx.java().version))
     if exists(jdks):
         for e in os.listdir(jdks):
@@ -353,6 +356,9 @@
                 shutil.copyfile(graalJar, tmp)
                 os.close(fd)
                 shutil.move(tmp, join(jreLibDir, 'graal.jar'))
+                
+                if exists(graalOptions):
+                    shutil.copy(graalOptions, join(jreLibDir, 'graal.options'))
 
 # run a command in the windows SDK Debug Shell
 def _runInDebugShell(cmd, workingDir, logFile=None, findInOutput=None, respondTo={}):
@@ -458,7 +464,7 @@
     out.element('property', {'name' : 'jar.dir', 'value' : '${shared.dir}'})
     out.element('property', {'name' : 'jar.file', 'value' : '${jar.dir}/graal.jar'})
     
-    out.element('target', {'name' : 'main', 'depends' : 'jar'})
+    out.element('target', {'name' : 'main', 'depends' : 'options,jar'})
 
     serviceMap = {};
     def addService(service, provider):
@@ -513,6 +519,16 @@
     out.element('delete', {'dir' : '${classes.dir}'})
     out.close('target')
 
+    out.open('target', {'name' : 'options', 'if' : 'graal.options.exists'})
+    out.open('copy', {'todir' : '${jar.dir}'})
+    out.element('filelist', {'dir' : '${gamma.dir}', 'files' : 'graal.options'})
+    out.close('copy')
+    out.close('target')
+
+    out.open('target', {'name' : 'check-graal-options-exists'})
+    out.element('available', {'property' : 'graal.options.exists', 'file' : '${gamma.dir}/graal.options'})
+    out.close('target')
+    
     out.open('target', {'name' : 'clean', 'depends' : 'cleanclasses'})
     out.element('delete', {'file' : '${jar.file}'})
     out.close('target')
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/sparc/vm/codeInstaller_sparc.hpp	Sat Jun 08 15:44:39 2013 +0200
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+#ifndef CPU_SPARC_VM_CODEINSTALLER_SPARC_HPP
+#define CPU_SPARC_VM_CODEINSTALLER_SPARC_HPP
+
+inline jint CodeInstaller::pd_next_offset(NativeInstruction* inst, jint pc_offset, oop method) {
+  fatal("CodeInstaller::pd_next_offset - sparc unimp");
+  return 0;
+}
+
+inline void CodeInstaller::pd_site_DataPatch(oop constant, oop kind, bool inlined,
+                                             address instruction, int alignment, char typeChar) {
+  fatal("CodeInstaller::pd_site_DataPatch - sparc unimp");
+}
+
+inline void CodeInstaller::pd_relocate_CodeBlob(CodeBlob* cb, NativeInstruction* inst) {
+  fatal("CodeInstaller::pd_relocate_CodeBlob - sparc unimp");
+}
+
+inline void CodeInstaller::pd_relocate_ForeignCall(NativeInstruction* inst, jlong foreign_call_destination) {
+  fatal("CodeInstaller::pd_relocate_ForeignCall - sparc unimp");
+}
+
+inline void CodeInstaller::pd_relocate_JavaMethod(oop method, jint pc_offset) {
+  fatal("CodeInstaller::pd_relocate_JavaMethod - sparc unimp");
+}
+
+inline int32_t* CodeInstaller::pd_locate_operand(address instruction) {
+  fatal("CodeInstaller::pd_locate_operand - sparc unimp");
+  return (int32_t*)0;
+}
+
+#endif // CPU_SPARC_VM_CODEINSTALLER_SPARC_HPP
--- a/src/cpu/sparc/vm/graalGlobals_sparc.hpp	Sat Jun 08 15:43:48 2013 +0200
+++ b/src/cpu/sparc/vm/graalGlobals_sparc.hpp	Sat Jun 08 15:44:39 2013 +0200
@@ -31,6 +31,32 @@
 // Sets the default values for platform dependent flags used by the Graal compiler.
 // (see graalGlobals.hpp)
 
-define_pd_global(intx, GraalSafepointPollOffset,     0    );
+#if !defined(COMPILER1) && !defined(COMPILER2)
+define_pd_global(bool, BackgroundCompilation,        true );
+define_pd_global(bool, UseTLAB,                      true );
+define_pd_global(bool, ResizeTLAB,                   true );
+define_pd_global(bool, InlineIntrinsics,             true );
+define_pd_global(bool, PreferInterpreterNativeStubs, false);
+define_pd_global(bool, TieredCompilation,            false);
+define_pd_global(intx, BackEdgeThreshold,            100000);
+
+define_pd_global(intx, OnStackReplacePercentage,     933  );
+define_pd_global(intx, FreqInlineSize,               325  );
+define_pd_global(intx, NewSizeThreadIncrease,        4*K  );
+define_pd_global(uintx,MetaspaceSize,                12*M );
+define_pd_global(bool, NeverActAsServerClassMachine, false);
+define_pd_global(uint64_t,MaxRAM,                    1ULL*G);
+define_pd_global(bool, CICompileOSR,                 true );
+define_pd_global(bool, ProfileTraps,                 true );
+define_pd_global(bool, UseOnStackReplacement,        true );
+define_pd_global(intx, CompileThreshold,             10000);
+define_pd_global(intx, InitialCodeCacheSize,         16*M );
+define_pd_global(intx, ReservedCodeCacheSize,        64*M );
+define_pd_global(bool, ProfileInterpreter,           true );
+define_pd_global(intx, CodeCacheExpansionSize,       64*K );
+define_pd_global(uintx,CodeCacheMinBlockLength,      4);
+define_pd_global(intx, TypeProfileWidth,             8);
+define_pd_global(intx, MethodProfileWidth,           4);
+#endif
 
 #endif // CPU_SPARC_VM_GRAALGLOBALS_SPARC_HPP
--- a/src/cpu/sparc/vm/interpreterGenerator_sparc.hpp	Sat Jun 08 15:43:48 2013 +0200
+++ b/src/cpu/sparc/vm/interpreterGenerator_sparc.hpp	Sat Jun 08 15:44:39 2013 +0200
@@ -27,11 +27,16 @@
 
  friend class AbstractInterpreterGenerator;
 
+  address generate_deopt_entry_for(TosState state, int step);
+
  private:
 
   address generate_normal_entry(bool synchronized);
   address generate_native_entry(bool synchronized);
-  address generate_abstract_entry(void);
+#ifdef GRAAL
+  address generate_execute_compiled_method_entry();
+#endif
+ address generate_abstract_entry(void);
   address generate_math_entry(AbstractInterpreter::MethodKind kind);
   address generate_empty_entry(void);
   address generate_accessor_entry(void);
--- a/src/cpu/sparc/vm/nativeInst_sparc.cpp	Sat Jun 08 15:43:48 2013 +0200
+++ b/src/cpu/sparc/vm/nativeInst_sparc.cpp	Sat Jun 08 15:44:39 2013 +0200
@@ -24,6 +24,8 @@
 
 #include "precompiled.hpp"
 #include "asm/macroAssembler.hpp"
+#include "asm/macroAssembler.inline.hpp"
+#include "code/codeCache.hpp"
 #include "memory/resourceArea.hpp"
 #include "nativeInst_sparc.hpp"
 #include "oops/oop.inline.hpp"
--- a/src/cpu/sparc/vm/sharedRuntime_sparc.cpp	Sat Jun 08 15:43:48 2013 +0200
+++ b/src/cpu/sparc/vm/sharedRuntime_sparc.cpp	Sat Jun 08 15:44:39 2013 +0200
@@ -1826,6 +1826,20 @@
   verify_oop_args(masm, method, sig_bt, regs);
   vmIntrinsics::ID iid = method->intrinsic_id();
 
+
+#ifdef GRAAL
+  if (iid == vmIntrinsics::_CompilerToVMImpl_executeCompiledMethod) {
+    // We are called from compiled code here. The three object arguments
+    // are already in the correct registers (j_rarg0, jrarg1, jrarg2). The
+    // fourth argument (j_rarg3) is a raw pointer to the nmethod. Make a tail
+    // call to its verified entry point.
+    __ set(nmethod::verified_entry_point_offset(), O0);
+    __ JMP(O0, 0);
+    __ delayed()->nop();
+    return;
+  }
+#endif
+
   // Now write the args into the outgoing interpreter space
   bool     has_receiver   = false;
   Register receiver_reg   = noreg;
--- a/src/cpu/sparc/vm/templateInterpreter_sparc.cpp	Sat Jun 08 15:43:48 2013 +0200
+++ b/src/cpu/sparc/vm/templateInterpreter_sparc.cpp	Sat Jun 08 15:44:39 2013 +0200
@@ -213,7 +213,7 @@
 }
 
 
-address TemplateInterpreterGenerator::generate_deopt_entry_for(TosState state, int step) {
+address InterpreterGenerator::generate_deopt_entry_for(TosState state, int step) {
   address entry = __ pc();
   __ get_constant_pool_cache(LcpoolCache); // load LcpoolCache
   { Label L;
@@ -813,6 +813,19 @@
   return generate_accessor_entry();
 }
 
+#ifdef GRAAL
+
+// Interpreter stub for calling a compiled method with 3 object arguments
+address InterpreterGenerator::generate_execute_compiled_method_entry() {
+  address entry_point = __ pc();
+
+  __ stop("graal-sparc unimp");
+
+  return entry_point;
+}
+
+#endif
+
 //
 // Interpreter stub for calling a native method. (asm interpreter)
 // This sets up a somewhat different looking stack for calling the native method
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/x86/vm/codeInstaller_x86.hpp	Sat Jun 08 15:44:39 2013 +0200
@@ -0,0 +1,191 @@
+/*
+ * 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.
+ */
+#ifndef CPU_SPARC_VM_CODEINSTALLER_X86_HPP
+#define CPU_SPARC_VM_CODEINSTALLER_X86_HPP
+
+#include "compiler/disassembler.hpp"
+#include "runtime/javaCalls.hpp"
+#include "graal/graalEnv.hpp"
+#include "graal/graalCompiler.hpp"
+#include "graal/graalCodeInstaller.hpp"
+#include "graal/graalJavaAccess.hpp"
+#include "graal/graalCompilerToVM.hpp"
+#include "graal/graalRuntime.hpp"
+#include "asm/register.hpp"
+#include "classfile/vmSymbols.hpp"
+#include "code/vmreg.hpp"
+
+inline jint CodeInstaller::pd_next_offset(NativeInstruction* inst, jint pc_offset, oop method) {
+  if (inst->is_call() || inst->is_jump()) {
+    assert(NativeCall::instruction_size == (int)NativeJump::instruction_size, "unexpected size");
+    return (pc_offset + NativeCall::instruction_size);
+  } else if (inst->is_mov_literal64()) {
+    // mov+call instruction pair
+    jint offset = pc_offset + NativeMovConstReg::instruction_size;
+    u_char* call = (u_char*) (_instructions->start() + offset);
+    assert((call[0] == 0x40 || call[0] == 0x41) && call[1] == 0xFF, "expected call with rex/rexb prefix byte");
+    offset += 3; /* prefix byte + opcode byte + modrm byte */
+    return (offset);
+  } else if (inst->is_call_reg()) {
+    // the inlined vtable stub contains a "call register" instruction
+    assert(method != NULL, "only valid for virtual calls");
+    return (pc_offset + ((NativeCallReg *) inst)->next_instruction_offset());
+  } else {
+    fatal("unsupported type of instruction for call site");
+  }
+}
+
+inline void CodeInstaller::pd_site_DataPatch(oop constant, oop kind, bool inlined,
+                                             address instruction, int alignment, char typeChar) {
+  switch (typeChar) {
+    case 'z':
+    case 'b':
+    case 's':
+    case 'c':
+    case 'i':
+      fatal("int-sized values not expected in DataPatch");
+      break;
+    case 'f':
+    case 'j':
+    case 'd': {
+      if (inlined) {
+        address operand = Assembler::locate_operand(instruction, Assembler::imm_operand);
+        *((jlong*) operand) = Constant::primitive(constant);
+      } else {
+        address operand = Assembler::locate_operand(instruction, Assembler::disp32_operand);
+        address next_instruction = Assembler::locate_next_instruction(instruction);
+        int size = _constants->size();
+        if (alignment > 0) {
+          guarantee(alignment <= _constants->alignment(), "Alignment inside constants section is restricted by alignment of section begin");
+          size = align_size_up(size, alignment);
+        }
+        // we don't care if this is a long/double/etc., the primitive field contains the right bits
+        address dest = _constants->start() + size;
+        _constants->set_end(dest + BytesPerLong);
+        *(jlong*) dest = Constant::primitive(constant);
+
+        long disp = dest - next_instruction;
+        assert(disp == (jint) disp, "disp doesn't fit in 32 bits");
+        *((jint*) operand) = (jint) disp;
+
+        _instructions->relocate(instruction, section_word_Relocation::spec((address) dest, CodeBuffer::SECT_CONSTS), Assembler::disp32_operand);
+        TRACE_graal_3("relocating (%c) at %p/%p with destination at %p (%d)", typeChar, instruction, operand, dest, size);
+      }
+      break;
+    }
+    case 'a': {
+      address operand = Assembler::locate_operand(instruction, Assembler::imm_operand);
+      Handle obj = Constant::object(constant);
+
+      jobject value = JNIHandles::make_local(obj());
+      *((jobject*) operand) = value;
+      _instructions->relocate(instruction, oop_Relocation::spec_for_immediate(), Assembler::imm_operand);
+      TRACE_graal_3("relocating (oop constant) at %p/%p", instruction, operand);
+      break;
+    }
+    default:
+      fatal(err_msg("unexpected Kind (%d) in DataPatch", typeChar));
+      break;
+  }
+}
+
+inline void CodeInstaller::pd_relocate_CodeBlob(CodeBlob* cb, NativeInstruction* inst) {
+  if (cb->is_nmethod()) {
+    nmethod* nm = (nmethod*) cb;
+    nativeJump_at((address)inst)->set_jump_destination(nm->verified_entry_point());
+  } else {
+    nativeJump_at((address)inst)->set_jump_destination(cb->code_begin());
+  }
+  _instructions->relocate((address)inst, runtime_call_Relocation::spec(), Assembler::call32_operand);
+}
+
+inline void CodeInstaller::pd_relocate_ForeignCall(NativeInstruction* inst, jlong foreign_call_destination) {
+  if (inst->is_call()) {
+    // NOTE: for call without a mov, the offset must fit a 32-bit immediate
+    //       see also CompilerToVM.getMaxCallTargetOffset()
+    NativeCall* call = nativeCall_at((address) (inst));
+    call->set_destination((address) foreign_call_destination);
+    _instructions->relocate(call->instruction_address(), runtime_call_Relocation::spec(), Assembler::call32_operand);
+  } else if (inst->is_mov_literal64()) {
+    NativeMovConstReg* mov = nativeMovConstReg_at((address) (inst));
+    mov->set_data((intptr_t) foreign_call_destination);
+    _instructions->relocate(mov->instruction_address(), runtime_call_Relocation::spec(), Assembler::imm_operand);
+  } else {
+    NativeJump* jump = nativeJump_at((address) (inst));
+    jump->set_jump_destination((address) foreign_call_destination);
+    _instructions->relocate((address)inst, runtime_call_Relocation::spec(), Assembler::call32_operand);
+  }
+  TRACE_graal_3("relocating (foreign call)  at %p", inst);
+}
+
+inline void CodeInstaller::pd_relocate_JavaMethod(oop hotspot_method, jint pc_offset) {
+#ifdef ASSERT
+  Method* method = NULL;
+  // we need to check, this might also be an unresolved method
+  if (hotspot_method->is_a(HotSpotResolvedJavaMethod::klass())) {
+    method = getMethodFromHotSpotMethod(hotspot_method);
+  }
+#endif
+  switch (_next_call_type) {
+    case MARK_INLINE_INVOKE:
+      break;
+    case MARK_INVOKEVIRTUAL:
+    case MARK_INVOKEINTERFACE: {
+      assert(method == NULL || !method->is_static(), "cannot call static method with invokeinterface");
+
+      NativeCall* call = nativeCall_at(_instructions->start() + pc_offset);
+      call->set_destination(SharedRuntime::get_resolve_virtual_call_stub());
+      _instructions->relocate(call->instruction_address(),
+                                             virtual_call_Relocation::spec(_invoke_mark_pc),
+                                             Assembler::call32_operand);
+      break;
+    }
+    case MARK_INVOKESTATIC: {
+      assert(method == NULL || method->is_static(), "cannot call non-static method with invokestatic");
+
+      NativeCall* call = nativeCall_at(_instructions->start() + pc_offset);
+      call->set_destination(SharedRuntime::get_resolve_static_call_stub());
+      _instructions->relocate(call->instruction_address(),
+                                             relocInfo::static_call_type, Assembler::call32_operand);
+      break;
+    }
+    case MARK_INVOKESPECIAL: {
+      assert(method == NULL || !method->is_static(), "cannot call static method with invokespecial");
+      NativeCall* call = nativeCall_at(_instructions->start() + pc_offset);
+      call->set_destination(SharedRuntime::get_resolve_opt_virtual_call_stub());
+      _instructions->relocate(call->instruction_address(),
+                              relocInfo::opt_virtual_call_type, Assembler::call32_operand);
+      break;
+    }
+    default:
+      fatal("invalid _next_call_type value");
+      break;
+  }
+}
+
+inline int32_t* CodeInstaller::pd_locate_operand(address instruction) {
+  return (int32_t*) Assembler::locate_operand(instruction, Assembler::disp32_operand);
+}
+
+#endif // CPU_SPARC_VM_CODEINSTALLER_X86_HPP
+
--- a/src/share/vm/classfile/vmSymbols.hpp	Sat Jun 08 15:43:48 2013 +0200
+++ b/src/share/vm/classfile/vmSymbols.hpp	Sat Jun 08 15:44:39 2013 +0200
@@ -314,6 +314,7 @@
   template(com_oracle_graal_hotspot_meta_HotSpotMonitorValue,        "com/oracle/graal/hotspot/meta/HotSpotMonitorValue")             \
   template(com_oracle_graal_hotspot_debug_LocalImpl,                 "com/oracle/graal/hotspot/debug/LocalImpl")                      \
   AMD64_ONLY(template(com_oracle_graal_hotspot_amd64_AMD64HotSpotGraalRuntime,"com/oracle/graal/hotspot/amd64/AMD64HotSpotGraalRuntime"))\
+  SPARC_ONLY(template(com_oracle_graal_hotspot_sparc_SPARCHotSpotGraalRuntime,"com/oracle/graal/hotspot/sparc/SPARCHotSpotGraalRuntime"))\
   /* graal.api.meta */                                                                                                                \
   template(com_oracle_graal_api_meta_Constant,                       "com/oracle/graal/api/meta/Constant")                            \
   template(com_oracle_graal_api_meta_ConstantPool,                   "com/oracle/graal/api/meta/ConstantPool")                        \
--- a/src/share/vm/graal/graalCodeInstaller.cpp	Sat Jun 08 15:43:48 2013 +0200
+++ b/src/share/vm/graal/graalCodeInstaller.cpp	Sat Jun 08 15:44:39 2013 +0200
@@ -35,18 +35,23 @@
 #include "code/vmreg.hpp"
 
 #ifdef TARGET_ARCH_x86
+# include "codeInstaller_x86.hpp"
 # include "vmreg_x86.inline.hpp"
 #endif
 #ifdef TARGET_ARCH_sparc
+# include "codeInstaller_sparc.hpp"
 # include "vmreg_sparc.inline.hpp"
 #endif
 #ifdef TARGET_ARCH_zero
+# include "codeInstaller_zero.hpp"
 # include "vmreg_zero.inline.hpp"
 #endif
 #ifdef TARGET_ARCH_arm
+# include "codeInstaller_arm.hpp"
 # include "vmreg_arm.inline.hpp"
 #endif
 #ifdef TARGET_ARCH_ppc
+# include "codeInstaller_ppc.hpp"
 # include "vmreg_ppc.inline.hpp"
 #endif
 
@@ -199,8 +204,16 @@
       }
       return value;
 #else
+#ifdef TARGET_ARCH_sparc
+      ScopeValue* value = new LocationValue(Location::new_reg_loc(locationType, as_FloatRegister(number)->as_VMReg()));
+      if (type == T_DOUBLE) {
+        second = value;
+      }
+      return value;
+#else
       ShouldNotReachHere("Platform currently does not support floating point values.");
 #endif
+#endif
     }
   } else if (value->is_a(StackSlot::klass())) {
     if (type == T_DOUBLE) {
@@ -704,36 +717,15 @@
   assert((hotspot_method ? 1 : 0) + (foreign_call ? 1 : 0) == 1, "Call site needs exactly one type");
 
   NativeInstruction* inst = nativeInstruction_at(_instructions->start() + pc_offset);
-  jint next_pc_offset = 0x0;
-  if (inst->is_call() || inst->is_jump()) {
-    assert(NativeCall::instruction_size == (int)NativeJump::instruction_size, "unexpected size");
-    next_pc_offset = pc_offset + NativeCall::instruction_size;
-  } else if (inst->is_mov_literal64()) {
-    // mov+call instruction pair
-    next_pc_offset = pc_offset + NativeMovConstReg::instruction_size;
-    u_char* call = (u_char*) (_instructions->start() + next_pc_offset);
-    assert((call[0] == 0x40 || call[0] == 0x41) && call[1] == 0xFF, "expected call with rex/rexb prefix byte");
-    next_pc_offset += 3; /* prefix byte + opcode byte + modrm byte */
-  } else if (inst->is_call_reg()) {
-    // the inlined vtable stub contains a "call register" instruction
-    assert(hotspot_method != NULL, "only valid for virtual calls");
-    next_pc_offset = pc_offset + ((NativeCallReg *) inst)->next_instruction_offset();
-  } else {
-    fatal("unsupported type of instruction for call site");
-  }
-
+  jint next_pc_offset = CodeInstaller::pd_next_offset(inst, pc_offset, hotspot_method);
+  
   if (target->is_a(SystemDictionary::HotSpotInstalledCode_klass())) {
     assert(inst->is_jump(), "jump expected");
 
     CodeBlob* cb = (CodeBlob*) (address) HotSpotInstalledCode::codeBlob(target);
     assert(cb != NULL, "npe");
-    if (cb->is_nmethod()) {
-      nmethod* nm = (nmethod*) cb;
-      nativeJump_at((address)inst)->set_jump_destination(nm->verified_entry_point());
-    } else {
-      nativeJump_at((address)inst)->set_jump_destination(cb->code_begin());
-    }
-    _instructions->relocate((address)inst, runtime_call_Relocation::spec(), Assembler::call32_operand);
+    
+    CodeInstaller::pd_relocate_CodeBlob(cb, inst);
 
     return;
   }
@@ -750,65 +742,14 @@
 
   if (foreign_call != NULL) {
     jlong foreign_call_destination = HotSpotForeignCallLinkage::address(foreign_call);
-    if (inst->is_call()) {
-      // NOTE: for call without a mov, the offset must fit a 32-bit immediate
-      //       see also CompilerToVM.getMaxCallTargetOffset()
-      NativeCall* call = nativeCall_at((address) (inst));
-      call->set_destination((address) foreign_call_destination);
-      _instructions->relocate(call->instruction_address(), runtime_call_Relocation::spec(), Assembler::call32_operand);
-    } else if (inst->is_mov_literal64()) {
-      NativeMovConstReg* mov = nativeMovConstReg_at((address) (inst));
-      mov->set_data((intptr_t) foreign_call_destination);
-      _instructions->relocate(mov->instruction_address(), runtime_call_Relocation::spec(), Assembler::imm_operand);
-    } else {
-      NativeJump* jump = nativeJump_at((address) (inst));
-      jump->set_jump_destination((address) foreign_call_destination);
-      _instructions->relocate((address)inst, runtime_call_Relocation::spec(), Assembler::call32_operand);
-    }
-    TRACE_graal_3("relocating (foreign call)  at %p", inst);
+
+    CodeInstaller::pd_relocate_ForeignCall(inst, foreign_call_destination);
   } else { // method != NULL
     assert(hotspot_method != NULL, "unexpected JavaMethod");
-#ifdef ASSERT
-    Method* method = NULL;
-    // we need to check, this might also be an unresolved method
-    if (hotspot_method->is_a(HotSpotResolvedJavaMethod::klass())) {
-      method = getMethodFromHotSpotMethod(hotspot_method);
-    }
-#endif
     assert(debug_info != NULL, "debug info expected");
 
     TRACE_graal_3("method call");
-    switch (_next_call_type) {
-      case MARK_INLINE_INVOKE:
-        break;
-      case MARK_INVOKEVIRTUAL:
-      case MARK_INVOKEINTERFACE: {
-        assert(method == NULL || !method->is_static(), "cannot call static method with invokeinterface");
-
-        NativeCall* call = nativeCall_at(_instructions->start() + pc_offset);
-        call->set_destination(SharedRuntime::get_resolve_virtual_call_stub());
-        _instructions->relocate(call->instruction_address(), virtual_call_Relocation::spec(_invoke_mark_pc), Assembler::call32_operand);
-        break;
-      }
-      case MARK_INVOKESTATIC: {
-        assert(method == NULL || method->is_static(), "cannot call non-static method with invokestatic");
-
-        NativeCall* call = nativeCall_at(_instructions->start() + pc_offset);
-        call->set_destination(SharedRuntime::get_resolve_static_call_stub());
-        _instructions->relocate(call->instruction_address(), relocInfo::static_call_type, Assembler::call32_operand);
-        break;
-      }
-      case MARK_INVOKESPECIAL: {
-        assert(method == NULL || !method->is_static(), "cannot call static method with invokespecial");
-        NativeCall* call = nativeCall_at(_instructions->start() + pc_offset);
-        call->set_destination(SharedRuntime::get_resolve_opt_virtual_call_stub());
-        _instructions->relocate(call->instruction_address(), relocInfo::opt_virtual_call_type, Assembler::call32_operand);
-        break;
-      }
-      default:
-        fatal("invalid _next_call_type value");
-        break;
-    }
+    CodeInstaller::pd_relocate_JavaMethod(hotspot_method, pc_offset);
   }
   _next_call_type = MARK_INVOKE_INVALID;
   if (debug_info != NULL) {
@@ -823,59 +764,15 @@
   oop kind = Constant::kind(constant);
 
   address instruction = _instructions->start() + pc_offset;
-
   char typeChar = Kind::typeChar(kind);
   switch (typeChar) {
-    case 'z':
-    case 'b':
-    case 's':
-    case 'c':
-    case 'i':
-      fatal("int-sized values not expected in DataPatch");
-      break;
     case 'f':
     case 'j':
-    case 'd': {
+    case 'd':
       record_metadata_in_constant(constant, _oop_recorder);
-      if (inlined) {
-        address operand = Assembler::locate_operand(instruction, Assembler::imm_operand);
-        *((jlong*) operand) = Constant::primitive(constant);
-      } else {
-        address operand = Assembler::locate_operand(instruction, Assembler::disp32_operand);
-        address next_instruction = Assembler::locate_next_instruction(instruction);
-        int size = _constants->size();
-        if (alignment > 0) {
-          guarantee(alignment <= _constants->alignment(), "Alignment inside constants section is restricted by alignment of section begin");
-          size = align_size_up(size, alignment);
-        }
-        // we don't care if this is a long/double/etc., the primitive field contains the right bits
-        address dest = _constants->start() + size;
-        _constants->set_end(dest + BytesPerLong);
-        *(jlong*) dest = Constant::primitive(constant);
-
-        long disp = dest - next_instruction;
-        assert(disp == (jint) disp, "disp doesn't fit in 32 bits");
-        *((jint*) operand) = (jint) disp;
-
-        _instructions->relocate(instruction, section_word_Relocation::spec((address) dest, CodeBuffer::SECT_CONSTS), Assembler::disp32_operand);
-        TRACE_graal_3("relocating (%c) at %p/%p with destination at %p (%d)", typeChar, instruction, operand, dest, size);
-      }
-      break;
-    }
-    case 'a': {
-      address operand = Assembler::locate_operand(instruction, Assembler::imm_operand);
-      Handle obj = Constant::object(constant);
-
-      jobject value = JNIHandles::make_local(obj());
-      *((jobject*) operand) = value;
-      _instructions->relocate(instruction, oop_Relocation::spec_for_immediate(), Assembler::imm_operand);
-      TRACE_graal_3("relocating (oop constant) at %p/%p", instruction, operand);
-      break;
-    }
-    default:
-      fatal(err_msg("unexpected Kind (%d) in DataPatch", typeChar));
       break;
   }
+  CodeInstaller::pd_site_DataPatch(constant, kind, inlined, instruction, alignment, typeChar);
 }
 
 void CodeInstaller::site_Mark(CodeBuffer& buffer, jint pc_offset, oop site) {
@@ -920,7 +817,8 @@
         break;
       case MARK_POLL_NEAR: {
         NativeInstruction* ni = nativeInstruction_at(instruction);
-        int32_t* disp = (int32_t*) Assembler::locate_operand(instruction, Assembler::disp32_operand);
+        int32_t* disp = (int32_t*) pd_locate_operand(instruction);
+        // int32_t* disp = (int32_t*) Assembler::locate_operand(instruction, Assembler::disp32_operand);
         int32_t offset = *disp; // The Java code installed the polling page offset into the disp32 operand
         intptr_t new_disp = (intptr_t) (os::get_polling_page() + offset) - (intptr_t) ni;
         *disp = (int32_t)new_disp;
@@ -930,7 +828,8 @@
         break;
       case MARK_POLL_RETURN_NEAR: {
         NativeInstruction* ni = nativeInstruction_at(instruction);
-        int32_t* disp = (int32_t*) Assembler::locate_operand(instruction, Assembler::disp32_operand);
+        int32_t* disp = (int32_t*) pd_locate_operand(instruction);
+        // int32_t* disp = (int32_t*) Assembler::locate_operand(instruction, Assembler::disp32_operand);
         int32_t offset = *disp; // The Java code installed the polling page offset into the disp32 operand
         intptr_t new_disp = (intptr_t) (os::get_polling_page() + offset) - (intptr_t) ni;
         *disp = (int32_t)new_disp;
--- a/src/share/vm/graal/graalCodeInstaller.hpp	Sat Jun 08 15:43:48 2013 +0200
+++ b/src/share/vm/graal/graalCodeInstaller.hpp	Sat Jun 08 15:44:39 2013 +0200
@@ -75,6 +75,13 @@
   Dependencies*             _dependencies;
   ExceptionHandlerTable     _exception_handler_table;
 
+  jint pd_next_offset(NativeInstruction* inst, jint pc_offset, oop method);
+  void pd_site_DataPatch(oop constant, oop kind, bool inlined, address instruction, int alignment, char typeChar);
+  void pd_relocate_CodeBlob(CodeBlob* cb, NativeInstruction* inst);
+  void pd_relocate_ForeignCall(NativeInstruction* inst, jlong foreign_call_destination);
+  void pd_relocate_JavaMethod(oop method, jint pc_offset);
+  int32_t* pd_locate_operand(address instruction);
+
 public:
 
   CodeInstaller(Handle& comp_result, GraalEnv::CodeInstallResult& result, CodeBlob*& cb, Handle installed_code, Handle triggered_deoptimizations);
@@ -106,4 +113,20 @@
 
 };
 
+#ifdef TARGET_ARCH_x86
+# include "codeInstaller_x86.hpp"
+#endif
+#ifdef TARGET_ARCH_sparc
+# include "codeInstaller_sparc.hpp"
+#endif
+#ifdef TARGET_ARCH_zero
+# error
+#endif
+#ifdef TARGET_ARCH_arm
+# error
+#endif
+#ifdef TARGET_ARCH_ppc
+# error
+#endif
+
 #endif // SHARE_VM_GRAAL_GRAAL_CODE_INSTALLER_HPP
--- a/src/share/vm/graal/graalCompiler.cpp	Sat Jun 08 15:43:48 2013 +0200
+++ b/src/share/vm/graal/graalCompiler.cpp	Sat Jun 08 15:44:39 2013 +0200
@@ -51,7 +51,7 @@
 
   uintptr_t heap_end = (uintptr_t) Universe::heap()->reserved_region().end();
   uintptr_t allocation_end = heap_end + ((uintptr_t)16) * 1024 * 1024 * 1024;
-  guarantee(heap_end < allocation_end, "heap end too close to end of address space (might lead to erroneous TLAB allocations)");
+  AMD64_ONLY(guarantee(heap_end < allocation_end, "heap end too close to end of address space (might lead to erroneous TLAB allocations)"));
   NOT_LP64(error("check TLAB allocation code for address space conflicts"));
 
   _deopted_leaf_graph_count = 0;
--- a/src/share/vm/graal/graalCompilerToVM.cpp	Sat Jun 08 15:43:48 2013 +0200
+++ b/src/share/vm/graal/graalCompilerToVM.cpp	Sat Jun 08 15:44:39 2013 +0200
@@ -658,8 +658,10 @@
   set_boolean("useAESIntrinsics", UseAESIntrinsics);
   set_boolean("useTLAB", UseTLAB);
   set_boolean("useG1GC", UseG1GC);
+#ifdef TARGET_ARCH_x86
   set_int("useSSE", UseSSE);
   set_int("useAVX", UseAVX);
+#endif
   set_int("codeEntryAlignment", CodeEntryAlignment);
   set_int("stackShadowPages", StackShadowPages);
   set_int("hubOffset", oopDesc::klass_offset_in_bytes());
@@ -695,9 +697,11 @@
   set_int("klassHasFinalizerFlag", JVM_ACC_HAS_FINALIZER);
   set_int("threadExceptionOopOffset", in_bytes(JavaThread::exception_oop_offset()));
   set_int("threadExceptionPcOffset", in_bytes(JavaThread::exception_pc_offset()));
+#ifdef TARGET_ARCH_x86
   set_boolean("isPollingPageFar", Assembler::is_polling_page_far());
+  set_int("runtimeCallStackSize", (jint)frame::arg_reg_save_area_bytes);
+#endif
   set_int("classMirrorOffset", in_bytes(Klass::java_mirror_offset()));
-  set_int("runtimeCallStackSize", (jint)frame::arg_reg_save_area_bytes);
   set_int("klassModifierFlagsOffset", in_bytes(Klass::modifier_flags_offset()));
   set_int("klassAccessFlagsOffset", in_bytes(Klass::access_flags_offset()));
   set_int("klassOffset", java_lang_Class::klass_offset_in_bytes());
@@ -734,6 +738,8 @@
   set_int("typeProfileWidth", TypeProfileWidth);
   set_int("methodProfileWidth", MethodProfileWidth);
 
+  set_int("interpreterProfilingThreshold", InvocationCounter::get_ProfileLimit());
+
   set_int("tlabAlignmentReserve", (int32_t)ThreadLocalAllocBuffer::alignment_reserve());
   set_long("tlabIntArrayMarkWord", (intptr_t)markOopDesc::prototype()->copy_set_hash(0x2));
   set_long("heapTopAddress", (jlong)(address) Universe::heap()->top_addr());
@@ -742,7 +748,9 @@
   set_int("threadTlabSizeOffset", in_bytes(JavaThread::tlab_size_offset()));
   set_int("threadAllocatedBytesOffset", in_bytes(JavaThread::allocated_bytes_offset()));
   set_int("threadLastJavaSpOffset", in_bytes(JavaThread::last_Java_sp_offset()));
+#ifdef TARGET_ARCH_x86
   set_int("threadLastJavaFpOffset", in_bytes(JavaThread::last_Java_fp_offset()));
+#endif
   set_int("threadLastJavaPcOffset", in_bytes(JavaThread::last_Java_pc_offset()));
   set_int("threadObjectResultOffset", in_bytes(JavaThread::vm_result_offset()));
   set_int("tlabSlowAllocationsOffset", in_bytes(JavaThread::tlab_slow_allocations_offset()));
--- a/src/share/vm/graal/graalVMToCompiler.cpp	Sat Jun 08 15:43:48 2013 +0200
+++ b/src/share/vm/graal/graalVMToCompiler.cpp	Sat Jun 08 15:44:39 2013 +0200
@@ -51,6 +51,9 @@
 #ifdef AMD64
     Symbol* name = vmSymbols::com_oracle_graal_hotspot_amd64_AMD64HotSpotGraalRuntime();
 #endif
+#ifdef SPARC
+    Symbol* name = vmSymbols::com_oracle_graal_hotspot_sparc_SPARCHotSpotGraalRuntime();
+#endif
     KlassHandle klass = loadClass(name);
 
     JavaValue result(T_OBJECT);
--- a/src/share/vm/interpreter/invocationCounter.hpp	Sat Jun 08 15:43:48 2013 +0200
+++ b/src/share/vm/interpreter/invocationCounter.hpp	Sat Jun 08 15:44:39 2013 +0200
@@ -95,9 +95,9 @@
   Action action() const                          { return _action[state()]; }
   int    count() const                           { return _counter >> number_of_noncount_bits; }
 
-  int   get_InvocationLimit() const              { return InterpreterInvocationLimit >> number_of_noncount_bits; }
-  int   get_BackwardBranchLimit() const          { return InterpreterBackwardBranchLimit >> number_of_noncount_bits; }
-  int   get_ProfileLimit() const                 { return InterpreterProfileLimit >> number_of_noncount_bits; }
+  static int   get_InvocationLimit()             { return InterpreterInvocationLimit >> number_of_noncount_bits; }
+  static int   get_BackwardBranchLimit()         { return InterpreterBackwardBranchLimit >> number_of_noncount_bits; }
+  static int   get_ProfileLimit()                { return InterpreterProfileLimit >> number_of_noncount_bits; }
 
   // Test counter using scaled limits like the asm interpreter would do rather than doing
   // the shifts to normalize the counter.
--- a/src/share/vm/runtime/fieldDescriptor.cpp	Sat Jun 08 15:43:48 2013 +0200
+++ b/src/share/vm/runtime/fieldDescriptor.cpp	Sat Jun 08 15:44:39 2013 +0200
@@ -27,9 +27,6 @@
 #include "classfile/vmSymbols.hpp"
 #include "memory/resourceArea.hpp"
 #include "memory/universe.inline.hpp"
-#include "oops/annotations.hpp"
-#include "oops/instanceKlass.hpp"
-#include "oops/fieldStreams.hpp"
 #include "runtime/fieldDescriptor.hpp"
 #include "runtime/handles.inline.hpp"
 #include "runtime/signature.hpp"
--- a/src/share/vm/runtime/fieldDescriptor.hpp	Sat Jun 08 15:43:48 2013 +0200
+++ b/src/share/vm/runtime/fieldDescriptor.hpp	Sat Jun 08 15:44:39 2013 +0200
@@ -25,7 +25,10 @@
 #ifndef SHARE_VM_RUNTIME_FIELDDESCRIPTOR_HPP
 #define SHARE_VM_RUNTIME_FIELDDESCRIPTOR_HPP
 
+#include "oops/annotations.hpp"
 #include "oops/constantPool.hpp"
+#include "oops/fieldStreams.hpp"
+#include "oops/instanceKlass.hpp"
 #include "oops/symbol.hpp"
 #include "runtime/fieldType.hpp"
 #include "utilities/accessFlags.hpp"