changeset 13785:55785507f4df

Merge.
author Doug Simon <doug.simon@oracle.com>
date Tue, 28 Jan 2014 18:32:30 +0100
parents 219a84093dda (current diff) 73f0f4755aa3 (diff)
children 4d89f51eae9e
files
diffstat 34 files changed, 389 insertions(+), 95 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/DefaultProfilingInfo.java	Mon Jan 27 20:24:12 2014 +0100
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/DefaultProfilingInfo.java	Tue Jan 28 18:32:30 2014 +0100
@@ -95,4 +95,8 @@
     public String toString() {
         return "BaseProfilingInfo<" + MetaUtil.profileToString(this, null, "; ") + ">";
     }
+
+    public void setMature() {
+        // Do nothing
+    }
 }
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ProfilingInfo.java	Mon Jan 27 20:24:12 2014 +0100
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ProfilingInfo.java	Tue Jan 28 18:32:30 2014 +0100
@@ -121,4 +121,9 @@
      */
     boolean isMature();
 
+    /**
+     * Force data to be treated as mature if possible.
+     */
+
+    void setMature();
 }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java	Mon Jan 27 20:24:12 2014 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java	Tue Jan 28 18:32:30 2014 +0100
@@ -578,7 +578,11 @@
     protected CompilationResult compile(ResolvedJavaMethod method, final StructuredGraph graph) {
         CallingConvention cc = getCallingConvention(getCodeCache(), Type.JavaCallee, graph.method(), false);
         return compileGraph(graph, cc, method, getProviders(), getBackend(), getCodeCache().getTarget(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL, getProfilingInfo(graph),
-                        new SpeculationLog(), getSuites(), true, new CompilationResult(), CompilationResultBuilderFactory.Default);
+                        getSpeculationLog(), getSuites(), true, new CompilationResult(), CompilationResultBuilderFactory.Default);
+    }
+
+    protected SpeculationLog getSpeculationLog() {
+        return null;
     }
 
     protected InstalledCode addMethod(final ResolvedJavaMethod method, final CompilationResult compResult) {
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InfopointReasonTest.java	Mon Jan 27 20:24:12 2014 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InfopointReasonTest.java	Tue Jan 28 18:32:30 2014 +0100
@@ -63,7 +63,7 @@
         final StructuredGraph graph = parse(method);
         CallingConvention cc = getCallingConvention(getCodeCache(), Type.JavaCallee, graph.method(), false);
         final CompilationResult cr = compileGraph(graph, cc, graph.method(), getProviders(), getBackend(), getCodeCache().getTarget(), null, getDefaultGraphBuilderSuite(),
-                        OptimisticOptimizations.ALL, getProfilingInfo(graph), new SpeculationLog(), getSuites(), true, new CompilationResult(), CompilationResultBuilderFactory.Default);
+                        OptimisticOptimizations.ALL, getProfilingInfo(graph), null, getSuites(), true, new CompilationResult(), CompilationResultBuilderFactory.Default);
         for (Infopoint sp : cr.getInfopoints()) {
             assertNotNull(sp.reason);
             if (sp instanceof Call) {
@@ -86,7 +86,7 @@
         CallingConvention cc = getCallingConvention(getCodeCache(), Type.JavaCallee, graph.method(), false);
         PhaseSuite<HighTierContext> graphBuilderSuite = getCustomGraphBuilderSuite(GraphBuilderConfiguration.getEagerInfopointDefault());
         final CompilationResult cr = compileGraph(graph, cc, graph.method(), getProviders(), getBackend(), getCodeCache().getTarget(), null, graphBuilderSuite, OptimisticOptimizations.ALL,
-                        getProfilingInfo(graph), new SpeculationLog(), getSuites(), true, new CompilationResult(), CompilationResultBuilderFactory.Default);
+                        getProfilingInfo(graph), getSpeculationLog(), getSuites(), true, new CompilationResult(), CompilationResultBuilderFactory.Default);
         int lineSPs = 0;
         for (Infopoint sp : cr.getInfopoints()) {
             assertNotNull(sp.reason);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ProfilingInfoTest.java	Mon Jan 27 20:24:12 2014 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ProfilingInfoTest.java	Tue Jan 28 18:32:30 2014 +0100
@@ -323,7 +323,10 @@
             }
         }
 
-        return javaMethod.getProfilingInfo();
+        ProfilingInfo info = javaMethod.getProfilingInfo();
+        // The execution counts are low so force maturity
+        info.setMature();
+        return info;
     }
 
     private void resetProfile(String methodName) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ShortCircuitNodeTest.java	Tue Jan 28 18:32:30 2014 +0100
@@ -0,0 +1,65 @@
+/*
+ * 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.compiler.test;
+
+import org.junit.*;
+
+import com.oracle.graal.compiler.test.ea.EATestBase.TestClassInt;
+
+public class ShortCircuitNodeTest extends GraalCompilerTest {
+
+    @Test
+    public void test1() {
+        // only executeActual, to avoid creating profiling information
+        executeActual(getMethod("test1Snippet"), 1, 2);
+    }
+
+    public static final TestClassInt field = null;
+    public static TestClassInt field2 = null;
+
+    @SuppressWarnings("unused")
+    public static void test1Snippet(int a, int b) {
+        /*
+         * if a ShortCircuitOrNode is created for the check inside test2, then faulty handling of
+         * guards can create a cycle in the graph.
+         */
+        int v;
+        if (a == 1) {
+            if (b != 1) {
+                int i = field.x;
+            }
+            field2 = null;
+            v = 0;
+        } else {
+            v = 1;
+        }
+
+        if (test2(v, b)) {
+            int i = field.x;
+        }
+    }
+
+    public static boolean test2(int a, int b) {
+        return a != 0 || b != 1;
+    }
+}
--- a/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotBackend.java	Mon Jan 27 20:24:12 2014 +0100
+++ b/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotBackend.java	Tue Jan 28 18:32:30 2014 +0100
@@ -155,7 +155,8 @@
             }
 
             private boolean canOffloadToGPU(ResolvedJavaMethod method) {
-                return method.getName().contains("lambda$") & method.isSynthetic();
+                HotSpotVMConfig config = getRuntime().getConfig();
+                return config.gpuOffload && method.getName().contains("lambda$") & method.isSynthetic();
             }
         };
     }
