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

Accelerate Unsafe CAS Intrinsics on Aarch64 #20432

Merged
merged 2 commits into from
Nov 1, 2024
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
249 changes: 180 additions & 69 deletions runtime/compiler/aarch64/codegen/J9TreeEvaluator.cpp

Large diffs are not rendered by default.

25 changes: 5 additions & 20 deletions runtime/compiler/env/j9method.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5552,28 +5552,15 @@ TR_ResolvedJ9Method::isJITInternalNative()
}

bool
TR_J9MethodBase::isUnsafeCAS(TR::Compilation * c)
TR_J9MethodBase::isUnsafeCAS()
{
/*
* The TR::Compilation parameter "c" is sometimes null. But, it is needed to perform a platform target check.
* So, if it is null, this code goes and gets comp.
*/
if (NULL == c)
{
c = TR::comp();
}

TR::RecognizedMethod rm = getRecognizedMethod();
switch (rm)
{
case TR::jdk_internal_misc_Unsafe_compareAndExchangeInt:
case TR::jdk_internal_misc_Unsafe_compareAndExchangeLong:
case TR::jdk_internal_misc_Unsafe_compareAndExchangeObject:
case TR::jdk_internal_misc_Unsafe_compareAndExchangeReference:
{
TR_ASSERT_FATAL(c, "comp should not be NULL");
return (c->target().cpu.isPower() || c->target().cpu.isX86() || c->target().cpu.isZ());
}
case TR::sun_misc_Unsafe_compareAndSwapInt_jlObjectJII_Z:
case TR::sun_misc_Unsafe_compareAndSwapLong_jlObjectJJJ_Z:
case TR::sun_misc_Unsafe_compareAndSwapObject_jlObjectJjlObjectjlObject_Z:
Expand All @@ -5587,10 +5574,8 @@ TR_J9MethodBase::isUnsafeCAS(TR::Compilation * c)
}

bool
//TR_ResolvedJ9Method::isUnsafeWithObjectArg(TR::Compilation * c)
TR_J9MethodBase::isUnsafeWithObjectArg(TR::Compilation * c)
TR_J9MethodBase::isUnsafeWithObjectArg()
{
//TR::RecognizedMethod rm = TR_ResolvedMethod::getRecognizedMethod();
TR::RecognizedMethod rm = getRecognizedMethod();
switch (rm)
{
Expand Down Expand Up @@ -5936,7 +5921,7 @@ TR_J9MethodBase::isVarHandleOperationMethod(TR::RecognizedMethod rm)
}

bool
TR_J9MethodBase::isVarHandleAccessMethod(TR::Compilation * comp)
TR_J9MethodBase::isVarHandleAccessMethod()
{
TR::RecognizedMethod rm = getMandatoryRecognizedMethod();
switch (rm)
Expand Down Expand Up @@ -5981,9 +5966,9 @@ TR_J9MethodBase::isVarHandleAccessMethod(TR::Compilation * comp)
}

bool
TR_J9MethodBase::isSignaturePolymorphicMethod(TR::Compilation * comp)
TR_J9MethodBase::isSignaturePolymorphicMethod()
{
if (isVarHandleAccessMethod(comp)) return true;
if (isVarHandleAccessMethod()) return true;

TR::RecognizedMethod rm = getMandatoryRecognizedMethod();
switch (rm)
Expand Down
8 changes: 4 additions & 4 deletions runtime/compiler/env/j9method.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,11 +123,11 @@ class TR_J9MethodBase : public TR::Method
static TR::DataType unsafeDataTypeForArray(TR::RecognizedMethod rm);
static TR::DataType unsafeDataTypeForObject(TR::RecognizedMethod rm);
static bool isVarHandleOperationMethod(TR::RecognizedMethod rm);
virtual bool isVarHandleAccessMethod(TR::Compilation * = NULL);
virtual bool isSignaturePolymorphicMethod(TR::Compilation * = NULL);
virtual bool isVarHandleAccessMethod();
virtual bool isSignaturePolymorphicMethod();

virtual bool isUnsafeWithObjectArg( TR::Compilation * comp = NULL);
virtual bool isUnsafeCAS(TR::Compilation * = NULL);
virtual bool isUnsafeWithObjectArg();
virtual bool isUnsafeCAS();
virtual uint32_t numberOfExplicitParameters();
virtual TR::DataType parmType(uint32_t parmNumber); // returns the type of the parmNumber'th parameter (0-based)

Expand Down
1 change: 0 additions & 1 deletion runtime/compiler/il/J9Node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2164,7 +2164,6 @@ J9::Node::isUnsafeGetPutCASCallOnNonArray()
if (!symbol)
return false;

//TR_ASSERT(symbol->castToResolvedMethodSymbol()->getResolvedMethod()->isUnsafeWithObjectArg(), "Attempt to check flag on a method that is not JNI Unsafe that needs special care for arraylets\n");
TR_ASSERT(symbol->getMethod()->isUnsafeWithObjectArg() || symbol->getMethod()->isUnsafeCAS(),"Attempt to check flag on a method that is not JNI Unsafe that needs special care for arraylets\n");
return _flags.testAny(unsafeGetPutOnNonArray);
}
Expand Down
15 changes: 3 additions & 12 deletions runtime/compiler/optimizer/InlinerTempForJ9.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -406,11 +406,7 @@ TR_J9InlinerPolicy::alwaysWorthInlining(TR_ResolvedMethod * calleeMethod, TR::No
case TR::jdk_internal_misc_Unsafe_compareAndExchangeInt:
case TR::jdk_internal_misc_Unsafe_compareAndExchangeLong:
case TR::jdk_internal_misc_Unsafe_compareAndExchangeReference:
if (comp()->target().cpu.isPower() || comp()->target().cpu.isX86() || comp()->target().cpu.isZ())
{
return false;
}
break;
return false;

/* In Java9 the compareAndSwap[Int|Long|Object] and copyMemory enums match
* both sun.misc.Unsafe and jdk.internal.misc.Unsafe. The sun.misc.Unsafe
Expand All @@ -427,11 +423,6 @@ TR_J9InlinerPolicy::alwaysWorthInlining(TR_ResolvedMethod * calleeMethod, TR::No
* failed the isInlineableJNI check and should not be force inlined.
*/
case TR::jdk_internal_misc_Unsafe_compareAndExchangeObject:
if (comp()->target().cpu.isPower() || comp()->target().cpu.isX86() || comp()->target().cpu.isZ())
{
return !calleeMethod->isNative();
}
break;
case TR::sun_misc_Unsafe_compareAndSwapInt_jlObjectJII_Z:
case TR::sun_misc_Unsafe_compareAndSwapLong_jlObjectJJJ_Z:
case TR::sun_misc_Unsafe_compareAndSwapObject_jlObjectJjlObjectjlObject_Z:
Expand Down Expand Up @@ -2669,7 +2660,7 @@ TR_J9InlinerPolicy::inlineUnsafeCall(TR::ResolvedMethodSymbol *calleeSymbol, TR:
case TR::jdk_internal_misc_Unsafe_compareAndExchangeLong:
case TR::jdk_internal_misc_Unsafe_compareAndExchangeObject:
case TR::jdk_internal_misc_Unsafe_compareAndExchangeReference:
if (disableCAEIntrinsic || !(comp()->target().cpu.isPower() || comp()->target().cpu.isX86() || comp()->target().cpu.isZ()))
if (disableCAEIntrinsic)
{
break;
}
Expand Down Expand Up @@ -2744,7 +2735,7 @@ TR_J9InlinerPolicy::isInlineableJNI(TR_ResolvedMethod *method,TR::Node *callNode
!comp->fej9()->traceableMethodsCanBeInlined()))
return false;

if (method->convertToMethod()->isUnsafeWithObjectArg(comp) || method->convertToMethod()->isUnsafeCAS(comp))
if (method->convertToMethod()->isUnsafeWithObjectArg() || method->convertToMethod()->isUnsafeCAS())
{
// In Java9 sun/misc/Unsafe methods are simple Java wrappers to JNI
// methods in jdk.internal, and the enum values above match both. Only
Expand Down
4 changes: 2 additions & 2 deletions runtime/compiler/optimizer/UnsafeFastPath.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ bool TR_UnsafeFastPath::tryTransformUnsafeAtomicCallInVarHandleAccessMethod(TR::
TR::MethodSymbol *symbol = node->getSymbol()->castToMethodSymbol();
// Codegen will inline the call with the flag
//
if (symbol->getMethod()->isUnsafeCAS(comp()))
if (symbol->getMethod()->isUnsafeCAS())
{
// codegen doesn't optimize CAS on a static field
//
Expand Down Expand Up @@ -415,7 +415,7 @@ int32_t TR_UnsafeFastPath::perform()

if (isVarHandleOperationMethod(caller) &&
(isTransformableUnsafeAtomic(comp(), callee) ||
symbol->getMethod()->isUnsafeCAS(comp())))
symbol->getMethod()->isUnsafeCAS()))
{
if (tryTransformUnsafeAtomicCallInVarHandleAccessMethod(tt, caller, callee))
{
Expand Down
2 changes: 1 addition & 1 deletion runtime/compiler/optimizer/VarHandleTransformer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ TR::RecognizedMethod TR_VarHandleTransformer::getVarHandleAccessMethod(TR::Node
}
else
{
if (method->isVarHandleAccessMethod(comp()))
if (method->isVarHandleAccessMethod())
varHandleAccessMethod = method->getMandatoryRecognizedMethod();
}
return varHandleAccessMethod;
Expand Down