changeset 18950:3fc907b46313

[SPARC] Fix Partial Escape Analysis for SPARC in Truffle
author Stefan Anzinger <stefan.anzinger@oracle.com>
date Mon, 26 Jan 2015 21:21:06 +0100
parents 886cf229e5ee
children 568baf3550d3
files graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaType.java graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushNodesThroughPiTest.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectTypeImpl.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedPrimitiveType.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeAccessNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeLoadNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreFieldNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreIndexedNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualArrayNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualInstanceNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualObjectNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/FrameWithoutBoxing.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeLoadFinalNode.java src/share/vm/graal/graalCodeInstaller.cpp
diffstat 18 files changed, 69 insertions(+), 44 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaType.java	Mon Jan 26 21:19:36 2015 +0100
+++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaType.java	Mon Jan 26 21:21:06 2015 +0100
@@ -54,7 +54,7 @@
                 ResolvedJavaField rf = lookupField(type.getInstanceFields(true), f);
                 assertNotNull(rf);
                 long offset = isStatic(f.getModifiers()) ? unsafe.staticFieldOffset(f) : unsafe.objectFieldOffset(f);
-                ResolvedJavaField result = type.findInstanceFieldWithOffset(offset);
+                ResolvedJavaField result = type.findInstanceFieldWithOffset(offset, rf.getKind());
                 assertNotNull(result);
                 assertTrue(fieldsEqual(f, result));
             }
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java	Mon Jan 26 21:19:36 2015 +0100
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java	Mon Jan 26 21:21:06 2015 +0100
@@ -298,7 +298,7 @@
      * @param offset the offset of the field to look for
      * @return the field with the given offset, or {@code null} if there is no such field.
      */
