8159010: [JVMCI] crashes with class redefinition

Reviewed-by: kvn
This commit is contained in:
Tom Rodriguez 2016-06-13 17:36:57 -07:00
parent f81f745028
commit fcff9c216b
4 changed files with 47 additions and 4 deletions

View File

@ -196,7 +196,9 @@ final class HotSpotConstantPool implements ConstantPool, MetaspaceWrapperObject
*/
@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) {

View File

@ -135,6 +135,7 @@ public class HotSpotJVMCIMetaAccessContext {
*/
metadataRoots = list.getHead();
}
assert isRegistered(metaspaceObject);
}
protected ResolvedJavaType createClass(Class<?> javaClass) {
@ -208,7 +209,7 @@ public class HotSpotJVMCIMetaAccessContext {
ChunkIterator() {
currentChunk = head;
currentIndex = -1;
findNext();
next = findNext();
}
Object[] currentChunk;
@ -245,4 +246,13 @@ public class HotSpotJVMCIMetaAccessContext {
}
}
synchronized boolean isRegistered(MetaspaceWrapperObject wrapper) {
for (WeakReference<MetaspaceWrapperObject> m : list) {
if (m != null && m.get() == wrapper) {
return true;
}
}
return false;
}
}

View File

@ -132,10 +132,20 @@ final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType implem
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 @@ final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType implem
}
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;

View File

@ -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 @@ package jdk.vm.ci.hotspot;
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);
}
}