Skip to content

Commit 1e3b2e5

Browse files
committed
Make disable CAS and CAE options consistant
Changes TR_DisableCASInlining envvar to disable inlining Unsafe compareAndSwap on all platforms. This used to only work on X and would also disable inlining compareAndExchange at the same time. Now it only disables inlining compareAndSwap. Renames TR_DisableCAEIntrinsic envvar to TR_DisableCAEIntrinsic and it disables inlining Unsafe compareAndExchange on all platforms. Envvars are now checked in fewer locations and set an option bit instead. The following methods were added to support this: getSupportsInlineUnsafeCompareAndSet setSupportsInlineUnsafeCompareAndSet getSupportsInlineUnsafeCompareAndExchange setSupportsInlineUnsafeCompareAndExchange These methods are used to indicate support for inlining CAS/CAE and also to query for suppport. Signed-off-by: jimmyk <jimmyk@ca.ibm.com>
1 parent 63a354b commit 1e3b2e5

10 files changed

Lines changed: 183 additions & 72 deletions

File tree

runtime/compiler/aarch64/codegen/J9CodeGenerator.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,18 @@ J9::ARM64::CodeGenerator::initialize()
101101
}
102102
if (comp->fej9()->hasFixedFrameC_CallingConvention())
103103
cg->setHasFixedFrameC_CallingConvention();
104+
105+
static bool disableCASInlining = feGetEnv("TR_DisableCASInlining") != NULL;
106+
if (!disableCASInlining)
107+
{
108+
cg->setSupportsInlineUnsafeCompareAndSet();
109+
}
110+
111+
static bool disableCAEInlining = feGetEnv("TR_DisableCAEInlining") != NULL;
112+
if (!disableCAEInlining)
113+
{
114+
cg->setSupportsInlineUnsafeCompareAndExchange();
115+
}
104116
}
105117

106118
TR::Linkage *

runtime/compiler/aarch64/codegen/J9TreeEvaluator.cpp

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6883,7 +6883,8 @@ J9::ARM64::CodeGenerator::inlineDirectCall(TR::Node *node, TR::Register *&result
68836883
break;
68846884
}
68856885

