54 markOop* oopDesc::mark_addr_raw() const { 55 return (markOop*) &_mark; 56 } 57 58 void oopDesc::set_mark(volatile markOop m) { 59 HeapAccess<MO_VOLATILE>::store_at(as_oop(), mark_offset_in_bytes(), m); 60 } 61 62 void oopDesc::set_mark_raw(volatile markOop m) { 63 _mark = m; 64 } 65 66 void oopDesc::release_set_mark(markOop m) { 67 HeapAccess<MO_RELEASE>::store_at(as_oop(), mark_offset_in_bytes(), m); 68 } 69 70 markOop oopDesc::cas_set_mark(markOop new_mark, markOop old_mark) { 71 return HeapAccess<>::atomic_cmpxchg_at(new_mark, as_oop(), mark_offset_in_bytes(), old_mark); 72 } 73 74 markOop oopDesc::cas_set_mark_raw(markOop new_mark, markOop old_mark) { 75 return Atomic::cmpxchg(new_mark, &_mark, old_mark); 76 } 77 78 void oopDesc::init_mark() { 79 set_mark(markOopDesc::prototype_for_object(this)); 80 } 81 82 void oopDesc::init_mark_raw() { 83 set_mark_raw(markOopDesc::prototype_for_object(this)); 84 } 85 86 Klass* oopDesc::klass() const { 87 if (UseCompressedClassPointers) { 88 return Klass::decode_klass_not_null(_metadata._compressed_klass); 89 } else { 90 return _metadata._klass; 91 } 92 } 93 94 Klass* oopDesc::klass_or_null() const volatile { 95 if (UseCompressedClassPointers) { 325 // The extra heap check is needed since the obj might be locked, in which case the 326 // mark would point to a stack location and have the sentinel bit cleared 327 return mark_raw()->is_marked(); 328 } 329 330 // Used by scavengers 331 void oopDesc::forward_to(oop p) { 332 assert(check_obj_alignment(p), 333 "forwarding to something not aligned"); 334 assert(Universe::heap()->is_in_reserved(p), 335 "forwarding to something not in heap"); 336 assert(!MetaspaceShared::is_archive_object(oop(this)) && 337 !MetaspaceShared::is_archive_object(p), 338 "forwarding archive object"); 339 markOop m = markOopDesc::encode_pointer_as_mark(p); 340 assert(m->decode_pointer() == p, "encoding must be reversable"); 341 set_mark_raw(m); 342 } 343 344 // Used by parallel scavengers 345 bool oopDesc::cas_forward_to(oop p, markOop compare) { 346 assert(check_obj_alignment(p), 347 "forwarding to something not aligned"); 348 assert(Universe::heap()->is_in_reserved(p), 349 "forwarding to something not in heap"); 350 markOop m = markOopDesc::encode_pointer_as_mark(p); 351 assert(m->decode_pointer() == p, "encoding must be reversable"); 352 return cas_set_mark_raw(m, compare) == compare; 353 } 354 355 oop oopDesc::forward_to_atomic(oop p) { 356 markOop oldMark = mark_raw(); 357 markOop forwardPtrMark = markOopDesc::encode_pointer_as_mark(p); 358 markOop curMark; 359 360 assert(forwardPtrMark->decode_pointer() == p, "encoding must be reversable"); 361 assert(sizeof(markOop) == sizeof(intptr_t), "CAS below requires this."); 362 363 while (!oldMark->is_marked()) { 364 curMark = cas_set_mark_raw(forwardPtrMark, oldMark); 365 assert(is_forwarded(), "object should have been forwarded"); 366 if (curMark == oldMark) { 367 return NULL; 368 } 369 // If the CAS was unsuccessful then curMark->is_marked() 370 // should return true as another thread has CAS'd in another 371 // forwarding pointer. 372 oldMark = curMark; | 54 markOop* oopDesc::mark_addr_raw() const { 55 return (markOop*) &_mark; 56 } 57 58 void oopDesc::set_mark(volatile markOop m) { 59 HeapAccess<MO_VOLATILE>::store_at(as_oop(), mark_offset_in_bytes(), m); 60 } 61 62 void oopDesc::set_mark_raw(volatile markOop m) { 63 _mark = m; 64 } 65 66 void oopDesc::release_set_mark(markOop m) { 67 HeapAccess<MO_RELEASE>::store_at(as_oop(), mark_offset_in_bytes(), m); 68 } 69 70 markOop oopDesc::cas_set_mark(markOop new_mark, markOop old_mark) { 71 return HeapAccess<>::atomic_cmpxchg_at(new_mark, as_oop(), mark_offset_in_bytes(), old_mark); 72 } 73 74 markOop oopDesc::cas_set_mark_raw(markOop new_mark, markOop old_mark, atomic_memory_order order) { 75 return Atomic::cmpxchg(new_mark, &_mark, old_mark, order); 76 } 77 78 void oopDesc::init_mark() { 79 set_mark(markOopDesc::prototype_for_object(this)); 80 } 81 82 void oopDesc::init_mark_raw() { 83 set_mark_raw(markOopDesc::prototype_for_object(this)); 84 } 85 86 Klass* oopDesc::klass() const { 87 if (UseCompressedClassPointers) { 88 return Klass::decode_klass_not_null(_metadata._compressed_klass); 89 } else { 90 return _metadata._klass; 91 } 92 } 93 94 Klass* oopDesc::klass_or_null() const volatile { 95 if (UseCompressedClassPointers) { 325 // The extra heap check is needed since the obj might be locked, in which case the 326 // mark would point to a stack location and have the sentinel bit cleared 327 return mark_raw()->is_marked(); 328 } 329 330 // Used by scavengers 331 void oopDesc::forward_to(oop p) { 332 assert(check_obj_alignment(p), 333 "forwarding to something not aligned"); 334 assert(Universe::heap()->is_in_reserved(p), 335 "forwarding to something not in heap"); 336 assert(!MetaspaceShared::is_archive_object(oop(this)) && 337 !MetaspaceShared::is_archive_object(p), 338 "forwarding archive object"); 339 markOop m = markOopDesc::encode_pointer_as_mark(p); 340 assert(m->decode_pointer() == p, "encoding must be reversable"); 341 set_mark_raw(m); 342 } 343 344 // Used by parallel scavengers 345 bool oopDesc::cas_forward_to(oop p, markOop compare, atomic_memory_order order) { 346 assert(check_obj_alignment(p), 347 "forwarding to something not aligned"); 348 assert(Universe::heap()->is_in_reserved(p), 349 "forwarding to something not in heap"); 350 markOop m = markOopDesc::encode_pointer_as_mark(p); 351 assert(m->decode_pointer() == p, "encoding must be reversable"); 352 return cas_set_mark_raw(m, compare, order) == compare; 353 } 354 355 oop oopDesc::forward_to_atomic(oop p) { 356 markOop oldMark = mark_raw(); 357 markOop forwardPtrMark = markOopDesc::encode_pointer_as_mark(p); 358 markOop curMark; 359 360 assert(forwardPtrMark->decode_pointer() == p, "encoding must be reversable"); 361 assert(sizeof(markOop) == sizeof(intptr_t), "CAS below requires this."); 362 363 while (!oldMark->is_marked()) { 364 curMark = cas_set_mark_raw(forwardPtrMark, oldMark); 365 assert(is_forwarded(), "object should have been forwarded"); 366 if (curMark == oldMark) { 367 return NULL; 368 } 369 // If the CAS was unsuccessful then curMark->is_marked() 370 // should return true as another thread has CAS'd in another 371 // forwarding pointer. 372 oldMark = curMark; |