changeset 9619:5e3c8dd80632

Merge.
author Doug Simon <doug.simon@oracle.com>
date Wed, 08 May 2013 21:09:38 +0200
parents bd4a7d657dcc (current diff) ae17e540c5d2 (diff)
children 0eda2b7df748
files graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java
diffstat 11 files changed, 74 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaMethod.java	Wed May 08 21:05:39 2013 +0200
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaMethod.java	Wed May 08 21:09:38 2013 +0200
@@ -208,4 +208,11 @@
      * @return a constant representing a reference to this method
      */
     Constant getEncoding();
+
+    /**
+     * Checks if this method is present in the virtual table.
+     * 
+     * @return true is this method is present in the virtual table
+     */
+    boolean isInVirtualMethodTable();
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java	Wed May 08 21:05:39 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java	Wed May 08 21:09:38 2013 +0200
@@ -210,6 +210,8 @@
 
     int getVtableEntryOffset(long metaspaceMethod);
 
+    boolean hasVtableEntry(long metaspaceMethod);
+
     long[] getDeoptedLeafGraphIds();
 
     long[] getLineNumberTable(HotSpotResolvedJavaMethod method);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java	Wed May 08 21:05:39 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java	Wed May 08 21:09:38 2013 +0200
@@ -145,6 +145,9 @@
     public native int getVtableEntryOffset(long metaspaceMethod);
 
     @Override
+    public native boolean hasVtableEntry(long metaspaceMethod);
+
+    @Override
     public native long[] getDeoptedLeafGraphIds();
 
     @Override
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java	Wed May 08 21:05:39 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java	Wed May 08 21:09:38 2013 +0200
@@ -383,7 +383,8 @@
 
     /**
      * Returns the offset of this method into the v-table. If the holder is not initialized, returns
-     * -1
+     * -1. If it is initialized the method must have a v-table entry has indicated by
+     * {@link #hasVtableEntry()}.
      * 
      * @return the offset of this method into the v-table
      */
@@ -394,6 +395,10 @@
         return graalRuntime().getCompilerToVM().getVtableEntryOffset(metaspaceMethod);
     }
 
+    public boolean hasVtableEntry() {
+        return graalRuntime().getCompilerToVM().hasVtableEntry(metaspaceMethod);
+    }
+
     public void setCurrentTask(CompilationTask task) {
         currentTask = task;
     }
@@ -455,4 +460,9 @@
             throw new IllegalArgumentException(ex);
         }
     }