6886-
static bool disableCAEIntrinsic = feGetEnv("TR_DisableCAEIntrinsic") != NULL;
6886+
bool disableCASInlining = !cg->getSupportsInlineUnsafeCompareAndSet();
6887+
bool disableCAEInlining = !cg->getSupportsInlineUnsafeCompareAndExchange();
68876888
switch (methodSymbol->getRecognizedMethod())
68886889
{
68896890
case TR::java_lang_Thread_onSpinWait:
@@ -6977,8 +6978,11 @@ J9::ARM64::CodeGenerator::inlineDirectCall(TR::Node *node, TR::Register *&result
69776978

69786979
if ((node->isUnsafeGetPutCASCallOnNonArray() || !TR::Compiler->om.canGenerateArraylets()) && node->isSafeForCGToFastPathUnsafeCall())
69796980
{
6980-
resultReg = VMinlineCompareAndSwap(node, cg, false);
6981-
return true;
6981+
if (!disableCASInlining)
6982+
{
6983+
resultReg = VMinlineCompareAndSwap(node, cg, false);
6984+
return true;
6985+
}
69826986
}
69836987
break;
69846988
}
@@ -6991,8 +6995,11 @@ J9::ARM64::CodeGenerator::inlineDirectCall(TR::Node *node, TR::Register *&result
69916995

69926996
if ((node->isUnsafeGetPutCASCallOnNonArray() || !TR::Compiler->om.canGenerateArraylets()) && node->isSafeForCGToFastPathUnsafeCall())
69936997
{
6994-
resultReg = VMinlineCompareAndSwap(node, cg, true);
6995-
return true;
6998+
if (!disableCASInlining)
6999+
{
7000+
resultReg = VMinlineCompareAndSwap(node, cg, true);
7001+
return true;
7002+
}
69967003
}
69977004
break;
69987005
}
@@ -7004,8 +7011,11 @@ J9::ARM64::CodeGenerator::inlineDirectCall(TR::Node *node, TR::Register *&result
70047011

70057012
if ((node->isUnsafeGetPutCASCallOnNonArray() || !TR::Compiler->om.canGenerateArraylets()) && node->isSafeForCGToFastPathUnsafeCall())
70067013
{
7007-
resultReg = VMinlineCompareAndSwapObject(node, cg);
7008-
return true;
7014+
if (!disableCASInlining)
7015+
{
7016+
resultReg = VMinlineCompareAndSwapObject(node, cg);
7017+
return true;
7018+
}
70097019
}
70107020
break;
70117021
}
@@ -7014,7 +7024,7 @@ J9::ARM64::CodeGenerator::inlineDirectCall(TR::Node *node, TR::Register *&result
70147024
{
70157025
if ((node->isUnsafeGetPutCASCallOnNonArray() || !TR::Compiler->om.canGenerateArraylets()) && node->isSafeForCGToFastPathUnsafeCall())
70167026
{
7017-
if (!disableCAEIntrinsic)
7027+
if (!disableCAEInlining)
70187028
{
70197029
resultReg = VMinlineCompareAndSwap(node, cg, false, true);
70207030
return true;
@@ -7027,7 +7037,7 @@ J9::ARM64::CodeGenerator::inlineDirectCall(TR::Node *node, TR::Register *&result
70277037
{
70287038
if ((node->isUnsafeGetPutCASCallOnNonArray() || !TR::Compiler->om.canGenerateArraylets()) && node->isSafeForCGToFastPathUnsafeCall())
70297039
{
7030-
if (!disableCAEIntrinsic)
7040+
if (!disableCAEInlining)
70317041
{
70327042
resultReg = VMinlineCompareAndSwap(node, cg, true, true);
70337043
return true;
@@ -7049,7 +7059,7 @@ J9::ARM64::CodeGenerator::inlineDirectCall(TR::Node *node, TR::Register *&result
70497059
{
70507060
if ((node->isUnsafeGetPutCASCallOnNonArray() || !TR::Compiler->om.canGenerateArraylets()) && node->isSafeForCGToFastPathUnsafeCall())
70517061
{
7052-
if (!disableCAEIntrinsic)
7062+
if (!disableCAEInlining)
70537063
{
70547064
resultReg = VMinlineCompareAndSwapObject(node, cg, true);
70557065
return true;

runtime/compiler/codegen/J9CodeGenerator.cpp

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -650,31 +650,32 @@ J9::CodeGenerator::lowerTreesPreChildrenVisit(TR::Node *parent, TR::TreeTop *tre
650650

651651
if (parent->getOpCode().isFunctionCall())
652652
{
653-
// J9
654-
//
655-
/* Hiding compressedref logic from CodeGen isn't a good practice, and the evaluator still needs the uncompressedref node for write barriers.
653+
/* J9
654+
*
655+
* Hiding compressedref logic from CodeGen isn't a good practice, and the evaluator still needs the uncompressedref node for write barriers.
656656
* Therefore, this part is deprecated. It can only be activated on X, P or Z with the TR_UseOldCompareAndSwapObject envvar.
657657
*
658-
* If TR_DisableCAEIntrinsic is set to disable inlining of compareAndExchange, compressedref logic will not be hidden for compareAndExchange
659-
* calls even if TR_UseOldCompareAndSwapObject is set. The reason is that TR_DisableCAEIntrinsic takes priority over TR_UseOldCompareAndSwapObject
658+
* If TR_DisableCAEInlining is set to disable inlining of compareAndExchange, compressedref logic will not be hidden for compareAndExchange
659+
* calls even if TR_UseOldCompareAndSwapObject is set. The reason is that TR_DisableCAEInlining takes priority over TR_UseOldCompareAndSwapObject
660660
* so neither the old nor new version of the inlined compareAndExchange are used and the non-inlined version expects that the compressedrefs are
661661
* not hidden.
662662
*
663-
* Similarly, TR_DisableCASInlining (which is only supported on X) can be used to disable inlining on both compareAndSwap and compareAndExchange.
664-
* This also takes priority over TR_UseOldCompareAndSwapObject. Once again, the compressedrefs logic will not be hidden since it is expected by
665-
* the non-inlined version.
663+
* Similarly, TR_DisableCASInlining can be used to disable inlining of compareAndSet. This also takes priority over TR_UseOldCompareAndSwapObject.
664+
* Once again, the compressedrefs logic will not be hidden since it is expected by the non-inlined version.
666665
*/
667666
static bool useOldCompareAndSwapObject = (bool)feGetEnv("TR_UseOldCompareAndSwapObject");
668-
static bool disableCASInlining = feGetEnv("TR_DisableCASInlining") != NULL;
669-
if (((self()->comp()->target().cpu.isX86() && !disableCASInlining) || self()->comp()->target().cpu.isPower() || self()->comp()->target().cpu.isZ()) &&
667+
if ((self()->comp()->target().cpu.isX86() || self()->comp()->target().cpu.isPower() || self()->comp()->target().cpu.isZ()) &&
670668
self()->comp()->useCompressedPointers() && useOldCompareAndSwapObject)
671669
{
672670
TR::MethodSymbol *methodSymbol = parent->getSymbol()->castToMethodSymbol();
673-
static bool disableCAEIntrinsic = feGetEnv("TR_DisableCAEIntrinsic") != NULL;
671+
672+
bool disableCASInlining = !self()->getSupportsInlineUnsafeCompareAndSet();
673+
bool disableCAEIntrinsic = !self()->getSupportsInlineUnsafeCompareAndExchange();
674+
674675
// In Java9 Unsafe could be the jdk.internal JNI method or the sun.misc ordinary method wrapper,
675676
// while in Java8 it can only be the sun.misc package which will itself contain the JNI method.
676677
// Test for isNative to distinguish between them.
677-
if (((methodSymbol->getRecognizedMethod() == TR::sun_misc_Unsafe_compareAndSwapObject_jlObjectJjlObjectjlObject_Z) ||
678+
if ((((methodSymbol->getRecognizedMethod() == TR::sun_misc_Unsafe_compareAndSwapObject_jlObjectJjlObjectjlObject_Z) && !disableCASInlining) ||
678679
((methodSymbol->getRecognizedMethod() == TR::jdk_internal_misc_Unsafe_compareAndExchangeObject) && !disableCAEIntrinsic) ||
679680
((methodSymbol->getRecognizedMethod() == TR::jdk_internal_misc_Unsafe_compareAndExchangeReference) && !disableCAEIntrinsic)) &&
680681
methodSymbol->isNative() &&

runtime/compiler/codegen/J9CodeGenerator.hpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -542,6 +542,26 @@ void addMonClass(TR::Node* monNode, TR_OpaqueClassBlock* clazz);
542542
*/
543543
void setSupportsInlineMath_MaxMin_FD() { _j9Flags.set(SupportsInlineMath_MaxMin_FD); }
544544

545+
/** \brief
546+
* Determines whether the code generator supports inlining of jdk/internal/misc/Unsafe.CompareAndSet[Object|Reference|Int|Long]
547+
*/
548+
bool getSupportsInlineUnsafeCompareAndSet() { return _j9Flags.testAny(SupportsInlineUnsafeCompareAndSet); }
549+
550+
/** \brief
551+
* The code generator supports inlining of jdk/internal/misc/Unsafe.CompareAndSet[Object|Reference|Int|Long]
552+
*/
553+
void setSupportsInlineUnsafeCompareAndSet() { _j9Flags.set(SupportsInlineUnsafeCompareAndSet); }
554+
555+
/** \brief
556+
* Determines whether the code generator supports inlining of jdk/internal/misc/Unsafe.CompareAndExchange[Object|Reference|Int|Long]
557+
*/
558+
bool getSupportsInlineUnsafeCompareAndExchange() { return _j9Flags.testAny(SupportsInlineUnsafeCompareAndExchange); }
559+
560+
/** \brief
561+
* The code generator supports inlining of jdk/internal/misc/Unsafe.CompareAndExchange[Object|Reference|Int|Long]
562+
*/
563+
void setSupportsInlineUnsafeCompareAndExchange() { _j9Flags.set(SupportsInlineUnsafeCompareAndExchange); }
564+
545565
/**
546566
* \brief
547567
* The number of nodes between a monext and the next monent before
@@ -710,6 +730,8 @@ void addMonClass(TR::Node* monNode, TR_OpaqueClassBlock* clazz);
710730
SupportsInlineStringCodingHasNegatives = 0x00004000,
711731
SupportsInlineStringCodingCountPositives = 0x00008000,
712732
SupportsInlineMath_MaxMin_FD = 0x00010000,
733+
SupportsInlineUnsafeCompareAndSet = 0x00020000,
734+
SupportsInlineUnsafeCompareAndExchange = 0x00040000,
713735
};
714736

715737
flags32_t _j9Flags;

runtime/compiler/optimizer/InlinerTempForJ9.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2517,7 +2517,8 @@ TR_J9InlinerPolicy::inlineUnsafeCall(TR::ResolvedMethodSymbol *calleeSymbol, TR:
25172517
!comp()->fej9()->traceableMethodsCanBeInlined()))
25182518
return false;
25192519

2520-
static bool disableCAEIntrinsic = feGetEnv("TR_DisableCAEIntrinsic") != NULL;
2520+
bool disableCASInlining = !comp()->cg()->getSupportsInlineUnsafeCompareAndSet();
2521+
bool disableCAEInlining = !comp()->cg()->getSupportsInlineUnsafeCompareAndExchange();
25212522
// I am not sure if having the same type between C/S and B/Z matters here.. ie. if the type is being used as the only distinguishing factor
25222523
switch (callNode->getSymbol()->castToResolvedMethodSymbol()->getRecognizedMethod())
25232524
{
@@ -2705,18 +2706,21 @@ TR_J9InlinerPolicy::inlineUnsafeCall(TR::ResolvedMethodSymbol *calleeSymbol, TR:
27052706
case TR::jdk_internal_misc_Unsafe_compareAndExchangeLong:
27062707
case TR::jdk_internal_misc_Unsafe_compareAndExchangeObject:
27072708
case TR::jdk_internal_misc_Unsafe_compareAndExchangeReference:
2708-
if (disableCAEIntrinsic)
2709+
if (disableCAEInlining || callNode->isSafeForCGToFastPathUnsafeCall())
27092710
{
2710-
break;
2711+
return false;
27112712
}
2712-
// Fallthrough if previous if condition is not met.
2713+
return createUnsafeCASCallDiamond(callNodeTreeTop, callNode);
2714+
27132715
case TR::sun_misc_Unsafe_compareAndSwapInt_jlObjectJII_Z:
27142716
case TR::sun_misc_Unsafe_compareAndSwapLong_jlObjectJJJ_Z:
27152717
case TR::sun_misc_Unsafe_compareAndSwapObject_jlObjectJjlObjectjlObject_Z:
2716-
if (callNode->isSafeForCGToFastPathUnsafeCall())
2718+
if (disableCASInlining || callNode->isSafeForCGToFastPathUnsafeCall())
2719+
{
27172720
return false;
2721+
}
27182722
#if defined(J9VM_GC_SPARSE_HEAP_ALLOCATION)
2719-
if(TR::Compiler->om.isOffHeapAllocationEnabled())
2723+
if (TR::Compiler->om.isOffHeapAllocationEnabled())
27202724
return createUnsafeCASCallDiamond(callNodeTreeTop, callNode);
27212725
#endif /* J9VM_GC_SPARSE_HEAP_ALLOCATION */
27222726
switch (callerSymbol->castToMethodSymbol()->getRecognizedMethod())

runtime/compiler/p/codegen/J9CodeGenerator.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,18 @@ J9::Power::CodeGenerator::initialize()
108108
!disableStringInflateIntrinsic)
109109
cg->setSupportsInlineStringLatin1Inflate();
110110

111+
static bool disableCASInlining = feGetEnv("TR_DisableCASInlining") != NULL;
112+
if (!disableCASInlining)
113+
{
114+
cg->setSupportsInlineUnsafeCompareAndSet();
115+
}
116+
117+
static bool disableCAEInlining = feGetEnv("TR_DisableCAEInlining") != NULL;
118+
if (!disableCAEInlining)
119+
{
120+
cg->setSupportsInlineUnsafeCompareAndExchange();
121+
}
122+
111123
if (!comp->getOption(TR_DisableReadMonitors))
112124
cg->setSupportsReadOnlyLocks();
113125

runtime/compiler/p/codegen/J9TreeEvaluator.cpp

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11900,7 +11900,8 @@ J9::Power::CodeGenerator::inlineDirectCall(TR::Node *node, TR::Register *&result
1190011900
}
1190111901
else if (methodSymbol)
1190211902
{
11903-
static bool disableCAEIntrinsic = feGetEnv("TR_DisableCAEIntrinsic") != NULL;
11903+
bool disableCASInlining = !cg->getSupportsInlineUnsafeCompareAndSet();
11904+
bool disableCAEInlining = !cg->getSupportsInlineUnsafeCompareAndExchange();
1190411905
switch (methodSymbol->getRecognizedMethod())
1190511906
{
1190611907
case TR::java_util_concurrent_ConcurrentLinkedQueue_tmOffer:
@@ -12189,8 +12190,11 @@ J9::Power::CodeGenerator::inlineDirectCall(TR::Node *node, TR::Register *&result
1218912190

1219012191
if ((node->isUnsafeGetPutCASCallOnNonArray() || !TR::Compiler->om.canGenerateArraylets()) && node->isSafeForCGToFastPathUnsafeCall())
1219112192
{
12192-
resultReg = VMinlineCompareAndSetOrExchange(node, cg, 4, false);
12193-
return true;
12193+
if (!disableCASInlining)
12194+
{
12195+
resultReg = VMinlineCompareAndSetOrExchange(node, cg, 4, false);
12196+
return true;
12197+
}
1219412198
}
1219512199
break;
1219612200

@@ -12203,13 +12207,19 @@ J9::Power::CodeGenerator::inlineDirectCall(TR::Node *node, TR::Register *&result
1220312207

1220412208
if (comp->target().is64Bit() && (node->isUnsafeGetPutCASCallOnNonArray() || !TR::Compiler->om.canGenerateArraylets()) && node->isSafeForCGToFastPathUnsafeCall())
1220512209
{
12206-
resultReg = VMinlineCompareAndSetOrExchange(node, cg, 8, false);
12207-
return true;
12210+
if (!disableCASInlining)
12211+
{
12212+
resultReg = VMinlineCompareAndSetOrExchange(node, cg, 8, false);
12213+
return true;
12214+
}
1220812215
}
1220912216
else if ((node->isUnsafeGetPutCASCallOnNonArray() || !TR::Compiler->om.canGenerateArraylets()) && node->isSafeForCGToFastPathUnsafeCall())
1221012217
{
12211-
resultReg = inlineAtomicOperation(node, cg, methodSymbol);
12212-
return true;
12218+
if (!disableCASInlining)
12219+
{
12220+
resultReg = inlineAtomicOperation(node, cg, methodSymbol);
12221+
return true;
12222+
}
1221312223
}
1221412224
break;
1221512225

@@ -12220,15 +12230,18 @@ J9::Power::CodeGenerator::inlineDirectCall(TR::Node *node, TR::Register *&result
1222012230

1222112231
if ((node->isUnsafeGetPutCASCallOnNonArray() || !TR::Compiler->om.canGenerateArraylets()) && node->isSafeForCGToFastPathUnsafeCall())
1222212232
{
12223-
resultReg = VMinlineCompareAndSetOrExchangeReference(node, cg, false);
12224-
return true;
12233+
if (!disableCASInlining)
12234+
{
12235+
resultReg = VMinlineCompareAndSetOrExchangeReference(node, cg, false);
12236+
return true;
12237+
}
1222512238
}
1222612239
break;
1222712240

1222812241
case TR::jdk_internal_misc_Unsafe_compareAndExchangeInt:
1222912242
if ((node->isUnsafeGetPutCASCallOnNonArray() || !TR::Compiler->om.canGenerateArraylets()) && node->isSafeForCGToFastPathUnsafeCall())
1223012243
{
12231-
if (!disableCAEIntrinsic)
12244+
if (!disableCAEInlining)
1223212245
{
1223312246
resultReg = VMinlineCompareAndSetOrExchange(node, cg, 4, true);
1223412247
return true;
@@ -12239,7 +12252,7 @@ J9::Power::CodeGenerator::inlineDirectCall(TR::Node *node, TR::Register *&result
1223912252
case TR::jdk_internal_misc_Unsafe_compareAndExchangeLong:
1224012253
if (comp->target().is64Bit() && (node->isUnsafeGetPutCASCallOnNonArray() || !TR::Compiler->om.canGenerateArraylets()) && node->isSafeForCGToFastPathUnsafeCall())
1224112254
{
12242-
if (!disableCAEIntrinsic)
12255+
if (!disableCAEInlining)
1224312256
{
1224412257
resultReg = VMinlineCompareAndSetOrExchange(node, cg, 8, true);
1224512258
return true;
@@ -12259,7 +12272,7 @@ J9::Power::CodeGenerator::inlineDirectCall(TR::Node *node, TR::Register *&result
1225912272
case TR::jdk_internal_misc_Unsafe_compareAndExchangeReference:
1226012273
if ((node->isUnsafeGetPutCASCallOnNonArray() || !TR::Compiler->om.canGenerateArraylets()) && node->isSafeForCGToFastPathUnsafeCall())
1226112274
{
12262-
if (!disableCAEIntrinsic)
12275+
if (!disableCAEInlining)
1226312276
{
1226412277
resultReg = VMinlineCompareAndSetOrExchangeReference(node, cg, true);
1226512278
return true;

0 commit comments

Comments
 (0)