@@ -175,8 +176,8 @@
         PhaseSuite<HighTierContext> graphBuilderSuite = providers.getSuites().getDefaultGraphBuilderSuite();
         graphBuilderSuite.appendPhase(new NonNullParametersPhase());
         Suites suites = providers.getSuites().getDefaultSuites();
-        ExternalCompilationResult ptxCode = compileGraph(graph, cc, method, providers, this, this.getTarget(), null, graphBuilderSuite, OptimisticOptimizations.NONE, getProfilingInfo(graph),
-                        new SpeculationLog(), suites, true, new ExternalCompilationResult(), CompilationResultBuilderFactory.Default);
+        ExternalCompilationResult ptxCode = compileGraph(graph, cc, method, providers, this, this.getTarget(), null, graphBuilderSuite, OptimisticOptimizations.NONE, getProfilingInfo(graph), null,
+                        suites, true, new ExternalCompilationResult(), CompilationResultBuilderFactory.Default);
         if (makeBinary) {
             try (Scope ds = Debug.scope("GeneratingKernelBinary")) {
                 assert ptxCode.getTargetCode() != null;
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/AheadOfTimeCompilationTest.java	Mon Jan 27 20:24:12 2014 +0100
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/AheadOfTimeCompilationTest.java	Tue Jan 28 18:32:30 2014 +0100
@@ -205,7 +205,7 @@
             // create suites everytime, as we modify options for the compiler
             final Suites suitesLocal = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend().getSuites().createSuites();
             final CompilationResult compResult = compileGraph(graph, cc, method, getProviders(), getBackend(), getCodeCache().getTarget(), null, getDefaultGraphBuilderSuite(),
-                            OptimisticOptimizations.ALL, getProfilingInfo(graph), new SpeculationLog(), suitesLocal, true, new CompilationResult(), CompilationResultBuilderFactory.Default);
+                            OptimisticOptimizations.ALL, getProfilingInfo(graph), getSpeculationLog(), suitesLocal, true, new CompilationResult(), CompilationResultBuilderFactory.Default);
             addMethod(method, compResult);
         }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Mon Jan 27 20:24:12 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Tue Jan 28 18:32:30 2014 +0100
@@ -39,12 +39,19 @@
 
     private static final long serialVersionUID = -4744897993263044184L;
 
