42 #include "utilities/macros.hpp" |
42 #include "utilities/macros.hpp" |
43 |
43 |
44 // Implementation of all inlined member functions defined in oop.hpp |
44 // Implementation of all inlined member functions defined in oop.hpp |
45 // We need a separate file to avoid circular references |
45 // We need a separate file to avoid circular references |
46 |
46 |
|
47 markOop oopDesc::mark() const { |
|
48 return HeapAccess<MO_VOLATILE>::load_at(as_oop(), mark_offset_in_bytes()); |
|
49 } |
|
50 |
|
51 markOop oopDesc::mark_raw() const { |
|
52 return _mark; |
|
53 } |
|
54 |
|
55 markOop* oopDesc::mark_addr_raw() const { |
|
56 return (markOop*) &_mark; |
|
57 } |
|
58 |
|
59 void oopDesc::set_mark(volatile markOop m) { |
|
60 HeapAccess<MO_VOLATILE>::store_at(as_oop(), mark_offset_in_bytes(), m); |
|
61 } |
|
62 |
|
63 void oopDesc::set_mark_raw(volatile markOop m) { |
|
64 _mark = m; |
|
65 } |
|
66 |
47 void oopDesc::release_set_mark(markOop m) { |
67 void oopDesc::release_set_mark(markOop m) { |
48 OrderAccess::release_store(&_mark, m); |
68 HeapAccess<MO_RELEASE>::store_at(as_oop(), mark_offset_in_bytes(), m); |
49 } |
69 } |
50 |
70 |
51 markOop oopDesc::cas_set_mark(markOop new_mark, markOop old_mark) { |
71 markOop oopDesc::cas_set_mark(markOop new_mark, markOop old_mark) { |
|
72 return HeapAccess<>::atomic_cmpxchg_at(new_mark, as_oop(), mark_offset_in_bytes(), old_mark); |
|
73 } |
|
74 |
|
75 markOop oopDesc::cas_set_mark_raw(markOop new_mark, markOop old_mark) { |
52 return Atomic::cmpxchg(new_mark, &_mark, old_mark); |
76 return Atomic::cmpxchg(new_mark, &_mark, old_mark); |
53 } |
77 } |
54 |
78 |
55 void oopDesc::init_mark() { |
79 void oopDesc::init_mark() { |
56 set_mark(markOopDesc::prototype_for_object(this)); |
80 set_mark(markOopDesc::prototype_for_object(this)); |
|
81 } |
|
82 |
|
83 void oopDesc::init_mark_raw() { |
|
84 set_mark_raw(markOopDesc::prototype_for_object(this)); |
57 } |
85 } |
58 |
86 |
59 Klass* oopDesc::klass() const { |
87 Klass* oopDesc::klass() const { |
60 if (UseCompressedClassPointers) { |
88 if (UseCompressedClassPointers) { |
61 return Klass::decode_klass_not_null(_metadata._compressed_klass); |
89 return Klass::decode_klass_not_null(_metadata._compressed_klass); |
279 |
307 |
280 bool oopDesc::has_bias_pattern() const { |
308 bool oopDesc::has_bias_pattern() const { |
281 return mark()->has_bias_pattern(); |
309 return mark()->has_bias_pattern(); |
282 } |
310 } |
283 |
311 |
|
312 bool oopDesc::has_bias_pattern_raw() const { |
|
313 return mark_raw()->has_bias_pattern(); |
|
314 } |
|
315 |
284 // Used only for markSweep, scavenging |
316 // Used only for markSweep, scavenging |
285 bool oopDesc::is_gc_marked() const { |
317 bool oopDesc::is_gc_marked() const { |
286 return mark()->is_marked(); |
318 return mark_raw()->is_marked(); |
287 } |
319 } |
288 |
320 |
289 // Used by scavengers |
321 // Used by scavengers |
290 bool oopDesc::is_forwarded() const { |
322 bool oopDesc::is_forwarded() const { |
291 // The extra heap check is needed since the obj might be locked, in which case the |
323 // The extra heap check is needed since the obj might be locked, in which case the |
292 // mark would point to a stack location and have the sentinel bit cleared |
324 // mark would point to a stack location and have the sentinel bit cleared |
293 return mark()->is_marked(); |
325 return mark_raw()->is_marked(); |
294 } |
326 } |
295 |
327 |
296 // Used by scavengers |
328 // Used by scavengers |
297 void oopDesc::forward_to(oop p) { |
329 void oopDesc::forward_to(oop p) { |
298 assert(check_obj_alignment(p), |
330 assert(check_obj_alignment(p), |
302 assert(!is_archive_object(oop(this)) && |
334 assert(!is_archive_object(oop(this)) && |
303 !is_archive_object(p), |
335 !is_archive_object(p), |
304 "forwarding archive object"); |
336 "forwarding archive object"); |
305 markOop m = markOopDesc::encode_pointer_as_mark(p); |
337 markOop m = markOopDesc::encode_pointer_as_mark(p); |
306 assert(m->decode_pointer() == p, "encoding must be reversable"); |
338 assert(m->decode_pointer() == p, "encoding must be reversable"); |
307 set_mark(m); |
339 set_mark_raw(m); |
308 } |
340 } |
309 |
341 |
310 // Used by parallel scavengers |
342 // Used by parallel scavengers |
311 bool oopDesc::cas_forward_to(oop p, markOop compare) { |
343 bool oopDesc::cas_forward_to(oop p, markOop compare) { |
312 assert(check_obj_alignment(p), |
344 assert(check_obj_alignment(p), |
313 "forwarding to something not aligned"); |
345 "forwarding to something not aligned"); |
314 assert(Universe::heap()->is_in_reserved(p), |
346 assert(Universe::heap()->is_in_reserved(p), |
315 "forwarding to something not in heap"); |
347 "forwarding to something not in heap"); |
316 markOop m = markOopDesc::encode_pointer_as_mark(p); |
348 markOop m = markOopDesc::encode_pointer_as_mark(p); |
317 assert(m->decode_pointer() == p, "encoding must be reversable"); |
349 assert(m->decode_pointer() == p, "encoding must be reversable"); |
318 return cas_set_mark(m, compare) == compare; |
350 return cas_set_mark_raw(m, compare) == compare; |
319 } |
351 } |
320 |
352 |
321 #if INCLUDE_ALL_GCS |
353 #if INCLUDE_ALL_GCS |
322 oop oopDesc::forward_to_atomic(oop p) { |
354 oop oopDesc::forward_to_atomic(oop p) { |
323 markOop oldMark = mark(); |
355 markOop oldMark = mark_raw(); |
324 markOop forwardPtrMark = markOopDesc::encode_pointer_as_mark(p); |
356 markOop forwardPtrMark = markOopDesc::encode_pointer_as_mark(p); |
325 markOop curMark; |
357 markOop curMark; |
326 |
358 |
327 assert(forwardPtrMark->decode_pointer() == p, "encoding must be reversable"); |
359 assert(forwardPtrMark->decode_pointer() == p, "encoding must be reversable"); |
328 assert(sizeof(markOop) == sizeof(intptr_t), "CAS below requires this."); |
360 assert(sizeof(markOop) == sizeof(intptr_t), "CAS below requires this."); |
329 |
361 |
330 while (!oldMark->is_marked()) { |
362 while (!oldMark->is_marked()) { |
331 curMark = Atomic::cmpxchg(forwardPtrMark, &_mark, oldMark); |
363 curMark = cas_set_mark_raw(forwardPtrMark, oldMark); |
332 assert(is_forwarded(), "object should have been forwarded"); |
364 assert(is_forwarded(), "object should have been forwarded"); |
333 if (curMark == oldMark) { |
365 if (curMark == oldMark) { |
334 return NULL; |
366 return NULL; |
335 } |
367 } |
336 // If the CAS was unsuccessful then curMark->is_marked() |
368 // If the CAS was unsuccessful then curMark->is_marked() |
344 |
376 |
345 // Note that the forwardee is not the same thing as the displaced_mark. |
377 // Note that the forwardee is not the same thing as the displaced_mark. |
346 // The forwardee is used when copying during scavenge and mark-sweep. |
378 // The forwardee is used when copying during scavenge and mark-sweep. |
347 // It does need to clear the low two locking- and GC-related bits. |
379 // It does need to clear the low two locking- and GC-related bits. |
348 oop oopDesc::forwardee() const { |
380 oop oopDesc::forwardee() const { |
349 return (oop) mark()->decode_pointer(); |
381 return (oop) mark_raw()->decode_pointer(); |
350 } |
382 } |
351 |
383 |
352 // The following method needs to be MT safe. |
384 // The following method needs to be MT safe. |
353 uint oopDesc::age() const { |
385 uint oopDesc::age() const { |
354 assert(!is_forwarded(), "Attempt to read age from forwarded mark"); |
386 assert(!is_forwarded(), "Attempt to read age from forwarded mark"); |
355 if (has_displaced_mark()) { |
387 if (has_displaced_mark_raw()) { |
356 return displaced_mark()->age(); |
388 return displaced_mark_raw()->age(); |
357 } else { |
389 } else { |
358 return mark()->age(); |
390 return mark_raw()->age(); |
359 } |
391 } |
360 } |
392 } |
361 |
393 |
362 void oopDesc::incr_age() { |
394 void oopDesc::incr_age() { |
363 assert(!is_forwarded(), "Attempt to increment age of forwarded mark"); |
395 assert(!is_forwarded(), "Attempt to increment age of forwarded mark"); |
364 if (has_displaced_mark()) { |
396 if (has_displaced_mark_raw()) { |
365 set_displaced_mark(displaced_mark()->incr_age()); |
397 set_displaced_mark_raw(displaced_mark_raw()->incr_age()); |
366 } else { |
398 } else { |
367 set_mark(mark()->incr_age()); |
399 set_mark_raw(mark_raw()->incr_age()); |
368 } |
400 } |
369 } |
401 } |
370 |
402 |
371 #if INCLUDE_ALL_GCS |
403 #if INCLUDE_ALL_GCS |
372 void oopDesc::pc_follow_contents(ParCompactionManager* cm) { |
404 void oopDesc::pc_follow_contents(ParCompactionManager* cm) { |
463 } else { |
495 } else { |
464 return slow_identity_hash(); |
496 return slow_identity_hash(); |
465 } |
497 } |
466 } |
498 } |
467 |
499 |
468 bool oopDesc::has_displaced_mark() const { |
500 bool oopDesc::has_displaced_mark_raw() const { |
469 return mark()->has_displaced_mark_helper(); |
501 return mark_raw()->has_displaced_mark_helper(); |
470 } |
502 } |
471 |
503 |
472 markOop oopDesc::displaced_mark() const { |
504 markOop oopDesc::displaced_mark_raw() const { |
473 return mark()->displaced_mark_helper(); |
505 return mark_raw()->displaced_mark_helper(); |
474 } |
506 } |
475 |
507 |
476 void oopDesc::set_displaced_mark(markOop m) { |
508 void oopDesc::set_displaced_mark_raw(markOop m) { |
477 mark()->set_displaced_mark_helper(m); |
509 mark_raw()->set_displaced_mark_helper(m); |
478 } |
510 } |
479 |
511 |
480 #endif // SHARE_VM_OOPS_OOP_INLINE_HPP |
512 #endif // SHARE_VM_OOPS_OOP_INLINE_HPP |