-    ResolvedJavaField findInstanceFieldWithOffset(long offset);
+    ResolvedJavaField findInstanceFieldWithOffset(long offset, Kind expectedKind);
 
     /**
      * Returns name of source file of this type.
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushNodesThroughPiTest.java	Mon Jan 26 21:19:36 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushNodesThroughPiTest.java	Mon Jan 26 21:21:06 2015 +0100
@@ -73,7 +73,7 @@
                 if (rn.location() instanceof ConstantLocationNode && rn.object().stamp() instanceof ObjectStamp) {
                     long disp = ((ConstantLocationNode) rn.location()).getDisplacement();
                     ResolvedJavaType receiverType = StampTool.typeOrNull(rn.object());
-                    ResolvedJavaField field = receiverType.findInstanceFieldWithOffset(disp);
+                    ResolvedJavaField field = receiverType.findInstanceFieldWithOffset(disp, rn.getKind());
 
                     assert field != null : "Node " + rn + " tries to access a field which doesn't exists for this type";
                     if (field.getName().equals("x")) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectTypeImpl.java	Mon Jan 26 21:19:36 2015 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectTypeImpl.java	Mon Jan 26 21:21:06 2015 +0100
@@ -29,6 +29,7 @@
 import java.lang.annotation.*;
 import java.lang.reflect.*;
 import java.net.*;
+import java.nio.*;
 import java.util.*;
 
 import com.oracle.graal.api.meta.*;
@@ -788,12 +789,24 @@
     }
 
     @Override
-    public ResolvedJavaField findInstanceFieldWithOffset(long offset) {
+    public ResolvedJavaField findInstanceFieldWithOffset(long offset, Kind expectedEntryKind) {
         ResolvedJavaField[] declaredFields = getInstanceFields(true);
         for (ResolvedJavaField field : declaredFields) {
-            if (((HotSpotResolvedJavaField) field).offset() == offset) {
+            HotSpotResolvedJavaField resolvedField = (HotSpotResolvedJavaField) field;
+            long resolvedFieldOffset = resolvedField.offset();
+            // @formatter:off
+            if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN  &&
+                            expectedEntryKind.isPrimitive() &&
+                            !expectedEntryKind.equals(Kind.Void) &&
+                            resolvedField.getKind().isPrimitive()) {
+                resolvedFieldOffset +=
+                                resolvedField.getKind().getByteCount() -
+                                Math.min(resolvedField.getKind().getByteCount(), 4 + expectedEntryKind.getByteCount());
+            }
+            if (resolvedFieldOffset == offset) {
                 return field;
             }
+            // @formatter:on
         }
         return null;
     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedPrimitiveType.java	Mon Jan 26 21:19:36 2015 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedPrimitiveType.java	Mon Jan 26 21:21:06 2015 +0100
@@ -225,7 +225,7 @@
     }
 
     @Override
-    public ResolvedJavaField findInstanceFieldWithOffset(long offset) {
+    public ResolvedJavaField findInstanceFieldWithOffset(long offset, Kind expectedType) {
         return null;
     }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java	Mon Jan 26 21:19:36 2015 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java	Mon Jan 26 21:21:06 2015 +0100
@@ -134,8 +134,8 @@
         if (receiverType == null) {
             return false;
         }
-
-        ResolvedJavaField field = receiverType.findInstanceFieldWithOffset(((ConstantLocationNode) location()).getDisplacement());
+        ConstantLocationNode constantLocationNode = (ConstantLocationNode) location();
+        ResolvedJavaField field = receiverType.findInstanceFieldWithOffset(constantLocationNode.getDisplacement(), constantLocationNode.getKind());
         if (field == null) {
             // field was not declared by receiverType
             return false;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeAccessNode.java	Mon Jan 26 21:19:36 2015 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeAccessNode.java	Mon Jan 26 21:21:06 2015 +0100
@@ -71,7 +71,7 @@
             // Try to canonicalize to a field access.
             ResolvedJavaType receiverType = StampTool.typeOrNull(object());
             if (receiverType != null) {
-                ResolvedJavaField field = receiverType.findInstanceFieldWithOffset(constantOffset);
+                ResolvedJavaField field = receiverType.findInstanceFieldWithOffset(constantOffset, accessKind());
                 // No need for checking that the receiver is non-null. The field access includes
                 // the null check and if a field is found, the offset is so small that this is
                 // never a valid access of an arbitrary address.
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeLoadNode.java	Mon Jan 26 21:19:36 2015 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeLoadNode.java	Mon Jan 26 21:21:06 2015 +0100
@@ -24,8 +24,6 @@
 
 import static com.oracle.graal.compiler.common.UnsafeAccess.*;
 
-import java.nio.*;
-
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.nodeinfo.*;
@@ -66,13 +64,12 @@
             ValueNode offsetValue = tool.getReplacedValue(offset());
             if (offsetValue.isConstant()) {
                 long off = offsetValue.asJavaConstant().asLong();
-                int entryIndex = state.getVirtualObject().entryIndexForOffset(off);
+                int entryIndex = state.getVirtualObject().entryIndexForOffset(off, accessKind());
 
                 if (entryIndex != -1) {
                     ValueNode entry = state.getEntry(entryIndex);
                     Kind entryKind = state.getVirtualObject().entryKind(entryIndex);
-                    boolean isLoadSafe = ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN || accessKind() == entryKind;
-                    if (isLoadSafe && (entry.getKind() == getKind() || entryKind == accessKind())) {
+                    if (entry.getKind() == getKind() || entryKind == accessKind()) {
                         tool.replaceWith(entry);
                     }
                 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java	Mon Jan 26 21:19:36 2015 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java	Mon Jan 26 21:21:06 2015 +0100
@@ -24,8 +24,6 @@
 
 import static com.oracle.graal.compiler.common.UnsafeAccess.*;
 
-import java.nio.*;
-
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.nodeinfo.*;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreFieldNode.java	Mon Jan 26 21:19:36 2015 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreFieldNode.java	Mon Jan 26 21:21:06 2015 +0100
@@ -22,8 +22,6 @@
  */
 package com.oracle.graal.nodes.java;
 
