Skip to content

Commit cb4b651

Browse files
committed
Update supportsInlineConcurrentLinkedQueue to check for CTX
Check is Constrained Transactional Execution feature supported on the CPU to inline ConcurrentLinkedQueue.tmOffer/Poll. Check if CPU has support for Transactional Exuecution feature which covers non constrained TM as well in addition to environment flag is set to generate non constrainedTM sequence for tmOffer and tmPoll. Signed-off-by: Rahil Shah <[email protected]>
1 parent 743425f commit cb4b651

File tree

2 files changed

+43
-24
lines changed

2 files changed

+43
-24
lines changed

runtime/compiler/z/codegen/J9CodeGenerator.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,16 @@ J9::Z::CodeGenerator::initialize()
106106
cg->setSupportsInlineStringLatin1Inflate();
107107
}
108108

109-
// See comment in `handleHardwareReadBarrier` implementation as to why we cannot support CTX under CS
110-
if (cg->getSupportsTM() && TR::Compiler->om.readBarrierType() == gc_modron_readbar_none)
109+
// For IBM Java 8 ConcurrentLinkedQueue.poll and offer has been accelerated
110+
// using constrained transactional execution instructions.
111+
// If CTX feature is supported on processor, and JIT has not disabled it
112+
// using TR_DisableTM option, then inlining of ConcurrentLinkedQueue.poll/offer
113+
// is supported.
114+
// See comment in `handleHardwareReadBarrier` implementation as to why we
115+
// cannot support CTX under CS
116+
if ((comp->target().cpu.supportsFeature(OMR_FEATURE_S390_CONSTRAINED_TRANSACTIONAL_EXECUTION_FACILITY)
117+
&& !comp->getOption(TR_DisableTM))
118+
&& TR::Compiler->om.readBarrierType() == gc_modron_readbar_none)
111119
{
112120
cg->setSupportsInlineConcurrentLinkedQueue();
113121
}

runtime/compiler/z/codegen/J9TreeEvaluator.cpp

