# HG changeset patch # User never # Date 1465864617 25200 # Mon Jun 13 17:36:57 2016 -0700 # Node ID 9919dc997df06b00b34b21417b6788b399eff7fe # Parent 4e13df329624a313fcb2fb8f0e3c3299df102880 8159010: [JVMCI] crashes with class redefinition diff --git a/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstantPool.java b/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstantPool.java --- a/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstantPool.java +++ b/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstantPool.java @@ -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 --git a/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIMetaAccessContext.java b/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIMetaAccessContext.java --- a/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIMetaAccessContext.java +++ b/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIMetaAccessContext.java @@ -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 --git a/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java b/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java --- a/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java +++ b/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java @@ -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; diff --git a/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/MetaspaceWrapperObject.java b/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/MetaspaceWrapperObject.java --- a/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/MetaspaceWrapperObject.java +++ b/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/MetaspaceWrapperObject.java @@ -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); + } }