-    private static boolean containsString(String[] array, String item) {
-        if (array == null) {
-            return false;
+    /**
+     * Determines if the current architecture is included in a given architecture set specification.
+     * 
+     * @param currentArch
+     * @param archsSpecification specifies a set of architectures. A zero length value implies all
+     *            architectures.
+     */
+    private static boolean isRequired(String currentArch, String[] archsSpecification) {
+        if (archsSpecification.length == 0) {
+            return true;
         }
-        for (String arch : array) {
-            if (arch.equals(item)) {
+        for (String arch : archsSpecification) {
+            if (arch.equals(currentArch)) {
                 return true;
             }
         }
@@ -90,7 +97,7 @@
                 String type = annotation.type();
                 VMFields.Field entry = vmFields.get(name);
                 if (entry == null) {
-                    if (annotation.optional() || !containsString(annotation.archs(), currentArch)) {
+                    if (annotation.optional() || !isRequired(currentArch, annotation.archs())) {
                         continue;
                     }
                     throw new IllegalArgumentException("field not found: " + name);
@@ -135,11 +142,10 @@
                 String name = annotation.name();
                 AbstractConstant entry = vmConstants.get(name);
                 if (entry == null) {
-                    if (!containsString(annotation.archs(), currentArch)) {
+                    if (!isRequired(currentArch, annotation.archs())) {
                         continue;
-                    } else {
-                        throw new IllegalArgumentException("constant not found: " + name);
                     }
+                    throw new IllegalArgumentException("constant not found: " + name);
                 }
                 setField(f, entry.getValue());
             } else if (f.isAnnotationPresent(HotSpotVMFlag.class)) {
@@ -147,11 +153,11 @@
                 String name = annotation.name();
                 Flags.Flag entry = flags.get(name);
                 if (entry == null) {
-                    if (annotation.optional() || !containsString(annotation.archs(), currentArch)) {
+                    if (!isRequired(currentArch, annotation.archs())) {
                         continue;
-                    } else {
-                        throw new IllegalArgumentException("flag not found: " + name);
                     }
+                    throw new IllegalArgumentException("flag not found: " + name);
+
                 }
                 setField(f, entry.getValue());
             }
@@ -712,6 +718,7 @@
     @HotSpotVMFlag(name = "PrintInlining") @Stable public boolean printInlining;
     @HotSpotVMFlag(name = "GraalUseFastLocking") @Stable public boolean useFastLocking;
     @HotSpotVMFlag(name = "ForceUnreachable") @Stable public boolean forceUnreachable;
+    @HotSpotVMFlag(name = "GPUOffload") @Stable public boolean gpuOffload;
 
     @HotSpotVMFlag(name = "UseTLAB") @Stable public boolean useTLAB;
     @HotSpotVMFlag(name = "UseBiasedLocking") @Stable public boolean useBiasedLocking;
@@ -832,8 +839,6 @@
     @HotSpotVMField(name = "JavaThread::_vm_result", type = "oop", get = HotSpotVMField.Type.OFFSET) @Stable public int threadObjectResultOffset;
     @HotSpotVMField(name = "JavaThread::_graal_counters[0]", type = "jlong", get = HotSpotVMField.Type.OFFSET, optional = true) @Stable public int graalCountersThreadOffset;
 
-    @HotSpotVMConstant(name = "GRAAL_COUNTERS_SIZE") @Stable public int graalCountersSize;
-
     /**
      * This field is used to pass exception objects into and out of the runtime system during
      * exception handling for compiled code.
@@ -1267,6 +1272,8 @@
     @Stable public long arithmeticTanAddress;
     @Stable public long loadAndClearExceptionAddress;
 
+    @Stable public int graalCountersSize;
+
     @HotSpotVMConstant(name = "Deoptimization::Reason_none") @Stable public int deoptReasonNone;
     @HotSpotVMConstant(name = "Deoptimization::Reason_null_check") @Stable public int deoptReasonNullCheck;
     @HotSpotVMConstant(name = "Deoptimization::Reason_range_check") @Stable public int deoptReasonRangeCheck;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConstant.java	Mon Jan 27 20:24:12 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConstant.java	Tue Jan 28 18:32:30 2014 +0100
@@ -32,7 +32,8 @@
 
     /**
      * List of architectures where this constant is required. Names are derived from
-     * {@link HotSpotVMConfig#getHostArchitectureName()}.
+     * {@link HotSpotVMConfig#getHostArchitectureName()}. An empty list implies that the constant is
+     * required on all architectures.
      */
     String[] archs() default {};
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMField.java	Mon Jan 27 20:24:12 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMField.java	Tue Jan 28 18:32:30 2014 +0100
@@ -40,7 +40,8 @@
 
     /**
      * List of architectures where this constant is required. Names are derived from
-     * {@link HotSpotVMConfig#getHostArchitectureName()}.
+     * {@link HotSpotVMConfig#getHostArchitectureName()}. An empty list implies that the constant is
+     * required on all architectures.
      */
     String[] archs() default {};
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMFlag.java	Mon Jan 27 20:24:12 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMFlag.java	Tue Jan 28 18:32:30 2014 +0100
@@ -32,7 +32,8 @@
 
     /**
      * List of architectures where this constant is required. Names are derived from
-     * {@link HotSpotVMConfig#getHostArchitectureName()}.
+     * {@link HotSpotVMConfig#getHostArchitectureName()}. An empty list implies that the constant is
+     * required on all architectures.
      */
     String[] archs() default {};
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java	Mon Jan 27 20:24:12 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java	Tue Jan 28 18:32:30 2014 +0100
@@ -258,6 +258,8 @@
      */
     long[] collectCounters();
 
+    boolean isMature(long metaspaceMethodData);
+
     /**
      * Generate a unique id to identify the result of the compile.
      */
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java	Mon Jan 27 20:24:12 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java	Tue Jan 28 18:32:30 2014 +0100
@@ -169,5 +169,7 @@
 
     public native long[] collectCounters();
 
+    public native boolean isMature(long method);
+
     public native int allocateCompileId(HotSpotResolvedJavaMethod method, int entryBCI);
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodData.java	Mon Jan 27 20:24:12 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodData.java	Tue Jan 28 18:32:30 2014 +0100
@@ -207,6 +207,14 @@
         return cells * config.dataLayoutCellSize;
     }
 
+    /**
+     * Returns whether profiling ran long enough that the profile information is mature. Other
+     * informational data will still be valid even if the profile isn't mature.
+     */
+    public boolean isProfileMature() {
+        return runtime().getCompilerToVM().isMature(metaspaceMethodData);
+    }
+
     @Override
     public String toString() {
         StringBuilder sb = new StringBuilder();
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotProfilingInfo.java	Mon Jan 27 20:24:12 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotProfilingInfo.java	Tue Jan 28 18:32:30 2014 +0100
@@ -34,6 +34,7 @@
     private final HotSpotMethodData methodData;
     private final HotSpotResolvedJavaMethod method;
 
+    private boolean isMature;
     private int position;
     private int hintPosition;
     private int hintBCI;
@@ -47,6 +48,7 @@
         this.method = method;
         this.includeNormal = includeNormal;
         this.includeOSR = includeOSR;
+        this.isMature = methodData.isProfileMature();
         hintPosition = 0;
         hintBCI = -1;
     }
@@ -58,24 +60,36 @@
 
     @Override
     public JavaTypeProfile getTypeProfile(int bci) {
+        if (!isMature) {
+            return null;
+        }
         findBCI(bci, false);
         return dataAccessor.getTypeProfile(methodData, position);
     }
 
     @Override
     public JavaMethodProfile getMethodProfile(int bci) {
+        if (!isMature) {
+            return null;
+        }
         findBCI(bci, false);
         return dataAccessor.getMethodProfile(methodData, position);
     }
 
     @Override
     public double getBranchTakenProbability(int bci) {
+        if (!isMature) {
+            return -1;
+        }
         findBCI(bci, false);
         return dataAccessor.getBranchTakenProbability(methodData, position);
     }
 
     @Override
     public double[] getSwitchProbabilities(int bci) {
+        if (!isMature) {
+            return null;
+        }
         findBCI(bci, false);
         return dataAccessor.getSwitchProbabilities(methodData, position);
     }
@@ -94,6 +108,9 @@
 
     @Override
     public int getExecutionCount(int bci) {
+        if (!isMature) {
+            return -1;
+        }
         findBCI(bci, false);
         return dataAccessor.getExecutionCount(methodData, position);
     }
@@ -172,11 +189,20 @@
 
     @Override
     public boolean isMature() {
-        return true;
+        return isMature;
+    }
+
+    public void ignoreMature() {
+        isMature = true;
     }
 
     @Override
     public String toString() {
         return "HotSpotProfilingInfo<" + MetaUtil.profileToString(this, null, "; ") + ">";
     }
+
+    @Override
+    public void setMature() {
+        isMature = true;
+    }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java	Mon Jan 27 20:24:12 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java	Tue Jan 28 18:32:30 2014 +0100
@@ -157,10 +157,14 @@
         return getMetaspaceMethodConstant();
     }
 
+    public int getRawModifiers() {
+        HotSpotVMConfig config = runtime().getConfig();
+        return unsafe.getInt(metaspaceMethod + config.methodAccessFlagsOffset);
+    }
+
     @Override
     public int getModifiers() {
-        HotSpotVMConfig config = runtime().getConfig();
-        return unsafe.getInt(metaspaceMethod + config.methodAccessFlagsOffset) & Modifier.methodModifiers();
+        return getRawModifiers() & Modifier.methodModifiers();
     }
 
     @Override
@@ -424,27 +428,21 @@
         return javaMethod == null ? null : javaMethod.getAnnotation(annotationClass);
     }
 
+    private static final int SYNTHETIC;
+    static {
+        try {
+            Field field = Modifier.class.getDeclaredField("SYNTHETIC");
+            field.setAccessible(true);
+            SYNTHETIC = field.getInt(null);
+        } catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException | SecurityException e) {
+            throw GraalInternalError.shouldNotReachHere(e.toString());
+        }
+    }
+
     @Override
     public boolean isSynthetic() {
-        if (isConstructor()) {
-            Constructor<?> javaConstructor = toJavaConstructor();
-            return javaConstructor == null ? false : javaConstructor.isSynthetic();
-        }
-
-        // Cannot use toJava() as it ignores the return type
-        HotSpotSignature sig = getSignature();
-        JavaType[] sigTypes = MetaUtil.signatureToTypes(sig, null);
-        MetaAccessProvider metaAccess = runtime().getHostProviders().getMetaAccess();
-        for (Method method : holder.mirror().getDeclaredMethods()) {
-            if (method.getName().equals(name)) {
-                if (metaAccess.lookupJavaType(method.getReturnType()).equals(sig.getReturnType(holder))) {
-                    if (matches(metaAccess, sigTypes, method.getParameterTypes())) {
-                        return method.isSynthetic();
-                    }
-                }
-            }
-        }
-        return false;
+        int modifiers = getRawModifiers();
+        return (SYNTHETIC & modifiers) != 0;
     }
 
     public boolean isDefault() {
@@ -476,18 +474,6 @@
         return result;
     }
 
-    private static boolean matches(MetaAccessProvider metaAccess, JavaType[] sigTypes, Class<?>[] parameterTypes) {
-        if (parameterTypes.length == sigTypes.length) {
-            for (int i = 0; i < parameterTypes.length; i++) {
-                if (!metaAccess.lookupJavaType(parameterTypes[i]).equals(sigTypes[i])) {
-                    return false;
-                }
-            }
-            return true;
-        }
-        return false;
-    }
-
     private Method toJava() {
         try {
             return holder.mirror().getDeclaredMethod(name, signatureToTypes());
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java	Mon Jan 27 20:24:12 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java	Tue Jan 28 18:32:30 2014 +0100
@@ -146,8 +146,8 @@
                 // The stub itself needs the incoming calling convention.
                 CallingConvention incomingCc = linkage.getIncomingCallingConvention();
                 final CompilationResult compResult = compileGraph(graph, incomingCc, getInstalledCodeOwner(), providers, backend, codeCache.getTarget(), null,
-                                providers.getSuites().getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL, getProfilingInfo(graph), new SpeculationLog(),
-                                providers.getSuites().getDefaultSuites(), true, new CompilationResult(), CompilationResultBuilderFactory.Default);
+                                providers.getSuites().getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL, getProfilingInfo(graph), null, providers.getSuites().getDefaultSuites(), true,
+                                new CompilationResult(), CompilationResultBuilderFactory.Default);
 
                 assert destroyedRegisters != null;
                 try (Scope s = Debug.scope("CodeInstall")) {
--- a/graal/com.oracle.graal.java.decompiler.test/src/com/oracle/graal/java/decompiler/test/TestUtil.java	Mon Jan 27 20:24:12 2014 +0100
+++ b/graal/com.oracle.graal.java.decompiler.test/src/com/oracle/graal/java/decompiler/test/TestUtil.java	Tue Jan 28 18:32:30 2014 +0100
@@ -49,7 +49,7 @@
         new GraphBuilderPhase.Instance(metaAccess, GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph);
         PhaseSuite<HighTierContext> graphBuilderSuite = suitesProvider.getDefaultGraphBuilderSuite();
         CallingConvention cc = getCallingConvention(providers.getCodeCache(), Type.JavaCallee, graph.method(), false);
-        compileGraph(graph, cc, method, providers, backend, providers.getCodeCache().getTarget(), null, graphBuilderSuite, OptimisticOptimizations.ALL, getProfilingInfo(graph), new SpeculationLog(),
-                        suites, true, new CompilationResult(), CompilationResultBuilderFactory.Default);
+        compileGraph(graph, cc, method, providers, backend, providers.getCodeCache().getTarget(), null, graphBuilderSuite, OptimisticOptimizations.ALL, getProfilingInfo(graph), null, suites, true,
+                        new CompilationResult(), CompilationResultBuilderFactory.Default);
     }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadFieldNode.java	Mon Jan 27 20:24:12 2014 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadFieldNode.java	Tue Jan 28 18:32:30 2014 +0100
@@ -74,6 +74,9 @@
                 return phi;
             }
         }
+        if (!isStatic() && object().isNullConstant()) {
+            return graph().add(new DeoptimizeNode(DeoptimizationAction.None, DeoptimizationReason.NullCheckException));
+        }
         return this;
     }
 
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/GraphOrder.java	Mon Jan 27 20:24:12 2014 +0100
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/GraphOrder.java	Tue Jan 28 18:32:30 2014 +0100
@@ -55,7 +55,7 @@
                         if (input instanceof FrameState && node instanceof StateSplit && input == ((StateSplit) node).stateAfter()) {
                             // nothing to do - after frame states are known, allowed cycles
                         } else {
-                            assert false : "cycle detected: " + node + " -> " + input;
+                            assert false : "unexpected cycle detected at input " + node + " -> " + input;
                         }
                     }
                 }
