Skip to content

Commit

Permalink
Merge pull request #12351 from Akira1Saitoh/aarch64FixImplicitNullCHK
Browse files Browse the repository at this point in the history
AArch64: Properly find compressed refs sequence in implicit NULLCHK
  • Loading branch information
knn-k authored Apr 8, 2021
2 parents 7735742 + 6c5727f commit 23c0557
Showing 1 changed file with 34 additions and 22 deletions.
56 changes: 34 additions & 22 deletions runtime/compiler/aarch64/codegen/J9TreeEvaluator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3437,13 +3437,11 @@ J9::ARM64::TreeEvaluator::evaluateNULLCHKWithPossibleResolve(TR::Node *node, boo
// pattern match the sequence under the l2a
// NULLCHK NULLCHK <- node
// aloadi f l2a
// aload O ladd
// lshl
// i2l
// iloadi/irdbari f <- n
// aload O <- reference
// iconst shftKonst
// lconst HB
// aload O lshl
// iu2l
// iloadi/irdbari f <- n
// aload O <- reference
// iconst shftKonst
//
hasCompressedPointers = true;
TR::ILOpCodes loadOp = cg->comp()->il.opCodeForIndirectLoad(TR::Int32);
Expand All @@ -3467,6 +3465,7 @@ J9::ARM64::TreeEvaluator::evaluateNULLCHKWithPossibleResolve(TR::Node *node, boo

bool needExplicitCheck = true;
bool needLateEvaluation = true;
bool firstChildEvaluated = false;

// Add the explicit check after this instruction
//
Expand All @@ -3475,9 +3474,8 @@ J9::ARM64::TreeEvaluator::evaluateNULLCHKWithPossibleResolve(TR::Node *node, boo
// determine if an explicit check is needed
if (cg->getHasResumableTrapHandler())
{
if (opCode.isLoadVar()
|| (opCode.getOpCodeValue() == TR::l2i)
|| (hasCompressedPointers && firstChild->getFirstChild()->getOpCode().getOpCodeValue() == TR::i2l))
if (n->getOpCode().isLoadVar()
|| (opCode.getOpCodeValue() == TR::l2i))
{
TR::SymbolReference *symRef = NULL;

Expand All @@ -3498,19 +3496,29 @@ J9::ARM64::TreeEvaluator::evaluateNULLCHKWithPossibleResolve(TR::Node *node, boo

// at this point, n is the raw iloadi (created by lowerTrees) and
// reference is the aload of the object. node->getFirstChild is the
// l2a sequence; as a result, n's refCount will always be 1
// and node->getFirstChild's refCount will be at least 2 (one under the nullchk
// and the other under the translate treetop)
// l2a sequence; as a result, n's refCount will always be 1.
//
if (hasCompressedPointers
&& node->getFirstChild()->getReferenceCount() > 2)
&& node->getFirstChild()->getReferenceCount() >= 2)
{
// In this case, the result of load is used in other places, so we need to evaluate it here
//
needLateEvaluation = true;

// Check if offset from a NULL reference will fall into the inaccessible bytes,
// resulting in an implicit trap being raised.
if (symRef
&& ((symRef->getSymbol()->getOffset() + symRef->getOffset()) < cg->getNumberBytesReadInaccessible()))
{
needExplicitCheck = false;
}
}
}

// Check if offset from a NULL reference will fall into the inaccessible bytes,
// resulting in an implicit trap being raised.
else if (symRef
&& ((symRef->getSymbol()->getOffset() + symRef->getOffset()) < cg->getNumberBytesReadInaccessible()))
&& ((symRef->getSymbol()->getOffset() + symRef->getOffset()) < cg->getNumberBytesReadInaccessible()))
{
needExplicitCheck = false;

Expand Down Expand Up @@ -3543,7 +3551,6 @@ J9::ARM64::TreeEvaluator::evaluateNULLCHKWithPossibleResolve(TR::Node *node, boo
{
needLateEvaluation = false;
needExplicitCheck = true;
reference->incReferenceCount(); // will be decremented again later
}
}
}
Expand Down Expand Up @@ -3597,17 +3604,15 @@ J9::ARM64::TreeEvaluator::evaluateNULLCHKWithPossibleResolve(TR::Node *node, boo
// The child may generate inline code that provides an implicit null check
// but we won't know until the child is evaluated.
//
reference->incReferenceCount(); // will be decremented again later
needLateEvaluation = false;
cg->evaluate(reference);
appendTo = cg->getAppendInstruction();
cg->evaluate(firstChild);

firstChildEvaluated = true;
if (cg->getImplicitExceptionPoint()
&& (cg->getNumberBytesReadInaccessible() > cg->fe()->getOffsetOfContiguousArraySizeField()))
{
needExplicitCheck = false;
cg->decReferenceCount(reference);
}
}
}
Expand Down Expand Up @@ -3639,12 +3644,19 @@ J9::ARM64::TreeEvaluator::evaluateNULLCHKWithPossibleResolve(TR::Node *node, boo
if (needLateEvaluation)
{
cg->evaluate(firstChild);
firstChildEvaluated = true;
}
else if (needExplicitCheck)
// If the firstChild is evaluated, we simply call decReferenceCount.
// Otherwise, we need to call recursivelyDecReferenceCount so that the ref count of
// child nodes of the firstChild is properly decremented when the ref count of the firstChild is 1.
if (firstChildEvaluated)
{
cg->decReferenceCount(reference);
cg->decReferenceCount(firstChild);
}
else
{
cg->recursivelyDecReferenceCount(firstChild);
}
cg->decReferenceCount(firstChild);

// If an explicit check has not been generated for the null check, there is
// an instruction that will cause a hardware trap if the exception is to be
Expand Down

0 comments on commit 23c0557

Please sign in to comment.