Skip to content

Commit ff967f7

Browse files
committed
Defer dataAddr eval & use mainline store for nullSource OffHeap x86 ArrayStoreCHK
ArrayStoreCHK in x86 uses null check and OOL store path for nullSource stores, evaluating the destination address early to be used in either the mainline or OOL store paths. For OffHeap evaluating the destination address includes loading the dataAddr pointer, where having it alive across GC point (OOL ArrayTypeCheck) will cause a crash [1]. To defer the evaluation and loading the dataAddr into a register, this consolidate the store paths for null and non-null stores and defers the destination address evaluation till before the store happens for OffHeap. Side-effect of this is null stores performing a wrtbar/card-marking even thought it's not necessary but opted for instead of a second null check. [1] Reason of crashing is evaluating the dataAddr pointer into a collectable register. A long-term solution is fixing that without the impact of setting every dataAddr as an internal-pointer.
1 parent b6b5bb6 commit ff967f7

File tree

1 file changed

+26
-5
lines changed

1 file changed

+26
-5
lines changed

runtime/compiler/x/codegen/J9TreeEvaluator.cpp

+26-5
Original file line numberDiff line numberDiff line change
@@ -2957,11 +2957,25 @@ TR::Register *J9::X86::TreeEvaluator::ArrayStoreCHKEvaluator(TR::Node *node, TR:
29572957
!fej9->classHasBeenExtended(node->getArrayStoreClassInNode())
29582958
) ? true : false;
29592959

2960+
// OffHeap runs defer destination evaluation after GC point.
2961+
static char *disableDeferDestinationEvaluation = feGetEnv("TR_DisableDeferDestinationEvaluation");
2962+
bool deferDestinationEvaluation = TR::Compiler->om.isOffHeapAllocationEnabled() && !disableDeferDestinationEvaluation;
2963+
29602964
doneLabel = generateLabelSymbol(cg);
29612965
doneLabel->setEndInternalControlFlow();
29622966

2963-
doNullStoreLabel = generateWriteBarrier ? generateLabelSymbol(cg) : doneLabel;
2964-
startOfWrtbarLabel = generateWriteBarrier ? generateLabelSymbol(cg) : doNullStoreLabel;
2967+
if(generateWriteBarrier)
2968+
{
2969+
startOfWrtbarLabel = generateLabelSymbol(cg);
2970+
// For OffHeap we use mainline store for null stores to consolidate store paths and defer
2971+
// destination evaluation. OffHeap will perform redundant wrtbar on null stores.
2972+
doNullStoreLabel = deferDestinationEvaluation ? startOfWrtbarLabel : generateLabelSymbol(cg);
2973+
}
2974+
else
2975+
{
2976+
startOfWrtbarLabel = doneLabel;
2977+
doNullStoreLabel = doneLabel;
2978+
}
29652979

29662980
bool usingCompressedPointers = false;
29672981
bool usingLowMemHeap = false;
@@ -2993,7 +3007,7 @@ TR::Register *J9::X86::TreeEvaluator::ArrayStoreCHKEvaluator(TR::Node *node, TR:
29933007

29943008
TR::MemoryReference *tempMR = NULL;
29953009

2996-
if (generateWriteBarrier)
3010+
if (generateWriteBarrier && !deferDestinationEvaluation)
29973011
{
29983012
tempMR = generateX86MemoryReference(firstChild, cg);
29993013
}
@@ -3123,6 +3137,12 @@ TR::Register *J9::X86::TreeEvaluator::ArrayStoreCHKEvaluator(TR::Node *node, TR:
31233137
sourceChild->setIsNonNull(true);
31243138
}
31253139

3140+
if (deferDestinationEvaluation)
3141+
{
3142+
// Perform deferred destination evaluation
3143+
tempMR = generateX86MemoryReference(firstChild, cg);
3144+
}
3145+
31263146
TR::TreeEvaluator::VMwrtbarWithStoreEvaluator(
31273147
node,
31283148
tempMR,
@@ -3153,7 +3173,8 @@ TR::Register *J9::X86::TreeEvaluator::ArrayStoreCHKEvaluator(TR::Node *node, TR:
31533173

31543174
if (!isRealTimeGC)
31553175
{
3156-
if (generateWriteBarrier)
3176+
// OffHeap uses the already generated mainline VMwrtbarWithStoreEvaluator for null stores
3177+
if (generateWriteBarrier && !deferDestinationEvaluation)
31573178
{
31583179
assert(isNonRTWriteBarrierRequired);
31593180
assert(tempMR);
@@ -3176,7 +3197,7 @@ TR::Register *J9::X86::TreeEvaluator::ArrayStoreCHKEvaluator(TR::Node *node, TR:
31763197
generateLabelInstruction(TR::InstOpCode::JMP4, node, doneLabel, cg);
31773198
og.endOutlinedInstructionSequence();
31783199
}
3179-
else
3200+
else if (!generateWriteBarrier)
31803201
{
31813202
// No write barrier emitted. Evaluate the store here.
31823203
//

0 commit comments

Comments
 (0)