@@ -2825,10 +2825,34 @@ hashCodeHelper(TR::Node* node, TR::CodeGenerator* cg, TR::DataType elementType,
2825
2825
TR::LabelSymbol * cFlowRegionEnd = generateLabelSymbol(cg);
2826
2826
2827
2827
// Create the necessary registers
2828
- TR::Register* registerValue = cg->evaluate(nodeValue) ;
2828
+ TR::Register* registerValue = NULL ;
2829
2829
TR::Register* registerIndex = cg->gprClobberEvaluate(nodeIndex);
2830
2830
TR::Register* registerCount = cg->gprClobberEvaluate(nodeCount);
2831
2831
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
+
2832
2856
if (cg->comp()->target().is64Bit())
2833
2857
{
2834
2858
generateRRInstruction(cg, TR::InstOpCode::getLoadRegWidenOpCode(), node, registerIndex, registerIndex);
@@ -2911,20 +2935,20 @@ hashCodeHelper(TR::Node* node, TR::CodeGenerator* cg, TR::DataType elementType,
2911
2935
{
2912
2936
case TR::Int8:
2913
2937
// 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);
2915
2939
// registerVC = unpack 4 (8 bit) byte elements into 4 (32 bit) int elements
2916
2940
generateVRRaInstruction(cg, isSigned ? TR::InstOpCode::VUPH : TR::InstOpCode::VUPLH, node, registerVC, registerVC, 0, 0, 0);
2917
2941
generateVRRaInstruction(cg, isSigned ? TR::InstOpCode::VUPL : TR::InstOpCode::VUPLL, node, registerVC, registerVC, 0, 0, 1);
2918
2942
break;
2919
2943
case TR::Int16:
2920
2944
// 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);
2922
2946
// registerVC = unpack 4 (16 bit) short elements into 4 (32 bit) int elements
2923
2947
generateVRRaInstruction(cg, isSigned ? TR::InstOpCode::VUPH : TR::InstOpCode::VUPLH, node, registerVC, registerVC, 0, 0, 1);
2924
2948
break;
2925
2949
case TR::Int32:
2926
2950
// 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));
2928
2952
break;
2929
2953
default:
2930
2954
TR_ASSERT_FATAL(false, "Unsupported vectorizedHashCode element type");
@@ -2990,15 +3014,15 @@ hashCodeHelper(TR::Node* node, TR::CodeGenerator* cg, TR::DataType elementType,
2990
3014
{
2991
3015
case TR::Int8:
2992
3016
// 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));
2994
3018
break;
2995
3019
case TR::Int16:
2996
3020
// 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));
2998
3022
break;
2999
3023
case TR::Int32:
3000
3024
// 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));
3002
3026
break;
3003
3027
default:
3004
3028
TR_ASSERT_FATAL(false, "Unsupported vectorizedHashCode element type");
0 commit comments