changeset 9480:d9fd6af5d200

Merge
author Christian Wimmer <christian.wimmer@oracle.com>
date Wed, 01 May 2013 10:01:17 -0700
parents fd2e12d41d18 (diff) e4e2686f30df (current diff)
children 1964cf13c376
files graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java
diffstat 10 files changed, 76 insertions(+), 25 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaUtil.java	Wed May 01 18:04:28 2013 +0200
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaUtil.java	Wed May 01 10:01:17 2013 -0700
@@ -162,6 +162,13 @@
         return (type == null) ? null : internalNameToJava(type.getName(), true, false);
     }
 
+    /**
+     * Returns the type name in the same format as {@link Class#getName()}.
+     */
+    public static String toClassName(JavaType type) {
+        return internalNameToJava(type.getName(), true, true);
+    }
+
     private static String internalNameToJava(String name, boolean qualified, boolean classForNameCompatible) {
         switch (name.charAt(0)) {
             case 'L': {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Wed May 01 18:04:28 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Wed May 01 10:01:17 2013 -0700
@@ -722,7 +722,7 @@
                 if (arrayType != null && array.objectStamp().isExactType()) {
                     ResolvedJavaType elementType = arrayType.getComponentType();
                     if (!MetaUtil.isJavaLangObject(elementType)) {
-                        CheckCastNode checkcast = graph.add(new CheckCastNode(elementType, value, null));
+                        CheckCastNode checkcast = graph.add(new CheckCastNode(elementType, value, null, true));
                         graph.addBeforeFixed(storeIndexed, checkcast);
                         value = checkcast;
                     }
@@ -730,7 +730,7 @@
                     LoadHubNode arrayClass = graph.add(new LoadHubNode(array, wordKind));
                     LocationNode location = ConstantLocationNode.create(LocationNode.FINAL_LOCATION, wordKind, config.arrayClassElementOffset, graph);
                     FloatingReadNode arrayElementKlass = graph.unique(new FloatingReadNode(arrayClass, location, null, StampFactory.forKind(wordKind())));
-                    CheckCastDynamicNode checkcast = graph.add(new CheckCastDynamicNode(arrayElementKlass, value));
+                    CheckCastDynamicNode checkcast = graph.add(new CheckCastDynamicNode(arrayElementKlass, value, true));
                     graph.addBeforeFixed(storeIndexed, checkcast);
                     graph.addBeforeFixed(checkcast, arrayClass);
                     value = checkcast;
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Wed May 01 18:04:28 2013 +0200
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Wed May 01 10:01:17 2013 -0700
@@ -803,7 +803,7 @@
         ValueNode object = frameState.apop();
         if (type instanceof ResolvedJavaType) {
             JavaTypeProfile profileForTypeCheck = getProfileForTypeCheck((ResolvedJavaType) type);
-            CheckCastNode checkCast = currentGraph.add(new CheckCastNode((ResolvedJavaType) type, object, profileForTypeCheck));
+            CheckCastNode checkCast = currentGraph.add(new CheckCastNode((ResolvedJavaType) type, object, profileForTypeCheck, false));
             append(checkCast);
             frameState.apush(checkCast);
         } else {
@@ -1661,7 +1661,7 @@
         if (typeInstruction != null) {
             Block nextBlock = block.successors.size() == 1 ? unwindBlock(block.deoptBci) : block.successors.get(1);
             ValueNode exception = frameState.stackAt(0);
-            CheckCastNode checkCast = currentGraph.add(new CheckCastNode((ResolvedJavaType) catchType, exception, null));
+            CheckCastNode checkCast = currentGraph.add(new CheckCastNode((ResolvedJavaType) catchType, exception, null, false));
             frameState.apop();
             frameState.push(Kind.Object, checkCast);
             FixedNode catchSuccessor = createTarget(block.successors.get(0), frameState);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java	Wed May 01 18:04:28 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java	Wed May 01 10:01:17 2013 -0700
@@ -90,7 +90,7 @@
     }
 
     @NodeIntrinsic
-    public static native void writeMemory(Object object, Object value, Object location, @ConstantNodeParameter boolean usePreciseWriteBarriers);
+    public static native void writeMemory(Object object, Object value, Object location, @ConstantNodeParameter WriteBarrierType barrierType);
 
     @Override
     public Object[] getLocationIdentities() {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastDynamicNode.java	Wed May 01 18:04:28 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastDynamicNode.java	Wed May 01 10:01:17 2013 -0700
@@ -22,6 +22,7 @@
  */
 package com.oracle.graal.nodes.java;
 
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
@@ -37,13 +38,27 @@
     @Input private ValueNode type;
 
     /**
+     * Determines the exception thrown by this node if the check fails: {@link ClassCastException}
+     * if false; {@link ArrayStoreException} if true.
+     */
+    private final boolean forStoreCheck;
+
+    /**
      * @param type the type being cast to
      * @param object the instruction producing the object
      */
-    public CheckCastDynamicNode(ValueNode type, ValueNode object) {
+    public CheckCastDynamicNode(ValueNode type, ValueNode object, boolean forStoreCheck) {
         super(object.stamp());
         this.type = type;
         this.object = object;
+        this.forStoreCheck = forStoreCheck;
+        assert type.kind() == Kind.Object;
+        assert type.objectStamp().isExactType();
+        assert type.objectStamp().type().getName().equals("Ljava/lang/Class;");
+    }
+
+    public boolean isForStoreCheck() {
+        return forStoreCheck;
     }
 
     @Override
@@ -67,6 +82,11 @@
         if (object().objectStamp().alwaysNull()) {
             return object();
         }
+        if (type().isConstant()) {
+            Class clazz = (Class) type().asConstant().asObject();
+            ResolvedJavaType t = tool.runtime().lookupJavaType(clazz);
+            return graph().add(new CheckCastNode(t, object(), null, forStoreCheck));
+        }
         return this;
     }
 
@@ -80,4 +100,7 @@
     public ValueNode type() {
         return type;
     }
+
+    @NodeIntrinsic
+    public static native <T> T checkCastDynamic(Class<T> type, Object object, @ConstantNodeParameter boolean forStoreCheck);
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java	Wed May 01 18:04:28 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java	Wed May 01 10:01:17 2013 -0700
@@ -38,17 +38,28 @@
     private final JavaTypeProfile profile;
 
     /**
+     * Determines the exception thrown by this node if the check fails: {@link ClassCastException}
+     * if false; {@link ArrayStoreException} if true.
+     */
+    private final boolean forStoreCheck;
+
+    /**
      * Creates a new CheckCast instruction.
      * 
      * @param type the type being cast to
      * @param object the instruction producing the object
      */
-    public CheckCastNode(ResolvedJavaType type, ValueNode object, JavaTypeProfile profile) {
+    public CheckCastNode(ResolvedJavaType type, ValueNode object, JavaTypeProfile profile, boolean forStoreCheck) {
         super(StampFactory.declared(type));
         assert type != null;
         this.type = type;
         this.object = object;
         this.profile = profile;
+        this.forStoreCheck = forStoreCheck;
+    }
+
+    public boolean isForStoreCheck() {
+        return forStoreCheck;
     }
 
     @Override
@@ -68,26 +79,31 @@
     public ValueNode canonical(CanonicalizerTool tool) {
         assert object() != null : this;
 
-        if (type != null) {
-            ResolvedJavaType objectType = object().objectStamp().type();
-            if (objectType != null && type.isAssignableFrom(objectType)) {
-                // we don't have to check for null types here because they will also pass the
-                // checkcast.
+        ResolvedJavaType objectType = object().objectStamp().type();
+        if (objectType != null && type.isAssignableFrom(objectType)) {
+            // we don't have to check for null types here because they will also pass the
+            // checkcast.
+            return object();
+        }
+        // remove checkcast if the only usage is a more specific checkcast
+        if (usages().count() == 1) {
+            CheckCastNode ccn = usages().filter(CheckCastNode.class).first();
+            if (ccn != null && ccn.type() != null && type.isAssignableFrom(ccn.type())) {
                 return object();
             }
-
-            // remove checkcast if the only usage is a more specific checkcast
-            if (usages().count() == 1) {
-                CheckCastNode ccn = usages().filter(CheckCastNode.class).first();
-                if (ccn != null && ccn.type() != null && type.isAssignableFrom(ccn.type())) {
-                    return object();
-                }
-            }
         }
 
         if (object().objectStamp().alwaysNull()) {
             return object();
         }
+        if (tool.assumptions().useOptimisticAssumptions()) {
+            ResolvedJavaType exactType = type.findUniqueConcreteSubtype();
+            if (exactType != null && exactType != type) {
+                // Propagate more precise type information to usages of the checkcast.
+                tool.assumptions().recordConcreteSubtype(type, exactType);
+                return graph().add(new CheckCastNode(exactType, object, profile, forStoreCheck));
+            }
+        }
 
         return this;
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadIndexedNode.java	Wed May 01 18:04:28 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadIndexedNode.java	Wed May 01 10:01:17 2013 -0700
@@ -53,6 +53,11 @@
     }
 
     @Override
+    public boolean inferStamp() {
+        return updateStamp(createStamp(array(), elementKind()));
+    }
+
+    @Override
     public void virtualize(VirtualizerTool tool) {
         State arrayState = tool.getObjectState(array());
         if (arrayState != null && arrayState.getState() == EscapeState.Virtual) {
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/CheckCastTest.java	Wed May 01 18:04:28 2013 +0200
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/CheckCastTest.java	Wed May 01 10:01:17 2013 -0700
@@ -22,7 +22,6 @@
  */
 package com.oracle.graal.replacements.test;
 
-
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.test.*;
 import com.oracle.graal.nodes.*;
@@ -37,7 +36,7 @@
     protected void replaceProfile(StructuredGraph graph, JavaTypeProfile profile) {
         CheckCastNode ccn = graph.getNodes(CheckCastNode.class).first();
         if (ccn != null) {
-            CheckCastNode ccnNew = graph.add(new CheckCastNode(ccn.type(), ccn.object(), profile));
+            CheckCastNode ccnNew = graph.add(new CheckCastNode(ccn.type(), ccn.object(), profile, false));
             graph.replaceFixedWithFixed(ccn, ccnNew);
         }
     }
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java	Wed May 01 18:04:28 2013 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java	Wed May 01 10:01:17 2013 -0700
@@ -366,9 +366,10 @@
                     afterInline(graph, originalGraph);
                     substituteCallsOriginal = true;
                 } else {
-                    if ((callTarget.invokeKind() == InvokeKind.Static || callTarget.invokeKind() == InvokeKind.Special) && policy.shouldInline(callee, methodToParse)) {
+                    StructuredGraph intrinsicGraph = InliningUtil.getIntrinsicGraph(ReplacementsImpl.this, callee);
+                    if ((callTarget.invokeKind() == InvokeKind.Static || callTarget.invokeKind() == InvokeKind.Special) &&
+                                    (policy.shouldInline(callee, methodToParse) || (intrinsicGraph != null && policy.shouldUseReplacement(callee, methodToParse)))) {
                         StructuredGraph targetGraph;
-                        StructuredGraph intrinsicGraph = InliningUtil.getIntrinsicGraph(ReplacementsImpl.this, callee);
                         if (intrinsicGraph != null && policy.shouldUseReplacement(callee, methodToParse)) {
                             targetGraph = intrinsicGraph;
                         } else {
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java	Wed May 01 18:04:28 2013 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java	Wed May 01 10:01:17 2013 -0700
@@ -440,7 +440,7 @@
                 if (loopBegin != null) {
                     LoopEx loop = new LoopsData(snippetCopy).loop(loopBegin);
                     int mark = snippetCopy.getMark();
-                    LoopTransformations.fullUnroll(loop, runtime, null);
+                    LoopTransformations.fullUnroll(loop, runtime, replacements.getAssumptions());
                     new CanonicalizerPhase.Instance(runtime, replacements.getAssumptions(), mark, null).apply(snippetCopy);
                 }
                 FixedNode explodeLoopNext = explodeLoop.next();