Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve linkToVirtual() and linkToInterface() dispatch #17850

Merged
merged 2 commits into from
Aug 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions runtime/codert_vm/arm64nathelp.m4
Original file line number Diff line number Diff line change
Expand Up @@ -321,8 +321,10 @@ OLD_DUAL_MODE_HELPER_NO_RETURN_VALUE(jitPutFlattenableStaticField,3)
OLD_DUAL_MODE_HELPER(jitLoadFlattenableArrayElement,2)
OLD_DUAL_MODE_HELPER_NO_RETURN_VALUE(jitStoreFlattenableArrayElement,3)
SLOW_PATH_ONLY_HELPER_NO_RETURN_VALUE(jitResolveFlattenableField,3)
FAST_PATH_ONLY_HELPER(jitLookupDynamicInterfaceMethod,3)
OLD_DUAL_MODE_HELPER(jitLookupDynamicPublicInterfaceMethod,3)

ifdef({ASM_J9VM_OPT_OPENJDK_METHODHANDLE},{
gacholio marked this conversation as resolved.
Show resolved Hide resolved
OLD_DUAL_MODE_HELPER(jitLookupDynamicPublicInterfaceMethod,2)
}) dnl ASM_J9VM_OPT_OPENJDK_METHODHANDLE

dnl Trap handlers

Expand Down
6 changes: 4 additions & 2 deletions runtime/codert_vm/armnathelp.m4
Original file line number Diff line number Diff line change
Expand Up @@ -299,8 +299,10 @@ OLD_DUAL_MODE_HELPER_NO_RETURN_VALUE(jitPutFlattenableStaticField,3)
OLD_DUAL_MODE_HELPER(jitLoadFlattenableArrayElement,2)
OLD_DUAL_MODE_HELPER_NO_RETURN_VALUE(jitStoreFlattenableArrayElement,3)
SLOW_PATH_ONLY_HELPER_NO_RETURN_VALUE(jitResolveFlattenableField,3)
FAST_PATH_ONLY_HELPER(jitLookupDynamicInterfaceMethod,3)
OLD_DUAL_MODE_HELPER(jitLookupDynamicPublicInterfaceMethod,3)

ifdef({ASM_J9VM_OPT_OPENJDK_METHODHANDLE},{
OLD_DUAL_MODE_HELPER(jitLookupDynamicPublicInterfaceMethod,2)
}) dnl ASM_J9VM_OPT_OPENJDK_METHODHANDLE

dnl Trap handlers

Expand Down
27 changes: 10 additions & 17 deletions runtime/codert_vm/cnathelp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1623,19 +1623,7 @@ old_fast_jitLookupInterfaceMethod(J9VMThread *currentThread)
return slowPath;
}

void J9FASTCALL
old_fast_jitLookupDynamicInterfaceMethod(J9VMThread *currentThread)
{
OLD_JIT_HELPER_PROLOGUE(3);
DECLARE_JIT_CLASS_PARM(receiverClass, 1);
DECLARE_JIT_CLASS_PARM(interfaceClass, 2);
DECLARE_JIT_PARM(UDATA, iTableIndex, 3);
UDATA iTableOffset = sizeof(struct J9ITable) + (iTableIndex * sizeof(UDATA));
UDATA vTableOffset = convertITableOffsetToVTableOffset(currentThread, receiverClass, interfaceClass, iTableOffset);
Assert_CodertVM_false(0 == vTableOffset);
JIT_RETURN_UDATA(vTableOffset);
}

