@@ -6163,6 +6163,26 @@ static void genInitArrayHeader(TR::Node *node, TR::Instruction *&iCursor, bool i
6163
6163
TR::MemoryReference::createWithDisplacement(cg, resReg, fej9->getOffsetOfContiguousArraySizeField(), 4),
6164
6164
instanceSizeReg, iCursor);
6165
6165
}
6166
+
6167
+ // Clear padding after size field
6168
+ if (needZeroInit)
6169
+ {
6170
+ TR_ASSERT_FATAL_WITH_NODE(node, zeroReg, "zeroReg is expected to be intialized but wasn't.\n");
6171
+ if (TR::Compiler->om.compressObjectReferences())
6172
+ {
6173
+ // padding field starts at fej9->getOffsetOfDiscontiguousArraySizeField() + 4
6174
+ iCursor = generateMemSrc1Instruction(cg, TR::InstOpCode::stw, node,
6175
+ TR::MemoryReference::createWithDisplacement(cg, resReg, fej9->getOffsetOfDiscontiguousArraySizeField() + 4, 4),
6176
+ zeroReg, iCursor);
6177
+ }
6178
+ else
6179
+ {
6180
+ // padding field starts at fej9->getOffsetOfContiguousArraySizeField() + 4
6181
+ iCursor = generateMemSrc1Instruction(cg, TR::InstOpCode::stw, node,
6182
+ TR::MemoryReference::createWithDisplacement(cg, resReg, fej9->getOffsetOfContiguousArraySizeField() + 4, 4),
6183
+ zeroReg, iCursor);
6184
+ }
6185
+ }
6166
6186
}
6167
6187
6168
6188
static void genZeroInit(TR::CodeGenerator *cg, TR::Node *node, TR::Register *objectReg, int32_t headerSize, int32_t totalSize, bool useInitInfo)
@@ -6492,7 +6512,8 @@ TR::Register *J9::Power::TreeEvaluator::VMnewEvaluator(TR::Node *node, TR::CodeG
6492
6512
* runtime size checks are needed to determine whether to use contiguous or discontiguous header layout.
6493
6513
*
6494
6514
* In both scenarios, arrays of non-zero size use contiguous header layout while zero size arrays use
6495
- * discontiguous header layout.
6515
+ * discontiguous header layout. DataAddr field of zero size arrays is intialized to NULL because they
6516
+ * don't have any data elements.
6496
6517
*/
6497
6518
TR::Register *offsetReg = tmp5Reg;
6498
6519
TR::Register *firstDataElementReg = tmp4Reg;
@@ -6517,17 +6538,22 @@ TR::Register *J9::Power::TreeEvaluator::VMnewEvaluator(TR::Node *node, TR::CodeG
6517
6538
iCursor = generateTrg1Src1Imm2Instruction(cg, TR::InstOpCode::rlwinm, node, offsetReg, offsetReg, 29, 8, iCursor);
6518
6539
// offsetReg should either be 0 (if enumReg > 0) or 8 (if enumReg == 0)
6519
6540
iCursor = generateTrg1Src2Instruction(cg, TR::InstOpCode::add, node, offsetReg, resReg, offsetReg, iCursor);
6520
-
6521
6541
iCursor = generateTrg1Src1ImmInstruction(cg, TR::InstOpCode::addi, node, firstDataElementReg, offsetReg, TR::Compiler->om.contiguousArrayHeaderSizeInBytes(), iCursor);
6522
6542
dataAddrSlotMR = TR::MemoryReference::createWithDisplacement(cg, offsetReg, fej9->getOffsetOfContiguousDataAddrField(), TR::Compiler->om.sizeofReferenceAddress());
6543
+
6544
+ // Clear firstDataElementReg reg if dealing with 0 size arrays
6545
+ iCursor = generateTrg1Src1ImmInstruction(cg,TR::InstOpCode::cmpi8, node, condReg, enumReg, 0, iCursor);
6546
+ iCursor = generateTrg1Src3Instruction(cg, TR::InstOpCode::iseleq, node, firstDataElementReg, NULL, firstDataElementReg, condReg, iCursor);
6523
6547
}
6524
6548
else if (!isVariableLen && node->getFirstChild()->getOpCode().isLoadConst() && node->getFirstChild()->getInt() == 0)
6525
6549
{
6526
6550
if (comp->getOption(TR_TraceCG))
6527
6551
traceMsg(comp, "Node (%p): Dealing with full/compressed refs fixed length zero size array.\n", node);
6528
6552
6529
- iCursor = generateTrg1Src1ImmInstruction(cg, TR::InstOpCode::addi, node, firstDataElementReg, resReg, TR::Compiler->om.discontiguousArrayHeaderSizeInBytes(), iCursor);
6530
6553
dataAddrSlotMR = TR::MemoryReference::createWithDisplacement(cg, resReg, fej9->getOffsetOfDiscontiguousDataAddrField(), TR::Compiler->om.sizeofReferenceAddress());
6554
+
6555
+ // NULL firstDataElementReg reg
6556
+ iCursor = generateTrg1Src2Instruction(cg, TR::InstOpCode::XOR, node, firstDataElementReg, firstDataElementReg, firstDataElementReg);
6531
6557
}
6532
6558
else
6533
6559
{
@@ -6547,8 +6573,16 @@ TR::Register *J9::Power::TreeEvaluator::VMnewEvaluator(TR::Node *node, TR::CodeG
6547
6573
fej9->getOffsetOfDiscontiguousDataAddrField(), fej9->getOffsetOfContiguousDataAddrField());
6548
6574
}
6549
6575
6576
+ // Load first element address into firstDataElementReg
6550
6577
iCursor = generateTrg1Src1ImmInstruction(cg, TR::InstOpCode::addi, node, firstDataElementReg, resReg, TR::Compiler->om.contiguousArrayHeaderSizeInBytes(), iCursor);
6551
6578
dataAddrSlotMR = TR::MemoryReference::createWithDisplacement(cg, resReg, fej9->getOffsetOfContiguousDataAddrField(), TR::Compiler->om.sizeofReferenceAddress());
6579
+
6580
+ // Clear firstDataElementReg reg if dealing with variable len 0 size arrays
6581
+ if (isVariableLen && !TR::Compiler->om.compressObjectReferences())
6582
+ {
6583
+ iCursor = generateTrg1Src1ImmInstruction(cg,TR::InstOpCode::cmpi8, node, condReg, enumReg, 0, iCursor);
6584
+ iCursor = generateTrg1Src3Instruction(cg, TR::InstOpCode::iseleq, node, firstDataElementReg, NULL, firstDataElementReg, condReg, iCursor);
6585
+ }
6552
6586
}
6553
6587
6554
6588
// store the first data element address to dataAddr slot
0 commit comments