# HG changeset patch # User Tom Rodriguez # Date 1465240934 25200 # Node ID f60746f36f3f35b86086c099ea4c5d2803689a95 # Parent 3fa6348084a053556ddfdc93afb617403d15aa6e Properly track HotSpotConstantPool as metadata and fix bug that cause metadata to be lost during unloading diff -r 3fa6348084a0 -r f60746f36f3f jvmci/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstantPool.java --- a/jvmci/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstantPool.java Thu Jun 02 15:25:22 2016 +0200 +++ b/jvmci/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstantPool.java Mon Jun 06 12:22:14 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) { diff -r 3fa6348084a0 -r f60746f36f3f jvmci/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIMetaAccessContext.java --- a/jvmci/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIMetaAccessContext.java Thu Jun 02 15:25:22 2016 +0200 +++ b/jvmci/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIMetaAccessContext.java Mon Jun 06 12:22:14 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 m : list) { + if (m != null && m.get() == wrapper) { + return true; + } + } + return false; + } } diff -r 3fa6348084a0 -r f60746f36f3f jvmci/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java --- a/jvmci/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java Thu Jun 02 15:25:22 2016 +0200 +++ b/jvmci/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java Mon Jun 06 12:22:14 2016 -0700 @@ -132,10 +132,20 @@ return UNSAFE.getInt(javaClass, (long) 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()) { diff -r 3fa6348084a0 -r f60746f36f3f jvmci/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/MetaspaceWrapperObject.java --- a/jvmci/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/MetaspaceWrapperObject.java Thu Jun 02 15:25:22 2016 +0200 +++ b/jvmci/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/MetaspaceWrapperObject.java Mon Jun 06 12:22:14 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); + } }