@@ -81,7 +81,7 @@
 
     private static void visitForward(ArrayList<Node> nodes, NodeBitMap visited, Node node, boolean floatingOnly) {
         if (node != null && !visited.isMarked(node)) {
-            assert !floatingOnly || !(node instanceof FixedNode) : "unexpected reference to fixed node: " + node;
+            assert !floatingOnly || !(node instanceof FixedNode) : "unexpected reference to fixed node: " + node + " (this indicates an unexpected cycle)";
             visited.mark(node);
             FrameState stateAfter = null;
             if (node instanceof StateSplit) {
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java	Mon Jan 27 20:24:12 2014 +0100
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java	Tue Jan 28 18:32:30 2014 +0100
@@ -24,8 +24,6 @@
 
 import static java.lang.reflect.Modifier.*;
 
-import java.lang.reflect.*;
-
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.Debug.Scope;
@@ -47,6 +45,7 @@
     private final int bci;
     private final ResolvedJavaMethod targetMethod;
     private final JavaType returnType;
+    private final InvokeKind invokeKind;
 
     protected MacroNode(Invoke invoke) {
         super(invoke.asNode().stamp(), invoke.stateAfter());
@@ -55,6 +54,7 @@
         this.bci = invoke.bci();
         this.targetMethod = methodCallTarget.targetMethod();
         this.returnType = methodCallTarget.returnType();
+        this.invokeKind = methodCallTarget.invokeKind();
     }
 
     public int getBci() {
@@ -148,17 +148,21 @@
         }
     }
 
-    private InvokeNode replaceWithInvoke() {
+    protected InvokeNode replaceWithInvoke() {
         InvokeNode invoke = createInvoke();
         graph().replaceFixedWithFixed(this, invoke);
         return invoke;
     }
 
     protected InvokeNode createInvoke() {
-        InvokeKind invokeKind = Modifier.isStatic(targetMethod.getModifiers()) ? InvokeKind.Static : InvokeKind.Special;
         MethodCallTargetNode callTarget = graph().add(new MethodCallTargetNode(invokeKind, targetMethod, arguments.toArray(new ValueNode[arguments.size()]), returnType));
         InvokeNode invoke = graph().add(new InvokeNode(callTarget, bci));
-        invoke.setStateAfter(stateAfter());
+        if (stateAfter() != null) {
+            invoke.setStateAfter(stateAfter().duplicate());
+            if (kind() != Kind.Void) {
+                invoke.stateAfter().replaceFirstInput(this, invoke);
+            }
+        }
         return invoke;
     }
 
--- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java	Mon Jan 27 20:24:12 2014 +0100
+++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java	Tue Jan 28 18:32:30 2014 +0100
@@ -70,7 +70,7 @@
     protected InstalledCode assertPartialEvalEquals(String methodName, RootNode root, Arguments arguments) {
         Assumptions assumptions = new Assumptions(true);
         StructuredGraph actual = partialEval(root, arguments, assumptions, true);
-        InstalledCode result = new TruffleCompilerImpl().compileMethodHelper(actual, GraphBuilderConfiguration.getDefault(), assumptions, root.toString());
+        InstalledCode result = new TruffleCompilerImpl().compileMethodHelper(actual, GraphBuilderConfiguration.getDefault(), assumptions, root.toString(), getSpeculationLog());
         StructuredGraph expected = parseForComparison(methodName);
         removeFrameStates(actual);
         Assert.assertEquals(getCanonicalGraphString(expected, true), getCanonicalGraphString(actual, true));
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java	Mon Jan 27 20:24:12 2014 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java	Tue Jan 28 18:32:30 2014 +0100
@@ -197,8 +197,8 @@
         CallingConvention cc = getCallingConvention(providers.getCodeCache(), Type.JavaCallee, graph.method(), false);
         Backend backend = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend();
         CompilationResultBuilderFactory factory = getOptimizedCallTargetInstrumentationFactory(backend.getTarget().arch.getName(), javaMethod);
-        return compileGraph(graph, cc, javaMethod, providers, backend, providers.getCodeCache().getTarget(), null, graphBuilderSuite, OptimisticOptimizations.ALL, getProfilingInfo(graph),
-                        new SpeculationLog(), suites, true, new CompilationResult(), factory);
+        return compileGraph(graph, cc, javaMethod, providers, backend, providers.getCodeCache().getTarget(), null, graphBuilderSuite, OptimisticOptimizations.ALL, getProfilingInfo(graph), null,
+                        suites, true, new CompilationResult(), factory);
     }
 
     private static Providers getGraalProviders() {
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java	Mon Jan 27 20:24:12 2014 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java	Tue Jan 28 18:32:30 2014 +0100
@@ -50,6 +50,7 @@
     private final TruffleInlining inlining;
     private boolean compilationEnabled;
     private int callCount;
+    private SpeculationLog speculationLog = new SpeculationLog();
 
     protected OptimizedCallTarget(RootNode rootNode, TruffleCompiler compiler, int invokeCounter, int compilationThreshold) {
         super(rootNode);
@@ -294,4 +295,8 @@
             });
         }
     }
+
+    public SpeculationLog getSpeculationLog() {
+        return speculationLog;
+    }
 }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java	Mon Jan 27 20:24:12 2014 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java	Tue Jan 28 18:32:30 2014 +0100