+
+    @Override
+    public boolean isInVirtualMethodTable() {
+        return hasVtableEntry();
+    }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Wed May 08 21:05:39 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Wed May 08 21:09:38 2013 +0200
@@ -772,8 +772,8 @@
 
                     HotSpotResolvedJavaMethod hsMethod = (HotSpotResolvedJavaMethod) callTarget.targetMethod();
                     if (!hsMethod.getDeclaringClass().isInterface()) {
-                        int vtableEntryOffset = hsMethod.vtableEntryOffset();
-                        if (vtableEntryOffset > 0) {
+                        if (hsMethod.hasVtableEntry()) {
+                            int vtableEntryOffset = hsMethod.vtableEntryOffset();
                             assert vtableEntryOffset > 0;
                             ReadNode hub = this.createReadHub(tool, graph, wordKind, receiver);
                             ReadNode metaspaceMethod = createReadVirtualMethod(graph, wordKind, hub, hsMethod);
@@ -1048,6 +1048,7 @@
     private static ReadNode createReadVirtualMethod(StructuredGraph graph, Kind wordKind, ValueNode hub, ResolvedJavaMethod method) {
         HotSpotResolvedJavaMethod hsMethod = (HotSpotResolvedJavaMethod) method;
         assert !hsMethod.getDeclaringClass().isInterface();
+        assert hsMethod.hasVtableEntry();
 
         int vtableEntryOffset = hsMethod.vtableEntryOffset();
         assert vtableEntryOffset > 0;
@@ -1107,11 +1108,11 @@
         return barrierType;
     }
 
-    private static ConstantLocationNode createFieldLocation(StructuredGraph graph, HotSpotResolvedJavaField field) {
+    protected static ConstantLocationNode createFieldLocation(StructuredGraph graph, HotSpotResolvedJavaField field) {
         return ConstantLocationNode.create(field, field.getKind(), field.offset(), graph);
     }
 
-    private IndexedLocationNode createArrayLocation(Graph graph, Kind elementKind, ValueNode index) {
+    protected IndexedLocationNode createArrayLocation(Graph graph, Kind elementKind, ValueNode index) {
         int scale = this.graalRuntime.getTarget().arch.getSizeInBytes(elementKind);
         return IndexedLocationNode.create(LocationNode.getArrayLocation(elementKind), elementKind, getArrayBaseOffset(elementKind), index, graph, scale);
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ObjectEqualsNode.java	Wed May 08 21:05:39 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ObjectEqualsNode.java	Wed May 08 21:09:38 2013 +0200
@@ -70,6 +70,26 @@
         return super.canonical(tool);
     }
 
+    private void virtualizeNonVirtualComparison(State state, ValueNode other, VirtualizerTool tool) {
+        if (!state.getVirtualObject().hasIdentity() && state.getVirtualObject().entryKind(0) == Kind.Boolean) {
+            if (other.isConstant()) {
+                int expectedValue = ((Boolean) other.asConstant().asObject()) ? 1 : 0;
+                final IntegerEqualsNode equals = new IntegerEqualsNode(state.getEntry(0), ConstantNode.forInt(expectedValue, graph()));
+                tool.customAction(new Runnable() {
+
+                    @Override
+                    public void run() {
+                        graph().add(equals);
+                    }
+                });
+                tool.replaceWithValue(equals);
+            }
+        } else {
+            // one of them is virtual: they can never be the same objects
+            tool.replaceWithValue(LogicConstantNode.contradiction(graph()));
+        }
+    }
+
     @Override
     public void virtualize(VirtualizerTool tool) {
         State stateX = tool.getObjectState(x());
@@ -78,15 +98,9 @@
         boolean yVirtual = stateY != null && stateY.getState() == EscapeState.Virtual;
 
         if (xVirtual && !yVirtual) {
-            if (stateX.getVirtualObject().hasIdentity()) {
-                // one of them is virtual: they can never be the same objects
-                tool.replaceWithValue(LogicConstantNode.contradiction(graph()));
-            }
+            virtualizeNonVirtualComparison(stateX, stateY != null ? stateY.getMaterializedValue() : y(), tool);
         } else if (!xVirtual && yVirtual) {
-            if (stateY.getVirtualObject().hasIdentity()) {
-                // one of them is virtual: they can never be the same objects
-                tool.replaceWithValue(LogicConstantNode.contradiction(graph()));
-            }
+            virtualizeNonVirtualComparison(stateY, stateX != null ? stateX.getMaterializedValue() : x(), tool);
         } else if (xVirtual && yVirtual) {
             boolean xIdentity = stateX.getVirtualObject().hasIdentity();
             boolean yIdentity = stateY.getVirtualObject().hasIdentity();
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/ControlFlowGraph.java	Wed May 08 21:05:39 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/ControlFlowGraph.java	Wed May 08 21:09:38 2013 +0200
@@ -53,7 +53,7 @@
             cfg.computePostdominators();
         }
         // there's not much to verify when connectBlocks == false
-        assert !connectBlocks || CFGVerifier.verify(cfg);
+        assert !(connectBlocks || computeLoops || computeDominators || computePostdominators) || CFGVerifier.verify(cfg);
         return cfg;
     }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadMethodNode.java	Wed May 08 21:05:39 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadMethodNode.java	Wed May 08 21:09:38 2013 +0200
@@ -47,6 +47,7 @@
         this.method = method;
         assert !Modifier.isAbstract(method.getModifiers()) : "Cannot load abstract method from a hub";
         assert !Modifier.isStatic(method.getModifiers()) : "Cannot load a static method from a hub";
+        assert method.isInVirtualMethodTable();
     }
 
     @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeArrayCastNode.java	Wed May 08 21:05:39 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeArrayCastNode.java	Wed May 08 21:09:38 2013 +0200
@@ -37,6 +37,11 @@
         return length;
     }
 
+    public UnsafeArrayCastNode(ValueNode object, ValueNode length, Stamp stamp) {
+        super(object, stamp);
+        this.length = length;
+    }
+
     public UnsafeArrayCastNode(ValueNode object, ValueNode length, Stamp stamp, ValueNode anchor) {
         super(object, stamp, anchor);
         this.length = length;
@@ -51,5 +56,8 @@
     }
 
     @NodeIntrinsic
+    public static native <T> T unsafeArrayCast(Object object, int length, @ConstantNodeParameter Stamp stamp);
+
+    @NodeIntrinsic
     public static native <T> T unsafeArrayCast(Object object, int length, @ConstantNodeParameter Stamp stamp, Object anchor);
 }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java	Wed May 08 21:05:39 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java	Wed May 08 21:09:38 2013 +0200
@@ -640,7 +640,6 @@
                 assert concretes.size() > 0;
                 Debug.log("Method check cascade with %d methods", concretes.size());
 
-                LoadMethodNode[] methods = new LoadMethodNode[concretes.size()];
                 ValueNode[] constantMethods = new ValueNode[concretes.size()];
                 double[] probability = new double[concretes.size()];
                 for (int i = 0; i < concretes.size(); ++i) {
@@ -665,8 +664,7 @@
                 FixedNode lastSucc = successors[concretes.size()];
                 for (int i = concretes.size() - 1; i >= 0; --i) {
                     LoadMethodNode method = graph.add(new LoadMethodNode(concretes.get(i), hub, constantMethods[i].kind()));
-                    methods[i] = method;
-                    CompareNode methodCheck = CompareNode.createCompareNode(Condition.EQ, methods[i], constantMethods[i]);
+                    CompareNode methodCheck = CompareNode.createCompareNode(Condition.EQ, method, constantMethods[i]);
                     IfNode ifNode = graph.add(new IfNode(methodCheck, successors[i], lastSucc, probability[i]));
                     method.setNext(ifNode);
                     lastSucc = method;
@@ -698,6 +696,12 @@
         }
 
         private boolean chooseMethodDispatch() {
+            for (ResolvedJavaMethod concrete : concretes) {
+                if (!concrete.isInVirtualMethodTable()) {
+                    return false;
+                }
+            }
+
             if (concretes.size() == 1 && this.notRecordedTypeProbability > 0) {
                 // Always chose method dispatch if there is a single concrete method and the call
                 // site is megamorphic.
--- a/src/share/vm/graal/graalCompilerToVM.cpp	Wed May 08 21:05:39 2013 +0200
+++ b/src/share/vm/graal/graalCompilerToVM.cpp	Wed May 08 21:09:38 2013 +0200
@@ -1001,6 +1001,7 @@
   Method* method = asMethod(metaspace_method);
   assert(!InstanceKlass::cast(method->method_holder())->is_interface(), "vtableEntryOffset cannot be called for interface methods");
   assert(InstanceKlass::cast(method->method_holder())->is_linked(), "vtableEntryOffset cannot be called is holder is not linked");
+  assert(method->vtable_index() >= 0, "vtable entry offset should not be used");
 
   // get entry offset in words
   int vtable_entry_offset = InstanceKlass::vtable_start_offset() + method->vtable_index() * vtableEntry::size();
@@ -1010,6 +1011,11 @@
   return vtable_entry_offset;
 C2V_END
 
+C2V_VMENTRY(jboolean, hasVtableEntry, (JNIEnv *, jobject, jlong metaspace_method))
+  Method* method = asMethod(metaspace_method);
+  return method->vtable_index() >= 0;
+C2V_END
+
 C2V_VMENTRY(jobject, getDeoptedLeafGraphIds, (JNIEnv *, jobject))
 
   // the contract for this method is as follows:
@@ -1177,6 +1183,7 @@
   {CC"getInvocationCount",            CC"("METASPACE_METHOD")I",                                        FN_PTR(getInvocationCount)},
   {CC"getCompiledCodeSize",           CC"("METASPACE_METHOD")I",                                        FN_PTR(getCompiledCodeSize)},
   {CC"getVtableEntryOffset",          CC"("METASPACE_METHOD")I",                                        FN_PTR(getVtableEntryOffset)},
+  {CC"hasVtableEntry",                CC"("METASPACE_METHOD")Z",                                        FN_PTR(hasVtableEntry)},
   {CC"constantPoolLength",            CC"("HS_RESOLVED_TYPE")I",                                        FN_PTR(constantPoolLength)},
   {CC"lookupType",                    CC"("STRING HS_RESOLVED_TYPE"Z)"TYPE,                             FN_PTR(lookupType)},
   {CC"lookupConstantInPool",          CC"("HS_RESOLVED_TYPE"I)"OBJECT,                                  FN_PTR(lookupConstantInPool)},