diff --git a/runtime/compiler/env/VMJ9.cpp b/runtime/compiler/env/VMJ9.cpp index b771cf39e48..0164483a01e 100644 --- a/runtime/compiler/env/VMJ9.cpp +++ b/runtime/compiler/env/VMJ9.cpp @@ -4779,6 +4779,58 @@ TR_J9VMBase::methodHandle_jitInvokeExactThunk(uintptr_t methodHandle) "invokeExactThunk"); } +#if defined(J9VM_OPT_OPENJDK_METHODHANDLE) +TR_OpaqueMethodBlock* +TR_J9VMBase::targetMethodFromMemberName(TR::Compilation* comp, TR::KnownObjectTable::Index objIndex) + { + auto knot = comp->getKnownObjectTable(); + if (objIndex != TR::KnownObjectTable::UNKNOWN && + knot && + !knot->isNull(objIndex)) + { + TR::VMAccessCriticalSection getTarget(this); + uintptr_t object = knot->getPointer(objIndex); + return targetMethodFromMemberName(object); + } + return NULL; + } + +TR_OpaqueMethodBlock* +TR_J9VMBase::targetMethodFromMemberName(uintptr_t memberName) + { + TR_ASSERT(haveAccess(), "targetFromMemberName requires VM access"); + return (TR_OpaqueMethodBlock*)J9OBJECT_U64_LOAD(vmThread(), memberName, vmThread()->javaVM->vmtargetOffset); + } + +TR_OpaqueMethodBlock* +TR_J9VMBase::targetMethodFromMethodHandle(TR::Compilation* comp, TR::KnownObjectTable::Index objIndex) + { + auto knot = comp->getKnownObjectTable(); + if (objIndex != TR::KnownObjectTable::UNKNOWN && + knot && + !knot->isNull(objIndex)) + { + TR::VMAccessCriticalSection getTarget(this); + uintptr_t object = knot->getPointer(objIndex); + return targetMethodFromMethodHandle(object); + } + return NULL; + } + +TR_OpaqueMethodBlock* +TR_J9VMBase::targetMethodFromMethodHandle(uintptr_t methodHandle) + { + TR_ASSERT(haveAccess(), "targetFromMethodHandle requires VM access"); + uintptr_t form = getReferenceField( + methodHandle, + "form", "Ljava/lang/invoke/LambdaForm;"); + uintptr_t vmentry = getReferenceField( + form, + "vmentry", "Ljava/lang/invoke/MemberName;"); + return targetMethodFromMemberName(vmentry); + } +#endif /* defined(J9VM_OPT_OPENJDK_METHODHANDLE) */ + /** * \brief * Check if two java/lang/String objects are equal. Equivalent to java/lang/String.equals. diff --git a/runtime/compiler/env/VMJ9.h b/runtime/compiler/env/VMJ9.h index c74c2a01226..0090a58ecca 100644 --- a/runtime/compiler/env/VMJ9.h +++ b/runtime/compiler/env/VMJ9.h @@ -754,6 +754,36 @@ class TR_J9VMBase : public TR_FrontEnd bool hasMethodTypesSideTable(); + // Openjdk implementation +#if defined(J9VM_OPT_OPENJDK_METHODHANDLE) + /* + * \brief + * Return MemberName.vmtarget, a J9method pointer for method represented by `memberName` + * Caller must acquire VM access + */ + TR_OpaqueMethodBlock* targetMethodFromMemberName(uintptr_t memberName); + /* + * \brief + * Return MemberName.vmtarget, a J9method pointer for method represented by `memberName` + * VM access is not required + */ + TR_OpaqueMethodBlock* targetMethodFromMemberName(TR::Compilation* comp, TR::KnownObjectTable::Index objIndex); + /* + * \brief + * Return MethodHandle.form.vmentry.vmtarget, J9method for the underlying java method + * The J9Method is the target to be invoked intrinsically by MethodHandle.invokeBasic + * Caller must acquire VM access + */ + TR_OpaqueMethodBlock* targetMethodFromMethodHandle(uintptr_t methodHandle); + /* + * \brief + * Return MethodHandle.form.vmentry.vmtarget, J9method for the underlying java method + * The J9Method is the target to be invoked intrinsically by MethodHandle.invokeBasic + * VM access is not required + */ + TR_OpaqueMethodBlock* targetMethodFromMethodHandle(TR::Compilation* comp, TR::KnownObjectTable::Index objIndex); +#endif + // JSR292 }}} virtual uintptr_t getFieldOffset( TR::Compilation * comp, TR::SymbolReference* classRef, TR::SymbolReference* fieldRef);