@@ -4885,10 +4885,6 @@ static TR::Register * generateMultianewArrayWithInlineAllocators(TR::Node *node,
48854885
48864886 TR::Register *dim2SizeReg = cg->allocateRegister();
48874887 dependencies->addPostCondition(dim2SizeReg, TR::RealRegister::AssignAny);
4888- cursor = generateRXInstruction(cg, TR::InstOpCode::LTGF, node, dim2SizeReg, generateS390MemoryReference(dimsPtrReg, 0, cg), cursor);
4889- iComment("Load 2st dim length.");
4890- // The size of zero length array is already loaded in size register. Jump over the array size calculation instructions if length is 0.
4891- TR::LabelSymbol *zeroSecondDimLabel = generateLabelSymbol(cg);
48924888
48934889 if (componentSize == 1)
48944890 {
@@ -4907,10 +4903,23 @@ static TR::Register * generateMultianewArrayWithInlineAllocators(TR::Node *node,
49074903 // allocate inline is not frequent.
49084904 cursor = generateRSInstruction(cg, TR::InstOpCode::SLA, node, dim2SizeReg, trailingZeroes(componentSize), cursor);
49094905 }
4910- // Bypass dim2 size calculation if the size is zero.
4911- cursor = generateS390BranchInstruction(cg, TR::InstOpCode::BRC, TR::InstOpCode::COND_BZ, node, zeroSecondDimLabel, cursor);
4912- // Call helper if the length is negative or length * componentSize is larger that INT32_MAX (overflow).
4913- cursor = generateS390BranchInstruction(cg, TR::InstOpCode::BRC, TR::InstOpCode::COND_MASK5, node, inlineAllocFailLabel, cursor);
4906+
4907+ TR::LabelSymbol *zeroSecondDimLabel = generateLabelSymbol(cg);
4908+ #if defined(J9VM_GC_SPARSE_HEAP_ALLOCATION)
4909+ bool isOffHeapAllocationEnabled = TR::Compiler->om.isOffHeapAllocationEnabled();
4910+ if (isOffHeapAllocationEnabled)
4911+ {
4912+ // Call helper if dim2 length is negative, zero, or larger that INT32_MAX (overflow).
4913+ cursor = generateS390BranchInstruction(cg, TR::InstOpCode::BRC, TR::InstOpCode::COND_BRNP, node, inlineAllocFailLabel, cursor);
4914+ }
4915+ else
4916+ #endif /* J9VM_GC_SPARSE_HEAP_ALLOCATION */
4917+ {
4918+ // Bypass dim2 size calculation if the size is zero.
4919+ cursor = generateS390BranchInstruction(cg, TR::InstOpCode::BRC, TR::InstOpCode::COND_BZ, node, zeroSecondDimLabel, cursor);
4920+ // Call helper if the length is negative or length * componentSize is larger that INT32_MAX (overflow).
4921+ cursor = generateS390BranchInstruction(cg, TR::InstOpCode::BRC, TR::InstOpCode::COND_MASK5, node, inlineAllocFailLabel, cursor);
4922+ }
49144923
49154924 int32_t headerSize= TR::Compiler->om.contiguousArrayHeaderSizeInBytes();
49164925 // size = (size + alignmentConstant - 1) & -alignmentConstant equation round up the size to a factor of alignmentConstant.
@@ -5016,6 +5025,17 @@ static TR::Register * generateMultianewArrayWithInlineAllocators(TR::Node *node,
50165025 // Load the address of the first element of the first dimension array in sizeReg.
50175026 cursor = generateRXInstruction(cg, TR::InstOpCode::LA, node, sizeReg,
50185027 generateS390MemoryReference(resultReg, TR::Compiler->om.contiguousArrayHeaderSizeInBytes(), cg), cursor);
5028+
5029+ #if defined(J9VM_GC_SPARSE_HEAP_ALLOCATION)
5030+ if (isOffHeapAllocationEnabled)
5031+ {
5032+ // Store first element's address in data address field.
5033+ cursor = generateRXInstruction(cg, TR::InstOpCode::STG, node, sizeReg, generateS390MemoryReference(resultReg, fej9->getOffsetOfContiguousDataAddrField(), cg), cursor);
5034+ // 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.
5035+ cursor = generateRILInstruction(cg, TR::InstOpCode::SLFI, node, dim2SizeReg, (int32_t)TR::Compiler->om.contiguousArrayHeaderSizeInBytes(), cursor);
5036+ }
5037+ #endif /* J9VM_GC_SPARSE_HEAP_ALLOCATION */
5038+
50195039 // Start setting second dim:
50205040 TR::LabelSymbol *secondDimLabel = generateLabelSymbol(cg);
50215041 cursor = generateS390LabelInstruction(cg, TR::InstOpCode::label, node, secondDimLabel, cursor);
@@ -5040,6 +5060,18 @@ static TR::Register * generateMultianewArrayWithInlineAllocators(TR::Node *node,
50405060 generateS390MemoryReference(sizeReg, 0, cg), cursor);
50415061 }
50425062
5063+ #if defined(J9VM_GC_SPARSE_HEAP_ALLOCATION)
5064+ if (isOffHeapAllocationEnabled)
5065+ {
5066+ // Load the first element address.
5067+ cursor = generateRXInstruction(cg, TR::InstOpCode::LA, node, dim1SizeReg,
5068+ generateS390MemoryReference(dim1SizeReg, TR::Compiler->om.contiguousArrayHeaderSizeInBytes(), cg), cursor);
5069+ // Store the first element address in data address field.
5070+ cursor = generateRXInstruction(cg, TR::InstOpCode::STG, node, dim1SizeReg, generateS390MemoryReference(dim1SizeReg,
5071+ (fej9->getOffsetOfContiguousDataAddrField() - TR::Compiler->om.contiguousArrayHeaderSizeInBytes()), cg), cursor);
5072+ }
5073+ #endif /* J9VM_GC_SPARSE_HEAP_ALLOCATION */
5074+
50435075 // Load the next leaf address in dim1SizeReg.
50445076 cursor = generateRREInstruction(cg, TR::InstOpCode::ALGFR, node, dim1SizeReg, dim2SizeReg, cursor);
50455077 // Load the next element address of the first dim array in sizeReg.
@@ -5107,9 +5139,7 @@ J9::Z::TreeEvaluator::multianewArrayEvaluator(TR::Node * node, TR::CodeGenerator
51075139
51085140 if ((nDims == 2) && (componentSize > 0)
51095141 && comp->target().cpu.isAtLeast(OMR_PROCESSOR_S390_Z196)
5110- && !comp->suppressAllocationInlining()
5111- // Temporarily disable inline allocation for offHeap.
5112- && !TR::Compiler->om.isOffHeapAllocationEnabled())
5142+ && !comp->suppressAllocationInlining())
51135143 {
51145144 return generateMultianewArrayWithInlineAllocators(node, cg, componentSize);
51155145 }
0 commit comments