changeset 8613:cd9e8dd9f488

Merge.
author Christian Haeubl <haeubl@ssw.jku.at>
date Thu, 28 Mar 2013 12:58:50 +0100
parents 02ef91b94656 (diff) da674936800c (current diff)
children c213fc99e2a8
files graal/com.oracle.graal.api.replacements/src/com/oracle/graal/api/replacements/Alias.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ArrayWriteBarrier.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CurrentThread.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/FieldWriteBarrier.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/HotSpotCurrentRawThreadNode.java graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java graal/com.oracle.graal.replacements/src/META-INF/services/com.oracle.graal.replacements.ReplacementsProvider graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/AliasResolutionPhase.java src/share/vm/graal/graalCompilerToVM.cpp
diffstat 23 files changed, 466 insertions(+), 68 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/DefaultProfilingInfo.java	Wed Mar 27 18:12:03 2013 +0100
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/DefaultProfilingInfo.java	Thu Mar 28 12:58:50 2013 +0100
@@ -28,12 +28,12 @@
  */
 public final class DefaultProfilingInfo implements ProfilingInfo {
 
-    private static final ProfilingInfo[] NO_PROFILING_INFO = new ProfilingInfo[]{new DefaultProfilingInfo(ExceptionSeen.TRUE), new DefaultProfilingInfo(ExceptionSeen.FALSE),
-                    new DefaultProfilingInfo(ExceptionSeen.NOT_SUPPORTED)};
+    private static final ProfilingInfo[] NO_PROFILING_INFO = new ProfilingInfo[]{new DefaultProfilingInfo(TriState.TRUE), new DefaultProfilingInfo(TriState.FALSE),
+                    new DefaultProfilingInfo(TriState.UNKNOWN)};
 
-    private final ExceptionSeen exceptionSeen;
+    private final TriState exceptionSeen;
 
-    DefaultProfilingInfo(ExceptionSeen exceptionSeen) {
+    DefaultProfilingInfo(TriState exceptionSeen) {
         this.exceptionSeen = exceptionSeen;
     }
 
@@ -58,16 +58,21 @@
     }
 
     @Override
-    public ExceptionSeen getExceptionSeen(int bci) {
+    public TriState getExceptionSeen(int bci) {
         return exceptionSeen;
     }
 
     @Override
+    public TriState getNullSeen(int bci) {
+        return TriState.UNKNOWN;
+    }
+
+    @Override
     public int getExecutionCount(int bci) {
         return -1;
     }
 
-    public static ProfilingInfo get(ExceptionSeen exceptionSeen) {
+    public static ProfilingInfo get(TriState exceptionSeen) {
         return NO_PROFILING_INFO[exceptionSeen.ordinal()];
     }
 
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaUtil.java	Wed Mar 27 18:12:03 2013 +0100
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaUtil.java	Thu Mar 28 12:58:50 2013 +0100
@@ -29,7 +29,7 @@
 import java.util.*;
 
 import com.oracle.graal.api.meta.JavaTypeProfile.ProfiledType;
-import com.oracle.graal.api.meta.ProfilingInfo.ExceptionSeen;
+import com.oracle.graal.api.meta.ProfilingInfo.TriState;
 
 /**
  * Miscellaneous collection of utility methods used by {@code com.oracle.graal.api.meta} and its
@@ -567,10 +567,14 @@
                 buf.append(sep);
             }
 
-            if (info.getExceptionSeen(i) != ExceptionSeen.FALSE) {
+            if (info.getExceptionSeen(i) == TriState.TRUE) {
                 buf.append(String.format("exceptionSeen@%d: %s%s", i, info.getExceptionSeen(i).name(), sep));
             }
 
+            if (info.getNullSeen(i) == TriState.TRUE) {
+                buf.append(String.format("nullSeen@%d: %s%s", i, info.getNullSeen(i).name(), sep));
+            }
+
             JavaTypeProfile typeProfile = info.getTypeProfile(i);
             if (typeProfile != null) {
                 ProfiledType[] ptypes = typeProfile.getTypes();
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ProfilingInfo.java	Wed Mar 27 18:12:03 2013 +0100
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ProfilingInfo.java	Thu Mar 28 12:58:50 2013 +0100
@@ -33,10 +33,10 @@
     /**
      * Represents the three possibilities that an exception was seen at a specific BCI.
      */
-    public enum ExceptionSeen {
-        TRUE, FALSE, NOT_SUPPORTED;
+    public enum TriState {
+        TRUE, FALSE, UNKNOWN;
 
-        public static ExceptionSeen get(boolean value) {
+        public static TriState get(boolean value) {
             return value ? TRUE : FALSE;
         }
     }
@@ -73,11 +73,20 @@
     /**
      * Returns information if the given BCI did ever throw an exception.
      * 
-     * @return {@link ExceptionSeen#TRUE} if the instruction has thrown an exception at least once,
-     *         {@link ExceptionSeen#FALSE} if it never threw an exception, and
-     *         {@link ExceptionSeen#NOT_SUPPORTED} if this information was not recorded.
+     * @return {@link TriState#TRUE} if the instruction has thrown an exception at least once,
+     *         {@link TriState#FALSE} if it never threw an exception, and
+     *         {@link TriState#UNKNOWN} if this information was not recorded.
      */
-    ExceptionSeen getExceptionSeen(int bci);
+    TriState getExceptionSeen(int bci);
+
+    /**
+     * Returns information if null was ever seen for the given BCI.
+     * 
+     * @return {@link TriState#TRUE} if null was seen for the instruction,
+     *         {@link TriState#FALSE} if null was NOT seen, and
+     *         {@link TriState#UNKNOWN} if this information was not recorded.
+     */
+    TriState getNullSeen(int bci);
 
     /**
      * Returns an estimate how often the current BCI was executed. Avoid comparing execution counts
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaMethod.java	Wed Mar 27 18:12:03 2013 +0100
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaMethod.java	Thu Mar 28 12:58:50 2013 +0100
@@ -125,6 +125,11 @@
     ProfilingInfo getProfilingInfo();
 
     /**
+     * Invalidates the profiling information and restarts profiling upon the next invocation.
+     */
+    void reprofile();
+
+    /**
      * Returns a map that the compiler can use to store objects that should survive the current
      * compilation.
      */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ProfilingInfoTest.java	Thu Mar 28 12:58:50 2013 +0100
@@ -0,0 +1,306 @@
+/*
+ * 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.compiler.test;
+
+import static org.junit.Assert.*;
+
+import java.io.*;
+import java.lang.reflect.*;
+
+import org.junit.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.meta.ProfilingInfo.TriState;
+
+public class ProfilingInfoTest extends GraalCompilerTest {
+
+    private static final int N = 100;
+
+    @Test
+    public void testBranchTakenProbability() {
+        ProfilingInfo info = profile("branchProbabilitySnippet", 0);
+        assertEquals(0.0, info.getBranchTakenProbability(1));
+        assertEquals(N, info.getExecutionCount(1));
+        assertEquals(-1.0, info.getBranchTakenProbability(8));
+        assertEquals(0, info.getExecutionCount(8));
+
+        info = profile("branchProbabilitySnippet", 1);
+        assertEquals(1.0, info.getBranchTakenProbability(1));
+        assertEquals(N, info.getExecutionCount(1));
+        assertEquals(0.0, info.getBranchTakenProbability(8));
+        assertEquals(N, info.getExecutionCount(8));
+
+        info = profile("branchProbabilitySnippet", 2);
+        assertEquals(1.0, info.getBranchTakenProbability(1));
+        assertEquals(N, info.getExecutionCount(1));
+        assertEquals(1.0, info.getBranchTakenProbability(8));
+        assertEquals(N, info.getExecutionCount(8));
+
+        continueProfiling(3 * N, "branchProbabilitySnippet", 0);
+        assertEquals(0.25, info.getBranchTakenProbability(1));
+        assertEquals(4 * N, info.getExecutionCount(1));
+        assertEquals(1.0, info.getBranchTakenProbability(8));
+        assertEquals(N, info.getExecutionCount(8));
+
+        resetProfile("branchProbabilitySnippet");
+        assertEquals(-1.0, info.getBranchTakenProbability(1));
+        assertEquals(0, info.getExecutionCount(1));
+        assertEquals(-1.0, info.getBranchTakenProbability(8));
+        assertEquals(0, info.getExecutionCount(8));
+    }
+
+    public static int branchProbabilitySnippet(int value) {
+        if (value == 0) {
+            return -1;
+        } else if (value == 1) {
+            return -2;
+        } else {
+            return -3;
+        }
+    }
+
+    @Test
+    public void testSwitchProbabilities() {
+        ProfilingInfo info = profile("switchProbabilitySnippet", 0);
+        assertEquals(new double[]{1.0, 0.0, 0.0}, info.getSwitchProbabilities(1));
+
+        info = profile("switchProbabilitySnippet", 1);
+        assertEquals(new double[]{0.0, 1.0, 0.0}, info.getSwitchProbabilities(1));
+
+        info = profile("switchProbabilitySnippet", 2);
+        assertEquals(new double[]{0.0, 0.0, 1.0}, info.getSwitchProbabilities(1));
+
+        resetProfile("switchProbabilitySnippet");
+        assertNull(info.getSwitchProbabilities(1));
+    }
+
+    public static int switchProbabilitySnippet(int value) {
+        switch (value) {
+            case 0:
+                return -1;
+            case 1:
+                return -2;
+            default:
+                return -3;
+        }
+    }
+
+    @Test
+    public void testTypeProfileInvokeVirtual() {
+        testTypeProfile("invokeVirtualSnippet", 1);
+    }
+
+    public static int invokeVirtualSnippet(Object obj) {
+        return obj.hashCode();
+    }
+
+    @Test
+    public void testTypeProfileInvokeInterface() {
+        testTypeProfile("invokeInterfaceSnippet", 1);
+    }
+
+    public static int invokeInterfaceSnippet(CharSequence a) {
+        return a.length();
+    }
+
+    @Test
+    public void testTypeProfileCheckCast() {
+        testTypeProfile("checkCastSnippet", 1);
+    }
+
+    public static Serializable checkCastSnippet(Object obj) {
+        return (Serializable) obj;
+    }
+
+    @Test
+    public void testTypeProfileInstanceOf() {
+        testTypeProfile("instanceOfSnippet", 1);
+    }
+
+    public static boolean instanceOfSnippet(Object obj) {
+        return obj instanceof Serializable;
+    }
+
+    private void testTypeProfile(String methodName, int bci) {
+        ResolvedJavaType stringType = runtime.lookupJavaType(String.class);
+        ResolvedJavaType stringBuilderType = runtime.lookupJavaType(StringBuilder.class);
+
+        ProfilingInfo info = profile(methodName, "ABC");
+        JavaTypeProfile typeProfile = info.getTypeProfile(bci);
+        assertEquals(0.0, typeProfile.getNotRecordedProbability());
+        assertEquals(1, typeProfile.getTypes().length);
+        assertEquals(stringType, typeProfile.getTypes()[0].getType());
+        assertEquals(1.0, typeProfile.getTypes()[0].getProbability());
+
+        continueProfiling(methodName, new StringBuilder());
+        typeProfile = info.getTypeProfile(bci);
+        assertEquals(0.0, typeProfile.getNotRecordedProbability());
+        assertEquals(2, typeProfile.getTypes().length);
+        assertEquals(stringType, typeProfile.getTypes()[0].getType());
+        assertEquals(stringBuilderType, typeProfile.getTypes()[1].getType());
+        assertEquals(0.5, typeProfile.getTypes()[0].getProbability());
+        assertEquals(0.5, typeProfile.getTypes()[1].getProbability());
+
+        resetProfile(methodName);
+        typeProfile = info.getTypeProfile(bci);
+        assertNull(typeProfile);
+    }
+
+    @Test
+    public void testExceptionSeen() {
+        // NullPointerException
+        ProfilingInfo info = profile("nullPointerExceptionSnippet", 5);
+        assertEquals(TriState.FALSE, info.getExceptionSeen(1));
+
+        info = profile("nullPointerExceptionSnippet", (Object) null);
+        assertEquals(TriState.TRUE, info.getExceptionSeen(1));
+
+        resetProfile("nullPointerExceptionSnippet");
+        assertEquals(TriState.FALSE, info.getExceptionSeen(1));
+
+        // ArrayOutOfBoundsException
+        info = profile("arrayIndexOutOfBoundsExceptionSnippet", new int[1]);
+        assertEquals(TriState.FALSE, info.getExceptionSeen(2));
+
+        info = profile("arrayIndexOutOfBoundsExceptionSnippet", new int[0]);
+        assertEquals(TriState.TRUE, info.getExceptionSeen(2));
+
+        resetProfile("arrayIndexOutOfBoundsExceptionSnippet");
+        assertEquals(TriState.FALSE, info.getExceptionSeen(2));
+
+        // CheckCastException
+        info = profile("checkCastExceptionSnippet", "ABC");
+        assertEquals(TriState.FALSE, info.getExceptionSeen(1));
+
+        info = profile("checkCastExceptionSnippet", 5);
+        assertEquals(TriState.TRUE, info.getExceptionSeen(1));
+
+        resetProfile("checkCastExceptionSnippet");
+        assertEquals(TriState.FALSE, info.getExceptionSeen(1));
+
+        // Invoke with exception
+        info = profile("invokeWithExceptionSnippet", false);
+        assertEquals(TriState.FALSE, info.getExceptionSeen(1));
+
+        info = profile("invokeWithExceptionSnippet", true);
+        assertEquals(TriState.TRUE, info.getExceptionSeen(1));
+
+        resetProfile("invokeWithExceptionSnippet");
+        assertEquals(TriState.FALSE, info.getExceptionSeen(1));
+    }
+
+    public static int nullPointerExceptionSnippet(Object obj) {
+        try {
+            return obj.hashCode();
+        } catch (NullPointerException e) {
+            return 1;
+        }
+    }
+
+    public static int arrayIndexOutOfBoundsExceptionSnippet(int[] array) {
+        try {
+            return array[0];
+        } catch (ArrayIndexOutOfBoundsException e) {
+            return 1;
+        }
+    }
+
+    public static int checkCastExceptionSnippet(Object obj) {
+        try {
+            return ((String) obj).length();
+        } catch (ClassCastException e) {
+            return 1;
+        }
+    }
+
+    public static int invokeWithExceptionSnippet(boolean doThrow) {
+        try {
+            return throwException(doThrow);
+        } catch (IllegalArgumentException e) {
+            return 1;
+        }
+    }
+
+    private static int throwException(boolean doThrow) {
+        if (doThrow) {
+            throw new IllegalArgumentException();
+        } else {
+            return 1;
+        }
+    }
+
+    @Test
+    public void testNullSeen() {
+        ProfilingInfo info = profile("instanceOfSnippet", 1);
+        assertEquals(TriState.FALSE, info.getNullSeen(1));
+
+        continueProfiling("instanceOfSnippet", "ABC");
+        assertEquals(TriState.FALSE, info.getNullSeen(1));
+
+        continueProfiling("instanceOfSnippet", (Object) null);
+        assertEquals(TriState.TRUE, info.getNullSeen(1));
+
+        continueProfiling("instanceOfSnippet", 0.0);
+        assertEquals(TriState.TRUE, info.getNullSeen(1));
+
+        resetProfile("instanceOfSnippet");
+        assertEquals(TriState.FALSE, info.getNullSeen(1));
+    }
+
+    private ProfilingInfo profile(String methodName, Object... args) {
+        return profile(true, N, methodName, args);
+    }
+
+    private void continueProfiling(String methodName, Object... args) {
+        profile(false, N, methodName, args);
+    }
+
+    private void continueProfiling(int executions, String methodName, Object... args) {
+        profile(false, executions, methodName, args);
+    }
+
+    private ProfilingInfo profile(boolean resetProfile, int executions, String methodName, Object... args) {
+        Method method = getMethod(methodName);
+        Assert.assertTrue(Modifier.isStatic(method.getModifiers()));
+
+        ResolvedJavaMethod javaMethod = runtime.lookupJavaMethod(method);
+        if (resetProfile) {
+            javaMethod.reprofile();
+        }
+
+        for (int i = 0; i < executions; ++i) {
+            try {
+                method.invoke(null, args);
+            } catch (Throwable e) {
+                fail("method should not throw an exception: " + e.toString());
+            }
+        }
+
+        return javaMethod.getProfilingInfo();
+    }
+
+    private void resetProfile(String methodName) {
+        ResolvedJavaMethod javaMethod = runtime.lookupJavaMethod(getMethod(methodName));
+        javaMethod.reprofile();
+    }
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java	Wed Mar 27 18:12:03 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java	Thu Mar 28 12:58:50 2013 +0100
@@ -214,4 +214,11 @@
     String getFileName(HotSpotResolvedJavaType method);
 
     void clearQueuedForCompilation(HotSpotResolvedJavaMethod method);
+    
+    /**
+     * Invalidates the profiling information and restarts profiling upon the next invocation.
+     * 
+     * @param metaspaceMethod the metaspace Method object
+     */
+    void reprofile(long metaspaceMethod);
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java	Wed Mar 27 18:12:03 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java	Thu Mar 28 12:58:50 2013 +0100
@@ -155,4 +155,7 @@
 
     @Override
     public native void clearQueuedForCompilation(HotSpotResolvedJavaMethod method);
+    
+    @Override
+    public native void reprofile(long metaspaceMethod);
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodData.java	Wed Mar 27 18:12:03 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodData.java	Thu Mar 28 12:58:50 2013 +0100
@@ -29,7 +29,7 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.meta.JavaTypeProfile.ProfiledType;
-import com.oracle.graal.api.meta.ProfilingInfo.ExceptionSeen;
+import com.oracle.graal.api.meta.ProfilingInfo.TriState;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.phases.*;
 
@@ -41,8 +41,8 @@
     private static final long serialVersionUID = -8873133496591225071L;
 
     private static final HotSpotVMConfig config = HotSpotGraalRuntime.getInstance().getConfig();
-    private static final HotSpotMethodDataAccessor NO_DATA_NO_EXCEPTION_ACCESSOR = new NoMethodData(ExceptionSeen.FALSE);
-    private static final HotSpotMethodDataAccessor NO_DATA_EXCEPTION_POSSIBLY_NOT_RECORDED_ACCESSOR = new NoMethodData(ExceptionSeen.NOT_SUPPORTED);
+    private static final HotSpotMethodDataAccessor NO_DATA_NO_EXCEPTION_ACCESSOR = new NoMethodData(TriState.FALSE);
+    private static final HotSpotMethodDataAccessor NO_DATA_EXCEPTION_POSSIBLY_NOT_RECORDED_ACCESSOR = new NoMethodData(TriState.UNKNOWN);
 
     // sorted by tag
     private static final HotSpotMethodDataAccessor[] PROFILE_DATA_ACCESSORS = {null, new BitData(), new CounterData(), new JumpData(), new TypeCheckData(), new VirtualCallData(), new RetData(),
@@ -194,8 +194,8 @@
         }
 
         @Override
-        public ExceptionSeen getExceptionSeen(HotSpotMethodData data, int position) {
-            return ExceptionSeen.get((getFlags(data, position) & EXCEPTIONS_MASK) != 0);
+        public TriState getExceptionSeen(HotSpotMethodData data, int position) {
+            return TriState.get((getFlags(data, position) & EXCEPTIONS_MASK) != 0);
         }
 
         @Override
@@ -218,6 +218,11 @@
             return -1;
         }
 
+        @Override
+        public TriState getNullSeen(HotSpotMethodData data, int position) {
+            return TriState.UNKNOWN;
+        }
+
         protected int getFlags(HotSpotMethodData data, int position) {
             return data.readUnsignedByte(position, config.dataLayoutFlagsOffset);
         }
@@ -232,9 +237,9 @@
         private static final int NO_DATA_TAG = 0;
         private static final int NO_DATA_SIZE = cellIndexToOffset(0);
 
-        private final ExceptionSeen exceptionSeen;
+        private final TriState exceptionSeen;
 
-        protected NoMethodData(ExceptionSeen exceptionSeen) {
+        protected NoMethodData(TriState exceptionSeen) {
             super(NO_DATA_TAG, NO_DATA_SIZE);
             this.exceptionSeen = exceptionSeen;
         }
@@ -245,7 +250,7 @@
         }
 
         @Override
-        public ExceptionSeen getExceptionSeen(HotSpotMethodData data, int position) {
+        public TriState getExceptionSeen(HotSpotMethodData data, int position) {
             return exceptionSeen;
         }
     }
@@ -264,9 +269,9 @@
             super(tag, staticSize);
         }
 
-        @SuppressWarnings("unused")
-        public boolean getNullSeen(HotSpotMethodData data, int position) {
-            return (getFlags(data, position) & BIT_DATA_NULL_SEEN_FLAG) != 0;
+        @Override
+        public TriState getNullSeen(HotSpotMethodData data, int position) {
+            return TriState.get((getFlags(data, position) & BIT_DATA_NULL_SEEN_FLAG) != 0);
         }
     }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodDataAccessor.java	Wed Mar 27 18:12:03 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodDataAccessor.java	Thu Mar 28 12:58:50 2013 +0100
@@ -23,7 +23,7 @@
 package com.oracle.graal.hotspot.meta;
 
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.api.meta.ProfilingInfo.ExceptionSeen;
+import com.oracle.graal.api.meta.ProfilingInfo.TriState;
 
 /**
  * Interface for accessor objects that encapsulate the logic for accessing the different kinds of
@@ -59,7 +59,9 @@
 
     double[] getSwitchProbabilities(HotSpotMethodData data, int position);
 
-    ExceptionSeen getExceptionSeen(HotSpotMethodData data, int position);
+    TriState getExceptionSeen(HotSpotMethodData data, int position);
+
+    TriState getNullSeen(HotSpotMethodData data, int position);
 
     int getExecutionCount(HotSpotMethodData data, int position);
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotProfilingInfo.java	Wed Mar 27 18:12:03 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotProfilingInfo.java	Thu Mar 28 12:58:50 2013 +0100
@@ -69,12 +69,18 @@
     }
 
     @Override
-    public ExceptionSeen getExceptionSeen(int bci) {
+    public TriState getExceptionSeen(int bci) {
         findBCI(bci, true);
         return dataAccessor.getExceptionSeen(methodData, position);
     }
 
     @Override
+    public TriState getNullSeen(int bci) {
+        findBCI(bci, false);
+        return dataAccessor.getNullSeen(methodData, position);
+    }
+
+    @Override
     public int getExecutionCount(int bci) {
         findBCI(bci, false);
         return dataAccessor.getExecutionCount(methodData, position);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java	Wed Mar 27 18:12:03 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java	Thu Mar 28 12:58:50 2013 +0100
@@ -32,7 +32,7 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.api.meta.ProfilingInfo.ExceptionSeen;
+import com.oracle.graal.api.meta.ProfilingInfo.TriState;
 import com.oracle.graal.bytecode.*;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.debug.*;
@@ -223,7 +223,7 @@
         if (methodData == null || (!methodData.hasNormalData() && !methodData.hasExtraData())) {
             // Be optimistic and return false for exceptionSeen. A methodDataOop is allocated in
             // case of a deoptimization.
-            info = DefaultProfilingInfo.get(ExceptionSeen.FALSE);
+            info = DefaultProfilingInfo.get(TriState.FALSE);
         } else {
             info = new HotSpotProfilingInfo(methodData, codeSize);
         }
@@ -231,6 +231,11 @@
     }
 
     @Override
+    public void reprofile() {
+        HotSpotGraalRuntime.getInstance().getCompilerToVM().reprofile(metaspaceMethod);
+    }
+
+    @Override
     public Map<Object, Object> getCompilerStorage() {
         if (compilerStorage == null) {
             compilerStorage = new ConcurrentHashMap<>();
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Wed Mar 27 18:12:03 2013 +0100
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Thu Mar 28 12:58:50 2013 +0100
@@ -34,7 +34,7 @@
 import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.meta.JavaTypeProfile.ProfiledType;
-import com.oracle.graal.api.meta.ProfilingInfo.ExceptionSeen;
+import com.oracle.graal.api.meta.ProfilingInfo.TriState;
 import com.oracle.graal.api.meta.ResolvedJavaType.Representation;
 import com.oracle.graal.bytecode.*;
 import com.oracle.graal.debug.*;
@@ -960,7 +960,7 @@
 
     protected void emitExplicitExceptions(ValueNode receiver, ValueNode outOfBoundsIndex) {
         assert receiver != null;
-        if (optimisticOpts.useExceptionProbabilityForOperations() && profilingInfo.getExceptionSeen(bci()) == ExceptionSeen.FALSE) {
+        if (optimisticOpts.useExceptionProbabilityForOperations() && profilingInfo.getExceptionSeen(bci()) == TriState.FALSE) {
             return;
         }
 
@@ -1123,7 +1123,7 @@
     protected Invoke createInvokeNode(MethodCallTargetNode callTarget, Kind resultType) {
         // be conservative if information was not recorded (could result in endless recompiles
         // otherwise)
-        if (graphBuilderConfig.omitAllExceptionEdges() || (optimisticOpts.useExceptionProbability() && profilingInfo.getExceptionSeen(bci()) == ExceptionSeen.FALSE)) {
+        if (graphBuilderConfig.omitAllExceptionEdges() || (optimisticOpts.useExceptionProbability() && profilingInfo.getExceptionSeen(bci()) == TriState.FALSE)) {
             InvokeNode invoke = new InvokeNode(callTarget, bci());
             ValueNode result = appendWithBCI(currentGraph.add(invoke));
             frameState.pushReturn(resultType, result);
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java	Wed Mar 27 18:12:03 2013 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java	Thu Mar 28 12:58:50 2013 +0100
@@ -50,7 +50,7 @@
 
     private final PhasePlan plan;
 
-    private final GraalCodeCacheProvider runtime;
+    private final MetaAccessProvider runtime;
     private final Assumptions assumptions;
     private final GraphCache cache;
     private final InliningPolicy inliningPolicy;
@@ -63,7 +63,7 @@
     private static final DebugMetric metricInliningStoppedByMaxDesiredSize = Debug.metric("InliningStoppedByMaxDesiredSize");
     private static final DebugMetric metricInliningRuns = Debug.metric("Runs");
 
-    public InliningPhase(GraalCodeCacheProvider runtime, Collection<Invoke> hints, Assumptions assumptions, GraphCache cache, PhasePlan plan, OptimisticOptimizations optimisticOpts) {
+    public InliningPhase(MetaAccessProvider runtime, Collection<Invoke> hints, Assumptions assumptions, GraphCache cache, PhasePlan plan, OptimisticOptimizations optimisticOpts) {
         this(runtime, assumptions, cache, plan, createInliningPolicy(runtime, assumptions, optimisticOpts, hints), optimisticOpts);
     }
 
@@ -71,7 +71,7 @@
         this.customCanonicalizer = customCanonicalizer;
     }
 
-    public InliningPhase(GraalCodeCacheProvider runtime, Assumptions assumptions, GraphCache cache, PhasePlan plan, InliningPolicy inliningPolicy, OptimisticOptimizations optimisticOpts) {
+    public InliningPhase(MetaAccessProvider runtime, Assumptions assumptions, GraphCache cache, PhasePlan plan, InliningPolicy inliningPolicy, OptimisticOptimizations optimisticOpts) {
         this.runtime = runtime;
         this.assumptions = assumptions;
         this.cache = cache;
@@ -163,10 +163,10 @@
 
     private static class GreedySizeBasedInliningDecision implements InliningDecision {
 
-        private final GraalCodeCacheProvider runtime;
+        private final MetaAccessProvider runtime;
         private final Collection<Invoke> hints;
 
-        public GreedySizeBasedInliningDecision(GraalCodeCacheProvider runtime, Collection<Invoke> hints) {
+        public GreedySizeBasedInliningDecision(MetaAccessProvider runtime, Collection<Invoke> hints) {
             this.runtime = runtime;
             this.hints = hints;
         }
@@ -500,7 +500,7 @@
         }
     }
 
-    private static InliningPolicy createInliningPolicy(GraalCodeCacheProvider runtime, Assumptions assumptions, OptimisticOptimizations optimisticOpts, Collection<Invoke> hints) {
+    private static InliningPolicy createInliningPolicy(MetaAccessProvider runtime, Assumptions assumptions, OptimisticOptimizations optimisticOpts, Collection<Invoke> hints) {
         InliningDecision inliningDecision = new GreedySizeBasedInliningDecision(runtime, hints);
         return new CFInliningPolicy(inliningDecision, hints, assumptions, optimisticOpts);
     }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java	Wed Mar 27 18:12:03 2013 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java	Thu Mar 28 12:58:50 2013 +0100
@@ -39,7 +39,6 @@
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind;
-import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.nodes.util.*;
 import com.oracle.graal.phases.*;
@@ -194,12 +193,12 @@
          * return value of the inlined method (or null for void methods and methods that have no
          * non-exceptional exit).
          **/
-        void inline(StructuredGraph graph, GraalCodeCacheProvider runtime, InliningCallback callback, Assumptions assumptions);
+        void inline(StructuredGraph graph, MetaAccessProvider runtime, InliningCallback callback, Assumptions assumptions);
 
         /**
          * Try to make the call static bindable to avoid interface and virtual method calls.
          */
-        void tryToDevirtualizeInvoke(StructuredGraph graph, GraalCodeCacheProvider runtime, Assumptions assumptions);
+        void tryToDevirtualizeInvoke(StructuredGraph graph, MetaAccessProvider runtime, Assumptions assumptions);
     }
 
     public abstract static class AbstractInlineInfo implements InlineInfo {
@@ -287,12 +286,12 @@
         }
 
         @Override
-        public void inline(StructuredGraph compilerGraph, GraalCodeCacheProvider runtime, InliningCallback callback, Assumptions assumptions) {
+        public void inline(StructuredGraph compilerGraph, MetaAccessProvider runtime, InliningCallback callback, Assumptions assumptions) {
             inline(invoke, concrete, callback, assumptions, true);
         }
 
         @Override
-        public void tryToDevirtualizeInvoke(StructuredGraph graph, GraalCodeCacheProvider runtime, Assumptions assumptions) {
+        public void tryToDevirtualizeInvoke(StructuredGraph graph, MetaAccessProvider runtime, Assumptions assumptions) {
             // nothing todo, can already be bound statically
         }
 
@@ -341,18 +340,18 @@
         }
 
         @Override
-        public void inline(StructuredGraph graph, GraalCodeCacheProvider runtime, InliningCallback callback, Assumptions assumptions) {
+        public void inline(StructuredGraph graph, MetaAccessProvider runtime, InliningCallback callback, Assumptions assumptions) {
             createGuard(graph, runtime);
             inline(invoke, concrete, callback, assumptions, false);
         }
 
         @Override
-        public void tryToDevirtualizeInvoke(StructuredGraph graph, GraalCodeCacheProvider runtime, Assumptions assumptions) {
+        public void tryToDevirtualizeInvoke(StructuredGraph graph, MetaAccessProvider runtime, Assumptions assumptions) {
             createGuard(graph, runtime);
             replaceInvokeCallTarget(graph, InvokeKind.Special, concrete);
         }
 
-        private void createGuard(StructuredGraph graph, GraalCodeCacheProvider runtime) {
+        private void createGuard(StructuredGraph graph, MetaAccessProvider runtime) {
             InliningUtil.receiverNullCheck(invoke);
             ValueNode receiver = invoke.methodCallTarget().receiver();
             ConstantNode typeHub = ConstantNode.forConstant(type.getEncoding(Representation.ObjectHub), runtime, graph);
@@ -411,7 +410,7 @@
         }
 
         @Override
-        public void inline(StructuredGraph graph, GraalCodeCacheProvider runtime, InliningCallback callback, Assumptions assumptions) {
+        public void inline(StructuredGraph graph, MetaAccessProvider runtime, InliningCallback callback, Assumptions assumptions) {
             // receiver null check must be the first node
             InliningUtil.receiverNullCheck(invoke);
             if (hasSingleMethod()) {
@@ -674,7 +673,7 @@
         }
 
         @Override
-        public void tryToDevirtualizeInvoke(StructuredGraph graph, GraalCodeCacheProvider runtime, Assumptions assumptions) {
+        public void tryToDevirtualizeInvoke(StructuredGraph graph, MetaAccessProvider runtime, Assumptions assumptions) {
             if (hasSingleMethod()) {
                 tryToDevirtualizeSingleMethod(graph);
             } else {
@@ -760,7 +759,7 @@
         }
 
         @Override
-        public void inline(StructuredGraph graph, GraalCodeCacheProvider runtime, InliningCallback callback, Assumptions assumptions) {
+        public void inline(StructuredGraph graph, MetaAccessProvider runtime, InliningCallback callback, Assumptions assumptions) {
             assumptions.record(takenAssumption);
             Debug.log("recording assumption: %s", takenAssumption);
 
@@ -768,7 +767,7 @@
         }
 
         @Override
-        public void tryToDevirtualizeInvoke(StructuredGraph graph, GraalCodeCacheProvider runtime, Assumptions assumptions) {
+        public void tryToDevirtualizeInvoke(StructuredGraph graph, MetaAccessProvider runtime, Assumptions assumptions) {
             assumptions.record(takenAssumption);
             replaceInvokeCallTarget(graph, InvokeKind.Special, concrete);
         }
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java	Wed Mar 27 18:12:03 2013 +0100
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java	Thu Mar 28 12:58:50 2013 +0100
@@ -113,7 +113,7 @@
 
     // Debug settings:
     public static boolean Debug                              = true;
-    public static boolean DebugReplacements                      = false;
+    public static boolean DebugReplacements                  = ____;
     public static boolean PerThreadDebugValues               = ____;
     public static boolean SummarizeDebugValues               = ____;
     public static boolean SummarizePerPhase                  = ____;
--- a/src/cpu/x86/vm/templateInterpreter_x86.hpp	Wed Mar 27 18:12:03 2013 +0100
+++ b/src/cpu/x86/vm/templateInterpreter_x86.hpp	Thu Mar 28 12:58:50 2013 +0100
@@ -34,7 +34,7 @@
   // Run with +PrintInterpreter to get the VM to print out the size.
   // Max size with JVMTI
 #ifdef AMD64
-  const static int InterpreterCodeSize = 220 * 1024;
+  const static int InterpreterCodeSize = 240 * 1024;
 #else
   const static int InterpreterCodeSize = 168 * 1024;
 #endif // AMD64
--- a/src/share/vm/graal/graalCompilerToVM.cpp	Wed Mar 27 18:12:03 2013 +0100
+++ b/src/share/vm/graal/graalCompilerToVM.cpp	Thu Mar 28 12:58:50 2013 +0100
@@ -1032,6 +1032,28 @@
 
 C2V_END
 
+
+C2V_VMENTRY(void, reprofile, (JNIEnv *env, jobject, jlong metaspace_method))
+  Method* method = asMethod(metaspace_method);
+  method->reset_counters();
+
+  nmethod* code = method->code();
+  if (code != NULL) {
+    code->make_not_entrant();
+  }
+
+  MethodData* method_data = method->method_data();
+  if (method_data == NULL) {
+    ClassLoaderData* loader_data = method->method_holder()->class_loader_data();
+    method_data = MethodData::allocate(loader_data, method, CHECK);
+    method->set_method_data(method_data);
+  } else {
+    method_data->initialize();
+  }
+C2V_END
+
+
+
 #define CC (char*)  /*cast a literal from (const char*)*/
 #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &(c2v_ ## f))
 
@@ -1106,6 +1128,7 @@
   {CC"getLocalVariableTable",         CC"("HS_RESOLVED_METHOD")["LOCAL,                                 FN_PTR(getLocalVariableTable)},
   {CC"getFileName",                   CC"("HS_RESOLVED_JAVA_TYPE")"STRING,                              FN_PTR(getFileName)},
   {CC"clearQueuedForCompilation",     CC"("HS_RESOLVED_METHOD")V",                                      FN_PTR(clearQueuedForCompilation)},
+  {CC"reprofile",                     CC"("METASPACE_METHOD")V",                                        FN_PTR(reprofile)},
 };
 
 int CompilerToVM_methods_count() {
--- a/src/share/vm/oops/method.cpp	Wed Mar 27 18:12:03 2013 +0100
+++ b/src/share/vm/oops/method.cpp	Thu Mar 28 12:58:50 2013 +0100
@@ -1940,3 +1940,15 @@
   guarantee(md == NULL ||
       md->is_methodData(), "should be method data");
 }
+
+#ifdef GRAAL
+void Method::reset_counters() {
+  invocation_counter()->reset();
+  backedge_counter()->reset();
+  _interpreter_invocation_count = 0;
+  _interpreter_throwout_count = 0;
+#ifndef PRODUCT
+  _compiled_invocation_count = 0;
+#endif
+}
+#endif
--- a/src/share/vm/oops/method.hpp	Wed Mar 27 18:12:03 2013 +0100
+++ b/src/share/vm/oops/method.hpp	Thu Mar 28 12:58:50 2013 +0100
@@ -370,6 +370,8 @@
 
   void set_graal_priority(int prio)      { _graal_priority = prio; }
   int graal_priority()                   { return _graal_priority; }
+
+  void reset_counters();
 #endif // GRAAL
 
   bool was_executed_more_than(int n);
@@ -386,7 +388,7 @@
     if (TieredCompilation) ShouldNotReachHere();
     return ++_interpreter_invocation_count;
   }
-
+  
 #ifndef PRODUCT
   int  compiled_invocation_count() const         { return _compiled_invocation_count;  }
   void set_compiled_invocation_count(int count)  { _compiled_invocation_count = count; }
--- a/src/share/vm/oops/methodData.cpp	Wed Mar 27 18:12:03 2013 +0100
+++ b/src/share/vm/oops/methodData.cpp	Thu Mar 28 12:58:50 2013 +0100
@@ -659,10 +659,14 @@
 
 // Initialize the MethodData* corresponding to a given method.
 MethodData::MethodData(methodHandle method, int size, TRAPS) {
+  // Set the method back-pointer.
+  _method = method();
+  initialize();
+}
+
+void MethodData::initialize() {
   No_Safepoint_Verifier no_safepoint;  // init function atomic wrt GC
   ResourceMark rm;
-  // Set the method back-pointer.
-  _method = method();
 
   if (TieredCompilation) {
     _invocation_counter.init();
@@ -689,7 +693,7 @@
   // corresponding data cells.
   int data_size = 0;
   int empty_bc_count = 0;  // number of bytecodes lacking data
-  BytecodeStream stream(method);
+  BytecodeStream stream(method());
   Bytecodes::Code c;
   while ((c = stream.next()) >= 0) {
     int size_in_bytes = initialize_data(&stream, data_size);
@@ -705,6 +709,8 @@
   int extra_size = extra_data_count * DataLayout::compute_size_in_bytes(0);
   object_size += extra_size;
 
+  Copy::zero_to_bytes((HeapWord*) extra_data_base(), extra_size);
+
 #ifndef GRAALVM
   // Add a cell to record information about modified arguments.
   // Set up _args_modified array after traps cells so that
--- a/src/share/vm/oops/methodData.hpp	Wed Mar 27 18:12:03 2013 +0100
+++ b/src/share/vm/oops/methodData.hpp	Thu Mar 28 12:58:50 2013 +0100
@@ -1178,6 +1178,7 @@
   MethodData() {}; // For ciMethodData
 
   bool is_methodData() const volatile { return true; }
+  void initialize();
 
   // Whole-method sticky bits and flags
   enum {
@@ -1295,10 +1296,7 @@
   static bool bytecode_has_profile(Bytecodes::Code code) {
     return bytecode_cell_count(code) != no_profile_data;
   }
-
-  // Perform initialization of a new MethodData*
-  void initialize(methodHandle method);
-
+  
   // My size
   int size_in_bytes() const { return _size; }
   int size() const    { return align_object_size(align_size_up(_size, BytesPerWord)/BytesPerWord); }
--- a/src/share/vm/runtime/deoptimization.cpp	Wed Mar 27 18:12:03 2013 +0100
+++ b/src/share/vm/runtime/deoptimization.cpp	Thu Mar 28 12:58:50 2013 +0100
@@ -212,10 +212,14 @@
   nmethod* nm = (nmethod*) deoptee.cb();
   GraalCompiler* compiler = (GraalCompiler*) nm->compiler();
   for (jlong* p = nm->leaf_graph_ids_begin(); p != nm->leaf_graph_ids_end(); p++) {
-    if (PrintDeoptimizationDetails) {
-      tty->print_cr("leaf graph id: %d", *p);
+    compiler->deopt_leaf_graph(*p);
+  }
+  if (PrintDeoptimizationDetails) {
+    tty->print("leaf graph ids: ");
+    for (jlong* p = nm->leaf_graph_ids_begin(); p != nm->leaf_graph_ids_end(); p++) {
+      tty->print("%d ", *p);
     }
-    compiler->deopt_leaf_graph(*p);
+    tty->cr();
   }
 #endif
 
--- a/src/share/vm/runtime/vframeArray.cpp	Wed Mar 27 18:12:03 2013 +0100
+++ b/src/share/vm/runtime/vframeArray.cpp	Thu Mar 28 12:58:50 2013 +0100
@@ -426,9 +426,6 @@
     ttyLocker ttyl;
     tty->print_cr("[%d Interpreted Frame]", ++unpack_counter);
     iframe()->print_on(tty);
-    RegisterMap map(thread);
-    vframe* f = vframe::new_vframe(iframe(), &map, thread);
-    f->print();
 
     tty->print_cr("locals size     %d", locals()->size());
     tty->print_cr("expression size %d", expressions()->size());