#if defined(J9VM_OPT_OPENJDK_METHODHANDLE)
void* J9FASTCALL
old_slow_jitLookupDynamicPublicInterfaceMethod(J9VMThread *currentThread)
{
Expand All @@ -1651,10 +1639,13 @@ void* J9FASTCALL
old_fast_jitLookupDynamicPublicInterfaceMethod(J9VMThread *currentThread)
{
void *slowPath = (void*)old_slow_jitLookupDynamicPublicInterfaceMethod;
OLD_JIT_HELPER_PROLOGUE(3);
OLD_JIT_HELPER_PROLOGUE(2);
DECLARE_JIT_CLASS_PARM(receiverClass, 1);
DECLARE_JIT_CLASS_PARM(interfaceClass, 2);
DECLARE_JIT_PARM(UDATA, iTableIndex, 3);
DECLARE_JIT_PARM(j9object_t, memberName, 2);
J9JavaVM *vm = currentThread->javaVM;
J9Method *interfaceMethod = (J9Method *)(UDATA)J9OBJECT_U64_LOAD(currentThread, memberName, vm->vmtargetOffset);
J9Class *interfaceClass = J9_CLASS_FROM_METHOD(interfaceMethod);
UDATA iTableIndex = (UDATA)J9OBJECT_U64_LOAD(currentThread, memberName, vm->vmindexOffset);
UDATA iTableOffset = sizeof(struct J9ITable) + (iTableIndex * sizeof(UDATA));
UDATA vTableOffset = convertITableOffsetToVTableOffset(currentThread, receiverClass, interfaceClass, iTableOffset);
Assert_CodertVM_false(0 == vTableOffset);
Expand All @@ -1668,6 +1659,7 @@ old_fast_jitLookupDynamicPublicInterfaceMethod(J9VMThread *currentThread)
}
return slowPath;
}
#endif /* defined(J9VM_OPT_OPENJDK_METHODHANDLE) */

void J9FASTCALL
old_fast_jitMethodIsNative(J9VMThread *currentThread)
Expand Down Expand Up @@ -3961,9 +3953,10 @@ initPureCFunctionTable(J9JavaVM *vm)
jitConfig->old_fast_jitInstanceOf = (void*)old_fast_jitInstanceOf;
jitConfig->old_fast_jitLookupInterfaceMethod = (void*)old_fast_jitLookupInterfaceMethod;
jitConfig->old_slow_jitLookupInterfaceMethod = (void*)old_slow_jitLookupInterfaceMethod;
jitConfig->old_fast_jitLookupDynamicInterfaceMethod = (void*)old_fast_jitLookupDynamicInterfaceMethod;
#if defined(J9VM_OPT_OPENJDK_METHODHANDLE)
jitConfig->old_fast_jitLookupDynamicPublicInterfaceMethod = (void*)old_fast_jitLookupDynamicPublicInterfaceMethod;
jitConfig->old_slow_jitLookupDynamicPublicInterfaceMethod = (void*)old_slow_jitLookupDynamicPublicInterfaceMethod;
#endif /* defined(J9VM_OPT_OPENJDK_METHODHANDLE) */
jitConfig->old_fast_jitMethodIsNative = (void*)old_fast_jitMethodIsNative;
jitConfig->old_fast_jitMethodIsSync = (void*)old_fast_jitMethodIsSync;
jitConfig->old_fast_jitMethodMonitorEntry = (void*)old_fast_jitMethodMonitorEntry;
Expand Down
6 changes: 4 additions & 2 deletions runtime/codert_vm/pnathelp.m4
Original file line number Diff line number Diff line change
Expand Up @@ -369,8 +369,10 @@ OLD_DUAL_MODE_HELPER_NO_RETURN_VALUE(jitPutFlattenableStaticField,3)
OLD_DUAL_MODE_HELPER(jitLoadFlattenableArrayElement,2)
OLD_DUAL_MODE_HELPER_NO_RETURN_VALUE(jitStoreFlattenableArrayElement,3)
SLOW_PATH_ONLY_HELPER_NO_RETURN_VALUE(jitResolveFlattenableField,3)
FAST_PATH_ONLY_HELPER(jitLookupDynamicInterfaceMethod,3)
OLD_DUAL_MODE_HELPER(jitLookupDynamicPublicInterfaceMethod,3)

ifdef({ASM_J9VM_OPT_OPENJDK_METHODHANDLE},{
OLD_DUAL_MODE_HELPER(jitLookupDynamicPublicInterfaceMethod,2)
}) dnl ASM_J9VM_OPT_OPENJDK_METHODHANDLE

