8159010: [JVMCI] crashes with class redefinition
authornever
Mon, 13 Jun 2016 17:36:57 -0700
changeset 39426 ea04b4d9d862
parent 39425 576058e9f728
child 39427 c154eca6daa5
8159010: [JVMCI] crashes with class redefinition Reviewed-by: kvn
hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstantPool.java
hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIMetaAccessContext.java
hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java
hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/MetaspaceWrapperObject.java
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstantPool.java	Fri Jun 17 16:50:49 2016 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstantPool.java	Mon Jun 13 17:36:57 2016 -0700
@@ -196,7 +196,9 @@
      */
     @SuppressWarnings("unused")
     private static HotSpotConstantPool fromMetaspace(long metaspaceConstantPool) {
-        return new HotSpotConstantPool(metaspaceConstantPool);
+        HotSpotConstantPool cp = new HotSpotConstantPool(metaspaceConstantPool);
+        runtime().metaAccessContext.add(cp);
+        return cp;
     }
 
     private HotSpotConstantPool(long metaspaceConstantPool) {
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIMetaAccessContext.java	Fri Jun 17 16:50:49 2016 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIMetaAccessContext.java	Mon Jun 13 17:36:57 2016 -0700
@@ -135,6 +135,7 @@
              */
             metadataRoots = list.getHead();
         }
+        assert isRegistered(metaspaceObject);
     }
 
     protected ResolvedJavaType createClass(Class<?> javaClass) {
@@ -208,7 +209,7 @@
             ChunkIterator() {
                 currentChunk = head;
                 currentIndex = -1;
-                findNext();
+                next = findNext();
             }
 
             Object[] currentChunk;
@@ -245,4 +246,13 @@
         }
 
     }
+
+    synchronized boolean isRegistered(MetaspaceWrapperObject wrapper) {
+        for (WeakReference<MetaspaceWrapperObject> m : list) {
+            if (m != null && m.get() == wrapper) {
+                return true;
+            }
+        }
+        return false;
+    }
 }
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java	Fri Jun 17 16:50:49 2016 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java	Mon Jun 13 17:36:57 2016 -0700
@@ -132,10 +132,20 @@
         return UNSAFE.getInt(javaClass, config().klassOffset) & 0xFFFFFFFFL;
     }
 
+    @Override
     public long getMetaspacePointer() {
         return getMetaspaceKlass();
     }
 
+    /**
+     * The Klass* for this object is kept alive by the direct reference to {@link #javaClass} so no
+     * extra work is required.
+     */
+    @Override
+    public boolean isRegistered() {
+        return true;
+    }
+
     @Override
     public int getModifiers() {
         if (isArray()) {
@@ -428,7 +438,13 @@
     }
 
     public HotSpotConstantPool getConstantPool() {
-        if (constantPool == null) {
+        if (constantPool == null || !isArray() && UNSAFE.getAddress(getMetaspaceKlass() + config().instanceKlassConstantsOffset) != constantPool.getMetaspaceConstantPool()) {
+            /*
+             * If the pointer to the ConstantPool has changed since this was last read refresh the
+             * HotSpotConstantPool wrapper object. This ensures that uses of the constant pool are
+             * operating on the latest one and that HotSpotResolvedJavaMethodImpls will be able to
+             * use the shared copy instead of creating their own instance.
+             */
             constantPool = compilerToVM().getConstantPool(this, config().instanceKlassConstantsOffset);
         }
         return constantPool;
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/MetaspaceWrapperObject.java	Fri Jun 17 16:50:49 2016 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/MetaspaceWrapperObject.java	Mon Jun 13 17:36:57 2016 -0700
@@ -23,7 +23,8 @@
 package jdk.vm.ci.hotspot;
 
 /**
- * A tag interface indicating that this type is a wrapper around a HotSpot metaspace object.
+ * A tag interface indicating that this type is a wrapper around a HotSpot metaspace object that
+ * requires GC interaction to keep alive.
  *
  * It would preferable if this were the base class containing the pointer but that would require
  * mixins since most of the wrapper types have complex supertype hierarchies.
@@ -31,4 +32,18 @@
 interface MetaspaceWrapperObject {
 
     long getMetaspacePointer();
+
+    /**
+     * Check if this object is properly registered for metadata tracking. All classes which
+     * implement this interface must be registered with the
+     * {@link HotSpotJVMCIMetaAccessContext#add} unless they are kept alive through other means.
+     * Currently the only type which doesn't require explicit registration is
+     * {@link HotSpotResolvedObjectTypeImpl} since it's kept alive by references to the
+     * {@link Class}.
+     *
+     * @return true if this object is properly registered for meta data tracking.
+     */
+    default boolean isRegistered() {
+        return HotSpotJVMCIRuntime.runtime().metaAccessContext.isRegistered(this);
+    }
 }