@@ -156,7 +156,7 @@
         }
         long timePartialEvaluationFinished = System.nanoTime();
         int nodeCountPartialEval = graph.getNodeCount();
-        InstalledCode compiledMethod = compileMethodHelper(graph, config, assumptions, compilable.toString());
+        InstalledCode compiledMethod = compileMethodHelper(graph, config, assumptions, compilable.toString(), compilable.getSpeculationLog());
         long timeCompilationFinished = System.nanoTime();
         int nodeCountLowered = graph.getNodeCount();
 
@@ -208,7 +208,7 @@
         }
     }
 
-    public InstalledCode compileMethodHelper(StructuredGraph graph, GraphBuilderConfiguration config, Assumptions assumptions, String name) {
+    public InstalledCode compileMethodHelper(StructuredGraph graph, GraphBuilderConfiguration config, Assumptions assumptions, String name, SpeculationLog speculationLog) {
         try (Scope s = Debug.scope("TruffleFinal")) {
             Debug.dump(graph, "After TruffleTier");
         } catch (Throwable e) {
@@ -221,7 +221,7 @@
             CallingConvention cc = getCallingConvention(codeCache, Type.JavaCallee, graph.method(), false);
             CompilationResult compilationResult = new CompilationResult(name);
             result = compileGraph(graph, cc, graph.method(), providers, backend, codeCache.getTarget(), null, createGraphBuilderSuite(config), OptimisticOptimizations.ALL, getProfilingInfo(graph),
-                            new SpeculationLog(), suites, false, compilationResult, CompilationResultBuilderFactory.Default);
+                            speculationLog, suites, false, compilationResult, CompilationResultBuilderFactory.Default);
         } catch (Throwable e) {
             throw Debug.handle(e);
         }
@@ -244,7 +244,7 @@
 
         InstalledCode installedCode = null;
         try (Scope s = Debug.scope("CodeInstall", providers.getCodeCache()); TimerCloseable a = CodeInstallationTime.start()) {
-            installedCode = providers.getCodeCache().addMethod(graph.method(), result, null);
+            installedCode = providers.getCodeCache().addMethod(graph.method(), result, speculationLog);
         } catch (Throwable e) {
             throw Debug.handle(e);
         }
--- a/mxtool/mx.py	Mon Jan 27 20:24:12 2014 +0100
+++ b/mxtool/mx.py	Tue Jan 28 18:32:30 2014 +0100
@@ -1565,6 +1565,9 @@
 
         return cmp(self.value, other.value)
 
+    def __hash__(self):
+        return self.value.__hash__()
+
 """
 A version specification as defined in JSR-56
 """
@@ -2742,10 +2745,7 @@
     slm.open('sourceLookupDirector')
     slm.open('sourceContainers', {'duplicates' : 'false'})
 
-    # Every Java program depends on the JRE
-    memento = XMLDoc().element('classpathContainer', {'path' : 'org.eclipse.jdt.launching.JRE_CONTAINER'}).xml(standalone='no')
-    slm.element('classpathContainer', {'memento' : memento, 'typeId':'org.eclipse.jdt.launching.sourceContainer.classpathContainer'})
-
+    javaCompliance = None
     for dep in deps:
         if dep.isLibrary():
             if hasattr(dep, 'eclipse.container'):
@@ -2757,6 +2757,15 @@
         else:
             memento = XMLDoc().element('javaProject', {'name' : dep.name}).xml(standalone='no')
             slm.element('container', {'memento' : memento, 'typeId':'org.eclipse.jdt.launching.sourceContainer.javaProject'})
+            if javaCompliance is None or dep.javaCompliance < javaCompliance:
+                javaCompliance = dep.javaCompliance
+
+    if javaCompliance:
+        memento = XMLDoc().element('classpathContainer', {'path' : 'org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-' + str(javaCompliance)}).xml(standalone='no')
+        slm.element('classpathContainer', {'memento' : memento, 'typeId':'org.eclipse.jdt.launching.sourceContainer.classpathContainer'})
+    else:
+        memento = XMLDoc().element('classpathContainer', {'path' : 'org.eclipse.jdt.launching.JRE_CONTAINER'}).xml(standalone='no')
+        slm.element('classpathContainer', {'memento' : memento, 'typeId':'org.eclipse.jdt.launching.sourceContainer.classpathContainer'})
 
     slm.close('sourceContainers')
     slm.close('sourceLookupDirector')
@@ -2933,7 +2942,7 @@
             out.element('classpathentry', {'kind' : 'src', 'path' : 'src_gen'})
             files.append(genDir)
 
-        # Every Java program depends on the JRE
+        # Every Java program depends on a JRE
         out.element('classpathentry', {'kind' : 'con', 'path' : 'org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-' + str(p.javaCompliance)})
 
         if exists(join(p.dir, 'plugin.xml')):  # eclipse plugin project
--- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/BinaryParser.java	Mon Jan 27 20:24:12 2014 +0100
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/BinaryParser.java	Tue Jan 28 18:32:30 2014 +0100
@@ -35,6 +35,8 @@
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import javax.swing.SwingUtilities;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
 
 public class BinaryParser implements GraphParser {
     private static final int BEGIN_GROUP = 0x00;
@@ -72,7 +74,10 @@
     private final ReadableByteChannel channel;
     private final GraphDocument rootDocument;
     private final Deque<Folder> folderStack;
+    private final Deque<byte[]> hashStack;
     private final ParseMonitor monitor;
+
+    private MessageDigest digest;
     
     private enum Length {
         S,
@@ -259,7 +264,12 @@
         this.channel = channel;
         this.rootDocument = rootDocument;
         folderStack = new LinkedList<>();
+        hashStack = new LinkedList<>();
         this.monitor = monitor;
+        try {
+            this.digest = MessageDigest.getInstance("SHA-256");
+        } catch (NoSuchAlgorithmException e) {
+        }
     }
     
     private void fill() throws IOException {
@@ -274,6 +284,11 @@
         while (buffer.remaining() < i) {
             fill();
         }
+        buffer.mark();
+        byte[] result = new byte[i];
+        buffer.get(result);
+        digest.update(result);
+        buffer.reset();
     }
     
     private int readByte() throws IOException {
@@ -547,6 +562,7 @@
     @Override
     public GraphDocument parse() throws IOException {
         folderStack.push(rootDocument);
+        hashStack.push(null);
         if (monitor != null) {
             monitor.setState("Starting parsing");
         }
@@ -589,6 +605,7 @@
                     });
                 }
                 folderStack.push(group);
+                hashStack.push(null);
                 if (callback != null && parent instanceof GraphDocument) {
                     callback.started(group);
                 }
@@ -599,6 +616,7 @@
                     throw new IOException("Unbalanced groups");
                 }
                 folderStack.pop();
