diff --git a/runtime/compiler/codegen/J9RecognizedMethodsEnum.hpp b/runtime/compiler/codegen/J9RecognizedMethodsEnum.hpp index 56e62e187aa..48119a2c0db 100644 --- a/runtime/compiler/codegen/J9RecognizedMethodsEnum.hpp +++ b/runtime/compiler/codegen/J9RecognizedMethodsEnum.hpp @@ -1151,6 +1151,13 @@ java_lang_invoke_MethodHandleImpl_profileBoolean, java_lang_invoke_MethodHandleImpl_isCompileConstant, + java_lang_invoke_VarHandleX_Array_method, + java_lang_invoke_VarHandleX_FieldInstanceReadOnlyOrReadWrite_method, + java_lang_invoke_VarHandleX_FieldStaticReadOnlyOrReadWrite_method, + + java_lang_invoke_VarHandleByteArrayAsX_ArrayHandle_method, + java_lang_invoke_VarHandleByteArrayAsX_ByteBufferHandle_method, + // Clone and Deep Copy java_lang_J9VMInternals_is32Bit, java_lang_J9VMInternals_isClassModifierPublic, diff --git a/runtime/compiler/env/j9method.cpp b/runtime/compiler/env/j9method.cpp index d5799044ef9..caf04c999f6 100644 --- a/runtime/compiler/env/j9method.cpp +++ b/runtime/compiler/env/j9method.cpp @@ -4524,6 +4524,245 @@ void TR_ResolvedJ9Method::construct() if (!strncmp(name, "invokeExact_thunkArchetype_", 27)) setRecognizedMethodInfo(TR::java_lang_invoke_InterfaceHandle_invokeExact); } +#if defined(J9VM_OPT_OPENJDK_METHODHANDLE) + // The classes containing VarHandle operator or access methods also contain methods that provide other functionality. + // There can be unintended consequences if we were to treat them the same way as VH operator/access methods. The VarHandle + // operator/access methods we need to recognize all have two things in common - they are static methods and their first + // parameter is Ljava/lang/invoke/VarHandle;, which is different from the non VH operator methods that we should not be + // treating the same way. The VH operator methods without the leading VH in the signature are just helper methods that + // are called from other VH operator methods which fulfil the leading VH parameter check. + else if (sigLen > 29 && !strncmp(sig, "(Ljava/lang/invoke/VarHandle;", 29) && isStatic()) + { + if ((classNameLen == 40 && !strncmp(className, "java/lang/invoke/VarHandleBooleans$Array", 40))) + { + setRecognizedMethodInfo(TR::java_lang_invoke_VarHandleX_Array_method); + } + else if ((classNameLen == 56 && !strncmp(className, "java/lang/invoke/VarHandleBooleans$FieldInstanceReadOnly", 56))) + { + setRecognizedMethodInfo(TR::java_lang_invoke_VarHandleX_FieldInstanceReadOnlyOrReadWrite_method); + } + else if ((classNameLen == 57 && !strncmp(className, "java/lang/invoke/VarHandleBooleans$FieldInstanceReadWrite", 57))) + { + setRecognizedMethodInfo(TR::java_lang_invoke_VarHandleX_FieldInstanceReadOnlyOrReadWrite_method); + } + else if ((classNameLen == 54 && !strncmp(className, "java/lang/invoke/VarHandleBooleans$FieldStaticReadOnly", 54))) + { + setRecognizedMethodInfo(TR::java_lang_invoke_VarHandleX_FieldStaticReadOnlyOrReadWrite_method); + } + else if ((classNameLen == 55 && !strncmp(className, "java/lang/invoke/VarHandleBooleans$FieldStaticReadWrite", 55))) + { + setRecognizedMethodInfo(TR::java_lang_invoke_VarHandleX_FieldStaticReadOnlyOrReadWrite_method); + } + else if ((classNameLen == 37 && !strncmp(className, "java/lang/invoke/VarHandleBytes$Array", 37))) + { + setRecognizedMethodInfo(TR::java_lang_invoke_VarHandleX_Array_method); + } + else if ((classNameLen == 53 && !strncmp(className, "java/lang/invoke/VarHandleBytes$FieldInstanceReadOnly", 53))) + { + setRecognizedMethodInfo(TR::java_lang_invoke_VarHandleX_FieldInstanceReadOnlyOrReadWrite_method); + } + else if ((classNameLen == 54 && !strncmp(className, "java/lang/invoke/VarHandleBytes$FieldInstanceReadWrite", 54))) + { + setRecognizedMethodInfo(TR::java_lang_invoke_VarHandleX_FieldInstanceReadOnlyOrReadWrite_method); + } + else if ((classNameLen == 51 && !strncmp(className, "java/lang/invoke/VarHandleBytes$FieldStaticReadOnly", 51))) + { + setRecognizedMethodInfo(TR::java_lang_invoke_VarHandleX_FieldStaticReadOnlyOrReadWrite_method); + } + else if ((classNameLen == 52 && !strncmp(className, "java/lang/invoke/VarHandleBytes$FieldStaticReadWrite", 52))) + { + setRecognizedMethodInfo(TR::java_lang_invoke_VarHandleX_FieldStaticReadOnlyOrReadWrite_method); + } + else if ((classNameLen == 37 && !strncmp(className, "java/lang/invoke/VarHandleChars$Array", 37))) + { + setRecognizedMethodInfo(TR::java_lang_invoke_VarHandleX_Array_method); + } + else if ((classNameLen == 53 && !strncmp(className, "java/lang/invoke/VarHandleChars$FieldInstanceReadOnly", 53))) + { + setRecognizedMethodInfo(TR::java_lang_invoke_VarHandleX_FieldInstanceReadOnlyOrReadWrite_method); + } + else if ((classNameLen == 54 && !strncmp(className, "java/lang/invoke/VarHandleChars$FieldInstanceReadWrite", 54))) + { + setRecognizedMethodInfo(TR::java_lang_invoke_VarHandleX_FieldInstanceReadOnlyOrReadWrite_method); + } + else if ((classNameLen == 51 && !strncmp(className, "java/lang/invoke/VarHandleChars$FieldStaticReadOnly", 51))) + { + setRecognizedMethodInfo(TR::java_lang_invoke_VarHandleX_FieldStaticReadOnlyOrReadWrite_method); + } + else if ((classNameLen == 52 && !strncmp(className, "java/lang/invoke/VarHandleChars$FieldStaticReadWrite", 52))) + { + setRecognizedMethodInfo(TR::java_lang_invoke_VarHandleX_FieldStaticReadOnlyOrReadWrite_method); + } + else if ((classNameLen == 39 && !strncmp(className, "java/lang/invoke/VarHandleDoubles$Array", 39))) + { + setRecognizedMethodInfo(TR::java_lang_invoke_VarHandleX_Array_method); + } + else if ((classNameLen == 55 && !strncmp(className, "java/lang/invoke/VarHandleDoubles$FieldInstanceReadOnly", 55))) + { + setRecognizedMethodInfo(TR::java_lang_invoke_VarHandleX_FieldInstanceReadOnlyOrReadWrite_method); + } + else if ((classNameLen == 56 && !strncmp(className, "java/lang/invoke/VarHandleDoubles$FieldInstanceReadWrite", 56))) + { + setRecognizedMethodInfo(TR::java_lang_invoke_VarHandleX_FieldInstanceReadOnlyOrReadWrite_method); + } + else if ((classNameLen == 53 && !strncmp(className, "java/lang/invoke/VarHandleDoubles$FieldStaticReadOnly", 53))) + { + setRecognizedMethodInfo(TR::java_lang_invoke_VarHandleX_FieldStaticReadOnlyOrReadWrite_method); + } + else if ((classNameLen == 54 && !strncmp(className, "java/lang/invoke/VarHandleDoubles$FieldStaticReadWrite", 54))) + { + setRecognizedMethodInfo(TR::java_lang_invoke_VarHandleX_FieldStaticReadOnlyOrReadWrite_method); + } + else if ((classNameLen == 38 && !strncmp(className, "java/lang/invoke/VarHandleFloats$Array", 38))) + { + setRecognizedMethodInfo(TR::java_lang_invoke_VarHandleX_Array_method); + } + else if ((classNameLen == 54 && !strncmp(className, "java/lang/invoke/VarHandleFloats$FieldInstanceReadOnly", 54))) + { + setRecognizedMethodInfo(TR::java_lang_invoke_VarHandleX_FieldInstanceReadOnlyOrReadWrite_method); + } + else if ((classNameLen == 55 && !strncmp(className, "java/lang/invoke/VarHandleFloats$FieldInstanceReadWrite", 55))) + { + setRecognizedMethodInfo(TR::java_lang_invoke_VarHandleX_FieldInstanceReadOnlyOrReadWrite_method); + } + else if ((classNameLen == 52 && !strncmp(className, "java/lang/invoke/VarHandleFloats$FieldStaticReadOnly", 52))) + { + setRecognizedMethodInfo(TR::java_lang_invoke_VarHandleX_FieldStaticReadOnlyOrReadWrite_method); + } + else if ((classNameLen == 53 && !strncmp(className, "java/lang/invoke/VarHandleFloats$FieldStaticReadWrite", 53))) + { + setRecognizedMethodInfo(TR::java_lang_invoke_VarHandleX_FieldStaticReadOnlyOrReadWrite_method); + } + else if ((classNameLen == 36 && !strncmp(className, "java/lang/invoke/VarHandleInts$Array", 36))) + { + setRecognizedMethodInfo(TR::java_lang_invoke_VarHandleX_Array_method); + } + else if ((classNameLen == 52 && !strncmp(className, "java/lang/invoke/VarHandleInts$FieldInstanceReadOnly", 52))) + { + setRecognizedMethodInfo(TR::java_lang_invoke_VarHandleX_FieldInstanceReadOnlyOrReadWrite_method); + } + else if ((classNameLen == 53 && !strncmp(className, "java/lang/invoke/VarHandleInts$FieldInstanceReadWrite", 53))) + { + setRecognizedMethodInfo(TR::java_lang_invoke_VarHandleX_FieldInstanceReadOnlyOrReadWrite_method); + } + else if ((classNameLen == 50 && !strncmp(className, "java/lang/invoke/VarHandleInts$FieldStaticReadOnly", 50))) + { + setRecognizedMethodInfo(TR::java_lang_invoke_VarHandleX_FieldStaticReadOnlyOrReadWrite_method); + } + else if ((classNameLen == 51 && !strncmp(className, "java/lang/invoke/VarHandleInts$FieldStaticReadWrite", 51))) + { + setRecognizedMethodInfo(TR::java_lang_invoke_VarHandleX_FieldStaticReadOnlyOrReadWrite_method); + } + else if ((classNameLen == 37 && !strncmp(className, "java/lang/invoke/VarHandleLongs$Array", 37))) + { + setRecognizedMethodInfo(TR::java_lang_invoke_VarHandleX_Array_method); + } + else if ((classNameLen == 53 && !strncmp(className, "java/lang/invoke/VarHandleLongs$FieldInstanceReadOnly", 53))) + { + setRecognizedMethodInfo(TR::java_lang_invoke_VarHandleX_FieldInstanceReadOnlyOrReadWrite_method); + } + else if ((classNameLen == 54 && !strncmp(className, "java/lang/invoke/VarHandleLongs$FieldInstanceReadWrite", 54))) + { + setRecognizedMethodInfo(TR::java_lang_invoke_VarHandleX_FieldInstanceReadOnlyOrReadWrite_method); + } + else if ((classNameLen == 51 && !strncmp(className, "java/lang/invoke/VarHandleLongs$FieldStaticReadOnly", 51))) + { + setRecognizedMethodInfo(TR::java_lang_invoke_VarHandleX_FieldStaticReadOnlyOrReadWrite_method); + } + else if ((classNameLen == 52 && !strncmp(className, "java/lang/invoke/VarHandleLongs$FieldStaticReadWrite", 52))) + { + setRecognizedMethodInfo(TR::java_lang_invoke_VarHandleX_FieldStaticReadOnlyOrReadWrite_method); + } + else if ((classNameLen == 42 && !strncmp(className, "java/lang/invoke/VarHandleReferences$Array", 42))) + { + setRecognizedMethodInfo(TR::java_lang_invoke_VarHandleX_Array_method); + } + else if ((classNameLen == 58 && !strncmp(className, "java/lang/invoke/VarHandleReferences$FieldInstanceReadOnly", 58))) + { + setRecognizedMethodInfo(TR::java_lang_invoke_VarHandleX_FieldInstanceReadOnlyOrReadWrite_method); + } + else if ((classNameLen == 59 && !strncmp(className, "java/lang/invoke/VarHandleReferences$FieldInstanceReadWrite", 59))) + { + setRecognizedMethodInfo(TR::java_lang_invoke_VarHandleX_FieldInstanceReadOnlyOrReadWrite_method); + } + else if ((classNameLen == 56 && !strncmp(className, "java/lang/invoke/VarHandleReferences$FieldStaticReadOnly", 56))) + { + setRecognizedMethodInfo(TR::java_lang_invoke_VarHandleX_FieldStaticReadOnlyOrReadWrite_method); + } + else if ((classNameLen == 57 && !strncmp(className, "java/lang/invoke/VarHandleReferences$FieldStaticReadWrite", 57))) + { + setRecognizedMethodInfo(TR::java_lang_invoke_VarHandleX_FieldStaticReadOnlyOrReadWrite_method); + } + else if ((classNameLen == 38 && !strncmp(className, "java/lang/invoke/VarHandleShorts$Array", 38))) + { + setRecognizedMethodInfo(TR::java_lang_invoke_VarHandleX_Array_method); + } + else if ((classNameLen == 54 && !strncmp(className, "java/lang/invoke/VarHandleShorts$FieldInstanceReadOnly", 54))) + { + setRecognizedMethodInfo(TR::java_lang_invoke_VarHandleX_FieldInstanceReadOnlyOrReadWrite_method); + } + else if ((classNameLen == 55 && !strncmp(className, "java/lang/invoke/VarHandleShorts$FieldInstanceReadWrite", 55))) + { + setRecognizedMethodInfo(TR::java_lang_invoke_VarHandleX_FieldInstanceReadOnlyOrReadWrite_method); + } + else if ((classNameLen == 52 && !strncmp(className, "java/lang/invoke/VarHandleShorts$FieldStaticReadOnly", 52))) + { + setRecognizedMethodInfo(TR::java_lang_invoke_VarHandleX_FieldStaticReadOnlyOrReadWrite_method); + } + else if ((classNameLen == 53 && !strncmp(className, "java/lang/invoke/VarHandleShorts$FieldStaticReadWrite", 53))) + { + setRecognizedMethodInfo(TR::java_lang_invoke_VarHandleX_FieldStaticReadOnlyOrReadWrite_method); + } + else if ((classNameLen == 54 && !strncmp(className, "java/lang/invoke/VarHandleByteArrayAsChars$ArrayHandle", 54))) + { + setRecognizedMethodInfo(TR::java_lang_invoke_VarHandleByteArrayAsX_ArrayHandle_method); + } + else if ((classNameLen == 59 && !strncmp(className, "java/lang/invoke/VarHandleByteArrayAsChars$ByteBufferHandle", 59))) + { + setRecognizedMethodInfo(TR::java_lang_invoke_VarHandleByteArrayAsX_ByteBufferHandle_method); + } + else if ((classNameLen == 56 && !strncmp(className, "java/lang/invoke/VarHandleByteArrayAsDoubles$ArrayHandle", 56))) + { + setRecognizedMethodInfo(TR::java_lang_invoke_VarHandleByteArrayAsX_ArrayHandle_method); + } + else if ((classNameLen == 61 && !strncmp(className, "java/lang/invoke/VarHandleByteArrayAsDoubles$ByteBufferHandle", 61))) + { + setRecognizedMethodInfo(TR::java_lang_invoke_VarHandleByteArrayAsX_ByteBufferHandle_method); + } + else if ((classNameLen == 55 && !strncmp(className, "java/lang/invoke/VarHandleByteArrayAsFloats$ArrayHandle", 55))) + { + setRecognizedMethodInfo(TR::java_lang_invoke_VarHandleByteArrayAsX_ArrayHandle_method); + } + else if ((classNameLen == 60 && !strncmp(className, "java/lang/invoke/VarHandleByteArrayAsFloats$ByteBufferHandle", 60))) + { + setRecognizedMethodInfo(TR::java_lang_invoke_VarHandleByteArrayAsX_ByteBufferHandle_method); + } + else if ((classNameLen == 53 && !strncmp(className, "java/lang/invoke/VarHandleByteArrayAsInts$ArrayHandle", 53))) + { + setRecognizedMethodInfo(TR::java_lang_invoke_VarHandleByteArrayAsX_ArrayHandle_method); + } + else if ((classNameLen == 58 && !strncmp(className, "java/lang/invoke/VarHandleByteArrayAsInts$ByteBufferHandle", 58))) + { + setRecognizedMethodInfo(TR::java_lang_invoke_VarHandleByteArrayAsX_ByteBufferHandle_method); + } + else if ((classNameLen == 54 && !strncmp(className, "java/lang/invoke/VarHandleByteArrayAsLongs$ArrayHandle", 54))) + { + setRecognizedMethodInfo(TR::java_lang_invoke_VarHandleByteArrayAsX_ArrayHandle_method); + } + else if ((classNameLen == 59 && !strncmp(className, "java/lang/invoke/VarHandleByteArrayAsLongs$ByteBufferHandle", 59))) + { + setRecognizedMethodInfo(TR::java_lang_invoke_VarHandleByteArrayAsX_ByteBufferHandle_method); + } + else if ((classNameLen == 55 && !strncmp(className, "java/lang/invoke/VarHandleByteArrayAsShorts$ArrayHandle", 55))) + { + setRecognizedMethodInfo(TR::java_lang_invoke_VarHandleByteArrayAsX_ArrayHandle_method); + } + else if ((classNameLen == 60 && !strncmp(className, "java/lang/invoke/VarHandleByteArrayAsShorts$ByteBufferHandle", 60))) + { + setRecognizedMethodInfo(TR::java_lang_invoke_VarHandleByteArrayAsX_ByteBufferHandle_method); + } + } +#endif else if ((classNameLen >= 59 + 3 && classNameLen <= 59 + 7) && !strncmp(className, "java/lang/invoke/ArrayVarHandle$ArrayVarHandleOperations$Op", 59)) { setRecognizedMethodInfo(TR::java_lang_invoke_ArrayVarHandle_ArrayVarHandleOperations_OpMethod); @@ -5630,10 +5869,18 @@ TR_J9MethodBase::isVarHandleOperationMethod(TR::RecognizedMethod rm) { switch (rm) { +#if defined (J9VM_OPT_OPENJDK_METHODHANDLE) + case TR::java_lang_invoke_VarHandleX_Array_method: + case TR::java_lang_invoke_VarHandleX_FieldInstanceReadOnlyOrReadWrite_method: + case TR::java_lang_invoke_VarHandleX_FieldStaticReadOnlyOrReadWrite_method: + case TR::java_lang_invoke_VarHandleByteArrayAsX_ArrayHandle_method: + case TR::java_lang_invoke_VarHandleByteArrayAsX_ByteBufferHandle_method: +#else case TR::java_lang_invoke_ArrayVarHandle_ArrayVarHandleOperations_OpMethod: case TR::java_lang_invoke_StaticFieldVarHandle_StaticFieldVarHandleOperations_OpMethod: case TR::java_lang_invoke_InstanceFieldVarHandle_InstanceFieldVarHandleOperations_OpMethod: case TR::java_lang_invoke_ByteArrayViewVarHandle_ByteArrayViewVarHandleOperations_OpMethod: +#endif return true; default: return false; diff --git a/runtime/compiler/optimizer/InlinerTempForJ9.cpp b/runtime/compiler/optimizer/InlinerTempForJ9.cpp index 53dcc6cce77..9ae2319065f 100644 --- a/runtime/compiler/optimizer/InlinerTempForJ9.cpp +++ b/runtime/compiler/optimizer/InlinerTempForJ9.cpp @@ -2492,11 +2492,16 @@ TR_J9InlinerPolicy::callMustBeInlined(TR_CallTarget *calltarget) { TR_ResolvedMethod *method = calltarget->_calleeMethod; - if (method->convertToMethod()->isArchetypeSpecimen()) +#if defined(J9VM_OPT_OPENJDK_METHODHANDLE) + if (comp()->fej9()->isLambdaFormGeneratedMethod(method)) return true; - if (comp()->fej9()->isLambdaFormGeneratedMethod(method)) + if (TR_J9MethodBase::isVarHandleOperationMethod(method->getRecognizedMethod())) return true; +#else + if (method->convertToMethod()->isArchetypeSpecimen()) + return true; +#endif return callMustBeInlinedInCold(method); } diff --git a/runtime/compiler/optimizer/UnsafeFastPath.cpp b/runtime/compiler/optimizer/UnsafeFastPath.cpp index ee17a6a122f..fa7dd1c1e61 100644 --- a/runtime/compiler/optimizer/UnsafeFastPath.cpp +++ b/runtime/compiler/optimizer/UnsafeFastPath.cpp @@ -103,6 +103,9 @@ static bool isTransformableUnsafeAtomic(TR::Compilation *comp, TR::RecognizedMet static bool isKnownUnsafeCaller(TR::RecognizedMethod rm) { +#if defined (J9VM_OPT_OPENJDK_METHODHANDLE) + return TR_J9MethodBase::isVarHandleOperationMethod(rm); +#else switch (rm) { case TR::java_lang_invoke_ArrayVarHandle_ArrayVarHandleOperations_OpMethod: @@ -118,15 +121,20 @@ static bool isKnownUnsafeCaller(TR::RecognizedMethod rm) return false; } return false; +#endif } static bool isUnsafeCallerAccessingStaticField(TR::RecognizedMethod rm) { switch (rm) { +#if defined(J9VM_OPT_OPENJDK_METHODHANDLE) + case TR::java_lang_invoke_VarHandleX_FieldStaticReadOnlyOrReadWrite_method: +#else case TR::java_lang_invoke_StaticFieldVarHandle_StaticFieldVarHandleOperations_OpMethod: case TR::java_lang_invoke_StaticFieldGetterHandle_invokeExact: case TR::java_lang_invoke_StaticFieldSetterHandle_invokeExact: +#endif return true; default: return false; @@ -134,12 +142,19 @@ static bool isUnsafeCallerAccessingStaticField(TR::RecognizedMethod rm) return false; } -static bool isUnsafeCallerAccessingArrayElement(TR::RecognizedMethod rm) + +static bool isVarHandleOperationMethodOnArray(TR::RecognizedMethod rm) { switch (rm) { +#if defined (J9VM_OPT_OPENJDK_METHODHANDLE) + case TR::java_lang_invoke_VarHandleX_Array_method: + case TR::java_lang_invoke_VarHandleByteArrayAsX_ArrayHandle_method: + case TR::java_lang_invoke_VarHandleByteArrayAsX_ByteBufferHandle_method: +#else case TR::java_lang_invoke_ArrayVarHandle_ArrayVarHandleOperations_OpMethod: case TR::java_lang_invoke_ByteArrayViewVarHandle_ByteArrayViewVarHandleOperations_OpMethod: +#endif return true; default: return false; @@ -147,8 +162,11 @@ static bool isUnsafeCallerAccessingArrayElement(TR::RecognizedMethod rm) return false; } -static bool isVarHandleOperationMethodOnArray(TR::RecognizedMethod rm) +static bool isUnsafeCallerAccessingArrayElement(TR::RecognizedMethod rm) { +#if defined (J9VM_OPT_OPENJDK_METHODHANDLE) + return isVarHandleOperationMethodOnArray(rm); +#else switch (rm) { case TR::java_lang_invoke_ArrayVarHandle_ArrayVarHandleOperations_OpMethod: @@ -157,6 +175,7 @@ static bool isVarHandleOperationMethodOnArray(TR::RecognizedMethod rm) default: return false; } +#endif return false; } @@ -164,9 +183,16 @@ static bool isVarHandleOperationMethodOnNonStaticField(TR::RecognizedMethod rm) { switch (rm) { +#if defined (J9VM_OPT_OPENJDK_METHODHANDLE) + case TR::java_lang_invoke_VarHandleX_FieldInstanceReadOnlyOrReadWrite_method: + case TR::java_lang_invoke_VarHandleX_Array_method: + case TR::java_lang_invoke_VarHandleByteArrayAsX_ArrayHandle_method: + case TR::java_lang_invoke_VarHandleByteArrayAsX_ByteBufferHandle_method: +#else case TR::java_lang_invoke_InstanceFieldVarHandle_InstanceFieldVarHandleOperations_OpMethod: case TR::java_lang_invoke_ArrayVarHandle_ArrayVarHandleOperations_OpMethod: case TR::java_lang_invoke_ByteArrayViewVarHandle_ByteArrayViewVarHandleOperations_OpMethod: +#endif return true; default: return false; @@ -336,6 +362,7 @@ int32_t TR_UnsafeFastPath::perform() { TR::Node *ttNode = tt->getNode(); TR::Node *node = ttNode->getNumChildren() > 0 ? ttNode->getFirstChild() : NULL; // Get the first child of the tree + TR::RecognizedMethod recognizedVarHandleOpMethod = TR::unknownMethod; if (node && node->getOpCode().isCall() && !node->getSymbol()->castToMethodSymbol()->isHelper()) { TR::SymbolReference *symRef = node->getSymbolReference(); @@ -345,6 +372,10 @@ int32_t TR_UnsafeFastPath::perform() { TR::RecognizedMethod caller = getVarHandleAccessMethodFromInlinedCallStack(comp(), node); TR::RecognizedMethod callee = symbol->getRecognizedMethod(); + + if (TR_J9MethodBase::isVarHandleOperationMethod(caller)) + recognizedVarHandleOpMethod = caller; + if (TR_J9MethodBase::isVarHandleOperationMethod(caller) && (isTransformableUnsafeAtomic(comp(), callee) || symbol->getMethod()->isUnsafeCAS(comp()))) @@ -696,6 +727,8 @@ int32_t TR_UnsafeFastPath::perform() // Handle VarHandle operation methods bool isStatic = false; TR::RecognizedMethod callerMethod = methodSymbol->getRecognizedMethod(); + if (recognizedVarHandleOpMethod != TR::unknownMethod) + callerMethod = recognizedVarHandleOpMethod; TR::RecognizedMethod calleeMethod = symbol->getRecognizedMethod(); if (isKnownUnsafeCaller(callerMethod) && TR_J9MethodBase::isUnsafeGetPutWithObjectArg(calleeMethod))