Skip to content

Commit e878b36

Browse files
committed
[GR-71715] Added ConstantReflectionProvider.makeIdentityHashCode
PullRequest: labsjdk-ce/252
2 parents 4b464e2 + 10c2786 commit e878b36

File tree

15 files changed

+204
-49
lines changed

15 files changed

+204
-49
lines changed

.ci/common.libsonnet

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
# The JVMCI releases that can be built from this repo.
33
jvmci_releases:: [
4-
self.JVMCIRelease(name='25.1', build='b11', jdk_version='25.0.1+8')
4+
self.JVMCIRelease(name='25.1', build='b12', jdk_version='25.0.1+8')
55
],
66

77
# Specifies a JVMCI release.

src/hotspot/share/jvmci/jvmciCompilerToVM.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2161,6 +2161,12 @@ C2V_VMENTRY_0(jint, getIdentityHashCode, (JNIEnv* env, jobject, jobject object))
21612161
return obj->identity_hash();
21622162
C2V_END
21632163

2164+
C2V_VMENTRY_0(jint, makeIdentityHashCode, (JNIEnv* env, jobject, jobject object, jint value))
2165+
Handle obj = JVMCIENV->asConstant(JVMCIENV->wrap(object), JVMCI_CHECK_0);
2166+
intptr_t req_hash = value;
2167+
return ObjectSynchronizer::FastHashCode(THREAD, obj(), &req_hash);
2168+
C2V_END
2169+
21642170
C2V_VMENTRY_0(jboolean, isInternedString, (JNIEnv* env, jobject, jobject object))
21652171
Handle str = JVMCIENV->asConstant(JVMCIENV->wrap(object), JVMCI_CHECK_0);
21662172
if (!java_lang_String::is_instance(str())) {
@@ -3494,6 +3500,7 @@ JNINativeMethod CompilerToVM::methods[] = {
34943500
{CC "lookupNameInPool", CC "(" HS_CONSTANT_POOL2 "II)" STRING, FN_PTR(lookupNameInPool)},
34953501
{CC "lookupSignatureInPool", CC "(" HS_CONSTANT_POOL2 "II)" STRING, FN_PTR(lookupSignatureInPool)},
34963502
{CC "lookupType", CC "(" STRING HS_KLASS2 "IZ)" HS_RESOLVED_TYPE, FN_PTR(lookupType)},
3503+
{CC "makeIdentityHashCode", CC "(" OBJECTCONSTANT "I)I", FN_PTR(makeIdentityHashCode)},
34973504
{CC "materializeVirtualObjects", CC "(" HS_STACK_FRAME_REF "Z)V", FN_PTR(materializeVirtualObjects)},
34983505
{CC "methodDataExceptionSeen", CC "(JI)I", FN_PTR(methodDataExceptionSeen)},
34993506
{CC "methodDataProfileDataSize", CC "(JI)I", FN_PTR(methodDataProfileDataSize)},

src/hotspot/share/jvmci/vmStructs_jvmci.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -843,6 +843,7 @@
843843
\
844844
declare_constant(markWord::klass_shift) \
845845
declare_constant(markWord::hash_shift) \
846+
declare_constant(markWord::hash_bits) \
846847
declare_constant(markWord::monitor_value) \
847848
\
848849
declare_constant(markWord::lock_mask_in_place) \
@@ -853,6 +854,7 @@
853854
declare_constant(markWord::unlocked_value) \
854855
declare_constant(markWord::marked_value) \
855856
\
857+
declare_constant(markWord::no_hash) \
856858
declare_constant(markWord::no_hash_in_place) \
857859
declare_constant(markWord::no_lock_in_place) \
858860

src/hotspot/share/runtime/synchronizer.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -965,7 +965,7 @@ static intptr_t get_next_hash(Thread* current, oop obj) {
965965
return value;
966966
}
967967

968-
static intptr_t install_hash_code(Thread* current, oop obj) {
968+
static intptr_t install_hash_code(Thread* current, oop obj, intptr_t* requested_value = nullptr) {
969969
assert(UseObjectMonitorTable && LockingMode == LM_LIGHTWEIGHT, "must be");
970970

971971
markWord mark = obj->mark_acquire();
@@ -975,7 +975,7 @@ static intptr_t install_hash_code(Thread* current, oop obj) {
975975
return hash;
976976
}
977977

978-
hash = get_next_hash(current, obj);
978+
hash = requested_value != nullptr ? *requested_value : get_next_hash(current, obj);
979979
const markWord old_mark = mark;
980980
const markWord new_mark = old_mark.copy_set_hash(hash);
981981

@@ -986,11 +986,14 @@ static intptr_t install_hash_code(Thread* current, oop obj) {
986986
}
987987
}
988988

989-
intptr_t ObjectSynchronizer::FastHashCode(Thread* current, oop obj) {
989+
intptr_t ObjectSynchronizer::FastHashCode(Thread* current, oop obj, intptr_t* requested_value) {
990+
assert(requested_value == nullptr ||
991+
(*requested_value != markWord::no_hash && *requested_value >> markWord::hash_bits == 0),
992+
"invalid identity hash: %ld", *requested_value);
990993
if (UseObjectMonitorTable) {
991994
// Since the monitor isn't in the object header, the hash can simply be
992995
// installed in the object header.
993-
return install_hash_code(current, obj);
996+
return install_hash_code(current, obj, requested_value);
994997
}
995998

996999
while (true) {
@@ -1007,7 +1010,7 @@ intptr_t ObjectSynchronizer::FastHashCode(Thread* current, oop obj) {
10071010
if (hash != 0) { // if it has a hash, just return it
10081011
return hash;
10091012
}
1010-
hash = get_next_hash(current, obj); // get a new hash
1013+
hash = requested_value != nullptr ? *requested_value : get_next_hash(current, obj); // get a new hash
10111014
temp = mark.copy_set_hash(hash); // merge the hash into header
10121015
// try to install the hash
10131016
test = obj->cas_set_mark(temp, mark);
@@ -1082,7 +1085,7 @@ intptr_t ObjectSynchronizer::FastHashCode(Thread* current, oop obj) {
10821085
assert(mark.is_neutral(), "invariant: header=" INTPTR_FORMAT, mark.value());
10831086
hash = mark.hash();
10841087
if (hash == 0) { // if it does not have a hash
1085-
hash = get_next_hash(current, obj); // get a new hash
1088+
hash = requested_value != nullptr ? *requested_value : get_next_hash(current, obj); // get a new hash
10861089
temp = mark.copy_set_hash(hash) ; // merge the hash into header
10871090
assert(temp.is_neutral(), "invariant: header=" INTPTR_FORMAT, temp.value());
10881091
uintptr_t v = Atomic::cmpxchg(monitor->metadata_addr(), mark.value(), temp.value());

src/hotspot/share/runtime/synchronizer.hpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,9 +148,11 @@ class ObjectSynchronizer : AllStatic {
148148
inline static ObjectMonitor* read_monitor(markWord mark);
149149
inline static ObjectMonitor* read_monitor(Thread* current, oop obj, markWord mark);
150150

151-
// Returns the identity hash value for an oop
151+
// Returns the identity hash value for an oop.
152+
// If `requested_value` is non-null and the identity hash is uninitialized,
153+
// `*requested_value` is used to try initialize the identity hash.
152154
// NOTE: It may cause monitor inflation
153-
static intptr_t FastHashCode(Thread* current, oop obj);
155+
static intptr_t FastHashCode(Thread* current, oop obj, intptr_t* requested_value = nullptr);
154156

155157
// java.lang.Thread support
156158
static bool current_thread_holds_lock(JavaThread* current, Handle h_obj);

src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/CompilerToVM.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1140,6 +1140,11 @@ void ensureLinked(HotSpotResolvedObjectTypeImpl klass) {
11401140
*/
11411141
native int getIdentityHashCode(HotSpotObjectConstantImpl object);
11421142

1143+
/**
1144+
* @see HotSpotObjectConstant#makeIdentityHashCode
1145+
*/
1146+
native int makeIdentityHashCode(HotSpotObjectConstantImpl object, int requestedValue);
1147+
11431148
/**
11441149
* Converts a constant object representing a boxed primitive into a boxed primitive.
11451150
*/

src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/DirectHotSpotObjectConstantImpl.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@
2424

2525
import jdk.vm.ci.meta.JavaConstant;
2626

27+
import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime;
28+
import static jdk.vm.ci.services.Services.IS_IN_NATIVE_IMAGE;
29+
2730
final class DirectHotSpotObjectConstantImpl extends HotSpotObjectConstantImpl {
2831

2932
static JavaConstant forObject(Object object, boolean compressed) {
@@ -69,4 +72,13 @@ public JavaConstant uncompress() {
6972
public int getIdentityHashCode() {
7073
return System.identityHashCode(object);
7174
}
75+
76+
@Override
77+
public int makeIdentityHashCode(int requestedValue) {
78+
if (IS_IN_NATIVE_IMAGE) {
79+
// Cannot set identity hash code of an object in libgraal's heap
80+
return System.identityHashCode(object);
81+
}
82+
return runtime().compilerToVm.makeIdentityHashCode(this, requestedValue);
83+
}
7284
}

src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotConstantReflectionProvider.java

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -192,14 +192,39 @@ public Constant asObjectHub(ResolvedJavaType type) {
192192
}
193193

194194
@Override
195-
public Integer identityHashCode(JavaConstant constant) {
195+
public int identityHashCode(JavaConstant constant) {
196196
JavaKind kind = Objects.requireNonNull(constant).getJavaKind();
197197
if (kind != JavaKind.Object) {
198198
throw new IllegalArgumentException("Constant has unexpected kind " + kind + ": " + constant);
199199
} else if (constant.isNull()) {
200200
/* System.identityHashCode is specified to return 0 when passed null. */
201201
return 0;
202202
}
203-
return ((HotSpotObjectConstant) constant).getIdentityHashCode();
203+
if (constant instanceof HotSpotObjectConstant hConstant) {
204+
return hConstant.getIdentityHashCode();
205+
}
206+
throw new IllegalArgumentException("Constant has unexpected type " + constant.getClass() + ": " + constant);
207+
}
208+
209+
@Override
210+
public int makeIdentityHashCode(JavaConstant constant, int requestedValue) {
211+
if (constant == null || constant.isNull()) {
212+
throw new NullPointerException();
213+
}
214+
215+
int hashBits = HotSpotVMConfig.config().markWordHashBits;
216+
int noHash = HotSpotVMConfig.config().markWordNoHash;
217+
int requestedValueBits = 32 - Integer.numberOfLeadingZeros(requestedValue);
218+
if (requestedValueBits == noHash || requestedValueBits > hashBits) {
219+
throw new IllegalArgumentException("Requested identity hash code is + " + noHash + " or not an unsigned " + hashBits + " bit value: " + requestedValue);
220+
}
221+
JavaKind kind = constant.getJavaKind();
222+
if (kind != JavaKind.Object) {
223+
throw new IllegalArgumentException("Constant has unexpected kind " + kind + ": " + constant);
224+
}
225+
if (!(constant instanceof HotSpotObjectConstant hConstant)) {
226+
throw new IllegalArgumentException("Constant has unexpected type " + constant.getClass() + ": " + constant);
227+
}
228+
return hConstant.makeIdentityHashCode(requestedValue);
204229
}
205230
}

src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotObjectConstant.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,16 @@ public interface HotSpotObjectConstant extends JavaConstant, HotSpotConstant, VM
4949
HotSpotResolvedObjectType getType();
5050

5151
/**
52-
* Gets the {@linkplain System#identityHashCode(Object) identity} has code for the object
53-
* represented by this constant.
52+
* Gets the identity hash code for the object represented by this constant.
5453
*/
5554
int getIdentityHashCode();
5655

56+
/**
57+
* Gets the identity hash code of the object represented by this constant, trying
58+
* to initialize it to {@code requestedValue} if it is not yet initialized.
59+
*/
60+
int makeIdentityHashCode(int requestedValue);
61+
5762
/**
5863
* Gets the result of {@link CallSite#getTarget()} for the {@link CallSite} object represented
5964
* by this constant.

src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedObjectType.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,6 @@ default JavaConstant getJavaMirror() {
105105

106106
int superCheckOffset();
107107

108-
long prototypeMarkWord();
109-
110108
int layoutHelper();
111109

112110
@Override

0 commit comments

Comments
 (0)