dnl Trap handlers

Expand Down
6 changes: 4 additions & 2 deletions runtime/codert_vm/riscvnathelp.m4
Original file line number Diff line number Diff line change
Expand Up @@ -292,8 +292,10 @@ OLD_DUAL_MODE_HELPER(jitGetFlattenableStaticField,2)
OLD_DUAL_MODE_HELPER_NO_RETURN_VALUE(jitPutFlattenableStaticField,3)
OLD_DUAL_MODE_HELPER(jitLoadFlattenableArrayElement,2)
OLD_DUAL_MODE_HELPER_NO_RETURN_VALUE(jitStoreFlattenableArrayElement,3)
FAST_PATH_ONLY_HELPER(jitLookupDynamicInterfaceMethod,3)
OLD_DUAL_MODE_HELPER(jitLookupDynamicPublicInterfaceMethod,3)

ifdef({ASM_J9VM_OPT_OPENJDK_METHODHANDLE},{
OLD_DUAL_MODE_HELPER(jitLookupDynamicPublicInterfaceMethod,2)
}) dnl ASM_J9VM_OPT_OPENJDK_METHODHANDLE

dnl Trap handlers

Expand Down
6 changes: 4 additions & 2 deletions runtime/codert_vm/xnathelp.m4
Original file line number Diff line number Diff line change
Expand Up @@ -419,8 +419,10 @@ OLD_DUAL_MODE_HELPER_NO_RETURN_VALUE(jitPutFlattenableStaticField,3)
OLD_DUAL_MODE_HELPER(jitLoadFlattenableArrayElement,2)
OLD_DUAL_MODE_HELPER_NO_RETURN_VALUE(jitStoreFlattenableArrayElement,3)
SLOW_PATH_ONLY_HELPER_NO_RETURN_VALUE(jitResolveFlattenableField,3)
FAST_PATH_ONLY_HELPER(jitLookupDynamicInterfaceMethod,3)
OLD_DUAL_MODE_HELPER(jitLookupDynamicPublicInterfaceMethod,3)

ifdef({ASM_J9VM_OPT_OPENJDK_METHODHANDLE},{
OLD_DUAL_MODE_HELPER(jitLookupDynamicPublicInterfaceMethod,2)
}) dnl ASM_J9VM_OPT_OPENJDK_METHODHANDLE

dnl Trap handlers

Expand Down
6 changes: 4 additions & 2 deletions runtime/codert_vm/znathelp.m4
Original file line number Diff line number Diff line change
Expand Up @@ -344,8 +344,10 @@ OLD_DUAL_MODE_HELPER_NO_RETURN_VALUE(jitPutFlattenableStaticField,3)
OLD_DUAL_MODE_HELPER(jitLoadFlattenableArrayElement,2)
OLD_DUAL_MODE_HELPER_NO_RETURN_VALUE(jitStoreFlattenableArrayElement,3)
SLOW_PATH_ONLY_HELPER_NO_RETURN_VALUE(jitResolveFlattenableField,3)
FAST_PATH_ONLY_HELPER(jitLookupDynamicInterfaceMethod,3)
OLD_DUAL_MODE_HELPER(jitLookupDynamicPublicInterfaceMethod,3)

ifdef({ASM_J9VM_OPT_OPENJDK_METHODHANDLE},{
OLD_DUAL_MODE_HELPER(jitLookupDynamicPublicInterfaceMethod,2)
}) dnl ASM_J9VM_OPT_OPENJDK_METHODHANDLE

dnl Trap handlers

Expand Down
29 changes: 22 additions & 7 deletions runtime/compiler/compile/J9SymbolReferenceTable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -306,13 +306,6 @@ J9::SymbolReferenceTable::findOrCreateStoreFlattenableArrayElementSymbolRef(TR::
}


TR::SymbolReference *
J9::SymbolReferenceTable::findOrCreateLookupDynamicInterfaceMethodSymbolRef()
{
return findOrCreateRuntimeHelper(TR_jitLookupDynamicInterfaceMethod, false, false, true);
}


