@@ -2908,10 +2908,34 @@ hashCodeHelper(TR::Node* node, TR::CodeGenerator* cg, TR::DataType elementType,
2908
2908
TR::LabelSymbol * cFlowRegionEnd = generateLabelSymbol(cg);
2909
2909
2910
2910
// Create the necessary registers
2911
- TR::Register* registerValue = cg->evaluate(nodeValue) ;
2911
+ TR::Register* registerValue = NULL ;
2912
2912
TR::Register* registerIndex = cg->gprClobberEvaluate(nodeIndex);
2913
2913
TR::Register* registerCount = cg->gprClobberEvaluate(nodeCount);
2914
2914
2915
+ // Offset to be added to array object pointer to get to the data elements
2916
+ int32_t offsetToDataElements = static_cast<int32_t>(TR::Compiler->om.contiguousArrayHeaderSizeInBytes());
2917
+ #ifdef J9VM_GC_SPARSE_HEAP_ALLOCATION
2918
+ if (TR::Compiler->om.isOffHeapAllocationEnabled())
2919
+ {
2920
+ // Clobber evaluate value node as we'll overwrite it with first data element address
2921
+ registerValue = cg->gprClobberEvaluate(nodeValue);
2922
+
2923
+ // Load first data element address
2924
+ generateRXInstruction(cg,
2925
+ TR::InstOpCode::getLoadOpCode(),
2926
+ nodeValue,
2927
+ registerValue,
2928
+ generateS390MemoryReference(registerValue, cg->comp()->fej9()->getOffsetOfContiguousDataAddrField(), cg));
2929
+
2930
+ // Since the first data element address is retrieved from the array header, the offset is set to 0
2931
+ offsetToDataElements = 0;
2932
+ }
2933
+ else
2934
+ #endif /* J9VM_GC_SPARSE_HEAP_ALLOCATION */
2935
+ {
2936
+ registerValue = cg->evaluate(nodeValue);
2937
+ }
2938
+
2915
2939
if (cg->comp()->target().is64Bit())
2916
2940
{
2917
2941
generateRRInstruction(cg, TR::InstOpCode::getLoadRegWidenOpCode(), node, registerIndex, registerIndex);
@@ -2994,20 +3018,20 @@ hashCodeHelper(TR::Node* node, TR::CodeGenerator* cg, TR::DataType elementType,
2994
3018
{
2995
3019
case TR::Int8:
2996
3020
// registerVC = 4 consecutive (8 bit) bytes at the current index
2997
- generateVRXInstruction(cg, TR::InstOpCode::VLLEZ, node, registerVC, generateS390MemoryReference(registerValue, registerIndex, TR::Compiler->om.contiguousArrayHeaderSizeInBytes() , cg), 2);
3021
+ generateVRXInstruction(cg, TR::InstOpCode::VLLEZ, node, registerVC, generateS390MemoryReference(registerValue, registerIndex, offsetToDataElements , cg), 2);
2998
3022
// registerVC = unpack 4 (8 bit) byte elements into 4 (32 bit) int elements
2999
3023
generateVRRaInstruction(cg, isSigned ? TR::InstOpCode::VUPH : TR::InstOpCode::VUPLH, node, registerVC, registerVC, 0, 0, 0);
3000
3024
generateVRRaInstruction(cg, isSigned ? TR::InstOpCode::VUPL : TR::InstOpCode::VUPLL, node, registerVC, registerVC, 0, 0, 1);
3001
3025
break;
3002
3026
case TR::Int16:
3003
3027
// registerVC = 4 consecutive (16 bit) shorts at the current index
3004
- generateVRXInstruction(cg, TR::InstOpCode::VLLEZ, node, registerVC, generateS390MemoryReference(registerValue, registerIndex, TR::Compiler->om.contiguousArrayHeaderSizeInBytes() , cg), 3);
3028
+ generateVRXInstruction(cg, TR::InstOpCode::VLLEZ, node, registerVC, generateS390MemoryReference(registerValue, registerIndex, offsetToDataElements , cg), 3);
3005
3029
// registerVC = unpack 4 (16 bit) short elements into 4 (32 bit) int elements
3006
3030
generateVRRaInstruction(cg, isSigned ? TR::InstOpCode::VUPH : TR::InstOpCode::VUPLH, node, registerVC, registerVC, 0, 0, 1);
3007
3031
break;
3008
3032
case TR::Int32:
3009
3033
// registerVC = 4 consecutive (32 bit) ints at the current index
3010
- generateVRXInstruction(cg, TR::InstOpCode::VL, node, registerVC, generateS390MemoryReference(registerValue, registerIndex, TR::Compiler->om.contiguousArrayHeaderSizeInBytes() , cg));
3034
+ generateVRXInstruction(cg, TR::InstOpCode::VL, node, registerVC, generateS390MemoryReference(registerValue, registerIndex, offsetToDataElements , cg));
3011
3035
break;
3012
3036
default:
3013
3037
TR_ASSERT_FATAL(false, "Unsupported vectorizedHashCode element type");
@@ -3073,15 +3097,15 @@ hashCodeHelper(TR::Node* node, TR::CodeGenerator* cg, TR::DataType elementType,
3073
3097
{
3074
3098
case TR::Int8:
3075
3099
// registerHash = byte at registerIndex
3076
- generateRXInstruction(cg, isSigned ? TR::InstOpCode::LB : TR::InstOpCode::LLC, node, registerHash, generateS390MemoryReference(registerValue, registerIndex, TR::Compiler->om.contiguousArrayHeaderSizeInBytes() , cg));
3100
+ generateRXInstruction(cg, isSigned ? TR::InstOpCode::LB : TR::InstOpCode::LLC, node, registerHash, generateS390MemoryReference(registerValue, registerIndex, offsetToDataElements , cg));
3077
3101
break;
3078
3102
case TR::Int16:
3079
3103
// registerHash = short at registerIndex
3080
- generateRXInstruction(cg, isSigned ? TR::InstOpCode::LH : TR::InstOpCode::LLH, node, registerHash, generateS390MemoryReference(registerValue, registerIndex, TR::Compiler->om.contiguousArrayHeaderSizeInBytes() , cg));
3104
+ generateRXInstruction(cg, isSigned ? TR::InstOpCode::LH : TR::InstOpCode::LLH, node, registerHash, generateS390MemoryReference(registerValue, registerIndex, offsetToDataElements , cg));
3081
3105
break;
3082
3106
case TR::Int32:
3083
3107
// registerHash = int at registerIndex
3084
- generateRXInstruction(cg, TR::InstOpCode::L, node, registerHash, generateS390MemoryReference(registerValue, registerIndex, TR::Compiler->om.contiguousArrayHeaderSizeInBytes() , cg));
3108
+ generateRXInstruction(cg, TR::InstOpCode::L, node, registerHash, generateS390MemoryReference(registerValue, registerIndex, offsetToDataElements , cg));
3085
3109
break;
3086
3110
default:
3087
3111
TR_ASSERT_FATAL(false, "Unsupported vectorizedHashCode element type");
0 commit comments