changeset 18719:6484e5c068c7

Generalize object reading in HotSpotMemoryAccessProvider.
author Roland Schatz <roland.schatz@oracle.com>
date Thu, 18 Dec 2014 15:31:12 +0100
parents 305e6a73117d
children ab9d3ff6829b
files graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMemoryAccessProviderImpl.java src/share/vm/graal/graalCompilerToVM.cpp
diffstat 4 files changed, 98 insertions(+), 55 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java	Thu Dec 18 15:23:08 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java	Thu Dec 18 15:31:12 2014 +0100
@@ -285,6 +285,8 @@
 
     long readUnsafeKlassPointer(Object o);
 
+    Object readUnsafeOop(Object base, long displacement, boolean compressed);
+
     void doNotInlineOrCompile(long metaspaceMethod);
 
     /**
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java	Thu Dec 18 15:23:08 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java	Thu Dec 18 15:31:12 2014 +0100
@@ -160,6 +160,9 @@
     public native long readUnsafeKlassPointer(Object o);
 
     @Override
+    public native Object readUnsafeOop(Object base, long displacement, boolean compressed);
+
+    @Override
     public native void doNotInlineOrCompile(long metaspaceMethod);
 
     @Override
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMemoryAccessProviderImpl.java	Thu Dec 18 15:23:08 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMemoryAccessProviderImpl.java	Thu Dec 18 15:31:12 2014 +0100
@@ -41,66 +41,92 @@
         this.runtime = runtime;
     }
 
-    private static long readRawValue(Constant baseConstant, long initialDisplacement, int bits) {
-        Object base;
-        long displacement;
-        if (baseConstant instanceof JavaConstant) {
-            JavaConstant javaConstant = (JavaConstant) baseConstant;
-            if (javaConstant instanceof HotSpotObjectConstantImpl) {
-                base = ((HotSpotObjectConstantImpl) javaConstant).object();
-                displacement = initialDisplacement;
-            } else if (javaConstant.getKind().isNumericInteger()) {
-                long baseLong = javaConstant.asLong();
-                assert baseLong != 0;
-                displacement = initialDisplacement + baseLong;
-                base = null;
-            } else {
-                throw GraalInternalError.shouldNotReachHere();
+    private static Object asObject(Constant base) {
+        if (base instanceof HotSpotObjectConstantImpl) {
+            return ((HotSpotObjectConstantImpl) base).object();
+        } else {
+            return null;
+        }
+    }
+
+    private static long asRawPointer(Constant base) {
+        if (base instanceof HotSpotMetaspaceConstant) {
+            return ((HotSpotMetaspaceConstant) base).rawValue();
+        } else if (base instanceof PrimitiveConstant) {
+            PrimitiveConstant prim = (PrimitiveConstant) base;
+            if (prim.getKind().isNumericInteger()) {
+                return prim.asLong();
+            }
+        }
+        throw GraalInternalError.shouldNotReachHere();
+    }
+
+    private static long readRawValue(Constant baseConstant, long displacement, int bits) {
+        Object base = asObject(baseConstant);
+        if (base != null) {
+            switch (bits) {
+                case 8:
+                    return unsafe.getByte(base, displacement);
+                case 16:
+                    return unsafe.getShort(base, displacement);
+                case 32:
+                    return unsafe.getInt(base, displacement);
+                case 64:
+                    return unsafe.getLong(base, displacement);
+                default:
+                    throw GraalInternalError.shouldNotReachHere();
             }
         } else {
-            throw GraalInternalError.shouldNotReachHere();
+            long pointer = asRawPointer(baseConstant);
+            switch (bits) {
+                case 8:
+                    return unsafe.getByte(pointer + displacement);
+                case 16:
+                    return unsafe.getShort(pointer + displacement);
+                case 32:
+                    return unsafe.getInt(pointer + displacement);
+                case 64:
+                    return unsafe.getLong(pointer + displacement);
+                default:
+                    throw GraalInternalError.shouldNotReachHere();
+            }
+        }
+    }
+
+    private boolean verifyReadRawObject(Object expected, Constant base, long displacement, boolean compressed) {
+        if (compressed == runtime.getConfig().useCompressedOops) {
+            Object obj = asObject(base);
+            if (obj != null) {
+                assert expected == unsafe.getObject(obj, displacement) : "readUnsafeOop doesn't agree with unsafe.getObject";
+            }
+        }
+        if (base instanceof HotSpotMetaspaceConstant) {
+            Object metaspaceObject = HotSpotMetaspaceConstantImpl.getMetaspaceObject(base);
+            if (metaspaceObject instanceof HotSpotResolvedObjectTypeImpl) {
+                if (displacement == runtime.getConfig().classMirrorOffset) {
+                    assert expected == ((HotSpotResolvedObjectTypeImpl) metaspaceObject).mirror();
+                } else if (displacement == runtime.getConfig().arrayKlassComponentMirrorOffset) {
+                    assert expected == ((HotSpotResolvedObjectTypeImpl) metaspaceObject).mirror().getComponentType();
+                } else if (displacement == runtime.getConfig().instanceKlassNodeClassOffset) {
+                    assert expected == NodeClass.get(((HotSpotResolvedObjectTypeImpl) metaspaceObject).mirror());
+                }
+            }
+        }
+        return true;
+    }
+
+    private Object readRawObject(Constant baseConstant, long initialDisplacement, boolean compressed) {
+        long displacement = initialDisplacement;
+
+        Object base = asObject(baseConstant);
+        if (base == null) {
+            displacement += asRawPointer(baseConstant);
         }
 
-        long rawValue;
-        switch (bits) {
-            case 8:
-                rawValue = base == null ? unsafe.getByte(displacement) : unsafe.getByte(base, displacement);
-                break;
-            case 16:
-                rawValue = base == null ? unsafe.getShort(displacement) : unsafe.getShort(base, displacement);
-                break;
-            case 32:
-                rawValue = base == null ? unsafe.getInt(displacement) : unsafe.getInt(base, displacement);
-                break;
-            case 64:
-                rawValue = base == null ? unsafe.getLong(displacement) : unsafe.getLong(base, displacement);
-                break;
-            default:
-                throw GraalInternalError.shouldNotReachHere();
-        }
-        return rawValue;
-    }
+        Object ret = runtime.getCompilerToVM().readUnsafeOop(base, displacement, compressed);
+        assert verifyReadRawObject(ret, baseConstant, initialDisplacement, compressed);
 
-    private Object readRawObject(Constant baseConstant, long displacement, boolean compressed) {
-        if (baseConstant instanceof HotSpotObjectConstantImpl) {
-            assert compressed == runtime.getConfig().useCompressedOops;
-            return unsafe.getObject(((HotSpotObjectConstantImpl) baseConstant).object(), displacement);
-        } else if (baseConstant instanceof HotSpotMetaspaceConstant) {
-            Object metaspaceObject = HotSpotMetaspaceConstantImpl.getMetaspaceObject(baseConstant);
-            if (metaspaceObject instanceof HotSpotResolvedObjectTypeImpl) {
-                assert !compressed : "unexpected compressed read from Klass*";
-                if (displacement == runtime.getConfig().classMirrorOffset) {
-                    return ((HotSpotResolvedObjectTypeImpl) metaspaceObject).mirror();
-                } else if (displacement == runtime.getConfig().arrayKlassComponentMirrorOffset) {
-                    return ((HotSpotResolvedObjectTypeImpl) metaspaceObject).mirror().getComponentType();
-                } else if (displacement == runtime.getConfig().instanceKlassNodeClassOffset) {
-                    return NodeClass.get(((HotSpotResolvedObjectTypeImpl) metaspaceObject).mirror());
-                }
-            }
-            throw GraalInternalError.shouldNotReachHere("read from unknown Klass* offset " + displacement);
-        } else {
-            throw GraalInternalError.shouldNotReachHere("unexpected base pointer: " + (baseConstant == null ? "null" : baseConstant.toString()));
-        }
+        return ret;
     }
 
     @Override
--- a/src/share/vm/graal/graalCompilerToVM.cpp	Thu Dec 18 15:23:08 2014 +0100
+++ b/src/share/vm/graal/graalCompilerToVM.cpp	Thu Dec 18 15:31:12 2014 +0100
@@ -699,6 +699,17 @@
   return klass;
 C2V_END
 
+C2V_VMENTRY(jobject, readUnsafeOop, (JNIEnv*, jobject, jobject base, jlong displacement, jboolean compressed))
+  address addr = (address)JNIHandles::resolve(base);
+  oop ret;
+  if (compressed) {
+    ret = oopDesc::load_decode_heap_oop((narrowOop*)(addr + displacement));
+  } else {
+    ret = oopDesc::load_decode_heap_oop((oop*)(addr + displacement));
+  }
+  return JNIHandles::make_local(ret);
+C2V_END
+
 C2V_VMENTRY(jlongArray, collectCounters, (JNIEnv*, jobject))
   typeArrayOop arrayOop = oopFactory::new_longArray(GraalCounterSize, CHECK_NULL);
   JavaThread::collect_counters(arrayOop);
@@ -1078,6 +1089,7 @@
   {CC"invalidateInstalledCode",                      CC"("INSTALLED_CODE")V",                                                  FN_PTR(invalidateInstalledCode)},
   {CC"getJavaMirror",                                CC"("METASPACE_KLASS")"CLASS,                                             FN_PTR(getJavaMirror)},
   {CC"readUnsafeKlassPointer",                       CC"("OBJECT")J",                                                          FN_PTR(readUnsafeKlassPointer)},
+  {CC"readUnsafeOop",                                CC"("OBJECT"JZ)"OBJECT,                                                   FN_PTR(readUnsafeOop)},
   {CC"collectCounters",                              CC"()[J",                                                                 FN_PTR(collectCounters)},
   {CC"getGPUs",                                      CC"()"STRING,                                                             FN_PTR(getGPUs)},
   {CC"allocateCompileId",                            CC"("METASPACE_METHOD"I)I",                                               FN_PTR(allocateCompileId)},