< prev index next > src/hotspot/share/oops/oop.inline.hpp
Print this page
markWord* oopDesc::mark_addr() const {
return (markWord*) &_mark;
}
void oopDesc::set_mark(markWord m) {
+ if (UseCompactObjectHeaders) {
+ Atomic::store(reinterpret_cast<uint32_t volatile*>(&_mark), m.value32());
+ } else {
+ Atomic::store(&_mark, m);
+ }
+ }
+
+ void oopDesc::set_mark_full(markWord m) {
Atomic::store(&_mark, m);
}
void oopDesc::set_mark(HeapWord* mem, markWord m) {
- *(markWord*)(((char*)mem) + mark_offset_in_bytes()) = m;
+ if (UseCompactObjectHeaders) {
+ *(uint32_t*)(((char*)mem) + mark_offset_in_bytes()) = m.value32();
+ } else {
+ *(markWord*)(((char*)mem) + mark_offset_in_bytes()) = m;
+ }
}
void oopDesc::release_set_mark(HeapWord* mem, markWord m) {
- Atomic::release_store((markWord*)(((char*)mem) + mark_offset_in_bytes()), m);
+ if (UseCompactObjectHeaders) {
+ Atomic::release_store((uint32_t*)(((char*)mem) + mark_offset_in_bytes()), m.value32());
+ } else {
+ Atomic::release_store((markWord*)(((char*)mem) + mark_offset_in_bytes()), m);
+ }
}
void oopDesc::release_set_mark(markWord m) {
- Atomic::release_store(&_mark, m);
+ if (UseCompactObjectHeaders) {
+ Atomic::release_store(reinterpret_cast<uint32_t volatile*>(&_mark), m.value32());
+ } else {
+ Atomic::release_store(&_mark, m);
+ }
}
markWord oopDesc::cas_set_mark(markWord new_mark, markWord old_mark) {
return Atomic::cmpxchg(&_mark, old_mark, new_mark);
}
return markWord::prototype();
}
}
void oopDesc::init_mark() {
- set_mark(prototype_mark());
+ if (UseCompactObjectHeaders) {
+ markWord m = prototype_mark().copy_hashctrl_from(mark());
+ assert(m.is_neutral(), "must be neutral");
+ set_mark(m);
+ } else {
+ set_mark(prototype_mark());
+ }
}
Klass* oopDesc::klass() const {
switch (ObjLayout::klass_mode()) {
case ObjLayout::Compact:
bool oopDesc::is_a(Klass* k) const {
return klass()->is_subtype_of(k);
}
+ size_t oopDesc::size_given_mark_and_klass(markWord mrk, const Klass* kls) {
+ size_t sz = base_size_given_klass(mrk, kls);
+ if (UseCompactObjectHeaders) {
+ assert(!mrk.has_displaced_mark_helper(), "must not be displaced");
+ if (mrk.is_expanded() && kls->expand_for_hash(cast_to_oop(this))) {
+ sz = align_object_size(sz + 1);
+ }
+ }
+ return sz;
+ }
+
+ size_t oopDesc::copy_size(size_t size, markWord mark) const {
+ if (UseCompactObjectHeaders) {
+ assert(!mark.has_displaced_mark_helper(), "must not be displaced");
+ Klass* klass = mark.klass();
+ if (mark.is_hashed_not_expanded() && klass->expand_for_hash(cast_to_oop(this))) {
+ size = align_object_size(size + 1);
+ }
+ }
+ assert(is_object_aligned(size), "Oop size is not properly aligned: " SIZE_FORMAT, size);
+ return size;
+ }
+
+ size_t oopDesc::copy_size_cds(size_t size, markWord mark) const {
+ if (UseCompactObjectHeaders) {
+ assert(!mark.has_displaced_mark_helper(), "must not be displaced");
+ Klass* klass = mark.klass();
+ if (mark.is_hashed_not_expanded() && klass->expand_for_hash(cast_to_oop(this))) {
+ size = align_object_size(size + 1);
+ }
+ if (mark.is_not_hashed_expanded() && klass->expand_for_hash(cast_to_oop(this))) {
+ size = align_object_size(size - ObjectAlignmentInBytes / HeapWordSize);
+ }
+ }
+ assert(is_object_aligned(size), "Oop size is not properly aligned: " SIZE_FORMAT, size);
+ return size;
+ }
+
size_t oopDesc::size() {
- return size_given_klass(klass());
+ return size_given_mark_and_klass(mark(), klass());
}
- size_t oopDesc::size_given_klass(Klass* klass) {
+ size_t oopDesc::base_size_given_klass(markWord mrk, const Klass* klass) {
int lh = klass->layout_helper();
size_t s;
// lh is now a value computed at class initialization that may hint
// at the size. For instances, this is positive and equal to the
if (lh > Klass::_lh_neutral_value) {
if (!Klass::layout_helper_needs_slow_path(lh)) {
s = lh >> LogHeapWordSize; // deliver size scaled by wordSize
} else {
- s = klass->oop_size(this);
+ s = klass->oop_size(this, mrk);
}
} else if (lh <= Klass::_lh_neutral_value) {
// The most common case is instances; fall through if so.
if (lh < Klass::_lh_neutral_value) {
// Second most common case is arrays. We have to fetch the
// length of the array, shift (multiply) it appropriately,
// up to wordSize, add the header, and align to object size.
size_t size_in_bytes;
- size_t array_length = (size_t) ((arrayOop)this)->length();
+ size_t array_length;
+ #ifdef _LP64
+ if (UseCompactObjectHeaders) {
+ array_length = (size_t) mrk.array_length();
+ } else
+ #endif
+ array_length = (size_t)((arrayOop)this)->length();
+
size_in_bytes = array_length << Klass::layout_helper_log2_element_size(lh);
size_in_bytes += Klass::layout_helper_header_size(lh);
// This code could be simplified, but by keeping array_header_in_bytes
// in units of bytes and doing it this way we can round up just once,
// skipping the intermediate round to HeapWordSize.
s = align_up(size_in_bytes, MinObjAlignmentInBytes) / HeapWordSize;
-
- assert(s == klass->oop_size(this), "wrong array object size");
+ if (s != klass->oop_size(this, mrk)) {
+ tty->print_cr("length: " SIZE_FORMAT, array_length);
+ tty->print_cr("log element size: %d", Klass::layout_helper_log2_element_size(lh));
+ tty->print_cr("is_objArray: %s", BOOL_TO_STR(klass->is_objArray_klass()));
+ }
+ assert(s == klass->oop_size(this, mrk), "wrong array object size, s: " SIZE_FORMAT ", oop_size: " SIZE_FORMAT, s, klass->oop_size(this, mrk));
} else {
// Must be zero, so bite the bullet and take the virtual call.
- s = klass->oop_size(this);
+ s = klass->oop_size(this, mrk);
}
}
assert(s > 0, "Oop size must be greater than zero, not " SIZE_FORMAT, s);
assert(is_object_aligned(s), "Oop size is not properly aligned: " SIZE_FORMAT, s);
void oopDesc::forward_to(oop p) {
assert(cast_from_oop<oopDesc*>(p) != this,
"must not be used for self-forwarding, use forward_to_self() instead");
markWord m = markWord::encode_pointer_as_mark(p);
assert(m.decode_pointer() == p, "encoding must be reversible");
- set_mark(m);
+ set_mark_full(m);
}
void oopDesc::forward_to_self() {
set_mark(mark().set_self_forwarded());
}
}
template <typename OopClosureType>
size_t oopDesc::oop_iterate_size(OopClosureType* cl) {
Klass* k = klass();
- size_t size = size_given_klass(k);
+ size_t size = size_given_mark_and_klass(mark(), k);
OopIteratorClosureDispatch::oop_oop_iterate(cl, this, k);
return size;
}
template <typename OopClosureType>
size_t oopDesc::oop_iterate_size(OopClosureType* cl, MemRegion mr) {
Klass* k = klass();
- size_t size = size_given_klass(k);
+ size_t size = size_given_mark_and_klass(mark(), k);
OopIteratorClosureDispatch::oop_oop_iterate(cl, this, k, mr);
return size;
}
template <typename OopClosureType>
}
intptr_t oopDesc::identity_hash() {
// Fast case; if the object is unlocked and the hash value is set, no locking is needed
// Note: The mark must be read into local variable to avoid concurrent updates.
- markWord mrk = mark();
- if (mrk.is_unlocked() && !mrk.has_no_hash()) {
- return mrk.hash();
- } else if (mrk.is_marked()) {
- return mrk.hash();
+ if (UseCompactObjectHeaders) {
+ markWord mrk = mark();
+ if (mrk.is_hashed_expanded()) {
+ Klass* klass = mrk.klass();
+ return int_field(klass->hash_offset_in_bytes(cast_to_oop(this)));
+ }
+ // Fall-through to slow-case.
} else {
- return slow_identity_hash();
+ markWord mrk = mark();
+ if (mrk.is_unlocked() && !mrk.has_no_hash()) {
+ return mrk.hash();
+ } else if (mrk.is_marked()) {
+ return mrk.hash();
+ }
+ // Fall-through to slow-case.
}
+ return slow_identity_hash();
}
// This checks fast simple case of whether the oop has_no_hash,
// to optimize JVMTI table lookup.
bool oopDesc::fast_no_hash_check() {
markWord mrk = mark_acquire();
assert(!mrk.is_marked(), "should never be marked");
- return mrk.is_unlocked() && mrk.has_no_hash();
+ return (UseCompactObjectHeaders || mrk.is_unlocked()) && mrk.has_no_hash();
}
bool oopDesc::has_displaced_mark() const {
return mark().has_displaced_mark_helper();
}
bool oopDesc::mark_must_be_preserved(markWord m) const {
return m.must_be_preserved(this);
}
+ inline void oopDesc::initialize_hash_if_necessary(oop obj) {
+ if (!UseCompactObjectHeaders) {
+ return;
+ }
+ markWord m = mark();
+ assert(!m.has_displaced_mark_helper(), "must not be displaced header");
+ assert(!m.is_forwarded(), "must not be forwarded header");
+ if (m.is_hashed_not_expanded()) {
+ initialize_hash_if_necessary(obj, m.klass(), m);
+ }
+ }
+
+
#endif // SHARE_OOPS_OOP_INLINE_HPP
< prev index next >