+                hashStack.pop();
                 break;
             }
             default:
@@ -629,7 +647,17 @@
             monitor.updateProgress();
         }
         String title = readPoolObject(String.class);
-        return parseGraph(title);
+        digest.reset();
+        InputGraph graph = parseGraph(title);
+        byte[] d = digest.digest();
+        byte[] hash = hashStack.peek();
+        if (hash != null && Arrays.equals(hash, d)) {
+            graph.getProperties().setProperty("_isDuplicate", "true");
+        } else {
+            hashStack.pop();
+            hashStack.push(d);
+        }
+        return graph;
     }
 
     private InputGraph parseGraph(String title) throws IOException {
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/DiagramViewModel.java	Mon Jan 27 20:24:12 2014 +0100
+++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/DiagramViewModel.java	Tue Jan 28 18:32:30 2014 +0100
@@ -43,6 +43,7 @@
 
     // Warning: Update setData method if fields are added
     private Group group;
+    private ArrayList<InputGraph> graphs;
     private Set<Integer> hiddenNodes;
     private Set<Integer> onScreenNodes;
     private Set<Integer> selectedNodes;
@@ -56,6 +57,7 @@
     private ChangedEvent<DiagramViewModel> hiddenNodesChangedEvent;
     private ChangedEvent<DiagramViewModel> viewPropertiesChangedEvent;
     private boolean showNodeHull;
+    private boolean hideDuplicates;
     private ChangedListener<FilterChain> filterChainChangedListener = new ChangedListener<FilterChain>() {
 
         @Override
@@ -83,6 +85,10 @@
 
         boolean groupChanged = (group == newModel.group);
         this.group = newModel.group;
+        if (groupChanged) {
+            filterGraphs();
+        }
+
         diagramChanged |= (filterChain != newModel.filterChain);
         this.filterChain = newModel.filterChain;
         diagramChanged |= (sequenceFilterChain != newModel.sequenceFilterChain);
@@ -122,11 +128,33 @@
         viewPropertiesChangedEvent.fire();
     }
 
+    public boolean getHideDuplicates() {
+        return hideDuplicates;
+    }
+
+    public void setHideDuplicates(boolean b) {
+        System.err.println("setHideDuplicates: " + b);
+        hideDuplicates = b;
+        InputGraph currentGraph = getFirstGraph();
+        if (hideDuplicates) {
+            // Back up to the unhidden equivalent graph
+            int index = graphs.indexOf(currentGraph);
+            while (graphs.get(index).getProperties().get("_isDuplicate") != null) {
+                index--;
+            }
+            currentGraph = graphs.get(index);
+        }
+        filterGraphs();
+        selectGraph(currentGraph);
+        viewPropertiesChangedEvent.fire();
+    }
+
     public DiagramViewModel(Group g, FilterChain filterChain, FilterChain sequenceFilterChain) {
-        super(calculateStringList(g));
+        super(Arrays.asList("default"));
 
         this.showNodeHull = true;
         this.group = g;
+        filterGraphs();
         assert filterChain != null;
         this.filterChain = filterChain;
         assert sequenceFilterChain != null;
@@ -165,7 +193,7 @@
         @Override
         public void changed(Group source) {
             assert source == group;
-            setPositions(calculateStringList(source));
+            filterGraphs();
             setSelectedNodes(selectedNodes);
         }
     };
@@ -211,7 +239,7 @@
                 }
                 InputNode last = null;
                 int index = 0;
