31 #include "gc/z/zResurrection.inline.hpp"
32 #include "oops/oop.hpp"
33 #include "runtime/atomic.hpp"
34
35 inline void ZBarrier::self_heal(volatile oop* p, uintptr_t addr, uintptr_t heal_addr) {
36 if (heal_addr == 0) {
37 // Never heal with null since it interacts badly with reference processing.
38 // A mutator clearing an oop would be similar to calling Reference.clear(),
39 // which would make the reference non-discoverable or silently dropped
40 // by the reference processor.
41 return;
42 }
43
44 for (;;) {
45 if (addr == heal_addr) {
46 // Already healed
47 return;
48 }
49
50 // Heal
51 const uintptr_t prev_addr = Atomic::cmpxchg(heal_addr, (volatile uintptr_t*)p, addr);
52 if (prev_addr == addr) {
53 // Success
54 return;
55 }
56
57 if (ZAddress::is_good_or_null(prev_addr)) {
58 // No need to heal
59 return;
60 }
61
62 // The oop location was healed by another barrier, but it is still not
63 // good or null. Re-apply healing to make sure the oop is not left with
64 // weaker (remapped or finalizable) metadata bits than what this barrier
65 // tried to apply.
66 assert(ZAddress::offset(prev_addr) == ZAddress::offset(heal_addr), "Invalid offset");
67 addr = prev_addr;
68 }
69 }
70
71 template <ZBarrierFastPath fast_path, ZBarrierSlowPath slow_path>
|
31 #include "gc/z/zResurrection.inline.hpp"
32 #include "oops/oop.hpp"
33 #include "runtime/atomic.hpp"
34
35 inline void ZBarrier::self_heal(volatile oop* p, uintptr_t addr, uintptr_t heal_addr) {
36 if (heal_addr == 0) {
37 // Never heal with null since it interacts badly with reference processing.
38 // A mutator clearing an oop would be similar to calling Reference.clear(),
39 // which would make the reference non-discoverable or silently dropped
40 // by the reference processor.
41 return;
42 }
43
44 for (;;) {
45 if (addr == heal_addr) {
46 // Already healed
47 return;
48 }
49
50 // Heal
51 const uintptr_t prev_addr = Atomic::cmpxchg((volatile uintptr_t*)p, addr, heal_addr);
52 if (prev_addr == addr) {
53 // Success
54 return;
55 }
56
57 if (ZAddress::is_good_or_null(prev_addr)) {
58 // No need to heal
59 return;
60 }
61
62 // The oop location was healed by another barrier, but it is still not
63 // good or null. Re-apply healing to make sure the oop is not left with
64 // weaker (remapped or finalizable) metadata bits than what this barrier
65 // tried to apply.
66 assert(ZAddress::offset(prev_addr) == ZAddress::offset(heal_addr), "Invalid offset");
67 addr = prev_addr;
68 }
69 }
70
71 template <ZBarrierFastPath fast_path, ZBarrierSlowPath slow_path>
|