@@ -4896,8 +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.");
49014899 // The size of zero length array is already loaded in size register. Jump over the array size calculation instructions if length is 0.
49024900 TR::LabelSymbol *zeroSecondDimLabel = generateLabelSymbol(cg);
49034901
@@ -4918,10 +4916,22 @@ static TR::Register * generateMultianewArrayWithInlineAllocators(TR::Node *node,
49184916 // allocate inline is not frequent.
49194917 cursor = generateRSInstruction(cg, TR::InstOpCode::SLA, node, dim2SizeReg, trailingZeroes(componentSize), cursor);
49204918 }
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);
4919+
4920+ #if defined(J9VM_GC_SPARSE_HEAP_ALLOCATION)
4921+ bool isOffHeapAllocationEnabled = TR::Compiler->om.isOffHeapAllocationEnabled();
4922+ if (isOffHeapAllocationEnabled)
4923+ {
4924+ // Call helper if dim2 length is negative, zero, or larger that INT32_MAX (overflow).
4925+ cursor = generateS390BranchInstruction(cg, TR::InstOpCode::BRC, TR::InstOpCode::COND_BRNP, node, inlineAllocFailLabel, cursor);
4926+ }
4927+ else
4928+ #endif /* J9VM_GC_SPARSE_HEAP_ALLOCATION */
4929+ {
4930+ // Bypass dim2 size calculation if the size is zero.
4931+ cursor = generateS390BranchInstruction(cg, TR::InstOpCode::BRC, TR::InstOpCode::COND_BZ, node, zeroSecondDimLabel, cursor);
4932+ // Call helper if the length is negative or length * componentSize is larger that INT32_MAX (overflow).
4933+ cursor = generateS390BranchInstruction(cg, TR::InstOpCode::BRC, TR::InstOpCode::COND_MASK5, node, inlineAllocFailLabel, cursor);
4934+ }
49254935
49264936 int32_t headerSize= TR::Compiler->om.contiguousArrayHeaderSizeInBytes();
49274937 // size = (size + alignmentConstant - 1) & -alignmentConstant equation round up the size to a factor of alignmentConstant.
@@ -5027,6 +5037,17 @@ static TR::Register * generateMultianewArrayWithInlineAllocators(TR::Node *node,
50275037 // Load the address of the first element of the first dimension array in sizeReg.
50285038 cursor = generateRXInstruction(cg, TR::InstOpCode::LA, node, sizeReg,
50295039 generateS390MemoryReference(resultReg, TR::Compiler->om.contiguousArrayHeaderSizeInBytes(), cg), cursor);
5040+
5041+ #if defined(J9VM_GC_SPARSE_HEAP_ALLOCATION)
5042+ if (isOffHeapAllocationEnabled)
5043+ {
5044+ // Store first element's address in data address field.
5045+ cursor = generateRXInstruction(cg, TR::InstOpCode::STG, node, sizeReg, generateS390MemoryReference(resultReg, fej9->getOffsetOfContiguousDataAddrField(), cg), cursor);
5046+ // 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.
5047+ cursor = generateRILInstruction(cg, TR::InstOpCode::SLFI, node, dim2SizeReg, (int32_t)TR::Compiler->om.contiguousArrayHeaderSizeInBytes(), cursor);
5048+ }
5049+ #endif /* J9VM_GC_SPARSE_HEAP_ALLOCATION */
5050+
50305051 // Start setting second dim:
50315052 TR::LabelSymbol *secondDimLabel = generateLabelSymbol(cg);
50325053 cursor = generateS390LabelInstruction(cg, TR::InstOpCode::label, node, secondDimLabel, cursor);
@@ -5051,6 +5072,18 @@ static TR::Register * generateMultianewArrayWithInlineAllocators(TR::Node *node,
50515072 generateS390MemoryReference(sizeReg, 0, cg), cursor);
50525073 }
50535074
5075+ #if defined(J9VM_GC_SPARSE_HEAP_ALLOCATION)
5076+ if (isOffHeapAllocationEnabled)
5077+ {
5078+ // Load the first element address.
5079+ cursor = generateRXInstruction(cg, TR::InstOpCode::LA, node, dim1SizeReg,
5080+ generateS390MemoryReference(dim1SizeReg, TR::Compiler->om.contiguousArrayHeaderSizeInBytes(), cg), cursor);
5081+ // Store the first element address in data address field.
5082+ cursor = generateRXInstruction(cg, TR::InstOpCode::STG, node, dim1SizeReg, generateS390MemoryReference(dim1SizeReg,
5083+ (fej9->getOffsetOfContiguousDataAddrField() - TR::Compiler->om.contiguousArrayHeaderSizeInBytes()), cg), cursor);
5084+ }
5085+ #endif /* J9VM_GC_SPARSE_HEAP_ALLOCATION */
5086+
50545087 // Load the next leaf address in dim1SizeReg.
50555088 cursor = generateRREInstruction(cg, TR::InstOpCode::ALGFR, node, dim1SizeReg, dim2SizeReg, cursor);
50565089 // Load the next element address of the first dim array in sizeReg.
@@ -5118,9 +5151,7 @@ J9::Z::TreeEvaluator::multianewArrayEvaluator(TR::Node * node, TR::CodeGenerator
51185151
51195152 if ((nDims == 2) && (componentSize > 0)
51205153 && comp->target().cpu.isAtLeast(OMR_PROCESSOR_S390_Z196)
5121- && !comp->suppressAllocationInlining()
5122- // Temporarily disable inline allocation for offHeap.
5123- && !TR::Compiler->om.isOffHeapAllocationEnabled())
5154+ && !comp->suppressAllocationInlining())
51245155 {
51255156 return generateMultianewArrayWithInlineAllocators(node, cg, componentSize);
51265157 }
0 commit comments