Skip to content

Commit deaab6d

Browse files
committed
Z: Add support for offheap allocation in multianewarray evaluator
Enhances the multianewarray evaluator to support offheap allocation on IBM Z platform. Offheap allocation for arrays with a zero-length second dimension is not supported; in such cases, a helper call is triggered to handle the allocation. signed-off-by: Ehsan Kiani Far <ehsan.kianifar@gmail.com>
1 parent 5d6eadb commit deaab6d

File tree

1 file changed

+41
-11
lines changed

1 file changed

+41
-11
lines changed

runtime/compiler/z/codegen/J9TreeEvaluator.cpp

Lines changed: 41 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4896,10 +4896,6 @@ static TR::Register * generateMultianewArrayWithInlineAllocators(TR::Node *node,
48964896

48974897
TR::Register *dim2SizeReg = cg->allocateRegister();
48984898
dependencies->addPostCondition(dim2SizeReg, TR::RealRegister::AssignAny);
4899-
cursor = generateRXInstruction(cg, TR::InstOpCode::LTGF, node, dim2SizeReg, generateS390MemoryReference(dimsPtrReg, 0, cg), cursor);
4900-
iComment("Load 2st dim length.");
4901-
// The size of zero length array is already loaded in size register. Jump over the array size calculation instructions if length is 0.
4902-
TR::LabelSymbol *zeroSecondDimLabel = generateLabelSymbol(cg);
49034899

49044900
if (componentSize == 1)
49054901
{
@@ -4918,10 +4914,23 @@ static TR::Register * generateMultianewArrayWithInlineAllocators(TR::Node *node,
49184914
// allocate inline is not frequent.
49194915
cursor = generateRSInstruction(cg, TR::InstOpCode::SLA, node, dim2SizeReg, trailingZeroes(componentSize), cursor);
49204916
}
4921-
// Bypass dim2 size calculation if the size is zero.
4922-
cursor = generateS390BranchInstruction(cg, TR::InstOpCode::BRC, TR::InstOpCode::COND_BZ, node, zeroSecondDimLabel, cursor);
4923-
// Call helper if the length is negative or length * componentSize is larger that INT32_MAX (overflow).
4924-
cursor = generateS390BranchInstruction(cg, TR::InstOpCode::BRC, TR::InstOpCode::COND_MASK5, node, inlineAllocFailLabel, cursor);
4917+
4918+
TR::LabelSymbol *zeroSecondDimLabel = generateLabelSymbol(cg);
4919+
#if defined(J9VM_GC_SPARSE_HEAP_ALLOCATION)
4920+
bool isOffHeapAllocationEnabled = TR::Compiler->om.isOffHeapAllocationEnabled();
4921+
if (isOffHeapAllocationEnabled)
4922+
{
4923+
// Call helper if dim2 length is negative, zero, or larger that INT32_MAX (overflow).
4924+
cursor = generateS390BranchInstruction(cg, TR::InstOpCode::BRC, TR::InstOpCode::COND_BRNP, node, inlineAllocFailLabel, cursor);
4925+
}
4926+
else
4927+
#endif /* J9VM_GC_SPARSE_HEAP_ALLOCATION */
4928+
{
4929+
// Bypass dim2 size calculation if the size is zero.
4930+
cursor = generateS390BranchInstruction(cg, TR::InstOpCode::BRC, TR::InstOpCode::COND_BZ, node, zeroSecondDimLabel, cursor);
4931+
// Call helper if the length is negative or length * componentSize is larger that INT32_MAX (overflow).
4932+
cursor = generateS390BranchInstruction(cg, TR::InstOpCode::BRC, TR::InstOpCode::COND_MASK5, node, inlineAllocFailLabel, cursor);
4933+
}
49254934

49264935
int32_t headerSize= TR::Compiler->om.contiguousArrayHeaderSizeInBytes();
49274936
// size = (size + alignmentConstant - 1) & -alignmentConstant equation round up the size to a factor of alignmentConstant.
@@ -5027,6 +5036,17 @@ static TR::Register * generateMultianewArrayWithInlineAllocators(TR::Node *node,
50275036
// Load the address of the first element of the first dimension array in sizeReg.
50285037
cursor = generateRXInstruction(cg, TR::InstOpCode::LA, node, sizeReg,
50295038
generateS390MemoryReference(resultReg, TR::Compiler->om.contiguousArrayHeaderSizeInBytes(), cg), cursor);
5039+
5040+
#if defined(J9VM_GC_SPARSE_HEAP_ALLOCATION)
5041+
if (isOffHeapAllocationEnabled)
5042+
{
5043+
// Store first element's address in data address field.
5044+
cursor = generateRXInstruction(cg, TR::InstOpCode::STG, node, sizeReg, generateS390MemoryReference(resultReg, fej9->getOffsetOfContiguousDataAddrField(), cg), cursor);
5045+
// Subtract the header size from the dim2 size, so we can move to the next leaf by adding this value to the address of the leaf's first element.
5046+
cursor = generateRILInstruction(cg, TR::InstOpCode::SLFI, node, dim2SizeReg, (int32_t)TR::Compiler->om.contiguousArrayHeaderSizeInBytes(), cursor);
5047+
}
5048+
#endif /* J9VM_GC_SPARSE_HEAP_ALLOCATION */
5049+
50305050
// Start setting second dim:
50315051
TR::LabelSymbol *secondDimLabel = generateLabelSymbol(cg);
50325052
cursor = generateS390LabelInstruction(cg, TR::InstOpCode::label, node, secondDimLabel, cursor);
@@ -5051,6 +5071,18 @@ static TR::Register * generateMultianewArrayWithInlineAllocators(TR::Node *node,
50515071
generateS390MemoryReference(sizeReg, 0, cg), cursor);
50525072
}
50535073

5074+
#if defined(J9VM_GC_SPARSE_HEAP_ALLOCATION)
5075+
if (isOffHeapAllocationEnabled)
5076+
{
5077+
// Load the first element address.
5078+
cursor = generateRXInstruction(cg, TR::InstOpCode::LA, node, dim1SizeReg,
5079+
generateS390MemoryReference(dim1SizeReg, TR::Compiler->om.contiguousArrayHeaderSizeInBytes(), cg), cursor);
5080+
// Store the first element address in data address field.
5081+
cursor = generateRXInstruction(cg, TR::InstOpCode::STG, node, dim1SizeReg, generateS390MemoryReference(dim1SizeReg,
5082+
(fej9->getOffsetOfContiguousDataAddrField() - TR::Compiler->om.contiguousArrayHeaderSizeInBytes()), cg), cursor);
5083+
}
5084+
#endif /* J9VM_GC_SPARSE_HEAP_ALLOCATION */
5085+
50545086
// Load the next leaf address in dim1SizeReg.
50555087
cursor = generateRREInstruction(cg, TR::InstOpCode::ALGFR, node, dim1SizeReg, dim2SizeReg, cursor);
50565088
// Load the next element address of the first dim array in sizeReg.
@@ -5118,9 +5150,7 @@ J9::Z::TreeEvaluator::multianewArrayEvaluator(TR::Node * node, TR::CodeGenerator
51185150

51195151
if ((nDims == 2) && (componentSize > 0)
51205152
&& comp->target().cpu.isAtLeast(OMR_PROCESSOR_S390_Z196)
5121-
&& !comp->suppressAllocationInlining()
5122-
// Temporarily disable inline allocation for offHeap.
5123-
&& !TR::Compiler->om.isOffHeapAllocationEnabled())
5153+
&& !comp->suppressAllocationInlining())
51245154
{
51255155
return generateMultianewArrayWithInlineAllocators(node, cg, componentSize);
51265156
}

0 commit comments

Comments
 (0)