Skip to content

Commit 8aa01fd

Browse files
committed
Update hashCodeHelper for off-heap
The acceleration was initially disabled because it added array header size to the array object, which was required to reach the elements. However, this is unnecessary for off-heap mode. As a result, the evaluator has been updated to add the array header size exclusively for non-off-heap mode, while in off-heap mode, it now retrieves the data element address directly from the array header, enabling acceleration in off-heap mode. Signed-off-by: Shubham Verma <[email protected]>
1 parent 7df76af commit 8aa01fd

File tree

2 files changed

+32
-9
lines changed

2 files changed

+32
-9
lines changed

runtime/compiler/z/codegen/J9CodeGenerator.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,7 @@ J9::Z::CodeGenerator::initialize()
9393
cg->setSupportsInlineStringIndexOf();
9494
}
9595

96-
if (cg->getSupportsVectorRegisters() && !comp->getOption(TR_DisableSIMDStringHashCode) &&
97-
!TR::Compiler->om.canGenerateArraylets() && !TR::Compiler->om.isOffHeapAllocationEnabled())
96+
if (cg->getSupportsVectorRegisters() && !comp->getOption(TR_DisableSIMDStringHashCode) && !TR::Compiler->om.canGenerateArraylets())
9897
{
9998
cg->setSupportsInlineStringHashCode();
10099
cg->setSupportsInlineVectorizedHashCode();

runtime/compiler/z/codegen/J9TreeEvaluator.cpp

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2825,10 +2825,34 @@ hashCodeHelper(TR::Node* node, TR::CodeGenerator* cg, TR::DataType elementType,
28252825
TR::LabelSymbol * cFlowRegionEnd = generateLabelSymbol(cg);
28262826

28272827
// Create the necessary registers
2828-
TR::Register* registerValue = cg->evaluate(nodeValue);
2828+
TR::Register* registerValue = NULL;
28292829
TR::Register* registerIndex = cg->gprClobberEvaluate(nodeIndex);
28302830
TR::Register* registerCount = cg->gprClobberEvaluate(nodeCount);
28312831

2832+
// Offset to be added to array object pointer to get to the data elements
2833+
int32_t offsetToDataElements = static_cast<int32_t>(TR::Compiler->om.contiguousArrayHeaderSizeInBytes());
2834+
#ifdef J9VM_GC_SPARSE_HEAP_ALLOCATION
2835+
if (TR::Compiler->om.isOffHeapAllocationEnabled())
2836+
{
2837+
// Clobber evaluate value node as we'll overwrite it with first data element address
2838+
registerValue = cg->gprClobberEvaluate(nodeValue);
2839+
2840+
// Load first data element address
2841+
generateRXInstruction(cg,
2842+
TR::InstOpCode::getLoadOpCode(),
2843+
nodeValue,
2844+
registerValue,
2845+
generateS390MemoryReference(registerValue, cg->comp()->fej9()->getOffsetOfContiguousDataAddrField(), cg));
2846+
2847+
// Since the first data element address is retrieved from the array header, the offset is set to 0
2848+
offsetToDataElements = 0;
2849+
}
2850+
else
2851+
#endif /* J9VM_GC_SPARSE_HEAP_ALLOCATION */
2852+
{
2853+
registerValue = cg->evaluate(nodeValue);
2854+
}
2855+
28322856
if (cg->comp()->target().is64Bit())
28332857
{
28342858
generateRRInstruction(cg, TR::InstOpCode::getLoadRegWidenOpCode(), node, registerIndex, registerIndex);
@@ -2911,20 +2935,20 @@ hashCodeHelper(TR::Node* node, TR::CodeGenerator* cg, TR::DataType elementType,
29112935
{
29122936
case TR::Int8:
29132937
// registerVC = 4 consecutive (8 bit) bytes at the current index
2914-
generateVRXInstruction(cg, TR::InstOpCode::VLLEZ, node, registerVC, generateS390MemoryReference(registerValue, registerIndex, TR::Compiler->om.contiguousArrayHeaderSizeInBytes(), cg), 2);
2938+
generateVRXInstruction(cg, TR::InstOpCode::VLLEZ, node, registerVC, generateS390MemoryReference(registerValue, registerIndex, offsetToDataElements, cg), 2);
29152939
// registerVC = unpack 4 (8 bit) byte elements into 4 (32 bit) int elements
29162940
generateVRRaInstruction(cg, isSigned ? TR::InstOpCode::VUPH : TR::InstOpCode::VUPLH, node, registerVC, registerVC, 0, 0, 0);
29172941
generateVRRaInstruction(cg, isSigned ? TR::InstOpCode::VUPL : TR::InstOpCode::VUPLL, node, registerVC, registerVC, 0, 0, 1);
29182942
break;
29192943
case TR::Int16:
29202944
// registerVC = 4 consecutive (16 bit) shorts at the current index
2921-
generateVRXInstruction(cg, TR::InstOpCode::VLLEZ, node, registerVC, generateS390MemoryReference(registerValue, registerIndex, TR::Compiler->om.contiguousArrayHeaderSizeInBytes(), cg), 3);
2945+
generateVRXInstruction(cg, TR::InstOpCode::VLLEZ, node, registerVC, generateS390MemoryReference(registerValue, registerIndex, offsetToDataElements, cg), 3);
29222946
// registerVC = unpack 4 (16 bit) short elements into 4 (32 bit) int elements
29232947
generateVRRaInstruction(cg, isSigned ? TR::InstOpCode::VUPH : TR::InstOpCode::VUPLH, node, registerVC, registerVC, 0, 0, 1);
29242948
break;
29252949
case TR::Int32:
29262950
// registerVC = 4 consecutive (32 bit) ints at the current index
2927-
generateVRXInstruction(cg, TR::InstOpCode::VL, node, registerVC, generateS390MemoryReference(registerValue, registerIndex, TR::Compiler->om.contiguousArrayHeaderSizeInBytes(), cg));
2951+
generateVRXInstruction(cg, TR::InstOpCode::VL, node, registerVC, generateS390MemoryReference(registerValue, registerIndex, offsetToDataElements, cg));
29282952
break;
29292953
default:
29302954
TR_ASSERT_FATAL(false, "Unsupported vectorizedHashCode element type");
@@ -2990,15 +3014,15 @@ hashCodeHelper(TR::Node* node, TR::CodeGenerator* cg, TR::DataType elementType,
29903014
{
29913015
case TR::Int8:
29923016
// registerHash = byte at registerIndex
2993-
generateRXInstruction(cg, isSigned ? TR::InstOpCode::LB : TR::InstOpCode::LLC, node, registerHash, generateS390MemoryReference(registerValue, registerIndex, TR::Compiler->om.contiguousArrayHeaderSizeInBytes(), cg));
3017+
generateRXInstruction(cg, isSigned ? TR::InstOpCode::LB : TR::InstOpCode::LLC, node, registerHash, generateS390MemoryReference(registerValue, registerIndex, offsetToDataElements, cg));
29943018
break;
29953019
case TR::Int16:
29963020
// registerHash = short at registerIndex
2997-
generateRXInstruction(cg, isSigned ? TR::InstOpCode::LH : TR::InstOpCode::LLH, node, registerHash, generateS390MemoryReference(registerValue, registerIndex, TR::Compiler->om.contiguousArrayHeaderSizeInBytes(), cg));
3021+
generateRXInstruction(cg, isSigned ? TR::InstOpCode::LH : TR::InstOpCode::LLH, node, registerHash, generateS390MemoryReference(registerValue, registerIndex, offsetToDataElements, cg));
29983022
break;
29993023
case TR::Int32:
30003024
// registerHash = int at registerIndex
3001-
generateRXInstruction(cg, TR::InstOpCode::L, node, registerHash, generateS390MemoryReference(registerValue, registerIndex, TR::Compiler->om.contiguousArrayHeaderSizeInBytes(), cg));
3025+
generateRXInstruction(cg, TR::InstOpCode::L, node, registerHash, generateS390MemoryReference(registerValue, registerIndex, offsetToDataElements, cg));
30023026
break;
30033027
default:
30043028
TR_ASSERT_FATAL(false, "Unsupported vectorizedHashCode element type");

0 commit comments

Comments
 (0)