Lines changed: 33 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -13056,28 +13056,29 @@ J9::Z::TreeEvaluator::inlineConcurrentLinkedQueueTMOffer(TR::Node *node, TR::Cod
1305613056

1305713057
bool usesCompressedrefs = comp->useCompressedPointers();
1305813058
int32_t shiftAmount = TR::Compiler->om.compressedReferenceShift();
13059-
static char * disableTMOfferenv = feGetEnv("TR_DisableTMOffer");
13060-
bool disableTMOffer = (disableTMOfferenv != NULL);
13061-
13059+
static bool disableTMOffer = feGetEnv("TR_DisableTMOffer") != NULL;
13060+
1306213061
classBlock1 = fej9->getClassFromSignature("Ljava/util/concurrent/ConcurrentLinkedQueue$Node;", 49, comp->getCurrentMethod(), true);
1306313062
classBlock2 = fej9->getClassFromSignature("Ljava/util/concurrent/ConcurrentLinkedQueue;", 44, comp->getCurrentMethod(), true);
1306413063

13065-
13066-
if (classBlock1 && classBlock2)
13064+
bool canInlineTMOffer = !disableTMOffer;
13065+
if (classBlock1 != NULL && classBlock2 != NULL)
1306713066
{
1306813067
offsetNext = fej9->getObjectHeaderSizeInBytes() + fej9->getInstanceFieldOffset(classBlock1, "next", 4, "Ljava/util/concurrent/ConcurrentLinkedQueue$Node;", 49);
1306913068
offsetTail = fej9->getObjectHeaderSizeInBytes() + fej9->getInstanceFieldOffset(classBlock2, "tail", 4, "Ljava/util/concurrent/ConcurrentLinkedQueue$Node;", 49);
1307013069
}
1307113070
else
13072-
disableTMOffer = true;
13071+
{
13072+
canInlineTMOffer = false;
13073+
}
1307313074

1307413075
cursor = generateRIInstruction(cg, TR::InstOpCode::LHI, node, rReturn, 1);
1307513076

13076-
static char * debugTM= feGetEnv("TR_DebugTM");
13077+
static bool debugTM= feGetEnv("TR_DebugTM") != NULL;
1307713078

1307813079
if (debugTM)
1307913080
{
13080-
if (disableTMOffer)
13081+
if (!canInlineTMOffer)
1308113082
{
1308213083
printf ("\nTM: disabling TM CLQ.Offer in %s (%s)", comp->signature(), comp->getHotnessName(comp->getMethodHotness()));
1308313084
fflush(stdout);
@@ -13088,14 +13089,16 @@ J9::Z::TreeEvaluator::inlineConcurrentLinkedQueueTMOffer(TR::Node *node, TR::Cod
1308813089
fflush(stdout);
1308913090
}
1309013091
}
13092+
static bool generateNonConstrainedTMEnvSeq = feGetEnv("TR_UseNonConstrainedTM") != NULL;
13093+
13094+
bool useNonConstrainedTM = generateNonConstrainedTMEnvSeq && comp->target().cpu.supportsFeature(OMR_FEATURE_S390_TRANSACTIONAL_EXECUTION_FACILITY);
1309113095

13092-
static char * useNonConstrainedTM = feGetEnv("TR_UseNonConstrainedTM");
13093-
static char * disableNIAI = feGetEnv("TR_DisableNIAI");
13096+
static bool disableNIAI = feGetEnv("TR_DisableNIAI") != NULL;
1309413097

1309513098
// the Transaction Diagnostic Block (TDB) is a memory location for the OS to write state info in the event of an abort
1309613099
TR::MemoryReference* TDBmemRef = generateS390MemoryReference(cg->getMethodMetaDataRealRegister(), fej9->thisThreadGetTDBOffset(), cg);
1309713100

13098-
if (!disableTMOffer)
13101+
if (canInlineTMOffer)
1309913102
{
1310013103
if (useNonConstrainedTM)
1310113104
{
@@ -13197,7 +13200,7 @@ J9::Z::TreeEvaluator::inlineConcurrentLinkedQueueTMOffer(TR::Node *node, TR::Cod
1319713200
cursor = generateSInstruction(cg, TR::InstOpCode::TEND, node, generateS390MemoryReference(cg->machine()->getRealRegister(TR::RealRegister::GPR0),0,cg));
1319813201
}
1319913202

13200-
if (useNonConstrainedTM || disableTMOffer)
13203+
if (useNonConstrainedTM || !canInlineTMOffer)
1320113204
cursor = generateS390LabelInstruction(cg, TR::InstOpCode::label, node, failLabel, deps);
1320213205

1320313206
genWrtBarForTM(node, cg, rP, rN, rReturn, true);
@@ -13248,28 +13251,33 @@ J9::Z::TreeEvaluator::inlineConcurrentLinkedQueueTMPoll(TR::Node *node, TR::Code
1324813251
deps->addPostCondition(rTmp, TR::RealRegister::AssignAny);
1324913252
}
1325013253

13251-
static char * disableTMPollenv = feGetEnv("TR_DisableTMPoll");
13252-
bool disableTMPoll = disableTMPollenv;
13254+
static bool disableTMPoll = feGetEnv("TR_DisableTMPoll") != NULL;
1325313255

1325413256
classBlock1 = fej9->getClassFromSignature("Ljava/util/concurrent/ConcurrentLinkedQueue;", 44, comp->getCurrentMethod(), true);
1325513257
classBlock2 = fej9->getClassFromSignature("Ljava/util/concurrent/ConcurrentLinkedQueue$Node;", 49, comp->getCurrentMethod(), true);
1325613258

13257-
if (classBlock1 && classBlock2)
13259+
bool canInlineTMPoll = !disableTMPoll;
13260+
if (classBlock1 != NULL && classBlock2 != NULL)
1325813261
{
1325913262
offsetHead = fej9->getObjectHeaderSizeInBytes() + fej9->getInstanceFieldOffset(classBlock1, "head", 4, "Ljava/util/concurrent/ConcurrentLinkedQueue$Node;", 49);
1326013263
offsetNext = fej9->getObjectHeaderSizeInBytes() + fej9->getInstanceFieldOffset(classBlock2, "next", 4, "Ljava/util/concurrent/ConcurrentLinkedQueue$Node;", 49);
1326113264
offsetItem = fej9->getObjectHeaderSizeInBytes() + fej9->getInstanceFieldOffset(classBlock2, "item", 4, "Ljava/lang/Object;", 18);
1326213265
}
1326313266
else
13264-
disableTMPoll = true;
13267+
{
13268+
// If we can not get Class object fo ConcurrentLinkedQueue /
13269+
// ConcurrentLinkedQueue$Node, then we can not inline the intrinsic
13270+
// operation.
13271+
canInlineTMPoll = false;
13272+
}
1326513273

1326613274
cursor = generateRRInstruction(cg, TR::InstOpCode::getXORRegOpCode(), node, rE, rE);
1326713275

13268-
static char * debugTM= feGetEnv("TR_DebugTM");
13276+
static bool debugTM= feGetEnv("TR_DebugTM") != NULL;
1326913277

1327013278
if (debugTM)
1327113279
{
13272-
if (disableTMPoll)
13280+
if (!canInlineTMPoll)
1327313281
{
1327413282
printf ("\nTM: disabling TM CLQ.Poll in %s (%s)", comp->signature(), comp->getHotnessName(comp->getMethodHotness()));
1327513283
fflush(stdout);
@@ -13281,13 +13289,16 @@ J9::Z::TreeEvaluator::inlineConcurrentLinkedQueueTMPoll(TR::Node *node, TR::Code
1328113289
}
1328213290
}
1328313291

13284-
static char * useNonConstrainedTM = feGetEnv("TR_UseNonConstrainedTM");
13285-
static char * disableNIAI = feGetEnv("TR_DisableNIAI");
13292+
static bool generateNonConstrainedTMEnvSeq = feGetEnv("TR_UseNonConstrainedTM") != NULL;
13293+
13294+
bool useNonConstrainedTM = generateNonConstrainedTMEnvSeq && comp->target().cpu.supportsFeature(OMR_FEATURE_S390_TRANSACTIONAL_EXECUTION_FACILITY);
13295+
13296+
static bool disableNIAI = feGetEnv("TR_DisableNIAI") != NULL;
1328613297

1328713298
// the Transaction Diagnostic Block (TDB) is a memory location for the OS to write state info in the event of an abort
1328813299
TR::MemoryReference* TDBmemRef = generateS390MemoryReference(cg->getMethodMetaDataRealRegister(), fej9->thisThreadGetTDBOffset(), cg);
1328913300

13290-
if (!disableTMPoll)
13301+
if (canInlineTMPoll)
1329113302
{
1329213303
if (useNonConstrainedTM)
1329313304
{
@@ -13379,7 +13390,7 @@ J9::Z::TreeEvaluator::inlineConcurrentLinkedQueueTMPoll(TR::Node *node, TR::Code
1337913390
cursor = generateSInstruction(cg, TR::InstOpCode::TEND, node, generateS390MemoryReference(cg->machine()->getRealRegister(TR::RealRegister::GPR0),0,cg));
1338013391
}
1338113392

13382-
if (useNonConstrainedTM || disableTMPoll)
13393+
if (useNonConstrainedTM || !canInlineTMPoll)
1338313394
cursor = generateS390LabelInstruction(cg, TR::InstOpCode::label, node, failLabel, deps);
1338413395

1338513396
if (usesCompressedrefs)

0 commit comments

Comments
 (0)