changeset 9998:e85afceb39e7

Merge
author Christos Kotselidis <christos.kotselidis@oracle.com>
date Tue, 11 Jun 2013 18:13:55 +0200
parents 4abd6387a612 (current diff) 3754bb5aab2f (diff)
children 3bc930dd9313 ebb32c4589f3
files
diffstat 26 files changed, 446 insertions(+), 60 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaMethod.java	Tue Jun 11 17:45:31 2013 +0200
+++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaMethod.java	Tue Jun 11 18:13:55 2013 +0200
@@ -132,6 +132,18 @@
     }
 
     @Test
+    public void isSyntheticTest() {
+        for (Map.Entry<Method, ResolvedJavaMethod> e : methods.entrySet()) {
+            ResolvedJavaMethod m = e.getValue();
+            assertEquals(e.getKey().isSynthetic(), m.isSynthetic());
+        }
+        for (Map.Entry<Constructor, ResolvedJavaMethod> e : constructors.entrySet()) {
+            ResolvedJavaMethod m = e.getValue();
+            assertEquals(e.getKey().isSynthetic(), m.isSynthetic());
+        }
+    }
+
+    @Test
     public void canBeStaticallyBoundTest() {
         for (Map.Entry<Method, ResolvedJavaMethod> e : methods.entrySet()) {
             ResolvedJavaMethod m = e.getValue();
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaField.java	Tue Jun 11 17:45:31 2013 +0200
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaField.java	Tue Jun 11 18:13:55 2013 +0200
@@ -45,6 +45,11 @@
     boolean isInternal();
 
     /**
+     * Determines if this field is a synthetic field as defined by the Java Language Specification.
+     */
+    boolean isSynthetic();
+
+    /**
      * Gets the constant value of this field for a given object, if available.
      * 
      * @param receiver object from which this field's value is to be read. This value is ignored if
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaMethod.java	Tue Jun 11 17:45:31 2013 +0200
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaMethod.java	Tue Jun 11 18:13:55 2013 +0200
@@ -80,6 +80,12 @@
     int getModifiers();
 
     /**
+     * Determines if this method is a synthetic method as defined by the Java Language
+     * Specification.
+     */
+    boolean isSynthetic();
+
+    /**
      * Checks whether this method is a class initializer.
      * 
      * @return {@code true} if the method is a class initializer
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotOptions.java	Tue Jun 11 17:45:31 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotOptions.java	Tue Jun 11 18:13:55 2013 +0200
@@ -48,7 +48,7 @@
         ServiceLoader<Options> sl = ServiceLoader.loadInstalled(Options.class);
         for (Options opts : sl) {
             for (OptionDescriptor desc : opts) {
-                if (desc.getClass().getName().startsWith("com.oracle.graal")) {
+                if (isHotSpotOption(desc)) {
                     String name = desc.getName();
                     OptionDescriptor existing = options.put(name, desc);
                     assert existing == null : "Option named \"" + name + "\" has multiple definitions: " + existing.getLocation() + " and " + desc.getLocation();
@@ -58,6 +58,13 @@
     }
 
     /**
+     * Determines if a given option is a HotSpot command line option.
+     */
+    public static boolean isHotSpotOption(OptionDescriptor desc) {
+        return desc.getClass().getName().startsWith("com.oracle.graal");
+    }
+
+    /**
      * Loads default option value overrides from a {@code graal.options} file if it exists. Each
      * line in this file starts with {@code "#"} and is ignored or must have the format of a Graal
      * command line option without the leading {@code "-G:"} prefix. These option value are set
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Tue Jun 11 17:45:31 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Tue Jun 11 18:13:55 2013 +0200
@@ -384,8 +384,6 @@
     public int typeProfileWidth;
     public int methodProfileWidth;
 
-    public int interpreterProfilingThreshold;
-
     public long inlineCacheMissStub;
     public long handleDeoptStub;
     public long uncommonTrapStub;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java	Tue Jun 11 17:45:31 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java	Tue Jun 11 18:13:55 2013 +0200
@@ -168,6 +168,8 @@
 
     HotSpotResolvedJavaField[] getInstanceFields(HotSpotResolvedObjectType klass);
 
+    HotSpotResolvedJavaMethod[] getMethods(HotSpotResolvedObjectType klass);
+
     boolean hasFinalizableSubclass(HotSpotResolvedObjectType klass);
 
     /**
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java	Tue Jun 11 17:45:31 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java	Tue Jun 11 18:13:55 2013 +0200
@@ -124,6 +124,9 @@
     public native HotSpotResolvedJavaField[] getInstanceFields(HotSpotResolvedObjectType klass);
 
     @Override
+    public native HotSpotResolvedJavaMethod[] getMethods(HotSpotResolvedObjectType klass);
+
+    @Override
     public native int getCompiledCodeSize(long metaspaceMethod);
 
     @Override
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java	Tue Jun 11 17:45:31 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java	Tue Jun 11 18:13:55 2013 +0200
@@ -183,6 +183,8 @@
             DebugEnvironment.initialize(log);
         }
 
+        assert VerifyHotSpotOptionsPhase.checkOptions();
+
         // Install intrinsics.
         final HotSpotRuntime runtime = graalRuntime.getCapability(HotSpotRuntime.class);
         final Replacements replacements = graalRuntime.getCapability(Replacements.class);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotProfilingInfo.java	Tue Jun 11 17:45:31 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotProfilingInfo.java	Tue Jun 11 18:13:55 2013 +0200
@@ -22,9 +22,6 @@
  */
 package com.oracle.graal.hotspot.meta;
 
-import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
-import static com.oracle.graal.phases.GraalOptions.*;
-
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.hotspot.*;
@@ -163,7 +160,7 @@
 
     @Override
     public boolean isMature() {
-        return method.invocationCount() >= graalRuntime().getConfig().interpreterProfilingThreshold + MatureProfilingInformationThreshold.getValue();
+        return true;
     }
 
     @Override
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java	Tue Jun 11 17:45:31 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java	Tue Jun 11 18:13:55 2013 +0200
@@ -160,6 +160,15 @@
     }
 
     @Override
+    public boolean isSynthetic() {
+        Field javaField = toJava();
+        if (javaField != null) {
+            return javaField.isSynthetic();
+        }
+        return false;
+    }
+
+    @Override
     public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
         Field javaField = toJava();
         if (javaField != null) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java	Tue Jun 11 17:45:31 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java	Tue Jun 11 18:13:55 2013 +0200
@@ -332,6 +332,29 @@
     }
 
     @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);
