8336663: [JVMCI] VM Crash on ZGC due to incompatible handle returned by HotSpotJVMCIRuntime#getJObjectValue
Reviewed-by: dnsimon, never
This commit is contained in:
parent
5ff7c57f9f
commit
3abe8a6e5e
@ -94,6 +94,12 @@ static void requireInHotSpot(const char* caller, JVMCI_TRAPS) {
|
||||
}
|
||||
}
|
||||
|
||||
static void requireNotInHotSpot(const char* caller, JVMCI_TRAPS) {
|
||||
if (JVMCIENV->is_hotspot()) {
|
||||
JVMCI_THROW_MSG(IllegalStateException, err_msg("Cannot call %s from HotSpot", caller));
|
||||
}
|
||||
}
|
||||
|
||||
class JVMCITraceMark : public StackObj {
|
||||
const char* _msg;
|
||||
public:
|
||||
@ -702,6 +708,17 @@ C2V_VMENTRY_NULL(jobject, lookupJClass, (JNIEnv* env, jobject, jlong jclass_valu
|
||||
return JVMCIENV->get_jobject(result);
|
||||
C2V_END
|
||||
|
||||
C2V_VMENTRY_0(jlong, getJObjectValue, (JNIEnv* env, jobject, jobject constant_jobject))
|
||||
requireNotInHotSpot("getJObjectValue", JVMCI_CHECK_0);
|
||||
if (!THREAD->has_last_Java_frame()) {
|
||||
JVMCI_THROW_MSG_0(IllegalStateException, err_msg("Cannot call getJObjectValue without Java frame anchor"));
|
||||
}
|
||||
JVMCIObject constant = JVMCIENV->wrap(constant_jobject);
|
||||
Handle constant_value = JVMCIENV->asConstant(constant, JVMCI_CHECK_0);
|
||||
jobject jni_handle = JNIHandles::make_local(THREAD, constant_value());
|
||||
return reinterpret_cast<jlong>(jni_handle);
|
||||
C2V_END
|
||||
|
||||
C2V_VMENTRY_NULL(jobject, getUncachedStringInPool, (JNIEnv* env, jobject, ARGUMENT_PAIR(cp), jint index))
|
||||
constantPoolHandle cp(THREAD, UNPACK_PAIR(ConstantPool, cp));
|
||||
constantTag tag = cp->tag_at(index);
|
||||
@ -3254,6 +3271,7 @@ JNINativeMethod CompilerToVM::methods[] = {
|
||||
{CC "shouldInlineMethod", CC "(" HS_METHOD2 ")Z", FN_PTR(shouldInlineMethod)},
|
||||
{CC "lookupType", CC "(" STRING HS_KLASS2 "IZ)" HS_RESOLVED_TYPE, FN_PTR(lookupType)},
|
||||
{CC "lookupJClass", CC "(J)" HS_RESOLVED_TYPE, FN_PTR(lookupJClass)},
|
||||
{CC "getJObjectValue", CC "(" OBJECTCONSTANT ")J", FN_PTR(getJObjectValue)},
|
||||
{CC "getArrayType", CC "(C" HS_KLASS2 ")" HS_KLASS, FN_PTR(getArrayType)},
|
||||
{CC "lookupClass", CC "(" CLASS ")" HS_RESOLVED_TYPE, FN_PTR(lookupClass)},
|
||||
{CC "lookupNameInPool", CC "(" HS_CONSTANT_POOL2 "II)" STRING, FN_PTR(lookupNameInPool)},
|
||||
|
@ -289,6 +289,12 @@ final class CompilerToVM {
|
||||
|
||||
native HotSpotResolvedJavaType lookupJClass(long jclass);
|
||||
|
||||
/**
|
||||
* Gets the {@code jobject} value wrapped by {@code peerObject}.
|
||||
* Must not be called if {@link Services#IS_IN_NATIVE_IMAGE} is {@code false}.
|
||||
*/
|
||||
native long getJObjectValue(HotSpotObjectConstantImpl peerObject);
|
||||
|
||||
/**
|
||||
* Resolves the entry at index {@code cpi} in {@code constantPool} to an interned String object.
|
||||
*
|
||||
|
@ -925,23 +925,23 @@ public final class HotSpotJVMCIRuntime implements JVMCIRuntime {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@code jobject} value wrapped by {@code peerObject}. The returned "naked" value is
|
||||
* only valid as long as {@code peerObject} is valid. Note that the latter may be shorter than
|
||||
* the lifetime of {@code peerObject}. As such, this method should only be used to pass an
|
||||
* object parameter across a JNI call from the JVMCI shared library to HotSpot. This method must
|
||||
* only be called from within the JVMCI shared library.
|
||||
* Gets the {@code jobject} value wrapped by {@code peerObject}. The returned value is
|
||||
* a JNI local reference whose lifetime is scoped by the nearest Java caller (from
|
||||
* HotSpot's perspective). You can use {@code PushLocalFrame} and {@code PopLocalFrame} to
|
||||
* shorten the lifetime of the reference. The current thread's state must be
|
||||
* {@code _thread_in_native}. A call from the JVMCI shared library (e.g. libgraal) is in such
|
||||
* a state.
|
||||
*
|
||||
* @param peerObject a reference to an object in the peer runtime
|
||||
* @return the {@code jobject} value wrapped by {@code peerObject}
|
||||
* @param peerObject a reference to an object in the HotSpot heap
|
||||
* @return the {@code jobject} value unpacked from {@code peerObject}
|
||||
* @throws IllegalArgumentException if the current runtime is not the JVMCI shared library or
|
||||
* {@code peerObject} is not a peer object reference
|
||||
* {@code peerObject} is not a HotSpot heap object reference
|
||||
* @throws IllegalStateException if not called from within the JVMCI shared library
|
||||
* or if there is no Java caller frame on the stack
|
||||
* (i.e., JavaThread::has_last_Java_frame returns false)
|
||||
*/
|
||||
public long getJObjectValue(HotSpotObjectConstant peerObject) {
|
||||
if (peerObject instanceof IndirectHotSpotObjectConstantImpl) {
|
||||
IndirectHotSpotObjectConstantImpl remote = (IndirectHotSpotObjectConstantImpl) peerObject;
|
||||
return remote.getHandle();
|
||||
}
|
||||
throw new IllegalArgumentException("Cannot get jobject value for " + peerObject + " (" + peerObject.getClass().getName() + ")");
|
||||
return compilerToVm.getJObjectValue((HotSpotObjectConstantImpl)peerObject);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
Loading…
Reference in New Issue
Block a user