Skip to content

Commit e20e6c8

Browse files
committed
8353849: [Lilliput] Avoid race in compact identity hashcode
Reviewed-by: zgu, wkemper
1 parent d8fd3df commit e20e6c8

14 files changed

+27
-23
lines changed

src/hotspot/share/cds/heapShared.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -589,7 +589,7 @@ static void copy_java_mirror_hashcode(oop orig_mirror, oop scratch_m) {
589589
scratch_m->initialize_hash_if_necessary(orig_mirror, orig_klass, mark);
590590
} else {
591591
assert(mark.is_hashed_expanded(), "must be hashed & moved");
592-
int offset = orig_klass->hash_offset_in_bytes(orig_mirror);
592+
int offset = orig_klass->hash_offset_in_bytes(orig_mirror, mark);
593593
assert(offset >= 8, "hash offset must not be in header");
594594
scratch_m->int_field_put(offset, (jint) src_hash);
595595
scratch_m->set_mark(mark);

src/hotspot/share/ci/ciInstanceKlass.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,7 @@ class ciInstanceKlass : public ciKlass {
297297
GrowableArray<ciInstanceKlass*>* transitive_interfaces() const;
298298

299299
int hash_offset_in_bytes() const {
300-
return get_instanceKlass()->hash_offset_in_bytes(nullptr);
300+
return get_instanceKlass()->hash_offset_in_bytes(nullptr, markWord(0));
301301
}
302302

303303
// Replay support

src/hotspot/share/gc/shenandoah/shenandoahForwarding.inline.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ inline size_t ShenandoahForwarding::size(oop obj) {
123123
size_t size = fwd->base_size_given_klass(fwd_mark, klass);
124124
if (UseCompactObjectHeaders) {
125125
if ((mark.value() & FWDED_HASH_TRANSITION) != FWDED_HASH_TRANSITION) {
126-
if (fwd_mark.is_expanded() && klass->expand_for_hash(fwd)) {
126+
if (fwd_mark.is_expanded() && klass->expand_for_hash(fwd, fwd_mark)) {
127127
size = align_object_size(size + 1);
128128
}
129129
}

src/hotspot/share/oops/arrayKlass.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -301,9 +301,10 @@ void ArrayKlass::oop_verify_on(oop obj, outputStream* st) {
301301
guarantee(a->length() >= 0, "array with negative length?");
302302
}
303303

304-
int ArrayKlass::hash_offset_in_bytes(oop obj) const {
304+
int ArrayKlass::hash_offset_in_bytes(oop obj, markWord m) const {
305305
assert(UseCompactObjectHeaders, "only with compact i-hash");
306306
arrayOop ary = arrayOop(obj);
307307
BasicType type = element_type();
308-
return ary->base_offset_in_bytes(type) + (ary->length() << log2_element_size());
308+
int length = LP64_ONLY(m.array_length()) NOT_LP64(ary->length());
309+
return ary->base_offset_in_bytes(type) + (length << log2_element_size());
309310
}

src/hotspot/share/oops/arrayKlass.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ class ArrayKlass: public Klass {
118118
// Return a handle.
119119
static void complete_create_array_klass(ArrayKlass* k, Klass* super_klass, ModuleEntry* module, TRAPS);
120120

121-
int hash_offset_in_bytes(oop obj) const;
121+
int hash_offset_in_bytes(oop obj, markWord m) const;
122122

123123
// JVMTI support
124124
jint jvmti_class_status() const;

src/hotspot/share/oops/instanceKlass.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -949,7 +949,7 @@ class InstanceKlass: public Klass {
949949
return layout_helper_to_size_helper(layout_helper());
950950
}
951951

952-
virtual int hash_offset_in_bytes(oop obj) const {
952+
virtual int hash_offset_in_bytes(oop obj, markWord m) const {
953953
assert(UseCompactObjectHeaders, "only with compact i-hash");
954954
return _hash_offset;
955955
}

src/hotspot/share/oops/instanceMirrorKlass.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,14 +80,14 @@ int InstanceMirrorKlass::compute_static_oop_field_count(oop obj) {
8080
return 0;
8181
}
8282

83-
int InstanceMirrorKlass::hash_offset_in_bytes(oop obj) const {
83+
int InstanceMirrorKlass::hash_offset_in_bytes(oop obj, markWord m) const {
8484
assert(UseCompactObjectHeaders, "only with compact i-hash");
8585
// TODO: There may be gaps that we could use, e.g. in the fields of Class,
8686
// between the fields of Class and the static fields or in or at the end of
8787
// the static fields block.
8888
// When implementing any change here, make sure that allocate_instance()
8989
// and corresponding code in InstanceMirrorKlass.java are in sync.
90-
return checked_cast<int>(obj->base_size_given_klass(obj->mark(), this) * BytesPerWord);
90+
return checked_cast<int>(obj->base_size_given_klass(m, this) * BytesPerWord);
9191
}
9292

9393
#if INCLUDE_CDS

src/hotspot/share/oops/instanceMirrorKlass.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ class InstanceMirrorKlass: public InstanceKlass {
6666

6767
// Returns the size of the instance including the extra static fields.
6868
size_t oop_size(oop obj, markWord mark) const;
69-
int hash_offset_in_bytes(oop obj) const;
69+
int hash_offset_in_bytes(oop obj, markWord m) const;
7070

7171
// Static field offset is an offset into the Heap, should be converted by
7272
// based on UseCompressedOop for traversal

src/hotspot/share/oops/klass.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1336,8 +1336,11 @@ static int expanded = 0;
13361336
static int not_expanded = 0;
13371337
static NumberSeq seq = NumberSeq();
13381338

1339-
bool Klass::expand_for_hash(oop obj) const {
1339+
bool Klass::expand_for_hash(oop obj, markWord m) const {
13401340
assert(UseCompactObjectHeaders, "only with compact i-hash");
1341-
assert((size_t)hash_offset_in_bytes(obj) <= (obj->base_size_given_klass(obj->mark(), this) * HeapWordSize), "hash offset must be eq or lt base size: hash offset: %d, base size: %zu", hash_offset_in_bytes(obj), obj->base_size_given_klass(obj->mark(), this) * HeapWordSize);
1342-
return obj->base_size_given_klass(obj->mark(), this) * HeapWordSize - hash_offset_in_bytes(obj) < (int)sizeof(uint32_t);
1341+
{
1342+
ResourceMark rm;
1343+
assert((size_t)hash_offset_in_bytes(obj,m ) <= (obj->base_size_given_klass(m, this) * HeapWordSize), "hash offset must be eq or lt base size: hash offset: %d, base size: %zu, class-name: %s", hash_offset_in_bytes(obj, m), obj->base_size_given_klass(m, this) * HeapWordSize, external_name());
1344+
}
1345+
return obj->base_size_given_klass(m, this) * HeapWordSize - hash_offset_in_bytes(obj, m) < (int)sizeof(uint32_t);
13431346
}

src/hotspot/share/oops/klass.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -791,10 +791,10 @@ class Klass : public Metadata {
791791
// Returns true if this Klass needs to be addressable via narrow Klass ID.
792792
inline bool needs_narrow_id() const;
793793

794-
virtual int hash_offset_in_bytes(oop obj) const = 0;
794+
virtual int hash_offset_in_bytes(oop obj, markWord m) const = 0;
795795
static int kind_offset_in_bytes() { return (int)offset_of(Klass, _kind); }
796796

797-
bool expand_for_hash(oop obj) const;
797+
bool expand_for_hash(oop obj, markWord m) const;
798798
};
799799

800800
#endif // SHARE_OOPS_KLASS_HPP

src/hotspot/share/oops/oop.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ void oopDesc::initialize_hash_if_necessary(oop obj, Klass* k, markWord m) {
135135
assert(m.is_hashed_not_expanded(), "must be hashed but not moved");
136136
assert(!m.is_hashed_expanded(), "must not be moved: " INTPTR_FORMAT, m.value());
137137
uint32_t hash = static_cast<uint32_t>(ObjectSynchronizer::get_next_hash(nullptr, obj));
138-
int offset = k->hash_offset_in_bytes(cast_to_oop(this));
138+
int offset = k->hash_offset_in_bytes(cast_to_oop(this), m);
139139
assert(offset >= 4, "hash offset must not be in header");
140140
#ifndef PRODUCT
141141
log_trace(ihash)("Initializing hash for " PTR_FORMAT ", old: " PTR_FORMAT ", hash: %d, offset: %d", p2i(this), p2i(obj), hash, offset);

src/hotspot/share/oops/oop.inline.hpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ size_t oopDesc::size_given_mark_and_klass(markWord mrk, const Klass* kls) {
202202
size_t sz = base_size_given_klass(mrk, kls);
203203
if (UseCompactObjectHeaders) {
204204
assert(!mrk.has_displaced_mark_helper(), "must not be displaced");
205-
if (mrk.is_expanded() && kls->expand_for_hash(cast_to_oop(this))) {
205+
if (mrk.is_expanded() && kls->expand_for_hash(cast_to_oop(this), mrk)) {
206206
sz = align_object_size(sz + 1);
207207
}
208208
}
@@ -213,7 +213,7 @@ size_t oopDesc::copy_size(size_t size, markWord mark) const {
213213
if (UseCompactObjectHeaders) {
214214
assert(!mark.has_displaced_mark_helper(), "must not be displaced");
215215
Klass* klass = mark.klass();
216-
if (mark.is_hashed_not_expanded() && klass->expand_for_hash(cast_to_oop(this))) {
216+
if (mark.is_hashed_not_expanded() && klass->expand_for_hash(cast_to_oop(this), mark)) {
217217
size = align_object_size(size + 1);
218218
}
219219
}
@@ -225,10 +225,10 @@ size_t oopDesc::copy_size_cds(size_t size, markWord mark) const {
225225
if (UseCompactObjectHeaders) {
226226
assert(!mark.has_displaced_mark_helper(), "must not be displaced");
227227
Klass* klass = mark.klass();
228-
if (mark.is_hashed_not_expanded() && klass->expand_for_hash(cast_to_oop(this))) {
228+
if (mark.is_hashed_not_expanded() && klass->expand_for_hash(cast_to_oop(this), mark)) {
229229
size = align_object_size(size + 1);
230230
}
231-
if (mark.is_not_hashed_expanded() && klass->expand_for_hash(cast_to_oop(this))) {
231+
if (mark.is_not_hashed_expanded() && klass->expand_for_hash(cast_to_oop(this), mark)) {
232232
size = align_object_size(size - ObjectAlignmentInBytes / HeapWordSize);
233233
}
234234
}
@@ -515,7 +515,7 @@ intptr_t oopDesc::identity_hash() {
515515
markWord mrk = mark();
516516
if (mrk.is_hashed_expanded()) {
517517
Klass* klass = mrk.klass();
518-
return int_field(klass->hash_offset_in_bytes(cast_to_oop(this)));
518+
return int_field(klass->hash_offset_in_bytes(cast_to_oop(this), mrk));
519519
}
520520
// Fall-through to slow-case.
521521
} else {

src/hotspot/share/runtime/lightweightSynchronizer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1232,7 +1232,7 @@ uint32_t LightweightSynchronizer::get_hash(markWord mark, oop obj, Klass* klass)
12321232
//assert(mark.is_neutral() | mark.is_fast_locked(), "only from neutral or fast-locked mark: " INTPTR_FORMAT, mark.value());
12331233
assert(mark.is_hashed(), "only from hashed or copied object");
12341234
if (mark.is_hashed_expanded()) {
1235-
return obj->int_field(klass->hash_offset_in_bytes(obj));
1235+
return obj->int_field(klass->hash_offset_in_bytes(obj, mark));
12361236
} else {
12371237
assert(mark.is_hashed_not_expanded(), "must be hashed");
12381238
assert(hashCode == 6 || hashCode == 2, "must have idempotent hashCode");

src/hotspot/share/runtime/synchronizer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -996,7 +996,7 @@ static intptr_t install_hash_code(Thread* current, oop obj) {
996996
markWord new_mark;
997997
if (mark.is_not_hashed_expanded()) {
998998
new_mark = mark.set_hashed_expanded();
999-
int offset = mark.klass()->hash_offset_in_bytes(obj);
999+
int offset = mark.klass()->hash_offset_in_bytes(obj, mark);
10001000
obj->int_field_put(offset, (jint) hash);
10011001
} else {
10021002
new_mark = mark.set_hashed_not_expanded();

0 commit comments

Comments
 (0)