TR::SymbolReference *
J9::SymbolReferenceTable::findOrCreateLookupDynamicPublicInterfaceMethodSymbolRef()
{
Expand Down Expand Up @@ -860,6 +853,28 @@ J9::SymbolReferenceTable::findOrFabricateShadowSymbol(
return symRef;
}

#if defined(J9VM_OPT_OPENJDK_METHODHANDLE)
TR::SymbolReference *
J9::SymbolReferenceTable::findOrFabricateMemberNameVmTargetShadow()
{
bool isVolatile = false;
bool isPrivate = false;
bool isFinal = true;
TR::SymbolReference *symRef = self()->findOrFabricateShadowSymbol(
comp()->getMethodSymbol(),
TR::Symbol::Java_lang_invoke_MemberName_vmtarget,
TR::Address,
comp()->fej9()->getVMTargetOffset(),
isVolatile,
isPrivate,
isFinal,
"java/lang/invoke/MemberName.vmtarget J");

symRef->getSymbol()->setNotCollected();
return symRef;
}
#endif

TR::SymbolReference *
J9::SymbolReferenceTable::findFlattenedArrayElementFieldShadow(
ResolvedFieldShadowKey key,
Expand Down
16 changes: 9 additions & 7 deletions runtime/compiler/compile/J9SymbolReferenceTable.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,16 +159,13 @@ class SymbolReferenceTable : public OMR::SymbolReferenceTableConnector

// This helper walks the iTables to find the VFT offset for an interface
// method that is not known until runtime (and therefore does not have an
// IPIC data snippet). The parameters are the receiver class, interface
// class, and iTable index (though in the trees they must appear as
// children in the opposite order), and the return value is the VFT offset.
// IPIC data snippet). The parameters are the receiver class and MemberName
// (though in the trees they must appear as children in the opposite order),
// and the return value is the VFT offset.
//
// The given receiver class must implement the given interface class.
// IllegalAccessError is thrown if the dispatched callee is not public.
//
TR::SymbolReference * findOrCreateLookupDynamicInterfaceMethodSymbolRef();

// This helper is a variant of jitLookupDynamicInterfaceMethod that requires
// the dispatched callee to be public, otherwise throwing IllegalAccessError.
TR::SymbolReference * findOrCreateLookupDynamicPublicInterfaceMethodSymbolRef();

TR::SymbolReference * findOrCreateShadowSymbol(TR::ResolvedMethodSymbol * owningMethodSymbol, int32_t cpIndex, bool isStore);
Expand Down Expand Up @@ -201,6 +198,11 @@ class SymbolReferenceTable : public OMR::SymbolReferenceTableConnector
*/
TR::SymbolReference * findOrFabricateShadowSymbol(TR_OpaqueClassBlock *containingClass, TR::DataType type, uint32_t offset, bool isVolatile, bool isPrivate, bool isFinal, const char *name, const char *signature);

#if defined(J9VM_OPT_OPENJDK_METHODHANDLE)
/// Find or fabricate the shadow symref for MemberName.vmtarget
TR::SymbolReference * findOrFabricateMemberNameVmTargetShadow();
#endif

/** \brief
* Returns an array shadow symbol reference fabricated for the field of a flattened array element.
*
Expand Down
6 changes: 4 additions & 2 deletions runtime/compiler/control/JITClientCompilationThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1135,10 +1135,12 @@ handleServerMessage(JITServer::ClientStream *client, TR_J9VM *fe, JITServer::Mes
client->write(response, fe->isLambdaFormGeneratedMethod(std::get<0>(recv)));
}
break;
case MessageType::VM_vTableOrITableIndexFromMemberName:
case MessageType::VM_getMemberNameMethodInfo:
{
auto recv = client->getRecvData<TR::KnownObjectTable::Index>();
client->write(response, fe->vTableOrITableIndexFromMemberName(comp, std::get<0>(recv)));
TR_J9VMBase::MemberNameMethodInfo info = {};
uintptr_t ok = fe->getMemberNameMethodInfo(comp, std::get<0>(recv), &info);
gacholio marked this conversation as resolved.
Show resolved Hide resolved
client->write(response, ok, info.vmtarget, info.vmindex, info.clazz, info.refKind);
}
break;
case MessageType::VM_delegatingMethodHandleTarget:
Expand Down
71 changes: 33 additions & 38 deletions runtime/compiler/env/VMJ9.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4755,49 +4755,44 @@ TR_J9VMBase::targetMethodFromMethodHandle(TR::Compilation* comp, TR::KnownObject
return NULL;
}

J9JNIMethodID*
TR_J9VMBase::jniMethodIdFromMemberName(uintptr_t memberName)
bool
TR_J9VMBase::getMemberNameMethodInfo(
TR::Compilation* comp,
TR::KnownObjectTable::Index objIndex,
MemberNameMethodInfo *out)
{
TR_ASSERT(haveAccess(), "jniMethodIdFromMemberName requires VM access");
return (J9JNIMethodID *)J9OBJECT_U64_LOAD(vmThread(), memberName, vmThread()->javaVM->vmindexOffset);
}
*out = {};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't compile on z/OS:

13:10:07  "/jenkins/workspace/Build_JDK17_s390x_zos_Personal/openj9/runtime/compiler/env/VMJ9.cpp", line 4764.11: CCN5063 (S) The text "{" is unexpected.
13:10:07  CCN0793(I) Compilation failed for file /jenkins/workspace/Build_JDK17_s390x_zos_Personal/openj9/runtime/compiler/env/VMJ9.cpp.  Object file not created.
13:10:07  runtime/compiler/CMakeFiles/j9jit.dir/build.make:960: recipe for target 'runtime/compiler/CMakeFiles/j9jit.dir/env/VMJ9.cpp.o' failed
13:10:07  make[6]: *** [runtime/compiler/CMakeFiles/j9jit.dir/env/VMJ9.cpp.o] Error 12

@jdmpapin Is there another way to say this that will be accepted by older compilers?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should it be {0} perhaps?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The text "{" is unexpected.

suggests that we might get the same error from {0}. I think {} should work as an initializer though. I'll try this:

MemberNameMethodInfo zero = {};
*out = zero;

and of course check to make sure that it compiles on z/OS

Copy link
Contributor Author

@jdmpapin jdmpapin Sep 7, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like it should work to use

MemberNameMethodInfo zero = {0};

With {}, the build compiler complained that zero was potentially uninitialized

My personal z/OS build failed for a reason I don't understand. I think it's unrelated, but I've asked for some help confirming that my change builds. I'll open a PR as soon as I get confirmation

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


if (objIndex == TR::KnownObjectTable::UNKNOWN)
return false;

J9JNIMethodID*
TR_J9VMBase::jniMethodIdFromMemberName(TR::Compilation* comp, TR::KnownObjectTable::Index objIndex)
{
auto knot = comp->getKnownObjectTable();
if (objIndex != TR::KnownObjectTable::UNKNOWN &&
knot &&
!knot->isNull(objIndex))
{
TR::VMAccessCriticalSection jniMethodId(this);
uintptr_t object = knot->getPointer(objIndex);
return jniMethodIdFromMemberName(object);
}
return NULL;
}
if (knot == NULL || knot->isNull(objIndex))
return false;

uintptr_t
TR_J9VMBase::vTableOrITableIndexFromMemberName(uintptr_t memberName)
{
TR_ASSERT(haveAccess(), "vTableOrITableIndexFromMemberName requires VM access");
auto methodID = jniMethodIdFromMemberName(memberName);
return methodID->vTableIndex;
}
TR::VMAccessCriticalSection getMemberNameMethodInfo(this);
uintptr_t object = knot->getPointer(objIndex);
const char *mnClassName = "java/lang/invoke/MemberName";
int32_t mnClassNameLen = (int32_t)strlen(mnClassName);
TR_OpaqueClassBlock *mnClass =
getSystemClassFromClassName(mnClassName, mnClassNameLen);

uintptr_t
TR_J9VMBase::vTableOrITableIndexFromMemberName(TR::Compilation* comp, TR::KnownObjectTable::Index objIndex)
{
auto knot = comp->getKnownObjectTable();
if (objIndex != TR::KnownObjectTable::UNKNOWN &&
knot &&
!knot->isNull(objIndex))
{
TR::VMAccessCriticalSection vTableOrITableIndex(this);
uintptr_t object = knot->getPointer(objIndex);
return vTableOrITableIndexFromMemberName(object);
}
return (uintptr_t)-1;
if (getObjectClass(object) != mnClass)
return false;

int32_t flags = getInt32Field(object, "flags");
if ((flags & (MN_IS_METHOD | MN_IS_CONSTRUCTOR)) == 0)
return false;

auto tgt = J9OBJECT_U64_LOAD(vmThread(), object, vmThread()->javaVM->vmtargetOffset);
auto ix = J9OBJECT_U64_LOAD(vmThread(), object, vmThread()->javaVM->vmindexOffset);
uintptr_t jlClass = getReferenceField(object, "clazz", "Ljava/lang/Class;");

out->vmtarget = (TR_OpaqueMethodBlock*)(uintptr_t)tgt;
out->vmindex = (uintptr_t)ix;
out->clazz = getClassFromJavaLangClass(jlClass);
out->refKind = (flags >> MN_REFERENCE_KIND_SHIFT) & MN_REFERENCE_KIND_MASK;
return true;
}

bool
Expand Down
42 changes: 20 additions & 22 deletions runtime/compiler/env/VMJ9.h
Original file line number Diff line number Diff line change
Expand Up @@ -875,30 +875,28 @@ class TR_J9VMBase : public TR_FrontEnd
* VM access is not required
*/
virtual TR_OpaqueMethodBlock* targetMethodFromMethodHandle(TR::Compilation* comp, TR::KnownObjectTable::Index objIndex);

/// A summary of the method dispatch information in a MemberName.
struct MemberNameMethodInfo
{
TR_OpaqueMethodBlock *vmtarget; ///< the target J9Method
uintptr_t vmindex; ///< the interpreter vtable offset, itable index, or -1
TR_OpaqueClassBlock *clazz; ///< the relevant subtype of the defining class of vmtarget
int32_t refKind; ///< one of the MH_REF_* constants (JVMS table 5.4.3.5-A)
};

/*
* \brief
* Return MemberName.vmindex, a J9JNIMethodID pointer containing vtable/itable offset for the MemberName method
* Caller must acquire VM access
*/
virtual J9JNIMethodID* jniMethodIdFromMemberName(uintptr_t memberName);
/*
* \brief
* Return MemberName.vmindex, a J9JNIMethodID pointer containing vtable/itable offset for the MemberName method
* VM access is not required
*/
virtual J9JNIMethodID* jniMethodIdFromMemberName(TR::Compilation* comp, TR::KnownObjectTable::Index objIndex);
/*
* \brief
* Return vtable or itable index of a method represented by MemberName
* Caller must acquire VM access
*/
virtual uintptr_t vTableOrITableIndexFromMemberName(uintptr_t memberName);
/*
* \brief
* Return vtable or itable index of a method represented by MemberName
* VM access is not required
* \brief Summarize a MemberName representing a method or constructor.
*
* \param comp the compilation object
* \param objIndex the known object index of the MemberName object
* \param[out] out filled on success, zeroed on failure
* \return true on success, false on error (e.g. not a MemberName)
*/
virtual uintptr_t vTableOrITableIndexFromMemberName(TR::Compilation* comp, TR::KnownObjectTable::Index objIndex);
virtual bool getMemberNameMethodInfo(
TR::Compilation* comp,
TR::KnownObjectTable::Index objIndex,
MemberNameMethodInfo *out);

/**
* \brief
Expand Down
Loading