+        HotSpotRuntime runtime = graalRuntime().getRuntime();
+        for (Method method : holder.mirror().getDeclaredMethods()) {
+            if (method.getName().equals(name)) {
+                if (runtime.lookupJavaType(method.getReturnType()).equals(sig.getReturnType(holder))) {
+                    if (matches(runtime, sigTypes, method.getParameterTypes())) {
+                        return method.isSynthetic();
+                    }
+                }
+            }
+        }
+        return false;
+    }
+
+    @Override
     public Type[] getGenericParameterTypes() {
         if (isConstructor()) {
             Constructor javaConstructor = toJavaConstructor();
@@ -351,6 +374,18 @@
         return result;
     }
 
+    private static boolean matches(HotSpotRuntime runtime, JavaType[] sigTypes, Class<?>[] parameterTypes) {
+        if (parameterTypes.length == sigTypes.length) {
+            for (int i = 0; i < parameterTypes.length; i++) {
+                if (!runtime.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/meta/HotSpotResolvedObjectType.java	Tue Jun 11 17:45:31 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java	Tue Jun 11 18:13:55 2013 +0200
@@ -541,6 +541,15 @@
         return result;
     }
 
+    /**
+     * Gets all methods and constructors declared by this class, including the {@code <clinit>}
+     * method if there is one. The latter is not made accessible via standard Java reflection.
+     */
+    public ResolvedJavaMethod[] getMethods() {
+        HotSpotResolvedJavaMethod[] methods = graalRuntime().getCompilerToVM().getMethods(this);
+        return methods;
+    }
+
     @Override
     public Constant newArray(int length) {
         return Constant.forObject(Array.newInstance(javaMirror, length));
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/VerifyHotSpotOptionsPhase.java	Tue Jun 11 18:13:55 2013 +0200
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.oracle.graal.hotspot.phases;
+
+import static com.oracle.graal.api.meta.MetaUtil.*;
+import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
+import static java.lang.reflect.Modifier.*;
+
+import java.util.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.java.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.java.*;
+import com.oracle.graal.nodes.util.*;
+import com.oracle.graal.options.*;
+import com.oracle.graal.phases.*;
+
+/**
+ * Verifies that a class that declares one or more HotSpot {@linkplain OptionValue options} has a
+ * class initializer that only initializes the option(s). This sanity check prevents an option being
+ * read to initialize some global state before it is parsed on the command line. The latter occurs
+ * if an option declaring class has a class initializer that reads options or triggers other class
+ * initializers that read options.
+ */
+public class VerifyHotSpotOptionsPhase extends Phase {
+
+    public static boolean checkOptions() {
+        HotSpotRuntime runtime = graalRuntime().getRuntime();
+        ServiceLoader<Options> sl = ServiceLoader.loadInstalled(Options.class);
+        Set<HotSpotResolvedObjectType> checked = new HashSet<>();
+        for (Options opts : sl) {
+            for (OptionDescriptor desc : opts) {
+                if (HotSpotOptions.isHotSpotOption(desc)) {
+                    HotSpotResolvedObjectType holder = (HotSpotResolvedObjectType) runtime.lookupJavaType(desc.getDeclaringClass());
+                    if (!checked.contains(holder)) {
+                        checked.add(holder);
+                        for (ResolvedJavaMethod method : holder.getMethods()) {
+                            if (method.isClassInitializer()) {
+                                StructuredGraph graph = new StructuredGraph(method);
+                                new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph);
+                                new VerifyHotSpotOptionsPhase(holder, runtime).apply(graph);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        return true;
+    }
+
+    private final HotSpotRuntime runtime;
+    private final ResolvedJavaType declaringClass;
+    private final ResolvedJavaType optionValueType;
+    private final Set<ResolvedJavaType> boxingTypes;
+
+    public VerifyHotSpotOptionsPhase(ResolvedJavaType declaringClass, HotSpotRuntime runtime) {
+        this.runtime = runtime;
+        this.declaringClass = declaringClass;
+        this.optionValueType = runtime.lookupJavaType(OptionValue.class);
+        this.boxingTypes = new HashSet<>();
+        for (Class c : new Class[]{Boolean.class, Byte.class, Short.class, Character.class, Integer.class, Float.class, Long.class, Double.class}) {
+            this.boxingTypes.add(runtime.lookupJavaType(c));
+        }
+    }
+
+    /**
+     * Checks whether a given method is allowed to be called.
+     */
+    private boolean checkInvokeTarget(ResolvedJavaMethod method) {
+        ResolvedJavaType holder = method.getDeclaringClass();
+        if (method.isConstructor()) {
+            if (optionValueType.isAssignableFrom(holder)) {
+                return true;
+            }
+        } else if (boxingTypes.contains(holder)) {
+            return method.getName().equals("valueOf");
+        } else if (method.getDeclaringClass() == runtime.lookupJavaType(Class.class)) {
+            return method.getName().equals("desiredAssertionStatus");
+        } else if (method.getDeclaringClass().equals(declaringClass)) {
+            return (method.getName().equals("$jacocoInit"));
+        }
+        return false;
+    }
+
+    @Override
+    protected void run(StructuredGraph graph) {
+        for (ValueNode node : graph.getNodes().filter(ValueNode.class)) {
+            if (node instanceof StoreFieldNode) {
+                HotSpotResolvedJavaField field = (HotSpotResolvedJavaField) ((StoreFieldNode) node).field();
+                verify(field.getDeclaringClass() == declaringClass, node, "store to field " + format("%H.%n", field));
+                verify(isStatic(field.getModifiers()), node, "store to field " + format("%H.%n", field));
+                if (optionValueType.isAssignableFrom((ResolvedJavaType) field.getType())) {
+                    verify(isFinal(field.getModifiers()), node, "option field " + format("%H.%n", field) + " not final");
+                } else {
+                    verify((field.isSynthetic()), node, "store to non-synthetic field " + format("%H.%n", field));
+                }
+            } else if (node instanceof Invoke) {
+                Invoke invoke = (Invoke) node;
+                MethodCallTargetNode callTarget = (MethodCallTargetNode) invoke.callTarget();
+                ResolvedJavaMethod targetMethod = callTarget.targetMethod();
+                verify(checkInvokeTarget(targetMethod), node, "invocation of " + format("%H.%n(%p)", targetMethod));
+            }
+        }
+    }
+
+    private void verify(boolean condition, Node node, String message) {
+        if (!condition) {
+            error(node, message);
+        }
+    }
+
+    private void error(Node node, String message) {
+        String loc = GraphUtil.approxSourceLocation(node);
+        throw new GraalInternalError(String.format("HotSpot option declarer %s contains code pattern implying action other than initialization of an option:%n    %s%n    %s",
+                        toJavaName(declaringClass), loc, message));
+    }
+}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ControlSplitNode.java	Tue Jun 11 17:45:31 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ControlSplitNode.java	Tue Jun 11 18:13:55 2013 +0200
@@ -35,4 +35,6 @@
     }
 
     public abstract double probability(AbstractBeginNode successor);
+
+    public abstract void setProbability(AbstractBeginNode successor, double value);
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java	Tue Jun 11 17:45:31 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java	Tue Jun 11 18:13:55 2013 +0200
@@ -132,6 +132,12 @@
     }
 
     @Override
+    public void setProbability(AbstractBeginNode successor, double value) {
+        assert successor == trueSuccessor || successor == falseSuccessor;
+        setTrueSuccessorProbability(successor == trueSuccessor ? value : 1 - value);
+    }
+
+    @Override
     public void generate(LIRGeneratorTool gen) {
         gen.emitIf(this);
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java	Tue Jun 11 17:45:31 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java	Tue Jun 11 18:13:55 2013 +0200
@@ -36,6 +36,8 @@
 @NodeInfo(nameTemplate = "Invoke!#{p#targetMethod/s}")
 public class InvokeWithExceptionNode extends ControlSplitNode implements Node.IterableNodeType, Invoke, MemoryCheckpoint, LIRLowerable {
 
+    private static final double EXCEPTION_PROBA = 1e-5;
+
     @Successor private AbstractBeginNode next;
     @Successor private DispatchBeginNode exceptionEdge;
     @Input private CallTargetNode callTarget;
@@ -45,6 +47,7 @@
     private final int bci;
     private boolean polymorphic;
     private boolean useForInlining;
+    private double exceptionProbability;
 
     public InvokeWithExceptionNode(CallTargetNode callTarget, DispatchBeginNode exceptionEdge, int bci) {
         super(callTarget.returnStamp());
@@ -53,6 +56,7 @@
         this.callTarget = callTarget;
         this.polymorphic = false;
         this.useForInlining = true;
+        this.exceptionProbability = EXCEPTION_PROBA;
     }
 
     public DispatchBeginNode exceptionEdge() {
@@ -205,11 +209,15 @@
         }
     }
 
-    private static final double EXCEPTION_PROBA = 1e-5;
+    @Override
+    public double probability(AbstractBeginNode successor) {
+        return successor == next ? 1 - exceptionProbability : exceptionProbability;
+    }
 
     @Override
-    public double probability(AbstractBeginNode successor) {
-        return successor == next ? 1 - EXCEPTION_PROBA : EXCEPTION_PROBA;
+    public void setProbability(AbstractBeginNode successor, double value) {
+        assert successor == next || successor == exceptionEdge;
+        this.exceptionProbability = successor == next ? 1 - value : value;
     }
 
     @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SwitchNode.java	Tue Jun 11 17:45:31 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SwitchNode.java	Tue Jun 11 18:13:55 2013 +0200
@@ -76,7 +76,8 @@
         return sum;
     }
 
-    public void setProbability(Node successor, double value) {
+    @Override
+    public void setProbability(AbstractBeginNode successor, double value) {
         double changeInProbability = 0;
         int nonZeroProbabilityCases = 0;
         for (int i = 0; i < keySuccessors.length; i++) {
--- a/graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionDescriptor.java	Tue Jun 11 17:45:31 2013 +0200
+++ b/graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionDescriptor.java	Tue Jun 11 18:13:55 2013 +0200
@@ -32,14 +32,16 @@
     protected final Class type;
     protected final String help;
     protected final OptionValue<?> option;
-    protected final String location;
+    protected final Class<?> declaringClass;
+    protected final String fieldName;
 
-    public OptionDescriptor(String name, Class type, String help, String location, OptionValue<?> option) {
+    public OptionDescriptor(String name, Class type, String help, Class<?> declaringClass, String fieldName, OptionValue<?> option) {
         this.name = name;
         this.type = type;
         this.help = help;
         this.option = option;
-        this.location = location;
+        this.declaringClass = declaringClass;
+        this.fieldName = fieldName;
     }
 
     /**
@@ -71,11 +73,18 @@
         return option;
     }
 
+    public Class<?> getDeclaringClass() {
+        return declaringClass;
+    }
+
+    public String getFieldName() {
+        return fieldName;
+    }
+
     /**
      * Gets a description of the location where this option is stored.
      */
     public String getLocation() {
-        return location;
-
+        return getDeclaringClass().getName() + "." + getFieldName();
     }
 }
--- a/graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionProcessor.java	Tue Jun 11 17:45:31 2013 +0200
+++ b/graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionProcessor.java	Tue Jun 11 18:13:55 2013 +0200
@@ -123,9 +123,9 @@
 
     private void createFiles(OptionsInfo info) {
         String pkg = ((PackageElement) info.topDeclaringType.getEnclosingElement()).getQualifiedName().toString();
-        Name declaringClass = info.topDeclaringType.getSimpleName();
+        Name topDeclaringClass = info.topDeclaringType.getSimpleName();
 
-        String optionsClassName = declaringClass + "_" + Options.class.getSimpleName();
+        String optionsClassName = topDeclaringClass + "_" + Options.class.getSimpleName();
         Element[] originatingElements = info.originatingElements.toArray(new Element[info.originatingElements.size()]);
 
         Filer filer = processingEnv.getFiler();
@@ -133,7 +133,7 @@
 
             out.println("// CheckStyle: stop header check");
             out.println("// GENERATED CONTENT - DO NOT EDIT");
-            out.println("// Source: " + declaringClass + ".java");
+            out.println("// Source: " + topDeclaringClass + ".java");
             out.println("package " + pkg + ";");
             out.println("");
             out.println("import java.util.*;");
@@ -141,8 +141,9 @@
             out.println("");
             out.println("public class " + optionsClassName + " implements " + Options.class.getSimpleName() + " {");
             out.println("    @Override");
-            out.println("    public Iterator<" + OptionDescriptor.class.getSimpleName() + "> iterator() {");
-            out.println("        List<" + OptionDescriptor.class.getSimpleName() + "> options = Arrays.asList(");
+            String desc = OptionDescriptor.class.getSimpleName();
+            out.println("    public Iterator<" + desc + "> iterator() {");
+            out.println("        List<" + desc + "> options = Arrays.asList(");
 
             boolean needPrivateFieldAccessor = false;
             int i = 0;
@@ -157,9 +158,10 @@
                 String name = option.name;
                 String type = option.type;
                 String help = option.help;
-                String location = pkg + "." + option.declaringClass + "." + option.field.getSimpleName();
+                String declaringClass = option.declaringClass;
+                Name fieldName = option.field.getSimpleName();
                 String comma = i == info.options.size() - 1 ? "" : ",";
-                out.printf("            new %s(\"%s\", %s.class, \"%s\", \"%s\", %s)%s\n", OptionDescriptor.class.getSimpleName(), name, type, help, location, optionValue, comma);
+                out.printf("            new %s(\"%s\", %s.class, \"%s\", %s.class, \"%s\", %s)%s\n", desc, name, type, help, declaringClass, fieldName, optionValue, comma);
                 i++;
             }
             out.println("        );");
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java	Tue Jun 11 17:45:31 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java	Tue Jun 11 18:13:55 2013 +0200
@@ -23,6 +23,7 @@
 package com.oracle.graal.phases.common;
 
 import static com.oracle.graal.phases.GraalOptions.*;
+import static com.oracle.graal.phases.common.InliningPhase.Options.*;
 
 import java.util.*;
 import java.util.concurrent.*;
@@ -48,10 +49,13 @@
 
 public class InliningPhase extends Phase {
 
-    // @formatter:off
-    @Option(help = "Unconditionally inline intrinsics")
-    public static final OptionValue<Boolean> AlwaysInlineIntrinsics = new OptionValue<>(false);
-    // @formatter:on
+    static class Options {
+
+        // @formatter:off
+        @Option(help = "Unconditionally inline intrinsics")
+        public static final OptionValue<Boolean> AlwaysInlineIntrinsics = new OptionValue<>(false);
+        // @formatter:on
+    }
 
     private final PhasePlan plan;
     private final MetaAccessProvider runtime;
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java	Tue Jun 11 17:45:31 2013 +0200
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java	Tue Jun 11 18:13:55 2013 +0200
@@ -86,8 +86,6 @@
     // profiling information
     @Option(help = "")
     public static final OptionValue<Integer> DeoptsToDisableOptimisticOptimization = new OptionValue<>(40);
-    @Option(help = "")
-    public static final OptionValue<Integer> MatureProfilingInformationThreshold = new OptionValue<>(100);
 
     // comilation queue
     @Option(help = "")
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/ComputeProbabilityClosure.java	Tue Jun 11 17:45:31 2013 +0200
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/ComputeProbabilityClosure.java	Tue Jun 11 18:13:55 2013 +0200
@@ -24,6 +24,7 @@
 
 import java.util.*;
 
+import com.oracle.graal.debug.internal.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.util.*;
@@ -63,12 +64,98 @@
     }
 
     public NodesToDoubles apply() {
+        adjustControlSplitProbabilities();
         new PropagateProbability(graph.start()).apply();
         computeLoopFactors();
         new PropagateLoopFrequency(graph.start()).apply();
+        assert verifyProbabilities();
         return nodeProbabilities;
     }
 
+    /**
+     * Assume that paths with a DeoptimizeNode at their end are taken infrequently.
+     */
+    private void adjustControlSplitProbabilities() {
+        HashSet<ControlSplitNode> result = new HashSet<>();
+        NodeBitMap visitedNodes = new NodeBitMap(graph);
+        for (DeoptimizeNode n : graph.getNodes(DeoptimizeNode.class)) {
+            if (n.action().doesInvalidateCompilation()) {
+                findParentControlSplitNodes(result, n, visitedNodes);
+            }
+        }
+
+        for (ControlSplitNode n : result) {
+            if (!allSuxVisited(n, visitedNodes)) {
+                modifyProbabilities(n, visitedNodes);
+            }
+        }
+    }
+
+    private static void findParentControlSplitNodes(HashSet<ControlSplitNode> result, DeoptimizeNode n, NodeBitMap visitedNodes) {
+        ArrayDeque<FixedNode> nodes = new ArrayDeque<>();
+        nodes.push(n);
+
+        Node currentNode;
+        do {
+            currentNode = nodes.pop();
+            visitedNodes.mark(currentNode);
+
+            for (Node pred : currentNode.cfgPredecessors()) {
+                FixedNode fixedPred = (FixedNode) pred;
+                if (visitedNodes.isMarked(fixedPred) && allPredsVisited(fixedPred, visitedNodes)) {
+                    DebugScope.dump(n.graph(), "ComputeProbabilityClosure");
+                    GraalInternalError.shouldNotReachHere(String.format("Endless loop because %s was already visited", fixedPred));
+                } else if (allSuxVisited(fixedPred, visitedNodes)) {
+                    nodes.push(fixedPred);
+                } else {
+                    assert fixedPred instanceof ControlSplitNode : "only control splits can have more than one sux";
+                    result.add((ControlSplitNode) fixedPred);
+                }
+            }
+        } while (!nodes.isEmpty());
+    }
+
+    private static void modifyProbabilities(ControlSplitNode controlSplit, NodeBitMap visitedNodes) {
+        assert !allSuxVisited(controlSplit, visitedNodes);
+        for (Node sux : controlSplit.successors()) {
+            if (visitedNodes.isMarked(sux)) {
+                controlSplit.setProbability((AbstractBeginNode) sux, 0);
+            }
+        }
+    }
+
+    private static boolean allSuxVisited(FixedNode node, NodeBitMap visitedNodes) {
+        return allVisited(node.successors(), visitedNodes);
+    }
+
+    private static boolean allPredsVisited(FixedNode node, NodeBitMap visitedNodes) {
+        return allVisited(node.cfgPredecessors(), visitedNodes);
+    }
+
+    private static boolean allVisited(Iterable<? extends Node> nodes, NodeBitMap visitedNodes) {
+        for (Node sux : nodes) {
+            if (!visitedNodes.contains(sux)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private boolean verifyProbabilities() {
+        if (doesNotAlwaysDeopt(graph)) {
+            for (DeoptimizeNode n : graph.getNodes(DeoptimizeNode.class)) {
+                if (n.action().doesInvalidateCompilation() && nodeProbabilities.get(n) > 0.01) {
+                    throw new AssertionError(String.format("%s with reason %s and probability %f in graph %s", n, n.reason(), nodeProbabilities.get(n), graph));
+                }
+            }
+        }
+        return true;
+    }
+
+    private static boolean doesNotAlwaysDeopt(StructuredGraph graph) {
+        return graph.getNodes(ReturnNode.class).iterator().hasNext();
+    }
+
     private void computeLoopFactors() {
         for (LoopInfo info : loopInfos) {
             double frequency = info.loopFrequency(nodeProbabilities);
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/Suites.java	Tue Jun 11 17:45:31 2013 +0200
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/Suites.java	Tue Jun 11 18:13:55 2013 +0200
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.phases.tiers;
 
+import static com.oracle.graal.phases.tiers.Suites.Options.*;
+
 import java.util.*;
 
 import com.oracle.graal.graph.*;
@@ -30,10 +32,13 @@
 
 public final class Suites {
 
-    // @formatter:off
-    @Option(help = "The compiler configuration to use")
-    private static final OptionValue<String> CompilerConfiguration = new OptionValue<>("basic");
-    // @formatter:on
+    static class Options {
+
+        // @formatter:off
+        @Option(help = "The compiler configuration to use")
+        static final OptionValue<String> CompilerConfiguration = new OptionValue<>("basic");
+        // @formatter:on
+    }
 
     private final PhaseSuite<HighTierContext> highTier;
     private final PhaseSuite<MidTierContext> midTier;
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/SourceSection.java	Tue Jun 11 17:45:31 2013 +0200
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/SourceSection.java	Tue Jun 11 18:13:55 2013 +0200
@@ -23,7 +23,7 @@
 package com.oracle.truffle.api;
 
 /**
- * Represents a section in the source code of a guest language program.
+ * Represents a contiguous text section within the source code of a guest language program.
  */
 public class SourceSection {
 
@@ -35,13 +35,26 @@
     private final int charLength;
 
     /**
-     * Creates a new object representing a section in the source code of a guest language program.
+     * Creates a new object representing a contiguous text section within the source code of a guest
+     * language program.
+     * <p>
+     * The starting location of the section is specified using two different coordinate:
+     * <ul>
+     * <li><b>(row, column)</b>: rows and columns are 1-based, so the first character in a source
+     * file is at position {@code (1,1)}.</li>
+     * <li><b>character index</b>: 0-based offset of the character from the beginning of the source,
+     * so the first character in a file is at index {@code 0}.</li>
+     * </ul>
+     * The <b>newline</b> that terminates each line counts as a single character for the purpose of
+     * a character index. The (row,column) coordinates of a newline character should never appear in
+     * a text section.
+     * <p>
      * 
-     * @param source object representing the source program this is should be a section of
+     * @param source object representing the complete source program that contains this section
      * @param identifier an identifier used when printing the section
-     * @param startLine the index of the start line of the section
-     * @param startColumn the index of the start column of the section
-     * @param charIndex the index of the first character of the section
+     * @param startLine the 1-based number of the start line of the section
+     * @param startColumn the 1-based number of the start column of the section
+     * @param charIndex the 0-based index of the first character of the section
      * @param charLength the length of the section in number of characters
      */
     public SourceSection(Source source, String identifier, int startLine, int startColumn, int charIndex, int charLength) {
@@ -54,7 +67,7 @@
     }
 
     /**
-     * Returns the source object representing the source program this is a section of.
+     * Returns the object representing the source program that contains this section.
      * 
      * @return the source object
      */
@@ -63,38 +76,42 @@
     }
 
     /**
-     * Returns the index of the start line of this source section (inclusive).
+     * Returns 1-based line number of the first character in this source section (inclusive).
      * 
-     * @return the start line
+     * @return the starting line number
      */
     public final int getStartLine() {
         return startLine;
     }
 
     /**
-     * Returns the index of the start column of this source section (inclusive).
+     * Returns the 1-based column number of the first character in this source section (inclusive).
      * 
-     * @return the start column
+     * @return the starting column number
      */
     public final int getStartColumn() {
         return startColumn;
     }
 
     /**
-     * Returns the index of the first character of this section. All characters of the source can be
-     * retrieved via the {@link Source#getCode()} method.
+     * Returns the 0-based index of the first character in this source section.
+     * <p>
+     * The complete text of the source that contains this section can be retrieved via
+     * {@link Source#getCode()}.
      * 
-     * @return the character index
+     * @return the starting character index
      */
     public final int getCharIndex() {
         return charIndex;
     }
 
     /**
-     * Returns the length of this section in characters. All characters of the source can be
-     * retrieved via the {@link Source#getCode()} method.
+     * Returns the length of this source section in characters.
+     * <p>
+     * The complete text of the source that contains this section can be retrieved via
+     * {@link Source#getCode()}.
      * 
-     * @return the character length
+     * @return the number of characters in the section
      */
     public final int getCharLength() {
         return charLength;
@@ -110,7 +127,7 @@
     }
 
     /**
-     * Returns the code represented by this code section.
+     * Returns text of the code represented by this source section.
      * 
      * @return the code as a String object
      */
--- a/src/share/vm/graal/graalCompilerToVM.cpp	Tue Jun 11 17:45:31 2013 +0200
+++ b/src/share/vm/graal/graalCompilerToVM.cpp	Tue Jun 11 18:13:55 2013 +0200
@@ -591,11 +591,11 @@
 
   for (AllFieldStream fs(k()); !fs.done(); fs.next()) {
     if (!fs.access_flags().is_static()) {
-      Handle type = GraalCompiler::get_JavaTypeFromSignature(fs.signature(), k, Thread::current());
+      Handle type = GraalCompiler::get_JavaTypeFromSignature(fs.signature(), k, THREAD);
       int flags = fs.access_flags().as_int();
       bool internal = fs.access_flags().is_internal();
-      Handle name = java_lang_String::create_from_symbol(fs.name(), Thread::current());
-      Handle field = VMToCompiler::createJavaField(JNIHandles::resolve(klass), name, type, fs.offset(), flags, internal, Thread::current());
+      Handle name = java_lang_String::create_from_symbol(fs.name(), THREAD);
+      Handle field = VMToCompiler::createJavaField(JNIHandles::resolve(klass), name, type, fs.offset(), flags, internal, THREAD);
       fields.append(field());
     }
   }
@@ -603,7 +603,28 @@
   for (int i = 0; i < fields.length(); ++i) {
     field_array->obj_at_put(i, fields.at(i)());
   }
-  return JNIHandles::make_local(field_array());
+  return JNIHandles::make_local(THREAD, field_array());
+C2V_END
+
+C2V_VMENTRY(jobject, getMethods, (JNIEnv *, jobject, jobject klass))
+  ResourceMark rm;
+
+  instanceKlassHandle k(THREAD, java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(klass)));
+  Array<Method*>* methods = k->methods();
+  int methods_length = methods->length();
+
+  // Allocate result
+  objArrayOop r = oopFactory::new_objArray(SystemDictionary::HotSpotResolvedJavaMethod_klass(), methods_length, CHECK_NULL);
+  objArrayHandle result (THREAD, r);
+
+  for (int i = 0; i < methods_length; i++) {
+    methodHandle method(THREAD, methods->at(i));
+    Handle holder = JNIHandles::resolve(klass);
+    oop m = VMToCompiler::createResolvedJavaMethod(holder, method(), THREAD);
+    result->obj_at_put(i, m);
+  }
+
+  return JNIHandles::make_local(THREAD, result());
 C2V_END
 
 C2V_VMENTRY(jlong, getMaxCallTargetOffset, (JNIEnv *env, jobject, jlong addr))
@@ -738,8 +759,6 @@
   set_int("typeProfileWidth", TypeProfileWidth);
   set_int("methodProfileWidth", MethodProfileWidth);
 
-  set_int("interpreterProfilingThreshold", InvocationCounter::get_ProfileLimit());
-
   set_int("tlabAlignmentReserve", (int32_t)ThreadLocalAllocBuffer::alignment_reserve());
   set_long("tlabIntArrayMarkWord", (intptr_t)markOopDesc::prototype()->copy_set_hash(0x2));
   set_long("heapTopAddress", (jlong)(address) Universe::heap()->top_addr());
@@ -1209,6 +1228,7 @@
   {CC"lookupFieldInPool",             CC"("HS_RESOLVED_TYPE"IB)"FIELD,                                  FN_PTR(lookupFieldInPool)},
   {CC"resolveMethod",                 CC"("HS_RESOLVED_TYPE STRING STRING")"METHOD,                     FN_PTR(resolveMethod)},
   {CC"getInstanceFields",             CC"("HS_RESOLVED_TYPE")["HS_RESOLVED_FIELD,                       FN_PTR(getInstanceFields)},
+  {CC"getMethods",                    CC"("HS_RESOLVED_TYPE")["HS_RESOLVED_METHOD,                      FN_PTR(getMethods)},
   {CC"isTypeInitialized",             CC"("HS_RESOLVED_TYPE")Z",                                        FN_PTR(isTypeInitialized)},
   {CC"hasFinalizableSubclass",        CC"("HS_RESOLVED_TYPE")Z",                                        FN_PTR(hasFinalizableSubclass)},
   {CC"initializeType",                CC"("HS_RESOLVED_TYPE")V",                                        FN_PTR(initializeType)},
--- a/src/share/vm/interpreter/invocationCounter.hpp	Tue Jun 11 17:45:31 2013 +0200
+++ b/src/share/vm/interpreter/invocationCounter.hpp	Tue Jun 11 18:13:55 2013 +0200
@@ -95,9 +95,9 @@
   Action action() const                          { return _action[state()]; }
   int    count() const                           { return _counter >> number_of_noncount_bits; }
 
-  static int   get_InvocationLimit()             { return InterpreterInvocationLimit >> number_of_noncount_bits; }
-  static int   get_BackwardBranchLimit()         { return InterpreterBackwardBranchLimit >> number_of_noncount_bits; }
-  static int   get_ProfileLimit()                { return InterpreterProfileLimit >> number_of_noncount_bits; }
+  int   get_InvocationLimit() const              { return InterpreterInvocationLimit >> number_of_noncount_bits; }
+  int   get_BackwardBranchLimit() const          { return InterpreterBackwardBranchLimit >> number_of_noncount_bits; }
+  int   get_ProfileLimit() const                 { return InterpreterProfileLimit >> number_of_noncount_bits; }
 
   // Test counter using scaled limits like the asm interpreter would do rather than doing
   // the shifts to normalize the counter.