Description
openedon Apr 4, 2023
The combination of Google Guice 5.1.0 and the Azul Prime JVM is causing a VM crash. I've reached out to Azul support about this and they believe that the root cause is that the class com.google.inject.internal.aop.HiddenClassDefiner
treats a klassOop
as though it were an Object
.
HiddenClassDefiner
defines TRUSTED_LOOKUP_BASE
like this:
private static final Object TRUSTED_LOOKUP_BASE;
And its value is obtained like this:
Method baseMethod = unsafeType.getMethod("staticFieldBase", Field.class);
TRUSTED_LOOKUP_BASE = baseMethod.invoke(THE_UNSAFE, trustedLookupField);
So TRUSTED_LOOKUP_BASE
, nominally a private static final Object
, is obtained by calling Unsafe.staticFieldBase()
via reflection.
Here's how it's used in Guice:
public Class<?> define(Class<?> hostClass, byte[] bytecode) throws Exception {
Lookup trustedLookup =
(Lookup) GET_OBJECT_METHOD.invoke(THE_UNSAFE, TRUSTED_LOOKUP_BASE, TRUSTED_LOOKUP_OFFSET);
Which calls Unsafe.getObject((Object)TRUSTED_LOOKUP_BASE, (long)TRUSTED_LOOKUP_OFFSET)
.
This use of TRUSTED_LOOKUP_BASE
ignores the admonitions of Unsafe.staticFieldBase()
, which says the value is not guaranteed to be a real Object
:
/**
* Reports the location of a given static field, in conjunction with {@link
* #staticFieldOffset}.
* <p>Fetch the base "Object", if any, with which static fields of the
* given class can be accessed via methods like {@link #getInt(Object,
* long)}. This value may be null. This value may refer to an object
* which is a "cookie", not guaranteed to be a real Object, and it should
* not be used in any way except as argument to the get and put routines in
* this class.
*/
@ForceInline
public Object staticFieldBase(Field f) {
Now, a lot of reflection code is generated on the fly at runtime and inlined. I'm also told the Prime VM emits a checkcast
bytecode, which does what it says and checks the reference to be returned by getObject
is, in fact, an Object
, which a klassOop
isn't. Hence the attempt to throw a ClassCastException
in a place where the VM shouldn't.
Here is the hs_err file for the crash: hs_err_pid12.log.gz