-                for (InputGraph g : group.getGraphs()) {
+                for (InputGraph g : graphs) {
                     Color curColor = colors.get(index);
                     InputNode cur = g.getNode(id);
                     if (cur != null) {
@@ -316,16 +344,24 @@
         diagramChanged();
     }
 
-    private static List<String> calculateStringList(Group g) {
-        List<String> result = new ArrayList<>();
-        for (InputGraph graph : g.getGraphs()) {
-            result.add(graph.getName());
+    /*
+     * Select the set of graphs to be presented.
+     */
+    private void filterGraphs() {
+        ArrayList<InputGraph> result = new ArrayList<>();
+        List<String> positions = new ArrayList<>();
+        for (InputGraph graph : group.getGraphs()) {
+            String duplicate = graph.getProperties().get("_isDuplicate");
+            if (duplicate == null || !hideDuplicates) {
+                result.add(graph);
+                positions.add(graph.getName());
+            }
         }
-        return result;
+        this.graphs = result;
+        setPositions(positions);
     }
 
     public InputGraph getFirstGraph() {
-        List<InputGraph> graphs = group.getGraphs();
         if (getFirstPosition() < graphs.size()) {
             return graphs.get(getFirstPosition());
         }
@@ -333,7 +369,6 @@
     }
 
     public InputGraph getSecondGraph() {
-        List<InputGraph> graphs = group.getGraphs();
         if (getSecondPosition() < graphs.size()) {
             return graphs.get(getSecondPosition());
         }
@@ -341,7 +376,12 @@
     }
 
     public void selectGraph(InputGraph g) {
-        int index = group.getGraphs().indexOf(g);
+        int index = graphs.indexOf(g);
+        if (index == -1 && hideDuplicates) {
+            // A graph was selected that's currently hidden, so unhide and select it.
+            setHideDuplicates(false);
+            index = graphs.indexOf(g);
+        }
         assert index != -1;
         setPositions(index, index);
     }
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/EditorTopComponent.java	Mon Jan 27 20:24:12 2014 +0100
+++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/EditorTopComponent.java	Tue Jan 28 18:32:30 2014 +0100
@@ -78,6 +78,7 @@
     private InstanceContent content;
     private InstanceContent graphContent;
     private OverviewAction overviewAction;
+    private HideDuplicatesAction hideDuplicatesAction;
     private PredSuccAction predSuccAction;
     private SelectionModeAction selectionModeAction;
     private PanModeAction panModeAction;
@@ -87,6 +88,7 @@
     private CardLayout cardLayout;
     private RangeSlider rangeSlider;
     private JToggleButton overviewButton;
+    private JToggleButton hideDuplicatesButton;
     private static final String PREFERRED_ID = "EditorTopComponent";
     private static final String SATELLITE_STRING = "satellite";
     private static final String SCENE_STRING = "scene";
@@ -207,6 +209,14 @@
 
         rangeSliderModel.getDiagramChangedEvent().addListener(diagramChangedListener);
         rangeSliderModel.selectGraph(diagram.getGraph());
+        rangeSliderModel.getViewPropertiesChangedEvent().addListener(new ChangedListener<DiagramViewModel>() {
+                @Override
+                public void changed(DiagramViewModel source) {
+                    hideDuplicatesButton.setSelected(getModel().getHideDuplicates());
+                    hideDuplicatesAction.setState(getModel().getHideDuplicates());
+                }
+            });
+
 
         toolBar.add(NextDiagramAction.get(NextDiagramAction.class));
         toolBar.add(PrevDiagramAction.get(PrevDiagramAction.class));
@@ -230,6 +240,12 @@
         toolBar.add(button);
         predSuccAction.addPropertyChangeListener(this);
 
+        hideDuplicatesAction = new HideDuplicatesAction();
+        hideDuplicatesButton = new JToggleButton(hideDuplicatesAction);
+        hideDuplicatesButton.setSelected(false);
+        toolBar.add(hideDuplicatesButton);
+        hideDuplicatesAction.addPropertyChangeListener(this);
+
         toolBar.addSeparator();
         toolBar.add(UndoAction.get(UndoAction.class));
         toolBar.add(RedoAction.get(RedoAction.class));
@@ -477,6 +493,9 @@
             } else {
                 showScene();
             }
+        } else if (evt.getSource() == this.hideDuplicatesAction) {
+            boolean b = (Boolean) hideDuplicatesAction.getValue(HideDuplicatesAction.STATE);
+            this.getModel().setHideDuplicates(b);
         } else if (evt.getSource() == this.selectionModeAction || evt.getSource() == this.panModeAction) {
             if (panModeAction.isSelected()) {
                 scene.setInteractionMode(DiagramViewer.InteractionMode.PANNING);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/HideDuplicatesAction.java	Tue Jan 28 18:32:30 2014 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+package com.sun.hotspot.igv.view.actions;
+
+import java.awt.event.ActionEvent;
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+import javax.swing.ImageIcon;
+import org.openide.util.ImageUtilities;
+
+/**
+ *
+ * @author Tom Rodriguez
+ */
+public class HideDuplicatesAction extends AbstractAction {
+
+    private boolean state;
+    public static final String STATE = "state";
+
+    public HideDuplicatesAction() {
+        putValue(AbstractAction.SMALL_ICON, new ImageIcon(ImageUtilities.loadImage(iconResource())));
+        putValue(Action.SHORT_DESCRIPTION, "Hide graphs which are the same as the previous graph");
+        setState(false);
+    }
+
+    @Override
+    public void actionPerformed(ActionEvent ev) {
+        setState(!state);
+    }
+
+    public void setState(boolean b) {
+        this.putValue(STATE, b);
+        this.state = b;
+    }
+
+    protected String iconResource() {
+        return "com/sun/hotspot/igv/view/images/hideDuplicates.png";
+    }
+}
Binary file src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/images/hideDuplicates.png has changed
--- a/src/share/vm/graal/graalCompilerToVM.cpp	Mon Jan 27 20:24:12 2014 +0100
+++ b/src/share/vm/graal/graalCompilerToVM.cpp	Tue Jan 28 18:32:30 2014 +0100
@@ -669,6 +669,9 @@
   } else {
     Disassembler::decode(cb, &st);
   }
+  if (st.size() <= 0) {
+    return NULL;
+  }
 
   Handle result = java_lang_String::create_from_platform_dependent_str(st.as_string(), CHECK_NULL);
   return JNIHandles::make_local(result());
@@ -827,6 +830,11 @@
 C2V_END
 
 
+C2V_VMENTRY(jboolean, isMature, (JNIEnv *env, jobject, jlong metaspace_method_data))
+  MethodData* mdo = asMethodData(metaspace_method_data);
+  return mdo != NULL && mdo->is_mature();
+C2V_END
+
 #define CC (char*)  /*cast a literal from (const char*)*/
 #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &(c2v_ ## f))
 
@@ -846,6 +854,7 @@
 #define HS_INSTALLED_CODE     "Lcom/oracle/graal/hotspot/meta/HotSpotInstalledCode;"
 #define METASPACE_KLASS       "J"
 #define METASPACE_METHOD      "J"
+#define METASPACE_METHOD_DATA "J"
 #define METASPACE_CONSTANT_POOL "J"
 
 JNINativeMethod CompilerToVM_methods[] = {
@@ -889,6 +898,7 @@
   {CC"readUnsafeKlassPointer",        CC"("OBJECT")J",                                                  FN_PTR(readUnsafeKlassPointer)},
   {CC"collectCounters",               CC"()[J",                                                         FN_PTR(collectCounters)},
   {CC"allocateCompileId",             CC"("HS_RESOLVED_METHOD"I)I",                                     FN_PTR(allocateCompileId)},
+  {CC"isMature",                      CC"("METASPACE_METHOD_DATA")Z",                                   FN_PTR(isMature)},
 };
 
 int CompilerToVM_methods_count() {
--- a/src/share/vm/runtime/deoptimization.cpp	Mon Jan 27 20:24:12 2014 +0100
+++ b/src/share/vm/runtime/deoptimization.cpp	Tue Jan 28 18:32:30 2014 +0100
@@ -1359,7 +1359,7 @@
     ScopeDesc*      trap_scope  = cvf->scope();
     
     if (TraceDeoptimization) {
-      tty->print_cr("  bci=%d pc=%d, relative_pc=%d, method=%s" GRAAL_ONLY(", debug_id=%d"), trap_scope->bci(), fr.pc(), fr.pc() - nm->code_begin(), trap_scope->method()->name()->as_C_string()
+      tty->print_cr("  bci=%d pc=%d, relative_pc=%d, method=%s" GRAAL_ONLY(", debug_id=%d"), trap_scope->bci(), fr.pc(), fr.pc() - nm->code_begin(), trap_scope->method()->name_and_sig_as_C_string()
 #ifdef GRAAL
           , debug_id
 #endif