From 236b7ceca45ed9c806a20d5870183a46feee5601 Mon Sep 17 00:00:00 2001 From: jimmyk Date: Wed, 30 Oct 2024 17:26:51 -0400 Subject: [PATCH] Move willBeEvaluatedAsCallByCodeGen from OMR The OMR willBeEvaluatedAsCallByCodeGen implementation for x is almost entirely guarded by the J9_PROJECT_SPECIFIC macro. If the macro is not set, it always returns true which is what the default implementation already does. Since this implementation is only meaningful to OpenJ9, it is being moved here. willNotInlineCompareAndSwapNative is only called from this implementation of willBeEvaluatedAsCallByCodeGen so it is being moved as well. Signed-off-by: jimmyk --- .../compiler/x/codegen/J9CodeGenerator.cpp | 78 +++++++++++++++++++ .../compiler/x/codegen/J9CodeGenerator.hpp | 2 + .../compiler/x/codegen/J9TreeEvaluator.cpp | 4 +- 3 files changed, 82 insertions(+), 2 deletions(-) diff --git a/runtime/compiler/x/codegen/J9CodeGenerator.cpp b/runtime/compiler/x/codegen/J9CodeGenerator.cpp index 6b0d3a6b636..5d2694d5f78 100644 --- a/runtime/compiler/x/codegen/J9CodeGenerator.cpp +++ b/runtime/compiler/x/codegen/J9CodeGenerator.cpp @@ -520,3 +520,81 @@ J9::X86::CodeGenerator::supportsNonHelper(TR::SymbolReferenceTable::CommonNonhel return J9::CodeGenerator::supportsNonHelper(symbol); } + +/* + * This method returns TRUE for all the cases we decide NOT to replace the call to CAS + * with inline assembly. The GRA and Evaluator should be consistent about whether to inline CAS natives. + */ +static bool willNotInlineCompareAndSwapNative(TR::Node *node, + int8_t size, + TR::Compilation *comp) + { + TR::SymbolReference *callSymRef = node->getSymbolReference(); + TR::MethodSymbol *methodSymbol = callSymRef->getSymbol()->castToMethodSymbol(); + + if (TR::Compiler->om.canGenerateArraylets() && !node->isUnsafeGetPutCASCallOnNonArray()) + return true; + static char *disableCASInlining = feGetEnv("TR_DisableCASInlining"); + + if (disableCASInlining) + return true; + + // In Java9 the sun.misc.Unsafe JNI methods have been moved to jdk.internal, + // with a set of wrappers remaining in sun.misc to delegate to the new package. + // We can be called in this function for the wrappers (which we will + // not be converting to assembly), the new jdk.internal JNI methods or the + // Java8 sun.misc JNI methods (both of which we will convert). We can + // differentiate between these cases by testing with isNative() on the method. + if (!methodSymbol->isNative()) + return true; + + if (size == 4) + { + return false; + } + else if (size == 8 && comp->target().is64Bit()) + { + return false; + } + else + { + if (!comp->cg()->getX86ProcessorInfo().supportsCMPXCHG8BInstruction()) + return true; + + return false; + } + } + +/** @brief Identify methods which are not transformed into inline assembly. + + Some recognized methods are transformed into very simple hardcoded + assembly sequences which don't need register spills as real calls do. + + @param node The TR::Node for the method call. NB this function assumes the Node is a call. + + @return true if the method will be treated as a normal call, false if the method + will be converted to inline assembly. + */ +bool +J9::X86::CodeGenerator::willBeEvaluatedAsCallByCodeGen(TR::Node *node, TR::Compilation *comp) + { + TR::SymbolReference *callSymRef = node->getSymbolReference(); + TR::MethodSymbol *methodSymbol = callSymRef->getSymbol()->castToMethodSymbol(); + switch (methodSymbol->getRecognizedMethod()) + { + case TR::sun_misc_Unsafe_compareAndSwapInt_jlObjectJII_Z: + case TR::jdk_internal_misc_Unsafe_compareAndExchangeInt: + return willNotInlineCompareAndSwapNative(node, 4, comp); + case TR::sun_misc_Unsafe_compareAndSwapLong_jlObjectJJJ_Z: + case TR::jdk_internal_misc_Unsafe_compareAndExchangeLong: + return willNotInlineCompareAndSwapNative(node, 8, comp); + case TR::sun_misc_Unsafe_compareAndSwapObject_jlObjectJjlObjectjlObject_Z: + case TR::jdk_internal_misc_Unsafe_compareAndExchangeObject: + case TR::jdk_internal_misc_Unsafe_compareAndExchangeReference: + return willNotInlineCompareAndSwapNative(node, TR::Compiler->om.sizeofReferenceField(), comp); + + default: + break; + } + return true; + } diff --git a/runtime/compiler/x/codegen/J9CodeGenerator.hpp b/runtime/compiler/x/codegen/J9CodeGenerator.hpp index ac9aedf0383..ce002c2b750 100644 --- a/runtime/compiler/x/codegen/J9CodeGenerator.hpp +++ b/runtime/compiler/x/codegen/J9CodeGenerator.hpp @@ -107,6 +107,8 @@ class OMR_EXTENSIBLE CodeGenerator : public J9::CodeGenerator // See J9::CodeGenerator::guaranteesResolvedVirtualDispatchForSVM bool guaranteesResolvedVirtualDispatchForSVM() { return true; } + bool willBeEvaluatedAsCallByCodeGen(TR::Node *node, TR::Compilation *comp); + private: TR::SymbolReference *_nanoTimeTemp; }; diff --git a/runtime/compiler/x/codegen/J9TreeEvaluator.cpp b/runtime/compiler/x/codegen/J9TreeEvaluator.cpp index 9cdb4e68f7f..b189f876408 100644 --- a/runtime/compiler/x/codegen/J9TreeEvaluator.cpp +++ b/runtime/compiler/x/codegen/J9TreeEvaluator.cpp @@ -9664,8 +9664,8 @@ static TR::Register* inlineCompareAndSwapObjectNative(TR::Node* node, TR::CodeGe /** Replaces a call to an Unsafe CAS method with inline instructions. @return true if the call was replaced, false if it was not. - Note that this function must have behaviour consistent with the OMR function - willNotInlineCompareAndSwapNative in omr/compiler/x/codegen/OMRCodeGenerator.cpp + Note that this function must have behaviour consistent with the function + willNotInlineCompareAndSwapNative in openj9/runtime/compiler/x/codegen/J9CodeGenerator.cpp */ static bool inlineCompareAndSwapNative(