-import java.nio.*;
-
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.nodeinfo.*;
@@ -75,13 +73,8 @@
         if (state != null && state.getState() == EscapeState.Virtual) {
             int fieldIndex = ((VirtualInstanceNode) state.getVirtualObject()).fieldIndex(field());
             if (fieldIndex != -1) {
-                Kind entryKind = state.getVirtualObject().entryKind(fieldIndex);
-                Kind valueKind = value().getKind();
-                boolean isStoreSafe = !entryKind.isPrimitive() || ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN || entryKind.getBitCount() == valueKind.getBitCount();
-                if (isStoreSafe) {
-                    tool.setVirtualEntry(state, fieldIndex, value(), false);
-                    tool.delete();
-                }
+                tool.setVirtualEntry(state, fieldIndex, value(), false);
+                tool.delete();
             }
         }
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreIndexedNode.java	Mon Jan 26 21:19:36 2015 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreIndexedNode.java	Mon Jan 26 21:21:06 2015 +0100
@@ -22,8 +22,6 @@
  */
 package com.oracle.graal.nodes.java;
 
-import java.nio.*;
-
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.nodeinfo.*;
@@ -71,11 +69,8 @@
             int idx = indexValue.isConstant() ? indexValue.asJavaConstant().asInt() : -1;
             if (idx >= 0 && idx < arrayState.getVirtualObject().entryCount()) {
                 ResolvedJavaType componentType = arrayState.getVirtualObject().type().getComponentType();
-                // isStoreSafe prevents on Little Endian machines to not do an implicit cast of
-                // primitives (Causes troubles with deoptimization)
-                boolean isStoreSafe = !componentType.isPrimitive() || ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN || componentType.equals(StampTool.typeOrNull(value));
-                if (isStoreSafe &&
-                                (componentType.isPrimitive() || StampTool.isPointerAlwaysNull(value) || componentType.getSuperclass() == null || (StampTool.typeOrNull(value) != null && componentType.isAssignableFrom(StampTool.typeOrNull(value))))) {
+                if (componentType.isPrimitive() || StampTool.isPointerAlwaysNull(value) || componentType.getSuperclass() == null ||
+                                (StampTool.typeOrNull(value) != null && componentType.isAssignableFrom(StampTool.typeOrNull(value)))) {
                     tool.setVirtualEntry(arrayState, idx, value(), false);
                     tool.delete();
                 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualArrayNode.java	Mon Jan 26 21:19:36 2015 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualArrayNode.java	Mon Jan 26 21:21:06 2015 +0100
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.nodes.virtual;
 
+import java.nio.*;
+
 import sun.misc.*;
 
 import com.oracle.graal.api.meta.*;
@@ -75,7 +77,7 @@
     }
 
     @Override
-    public int entryIndexForOffset(long constantOffset) {
+    public int entryIndexForOffset(long constantOffset, Kind expectedEntryKind) {
         int baseOffset;
         int indexScale;
         switch (componentType.getKind()) {
@@ -118,7 +120,14 @@
             default:
                 return -1;
         }
-        long index = constantOffset - baseOffset;
+        long offset;
+        if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN && componentType.isPrimitive()) {
+            // On big endian, we do just get expect the type be right aligned in this memory slot
+            offset = constantOffset - (componentType.getKind().getByteCount() - Math.min(componentType.getKind().getByteCount(), 4 + expectedEntryKind.getByteCount()));
+        } else {
+            offset = constantOffset;
+        }
+        long index = offset - baseOffset;
         if (index % indexScale != 0) {
             return -1;
         }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualInstanceNode.java	Mon Jan 26 21:19:36 2015 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualInstanceNode.java	Mon Jan 26 21:21:06 2015 +0100
@@ -85,8 +85,8 @@
     }
 
     @Override
-    public int entryIndexForOffset(long constantOffset) {
-        return fieldIndex(type.findInstanceFieldWithOffset(constantOffset));
+    public int entryIndexForOffset(long constantOffset, Kind expectedEntryKind) {
+        return fieldIndex(type.findInstanceFieldWithOffset(constantOffset, expectedEntryKind));
     }
 
     @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualObjectNode.java	Mon Jan 26 21:19:36 2015 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualObjectNode.java	Mon Jan 26 21:21:06 2015 +0100
@@ -59,8 +59,12 @@
     /**
      * If the given index denotes an entry in this virtual object, the index of this entry is
      * returned. If no such entry can be found, this method returns -1.
+     *
+     * @param constantOffset offset, where the value is placed.
+     * @param expectedEntryKind Specifies which type is expected at this offset (Is important when
+     *            doing implicit casts, especially on big endian systems.
      */
-    public abstract int entryIndexForOffset(long constantOffset);
+    public abstract int entryIndexForOffset(long constantOffset, Kind expectedEntryKind);
 
     /**
      * Returns the {@link Kind} of the entry at the given index.
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/FrameWithoutBoxing.java	Mon Jan 26 21:19:36 2015 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/FrameWithoutBoxing.java	Mon Jan 26 21:21:06 2015 +0100
@@ -257,6 +257,16 @@
         }
     }
 
+    private static long alignPrimitive(FrameSlot slot, Kind forKind) {
+        long offset = PRIMITIVE_BASE_OFFSET + slot.getIndex() * PRIMITIVE_INDEX_SCALE;
+        if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN) {
+            // On big endian, we use int in long type, which means, when byteCount() <=4, the value
+            // is right aligned in the 4 byte half, which has the lower address.
+            offset += Kind.Long.getByteCount() - Math.min(PRIMITIVE_INDEX_SCALE, 4 + forKind.getByteCount());
+        }
+        return offset;
+    }
+
     @Override
     public Object getValue(FrameSlot slot) {
         int slotIndex = slot.getIndex();
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java	Mon Jan 26 21:19:36 2015 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java	Mon Jan 26 21:21:06 2015 +0100
@@ -27,6 +27,7 @@
 import java.io.*;
 import java.lang.reflect.*;
 import java.util.*;
+import java.util.concurrent.*;
 import java.util.concurrent.atomic.*;
 import java.util.stream.*;
 
@@ -314,8 +315,18 @@
     }
 
     public void compile() {
+        compile(TruffleBackgroundCompilation.getValue() && !TruffleCompilationExceptionsAreThrown.getValue());
+    }
+
+    public void compile(boolean mayBeAsynchronous) {
         if (!runtime.isCompiling(this)) {
-            runtime.compile(this, TruffleBackgroundCompilation.getValue() && !TruffleCompilationExceptionsAreThrown.getValue());
+            runtime.compile(this, mayBeAsynchronous);
+        } else if (!mayBeAsynchronous && runtime.isCompiling(this)) {
+            try {
+                runtime.waitForCompilation(this, 20000);
+            } catch (ExecutionException | TimeoutException e) {
+                Debug.log(3, e.getMessage());
+            }
         }
     }
 
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeLoadFinalNode.java	Mon Jan 26 21:19:36 2015 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeLoadFinalNode.java	Mon Jan 26 21:21:06 2015 +0100
@@ -75,7 +75,7 @@
             ValueNode offsetValue = tool.getReplacedValue(offset);
             if (offsetValue.isConstant()) {
                 long constantOffset = offsetValue.asJavaConstant().asLong();
-                int entryIndex = state.getVirtualObject().entryIndexForOffset(constantOffset);
+                int entryIndex = state.getVirtualObject().entryIndexForOffset(constantOffset, accessKind);
                 if (entryIndex != -1) {
                     ValueNode entry = state.getEntry(entryIndex);
                     if (entry.getKind() == getKind() || state.getVirtualObject().entryKind(entryIndex) == accessKind) {
--- a/src/share/vm/graal/graalCodeInstaller.cpp	Mon Jan 26 21:19:36 2015 +0100
+++ b/src/share/vm/graal/graalCodeInstaller.cpp	Mon Jan 26 21:21:06 2015 +0100
@@ -347,12 +347,7 @@
       if (isLongArray && cur_second == NULL) {
         // we're trying to put ints into a long array... this isn't really valid, but it's used for some optimizations.
         // add an int 0 constant
-#ifdef VM_LITTLE_ENDIAN
         cur_second = _int_0_scope_value;
-#else
-        cur_second = value;
-        value = _int_0_scope_value;
-#endif
       }
 
       if (cur_second != NULL) {