diff --git a/debugtools/DDR_VM/src/com/ibm/j9ddr/vm29/j9/ObjectHash.java b/debugtools/DDR_VM/src/com/ibm/j9ddr/vm29/j9/ObjectHash.java index 01a81e0a9a3..7166a178132 100644 --- a/debugtools/DDR_VM/src/com/ibm/j9ddr/vm29/j9/ObjectHash.java +++ b/debugtools/DDR_VM/src/com/ibm/j9ddr/vm29/j9/ObjectHash.java @@ -23,9 +23,11 @@ import com.ibm.j9ddr.CorruptDataException; import com.ibm.j9ddr.vm29.pointer.generated.J9BuildFlags; +import com.ibm.j9ddr.vm29.structure.J9Consts; import com.ibm.j9ddr.vm29.pointer.generated.J9IdentityHashDataPointer; import com.ibm.j9ddr.vm29.pointer.generated.J9JavaVMPointer; import com.ibm.j9ddr.vm29.pointer.generated.J9ObjectPointer; +import com.ibm.j9ddr.vm29.pointer.helper.J9JavaVMHelper; import com.ibm.j9ddr.vm29.structure.J9IdentityHashData; import com.ibm.j9ddr.vm29.types.I32; import com.ibm.j9ddr.vm29.types.U32; @@ -134,6 +136,10 @@ private static I32 inlineConvertValueToHash(J9JavaVMPointer vm, UDATA objectPoin hashValue = hashValue.mult(MUL2); hashValue = hashValue.bitXor(hashValue.rightShift(16)); + /* If forcing positive hash codes, AND out the sign bit */ + if (J9JavaVMHelper.extendedRuntimeFlagIsSet(vm, J9Consts.J9_EXTENDED_RUNTIME_POSITIVE_HASHCODE)) { + hashValue = hashValue.bitAnd(0x7FFFFFFF); + } return new I32(hashValue); } diff --git a/runtime/oti/ObjectHash.hpp b/runtime/oti/ObjectHash.hpp index f109e691113..2c2a2b04db2 100644 --- a/runtime/oti/ObjectHash.hpp +++ b/runtime/oti/ObjectHash.hpp @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 1991, 2017 IBM Corp. and others + * Copyright (c) 1991, 2018 IBM Corp. and others * * This program and the accompanying materials are made available under * the terms of the Eclipse Public License 2.0 which accompanies this @@ -174,6 +174,11 @@ class VM_ObjectHash hashValue *= MUL2; hashValue ^= hashValue >> 16; + /* If forcing positive hash codes, AND out the sign bit */ + if (J9_ARE_ANY_BITS_SET(vm->extendedRuntimeFlags, J9_EXTENDED_RUNTIME_POSITIVE_HASHCODE)) { + hashValue &= (U_32)0x7FFFFFFF; + } + return (I_32) hashValue; } diff --git a/runtime/oti/j9consts.h b/runtime/oti/j9consts.h index 9b70b64f877..d72d1d8b1a7 100644 --- a/runtime/oti/j9consts.h +++ b/runtime/oti/j9consts.h @@ -360,7 +360,7 @@ extern "C" { #define J9_EXTENDED_RUNTIME_METHOD_TRACE_ENABLED 0x100000 #define J9_EXTENDED_RUNTIME_FOUND_JAVA_ASSERT_OPTION 0x200000 #define J9_EXTENDED_RUNTIME_ALLOW_NON_VIRTUAL_CALLS 0x400000 -#define J9_EXTENDED_RUNTIME_UNUSED_0x800000 0x800000 +#define J9_EXTENDED_RUNTIME_POSITIVE_HASHCODE 0x800000 #define J9_EXTENDED_RUNTIME_CLASS_OBJECT_ASSIGNED 0x1000000 #define J9_EXTENDED_RUNTIME_FORCE_CLASSFILE_AS_INTERMEDIATE_DATA 0x2000000 #define J9_EXTENDED_RUNTIME_RECREATE_CLASSFILE_ONLOAD 0x4000000 diff --git a/runtime/oti/jvminit.h b/runtime/oti/jvminit.h index c9b68c5e1cd..c7a2b1441ca 100644 --- a/runtime/oti/jvminit.h +++ b/runtime/oti/jvminit.h @@ -366,6 +366,8 @@ enum INIT_STAGE { #define VMOPT_XXDISABLEJITWATCH "-XX:-JITInlineWatches" #define VMOPT_XXENABLEALWAYSSPLITBYTECODES "-XX:+AlwaysSplitBytecodes" #define VMOPT_XXDISABLEALWAYSSPLITBYTECODES "-XX:-AlwaysSplitBytecodes" +#define VMOPT_XXENABLEPOSITIVEHASHCODE "-XX:+PositiveIdentityHash" +#define VMOPT_XXDISABLEPOSITIVEHASHCODE "-XX:-PositiveIdentityHash" #define VMOPT_XX_NOSUBALLOC32BITMEM "-XXnosuballoc32bitmem" diff --git a/runtime/vm/jvminit.c b/runtime/vm/jvminit.c index b28423f4d22..773b2a9cebf 100644 --- a/runtime/vm/jvminit.c +++ b/runtime/vm/jvminit.c @@ -2956,6 +2956,10 @@ processVMArgsFromFirstToLast(J9JavaVM * vm) vm->runtimeFlags |= J9_RUNTIME_ALWAYS_SPLIT_BYTECODES; } else if (0 == strcmp(testString, VMOPT_XXDISABLEALWAYSSPLITBYTECODES)) { vm->runtimeFlags &= ~(UDATA)J9_RUNTIME_ALWAYS_SPLIT_BYTECODES; + } else if (0 == strcmp(testString, VMOPT_XXENABLEPOSITIVEHASHCODE)) { + vm->extendedRuntimeFlags |= J9_EXTENDED_RUNTIME_POSITIVE_HASHCODE; + } else if (0 == strcmp(testString, VMOPT_XXDISABLEPOSITIVEHASHCODE)) { + vm->extendedRuntimeFlags &= ~(UDATA)J9_EXTENDED_RUNTIME_POSITIVE_HASHCODE; } /* -Xbootclasspath and -Xbootclasspath/p are not supported from Java 9 onwards */ if (J2SE_VERSION(vm) >= J2SE_19) {