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

Do not skip InjectedInvoker class in getCallerClass and getStackClass #18285

Merged
merged 1 commit into from
Oct 20, 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
11 changes: 3 additions & 8 deletions runtime/bcutil/ClassFileWriter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -358,15 +358,10 @@ class ClassFileWriter {
U_16 originalNameLength = anonNameLength - ROM_ADDRESS_LENGTH - 1;
U_8 *anonClassNameData = J9UTF8_DATA(_anonClassName);
#if defined(J9VM_OPT_OPENJDK_METHODHANDLE)
/* ROM class format: <HOST_NAME>/InjectedInvoker/<ROM_ADDRESS_LENGTH>.
* Search for InjectedInvoker in _anonClassName using the above format.
* If found, reset the class name to "InjectedInvoker" in the class file.
/* If the class is an InjectedInvoker, reset the class name to
* "InjectedInvoker" in the class file.
*/
IDATA startIndex = anonNameLength - J9UTF8_LENGTH(&injectedInvokerClassname) - ROM_ADDRESS_LENGTH - 1;
U_8 *start = anonClassNameData + startIndex;
if ((startIndex >= 0)
&& (0 == memcmp(start, J9UTF8_DATA(&injectedInvokerClassname), J9UTF8_LENGTH(&injectedInvokerClassname)))
) {
if (J9_ARE_ALL_BITS_SET(_romClass->extraModifiers, J9AccClassIsInjectedInvoker)) {
_isInjectedInvoker = TRUE;
originalNameLength = J9UTF8_LENGTH(&injectedInvokerClassname);
anonClassNameData = J9UTF8_DATA(&injectedInvokerClassname);
Expand Down
36 changes: 33 additions & 3 deletions runtime/bcutil/ROMClassBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ ROMClassBuilder::handleAnonClassName(J9CfrClassFile *classfile, bool *isLambda,
UDATA hostPackageLength = context->hostPackageLength();
PORT_ACCESS_FROM_PORT(_portLibrary);

#if defined(J9VM_OPT_OPENJDK_METHODHANDLE)
#if defined(J9VM_OPT_OPENJDK_METHODHANDLE) && (JAVA_SPEC_VERSION >= 15)
/* InjectedInvoker is a hidden class without the strong attribute set. It
* is created by MethodHandleImpl.makeInjectedInvoker on the OpenJDK side.
* So, OpenJ9 does not have control over the implementation of InjectedInvoker.
Expand Down Expand Up @@ -321,7 +321,7 @@ ROMClassBuilder::handleAnonClassName(J9CfrClassFile *classfile, bool *isLambda,
}
#undef J9_INJECTED_INVOKER_CLASSNAME
}
#endif /* defined(J9VM_OPT_OPENJDK_METHODHANDLE) */
#endif /* defined(J9VM_OPT_OPENJDK_METHODHANDLE) && (JAVA_SPEC_VERSION >= 15) */

/* check if adding host package name to anonymous class is needed */
UDATA newHostPackageLength = 0;
Expand Down Expand Up @@ -1180,7 +1180,7 @@ ROMClassBuilder::finishPrepareAndLaydown(
* + AccRecord
* + AccClassAnonClass
*
* + UNUSED
* + J9AccClassIsInjectedInvoker
* + AccClassUseBisectionSearch
* + AccClassInnerClass
* + J9AccClassHidden
Expand Down Expand Up @@ -1259,6 +1259,12 @@ ROMClassBuilder::computeExtraModifiers(ClassFileOracle *classFileOracle, ROMClas
modifiers |= J9AccClassIsValueBased;
}

#if defined(J9VM_OPT_OPENJDK_METHODHANDLE)
if (isInjectedInvoker()) {
modifiers |= J9AccClassIsInjectedInvoker;
}
#endif /* defined(J9VM_OPT_OPENJDK_METHODHANDLE) */

U_32 classNameindex = classFileOracle->getClassNameIndex();

#define WEAK_NAME "java/lang/ref/WeakReference"
Expand Down Expand Up @@ -1558,3 +1564,27 @@ ROMClassBuilder::getSharedCacheSRPRangeInfo(void *address)
}
#endif
#endif

#if defined(J9VM_OPT_OPENJDK_METHODHANDLE)
bool
ROMClassBuilder::isInjectedInvoker(void) const
{
#define J9_INJECTED_INVOKER_CLASSNAME "InjectedInvoker"
/* InjectedInvoker classes are anon or hidden */
bool result = false;
if (NULL != _anonClassNameBuffer) {
IDATA injectedInvokerLength = LITERAL_STRLEN(J9_INJECTED_INVOKER_CLASSNAME);
/* computeExtraModifiers is called after appending 0's to hidden and anoymous classes. */
IDATA startIndex = strlen((const char *)_anonClassNameBuffer) - injectedInvokerLength - ROM_ADDRESS_LENGTH - 1;
if (startIndex >= 0) {
/* start is the potential beginning of "InjectedInvoker", after the potential package name. */
U_8 *start = _anonClassNameBuffer + startIndex;
if (0 == memcmp(start, J9_INJECTED_INVOKER_CLASSNAME, injectedInvokerLength)) {
result = true;
}
}
}
return result;
#undef J9_INJECTED_INVOKER_CLASSNAME
}
#endif /* defined(J9VM_OPT_OPENJDK_METHODHANDLE) */
3 changes: 3 additions & 0 deletions runtime/bcutil/ROMClassBuilder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,9 @@ class ROMClassBuilder
U_32 modifiers, U_32 extraModifiers, U_32 optionalFlags, ROMClassCreationContext * context, U_32 sizeToCompareForLambda, bool isLambda);
SharedCacheRangeInfo getSharedCacheSRPRangeInfo(void *address);
void getSizeInfo(ROMClassCreationContext *context, ROMClassWriter *romClassWriter, SRPOffsetTable *srpOffsetTable, bool *countDebugDataOutOfLine, SizeInformation *sizeInformation);
#if defined(J9VM_OPT_OPENJDK_METHODHANDLE)
bool isInjectedInvoker(void) const;
#endif /* defined(J9VM_OPT_OPENJDK_METHODHANDLE) */
};

#endif /* ROMCLASSBUILDER_HPP_ */
1 change: 1 addition & 0 deletions runtime/oti/j9javaaccessflags.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@
#define J9AccSealed 0x200
#define J9AccRecord 0x400
#define J9AccClassAnonClass 0x800
#define J9AccClassIsInjectedInvoker 0x1000
ThanHenderson marked this conversation as resolved.
Show resolved Hide resolved
#define J9AccClassUseBisectionSearch 0x2000
#define J9AccClassInnerClass 0x4000
#define J9AccClassHidden 0x8000
Expand Down
21 changes: 14 additions & 7 deletions runtime/sunvmi/sunvmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -209,15 +209,23 @@ getCallerClassIterator(J9VMThread * currentThread, J9StackWalkState * walkState)


static UDATA
getCallerClassJEP176Iterator(J9VMThread * currentThread, J9StackWalkState * walkState)
getCallerClassJEP176Iterator(J9VMThread *currentThread, J9StackWalkState *walkState)
ThanHenderson marked this conversation as resolved.
Show resolved Hide resolved
{
J9JavaVM * vm = currentThread->javaVM;
J9JavaVM *vm = currentThread->javaVM;
J9InternalVMFunctions *vmFuncs = vm->internalVMFunctions;
J9Class * currentClass = J9_CLASS_FROM_CP(walkState->constantPool);
J9Class *currentClass = J9_CLASS_FROM_CP(walkState->constantPool);

Assert_SunVMI_mustHaveVMAccess(currentThread);

if (J9_ARE_ALL_BITS_SET(J9_ROM_METHOD_FROM_RAM_METHOD(walkState->method)->modifiers, J9AccMethodFrameIteratorSkip)) {
if (J9_ARE_ALL_BITS_SET(J9_ROM_METHOD_FROM_RAM_METHOD(walkState->method)->modifiers, J9AccMethodFrameIteratorSkip)
#if defined(J9VM_OPT_OPENJDK_METHODHANDLE) && (JAVA_SPEC_VERSION <= 11)
/* Do not skip InjectedInvoker classes despite them having the J9AccMethodFrameIteratorSkip
* modifier set via the @Hidden attribute. Skipping them causes incorrect, unexpected
* behaviour when using OpenJDK method handles pre-hidden-class support.
*/
&& J9_ARE_NO_BITS_SET(currentClass->romClass->extraModifiers, J9AccClassIsInjectedInvoker)
#endif /* defined(J9VM_OPT_OPENJDK_METHODHANDLE) && (JAVA_SPEC_VERSION <= 11) */
) {
/* Skip methods with java.lang.invoke.FrameIteratorSkip / jdk.internal.vm.annotation.Hidden / java.lang.invoke.LambdaForm$Hidden annotation */
return J9_STACKWALK_KEEP_ITERATING;
}
Expand All @@ -239,8 +247,8 @@ getCallerClassJEP176Iterator(J9VMThread * currentThread, J9StackWalkState * walk
#if JAVA_SPEC_VERSION >= 18
|| (walkState->method == vm->jlrMethodInvokeMH)
#endif /* JAVA_SPEC_VERSION >= 18 */
|| (vm->srMethodAccessor && vmFuncs->instanceOfOrCheckCast(currentClass, J9VM_J9CLASS_FROM_HEAPCLASS(currentThread, *((j9object_t*) vm->srMethodAccessor))))
|| (vm->srConstructorAccessor && vmFuncs->instanceOfOrCheckCast(currentClass, J9VM_J9CLASS_FROM_HEAPCLASS(currentThread, *((j9object_t*) vm->srConstructorAccessor))))
|| (vm->srMethodAccessor && vmFuncs->instanceOfOrCheckCast(currentClass, J9VM_J9CLASS_FROM_HEAPCLASS(currentThread, *((j9object_t *)vm->srMethodAccessor))))
|| (vm->srConstructorAccessor && vmFuncs->instanceOfOrCheckCast(currentClass, J9VM_J9CLASS_FROM_HEAPCLASS(currentThread, *((j9object_t *)vm->srConstructorAccessor))))
) {
/* skip reflection classes and MethodHandle.invokeWithArguments() when reaching depth 0 */
return J9_STACKWALK_KEEP_ITERATING;
Expand All @@ -254,7 +262,6 @@ getCallerClassJEP176Iterator(J9VMThread * currentThread, J9StackWalkState * walk
return J9_STACKWALK_KEEP_ITERATING;
}


/**
* JVM_GetCallerClass
*/
Expand Down
20 changes: 14 additions & 6 deletions runtime/vm/NativeHelpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,15 +82,23 @@ getInterfacesHelper(J9VMThread *currentThread, j9object_t clazz)
}

UDATA
cInterpGetStackClassJEP176Iterator(J9VMThread * currentThread, J9StackWalkState * walkState)
cInterpGetStackClassJEP176Iterator(J9VMThread *currentThread, J9StackWalkState *walkState)
{
J9JavaVM * vm = currentThread->javaVM;
J9Class * currentClass = J9_CLASS_FROM_CP(walkState->constantPool);
J9JavaVM *vm = currentThread->javaVM;
J9Class *currentClass = J9_CLASS_FROM_CP(walkState->constantPool);
J9InternalVMFunctions *vmFuncs = vm->internalVMFunctions;

Assert_VM_mustHaveVMAccess(currentThread);

if (J9_ARE_ALL_BITS_SET(J9_ROM_METHOD_FROM_RAM_METHOD(walkState->method)->modifiers, J9AccMethodFrameIteratorSkip)) {
if (J9_ARE_ALL_BITS_SET(J9_ROM_METHOD_FROM_RAM_METHOD(walkState->method)->modifiers, J9AccMethodFrameIteratorSkip)
#if defined(J9VM_OPT_OPENJDK_METHODHANDLE) && (JAVA_SPEC_VERSION <= 11)
/* Do not skip InjectedInvoker classes despite them having the J9AccMethodFrameIteratorSkip
* modifier set via the @Hidden attribute. Skipping them causes incorrect, unexpected
* behaviour when using OpenJDK method handles pre-hidden-class support.
*/
&& J9_ARE_NO_BITS_SET(currentClass->romClass->extraModifiers, J9AccClassIsInjectedInvoker)
babsingh marked this conversation as resolved.
Show resolved Hide resolved
#endif /* defined(J9VM_OPT_OPENJDK_METHODHANDLE) && (JAVA_SPEC_VERSION <= 11) */
) {
/* Skip methods with java.lang.invoke.FrameIteratorSkip / jdk.internal.vm.annotation.Hidden / java.lang.invoke.LambdaForm$Hidden annotation */
return J9_STACKWALK_KEEP_ITERATING;
}
Expand All @@ -112,8 +120,8 @@ cInterpGetStackClassJEP176Iterator(J9VMThread * currentThread, J9StackWalkState
#if JAVA_SPEC_VERSION >= 18
|| (walkState->method == vm->jlrMethodInvokeMH)
#endif /* JAVA_SPEC_VERSION >= 18 */
|| (vm->srMethodAccessor && vmFuncs->instanceOfOrCheckCast(currentClass, J9VM_J9CLASS_FROM_HEAPCLASS(currentThread, *((j9object_t*) vm->srMethodAccessor))))
|| (vm->srConstructorAccessor && vmFuncs->instanceOfOrCheckCast(currentClass, J9VM_J9CLASS_FROM_HEAPCLASS(currentThread, *((j9object_t*) vm->srConstructorAccessor))))
|| (vm->srMethodAccessor && vmFuncs->instanceOfOrCheckCast(currentClass, J9VM_J9CLASS_FROM_HEAPCLASS(currentThread, *((j9object_t *)vm->srMethodAccessor))))
|| (vm->srConstructorAccessor && vmFuncs->instanceOfOrCheckCast(currentClass, J9VM_J9CLASS_FROM_HEAPCLASS(currentThread, *((j9object_t *)vm->srConstructorAccessor))))
) {
/* skip reflection classes and MethodHandle.invokeWithArguments() when reaching depth 0 */
return J9_STACKWALK_KEEP_ITERATING;
Expand Down