changeset 18691:3f38534e9a10

Merge
author Tom Rodriguez <tom.rodriguez@oracle.com>
date Mon, 15 Dec 2014 17:53:36 -0800
parents abcff66a23b0 (diff) 3f15de59df5e (current diff)
children d6c33eb93b9f
files
diffstat 7 files changed, 148 insertions(+), 68 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/TopLevelDebugConfig.java	Mon Dec 15 17:53:36 2014 -0800
@@ -0,0 +1,31 @@
+/*
+ * 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.oracle.graal.debug;
+
+/**
+ * A marker class for a scoped debug configuration covering a compilation region. Useful for
+ * programmatically enabling debug config features.
+ *
+ */
+public class TopLevelDebugConfig extends DelegatingDebugConfig {
+}
--- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/DebugScope.java	Mon Dec 15 17:00:11 2014 -0800
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/DebugScope.java	Mon Dec 15 17:53:36 2014 -0800
@@ -169,6 +169,58 @@
         return currentDumpLevel >= dumpLevel;
     }
 
+    /**
+     * Enable dumping at the new {@code dumpLevel} for remainder of compile. Requires a
+     * TopLevelDebugConfig
+     *
+     * @param dumpLevel
+     */
+    public static void setDumpLevel(int dumpLevel) {
+        TopLevelDebugConfig config = fetchTopLevelDebugConfig("setLogLevel");
+        if (config != null) {
+            config.override(DelegatingDebugConfig.Level.DUMP, dumpLevel);
+            recursiveUpdateFlags();
+        }
+    }
+
+    /**
+     * Enable logging at the new {@code logLevel} for remainder of compile. Requires a
+     * TopLevelDebugConfig
+     *
+     * @param logLevel
+     */
+    public static void setLogLevel(int logLevel) {
+        TopLevelDebugConfig config = fetchTopLevelDebugConfig("setLogLevel");
+        if (config != null) {
+            config.override(DelegatingDebugConfig.Level.LOG, logLevel);
+            config.delegate(DelegatingDebugConfig.Feature.LOG_METHOD);
+            recursiveUpdateFlags();
+        }
+    }
+
+    private static void recursiveUpdateFlags() {
+        DebugScope c = DebugScope.getInstance();
+        while (c != null) {
+            c.updateFlags();
+            c = c.parent;
+        }
+    }
+
+    private static TopLevelDebugConfig fetchTopLevelDebugConfig(String msg) {
+        DebugConfig config = getConfig();
+        if (config instanceof TopLevelDebugConfig) {
+            return (TopLevelDebugConfig) config;
+        } else {
+            PrintStream out = System.out;
+            if (config == null) {
+                out.printf("DebugScope.%s ignored because debugging is disabled%n", msg);
+            } else {
+                out.printf("DebugScope.%s ignored because top level delegate config missing%n", msg);
+            }
+            return null;
+        }
+    }
+
     public boolean isVerifyEnabled() {
         return verifyEnabled;
     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java	Mon Dec 15 17:00:11 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java	Mon Dec 15 17:53:36 2014 -0800
@@ -27,6 +27,7 @@
 import static com.oracle.graal.compiler.GraalCompiler.*;
 import static com.oracle.graal.compiler.common.GraalOptions.*;
 import static com.oracle.graal.compiler.common.UnsafeAccess.*;
+import static com.oracle.graal.debug.Debug.*;
 import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
 import static com.oracle.graal.hotspot.InitTimer.*;
 import static com.oracle.graal.hotspot.meta.HotSpotSuitesProvider.*;
@@ -365,7 +366,9 @@
     static void compileMethod(HotSpotResolvedJavaMethod method, int entryBCI, long ctask, int id) {
         HotSpotBackend backend = runtime().getHostBackend();
         CompilationTask task = new CompilationTask(backend, method, entryBCI, ctask, id, true);
-        task.runCompilation();
+        try (DebugConfigScope dcs = setConfig(new TopLevelDebugConfig())) {
+            task.runCompilation();
+        }
         return;
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneSnippets.java	Mon Dec 15 17:00:11 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneSnippets.java	Mon Dec 15 17:53:36 2014 -0800
@@ -114,7 +114,7 @@
 
     @Snippet(removeAllFrameStates = true)
     public static Object[] objectArrayClone(Object[] src) {
-        Object[] result = (Object[]) DynamicNewArrayNode.newUninitializedArray(GuardingPiNode.guardingNonNull(src.getClass().getComponentType()), src.length);
+        Object[] result = (Object[]) DynamicNewArrayNode.newUninitializedArray(GuardingPiNode.guardingNonNull(src.getClass().getComponentType()), src.length, Kind.Object);
         ArrayCopyCallNode.disjointUninitializedArraycopy(src, 0, result, 0, src.length, Kind.Object);
         return result;
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/DynamicNewArrayNode.java	Mon Dec 15 17:00:11 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/DynamicNewArrayNode.java	Mon Dec 15 17:53:36 2014 -0800
@@ -42,27 +42,38 @@
 
     @Input ValueNode elementType;
 
+    /**
+     * A non-null value indicating the worst case element type. Mainly useful for distinguishing
+     * Object arrays from primitive arrays.
+     */
+    protected final Kind knownElementKind;
+
     public static DynamicNewArrayNode create(ValueNode elementType, ValueNode length) {
         return new DynamicNewArrayNode(elementType, length);
     }
 
     protected DynamicNewArrayNode(ValueNode elementType, ValueNode length) {
-        this(elementType, length, true);
+        this(elementType, length, true, null);
     }
 
-    public static DynamicNewArrayNode create(ValueNode elementType, ValueNode length, boolean fillContents) {
-        return new DynamicNewArrayNode(elementType, length, fillContents);
+    public static DynamicNewArrayNode create(ValueNode elementType, ValueNode length, boolean fillContents, Kind knownElementKind) {
+        return new DynamicNewArrayNode(elementType, length, fillContents, knownElementKind);
     }
 
-    protected DynamicNewArrayNode(ValueNode elementType, ValueNode length, boolean fillContents) {
+    protected DynamicNewArrayNode(ValueNode elementType, ValueNode length, boolean fillContents, Kind knownElementKind) {
         super(StampFactory.objectNonNull(), length, fillContents);
         this.elementType = elementType;
+        this.knownElementKind = knownElementKind;
     }
 
     public ValueNode getElementType() {
         return elementType;
     }
 
+    public Kind getKnownElementKind() {
+        return knownElementKind;
+    }
+
     protected NewArrayNode forConstantType(ResolvedJavaType type) {
         ValueNode len = length();
         NewArrayNode ret = graph().add(NewArrayNode.create(type, len.isAlive() ? len : graph().addOrUniqueWithInputs(len), fillContents()));
@@ -94,10 +105,10 @@
     }
 
     @NodeIntrinsic
-    private static native Object newArray(Class<?> componentType, int length, @ConstantNodeParameter boolean fillContents);
+    private static native Object newArray(Class<?> componentType, int length, @ConstantNodeParameter boolean fillContents, @ConstantNodeParameter Kind knownElementKind);
 
-    public static Object newUninitializedArray(Class<?> componentType, int length) {
-        return newArray(componentType, length, false);
+    public static Object newUninitializedArray(Class<?> componentType, int length, Kind knownElementKind) {
+        return newArray(componentType, length, false, knownElementKind);
     }
 
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java	Mon Dec 15 17:00:11 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java	Mon Dec 15 17:53:36 2014 -0800
@@ -112,20 +112,52 @@
             }
 
             // check if the type of the receiver can narrow the result
-            if (tryToResolveMethod(tool)) {
-                return;
+            ValueNode receiver = receiver();
+            ResolvedJavaType type = StampTool.typeOrNull(receiver);
+            if (type == null && invokeKind == InvokeKind.Virtual) {
+                // For virtual calls, we are guaranteed to receive a correct receiver type.
+                type = targetMethod.getDeclaringClass();
             }
+            if (type != null && (invoke().stateAfter() != null || invoke().stateDuring() != null)) {
+                /*
+                 * either the holder class is exact, or the receiver object has an exact type, or
+                 * it's an array type
+                 */
+                ResolvedJavaMethod resolvedMethod = type.resolveConcreteMethod(targetMethod(), invoke().getContextType());
+                if (resolvedMethod != null && (resolvedMethod.canBeStaticallyBound() || StampTool.isExactType(receiver) || type.isArray())) {
+                    setInvokeKind(InvokeKind.Special);
+                    setTargetMethod(resolvedMethod);
+                    return;
+                }
+                if (tool.assumptions() != null && tool.assumptions().useOptimisticAssumptions()) {
+                    ResolvedJavaType uniqueConcreteType = type.findUniqueConcreteSubtype();
+                    if (uniqueConcreteType != null) {
+                        ResolvedJavaMethod methodFromUniqueType = uniqueConcreteType.resolveConcreteMethod(targetMethod(), invoke().getContextType());
+                        if (methodFromUniqueType != null) {
+                            tool.assumptions().recordConcreteSubtype(type, uniqueConcreteType);
+                            setInvokeKind(InvokeKind.Special);
+                            setTargetMethod(methodFromUniqueType);
+                            return;
+                        }
+                    }
 
-            ValueNode receiver = receiver();
-
-            // try to turn an interface call into a virtual call
+                    ResolvedJavaMethod uniqueConcreteMethod = type.findUniqueConcreteMethod(targetMethod());
+                    if (uniqueConcreteMethod != null) {
+                        tool.assumptions().recordConcreteMethod(targetMethod(), type, uniqueConcreteMethod);
+                        setInvokeKind(InvokeKind.Special);
+                        setTargetMethod(uniqueConcreteMethod);
+                        return;
+                    }
+                }
+            }
+            // try to turn a interface call into a virtual call
             ResolvedJavaType declaredReceiverType = targetMethod().getDeclaringClass();
             /*
              * We need to check the invoke kind to avoid recursive simplification for virtual
              * interface methods calls.
              */
             if (declaredReceiverType.isInterface() && !invokeKind().equals(InvokeKind.Virtual)) {
-                tryCheckCastSingleImplementor(tool, receiver, declaredReceiverType);
+                tryCheckCastSingleImplementor(receiver, declaredReceiverType);
             }
 
             if (invokeKind().equals(InvokeKind.Interface) && receiver instanceof UncheckedInterfaceProvider) {
@@ -134,62 +166,14 @@
                 if (uncheckedStamp != null) {
                     ResolvedJavaType uncheckedReceiverType = StampTool.typeOrNull(uncheckedStamp);
                     if (uncheckedReceiverType.isInterface()) {
-                        tryCheckCastSingleImplementor(tool, receiver, uncheckedReceiverType);
+                        tryCheckCastSingleImplementor(receiver, uncheckedReceiverType);
                     }
                 }
             }
         }
     }
 
-    /**
-     * Try to use receiver type information to statically bind the method.
-     *
-     * @param tool
-     * @return true if successfully converted to InvokeKind.Special
-     */
-    private boolean tryToResolveMethod(SimplifierTool tool) {
-        ValueNode receiver = receiver();
-        ResolvedJavaType type = StampTool.typeOrNull(receiver);
-        if (type == null && invokeKind == InvokeKind.Virtual) {
-            // For virtual calls, we are guaranteed to receive a correct receiver type.
-            type = targetMethod.getDeclaringClass();
-        }
-        if (type != null && (invoke().stateAfter() != null || invoke().stateDuring() != null)) {
-            /*
-             * either the holder class is exact, or the receiver object has an exact type, or it's
-             * an array type
-             */
-            ResolvedJavaMethod resolvedMethod = type.resolveConcreteMethod(targetMethod(), invoke().getContextType());
-            if (resolvedMethod != null && (resolvedMethod.canBeStaticallyBound() || StampTool.isExactType(receiver) || type.isArray())) {
-                setInvokeKind(InvokeKind.Special);
-                setTargetMethod(resolvedMethod);
-                return true;
-            }
-            if (tool.assumptions() != null && tool.assumptions().useOptimisticAssumptions()) {
-                ResolvedJavaType uniqueConcreteType = type.findUniqueConcreteSubtype();
-                if (uniqueConcreteType != null) {
-                    ResolvedJavaMethod methodFromUniqueType = uniqueConcreteType.resolveConcreteMethod(targetMethod(), invoke().getContextType());
-                    if (methodFromUniqueType != null) {
-                        tool.assumptions().recordConcreteSubtype(type, uniqueConcreteType);
-                        setInvokeKind(InvokeKind.Special);
-                        setTargetMethod(methodFromUniqueType);
-                        return true;
-                    }
-                }
-
-                ResolvedJavaMethod uniqueConcreteMethod = type.findUniqueConcreteMethod(targetMethod());
-                if (uniqueConcreteMethod != null) {
-                    tool.assumptions().recordConcreteMethod(targetMethod(), type, uniqueConcreteMethod);
-                    setInvokeKind(InvokeKind.Special);
-                    setTargetMethod(uniqueConcreteMethod);
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    private void tryCheckCastSingleImplementor(SimplifierTool tool, ValueNode receiver, ResolvedJavaType declaredReceiverType) {
+    private void tryCheckCastSingleImplementor(ValueNode receiver, ResolvedJavaType declaredReceiverType) {
         ResolvedJavaType singleImplementor = declaredReceiverType.getSingleImplementor();
         if (singleImplementor != null && !singleImplementor.equals(declaredReceiverType)) {
             ResolvedJavaMethod singleImplementorMethod = singleImplementor.resolveMethod(targetMethod(), invoke().getContextType(), true);
@@ -214,8 +198,6 @@
                 arguments().set(0, piNode);
                 setInvokeKind(InvokeKind.Virtual);
                 setTargetMethod(singleImplementorMethod);
-                // Now try to bind the method exactly.
-                tryToResolveMethod(tool);
             }
         }
     }
--- a/src/share/vm/compiler/compilerOracle.cpp	Mon Dec 15 17:00:11 2014 -0800
+++ b/src/share/vm/compiler/compilerOracle.cpp	Mon Dec 15 17:53:36 2014 -0800
@@ -397,7 +397,8 @@
   int match = MethodMatcher::Exact;
   while (name[0] == '*') {
     match |= MethodMatcher::Suffix;
-    strcpy(name, name + 1);
+    // Copy remaining string plus NUL to the beginning
+    memcpy(name, name + 1, strlen(name + 1) + 1);
   }
 
   if (strcmp(name, "*") == 0) return MethodMatcher::Any;