Skip to content

Commit

Permalink
Merge pull request #18285 from ThanHenderson/14553
Browse files Browse the repository at this point in the history
Do not skip InjectedInvoker class in getCallerClass and getStackClass
  • Loading branch information
babsingh committed Oct 20, 2023
2 parents fcad0b8 + e32653e commit 8ad165f
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 24 deletions.
11 changes: 3 additions & 8 deletions runtime/bcutil/ClassFileWriter.hpp
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
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
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
Expand Up @@ -107,6 +107,7 @@
#define J9AccSealed 0x200
#define J9AccRecord 0x400
#define J9AccClassAnonClass 0x800
#define J9AccClassIsInjectedInvoker 0x1000
#define J9AccClassUseBisectionSearch 0x2000
#define J9AccClassInnerClass 0x4000
#define J9AccClassHidden 0x8000
Expand Down
21 changes: 14 additions & 7 deletions runtime/sunvmi/sunvmi.c
Expand Up @@ -209,15 +209,23 @@ getCallerClassIterator(J9VMThread * currentThread, J9StackWalkState * walkState)


static UDATA
getCallerClassJEP176Iterator(J9VMThread * currentThread, J9StackWalkState * walkState)
getCallerClassJEP176Iterator(J9VMThread *currentThread, J9StackWalkState *walkState)
{
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
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)
#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

0 comments on commit 8ad165f

Please sign in to comment.