29 #include "gc/shared/referenceProcessor.hpp"
30 #include "logging/log.hpp"
31 #include "oops/access.inline.hpp"
32 #include "oops/compressedOops.inline.hpp"
33 #include "oops/instanceKlass.inline.hpp"
34 #include "oops/instanceRefKlass.hpp"
35 #include "oops/oop.inline.hpp"
36 #include "utilities/debug.hpp"
37 #include "utilities/globalDefinitions.hpp"
38 #include "utilities/macros.hpp"
39
40 template <bool nv, typename T, class OopClosureType, class Contains>
41 void InstanceRefKlass::do_referent(oop obj, OopClosureType* closure, Contains& contains) {
42 T* referent_addr = (T*)java_lang_ref_Reference::referent_addr_raw(obj);
43 if (contains(referent_addr)) {
44 Devirtualizer<nv>::do_oop(closure, referent_addr);
45 }
46 }
47
48 template <bool nv, typename T, class OopClosureType, class Contains>
49 void InstanceRefKlass::do_next(oop obj, OopClosureType* closure, Contains& contains) {
50 T* next_addr = (T*)java_lang_ref_Reference::next_addr_raw(obj);
51 if (contains(next_addr)) {
52 Devirtualizer<nv>::do_oop(closure, next_addr);
53 }
54 }
55
56 template <bool nv, typename T, class OopClosureType, class Contains>
57 void InstanceRefKlass::do_discovered(oop obj, OopClosureType* closure, Contains& contains) {
58 T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr_raw(obj);
59 if (contains(discovered_addr)) {
60 Devirtualizer<nv>::do_oop(closure, discovered_addr);
61 }
62 }
63
64 template <typename T, class OopClosureType>
65 bool InstanceRefKlass::try_discover(oop obj, ReferenceType type, OopClosureType* closure) {
66 ReferenceDiscoverer* rd = closure->ref_discoverer();
67 if (rd != NULL) {
68 T referent_oop = RawAccess<>::oop_load((T*)java_lang_ref_Reference::referent_addr_raw(obj));
69 if (!CompressedOops::is_null(referent_oop)) {
70 oop referent = CompressedOops::decode_not_null(referent_oop);
71 if (!referent->is_gc_marked()) {
72 // Only try to discover if not yet marked.
73 return rd->discover_reference(obj, type);
74 }
75 }
76 }
77 return false;
78 }
79
80 template <bool nv, typename T, class OopClosureType, class Contains>
81 void InstanceRefKlass::oop_oop_iterate_discovery(oop obj, ReferenceType type, OopClosureType* closure, Contains& contains) {
82 // Try to discover reference and return if it succeeds.
83 if (try_discover<T>(obj, type, closure)) {
84 return;
85 }
86
87 // Treat referent as normal oop.
88 do_referent<nv, T>(obj, closure, contains);
89
90 // Treat discovered as normal oop, if ref is not "active" (next non-NULL).
91 T next_oop = RawAccess<>::oop_load((T*)java_lang_ref_Reference::next_addr_raw(obj));
92 if (!CompressedOops::is_null(next_oop)) {
93 do_discovered<nv, T>(obj, closure, contains);
94 }
95
96 // Treat next as normal oop.
97 do_next<nv, T>(obj, closure, contains);
98 }
99
100 template <bool nv, typename T, class OopClosureType, class Contains>
101 void InstanceRefKlass::oop_oop_iterate_fields(oop obj, OopClosureType* closure, Contains& contains) {
102 do_referent<nv, T>(obj, closure, contains);
103 do_discovered<nv, T>(obj, closure, contains);
104 do_next<nv, T>(obj, closure, contains);
105 }
106
107 template <bool nv, typename T, class OopClosureType, class Contains>
108 void InstanceRefKlass::oop_oop_iterate_discovered_and_discovery(oop obj, ReferenceType type, OopClosureType* closure, Contains& contains) {
109 // Explicitly apply closure to the discovered field.
110 do_discovered<nv, T>(obj, closure, contains);
111 // Then do normal reference processing with discovery.
112 oop_oop_iterate_discovery<nv, T>(obj, type, closure, contains);
113 }
114
115 template <bool nv, typename T, class OopClosureType, class Contains>
116 void InstanceRefKlass::oop_oop_iterate_ref_processing_specialized(oop obj, OopClosureType* closure, Contains& contains) {
117 switch (closure->reference_iteration_mode()) {
118 case ExtendedOopClosure::DO_DISCOVERY:
119 trace_reference_gc<T>("do_discovery", obj);
120 oop_oop_iterate_discovery<nv, T>(obj, reference_type(), closure, contains);
121 break;
122 case ExtendedOopClosure::DO_DISCOVERED_AND_DISCOVERY:
123 trace_reference_gc<T>("do_discovered_and_discovery", obj);
124 oop_oop_iterate_discovered_and_discovery<nv, T>(obj, reference_type(), closure, contains);
175 template <bool nv, class OopClosureType>
176 void InstanceRefKlass::oop_oop_iterate_reverse(oop obj, OopClosureType* closure) {
177 InstanceKlass::oop_oop_iterate_reverse<nv>(obj, closure);
178
179 oop_oop_iterate_ref_processing<nv>(obj, closure);
180 }
181 #endif // INCLUDE_OOP_OOP_ITERATE_BACKWARDS
182
183
184 template <bool nv, class OopClosureType>
185 void InstanceRefKlass::oop_oop_iterate_bounded(oop obj, OopClosureType* closure, MemRegion mr) {
186 InstanceKlass::oop_oop_iterate_bounded<nv>(obj, closure, mr);
187
188 oop_oop_iterate_ref_processing_bounded<nv>(obj, closure, mr);
189 }
190
191 #ifdef ASSERT
192 template <typename T>
193 void InstanceRefKlass::trace_reference_gc(const char *s, oop obj) {
194 T* referent_addr = (T*) java_lang_ref_Reference::referent_addr_raw(obj);
195 T* next_addr = (T*) java_lang_ref_Reference::next_addr_raw(obj);
196 T* discovered_addr = (T*) java_lang_ref_Reference::discovered_addr_raw(obj);
197
198 log_develop_trace(gc, ref)("InstanceRefKlass %s for obj " PTR_FORMAT, s, p2i(obj));
199 log_develop_trace(gc, ref)(" referent_addr/* " PTR_FORMAT " / " PTR_FORMAT,
200 p2i(referent_addr), p2i(referent_addr ? RawAccess<>::oop_load(referent_addr) : (oop)NULL));
201 log_develop_trace(gc, ref)(" next_addr/* " PTR_FORMAT " / " PTR_FORMAT,
202 p2i(next_addr), p2i(next_addr ? RawAccess<>::oop_load(next_addr) : (oop)NULL));
203 log_develop_trace(gc, ref)(" discovered_addr/* " PTR_FORMAT " / " PTR_FORMAT,
204 p2i(discovered_addr), p2i(discovered_addr ? RawAccess<>::oop_load(discovered_addr) : (oop)NULL));
205 }
206 #endif
207
208 // Macro to define InstanceRefKlass::oop_oop_iterate for virtual/nonvirtual for
209 // all closures. Macros calling macros above for each oop size.
210 #define ALL_INSTANCE_REF_KLASS_OOP_OOP_ITERATE_DEFN(OopClosureType, nv_suffix) \
211 OOP_OOP_ITERATE_DEFN( InstanceRefKlass, OopClosureType, nv_suffix) \
212 OOP_OOP_ITERATE_DEFN_BOUNDED( InstanceRefKlass, OopClosureType, nv_suffix) \
213 OOP_OOP_ITERATE_DEFN_BACKWARDS(InstanceRefKlass, OopClosureType, nv_suffix)
214
215 #endif // SHARE_VM_OOPS_INSTANCEREFKLASS_INLINE_HPP
|
29 #include "gc/shared/referenceProcessor.hpp"
30 #include "logging/log.hpp"
31 #include "oops/access.inline.hpp"
32 #include "oops/compressedOops.inline.hpp"
33 #include "oops/instanceKlass.inline.hpp"
34 #include "oops/instanceRefKlass.hpp"
35 #include "oops/oop.inline.hpp"
36 #include "utilities/debug.hpp"
37 #include "utilities/globalDefinitions.hpp"
38 #include "utilities/macros.hpp"
39
40 template <bool nv, typename T, class OopClosureType, class Contains>
41 void InstanceRefKlass::do_referent(oop obj, OopClosureType* closure, Contains& contains) {
42 T* referent_addr = (T*)java_lang_ref_Reference::referent_addr_raw(obj);
43 if (contains(referent_addr)) {
44 Devirtualizer<nv>::do_oop(closure, referent_addr);
45 }
46 }
47
48 template <bool nv, typename T, class OopClosureType, class Contains>
49 void InstanceRefKlass::do_discovered(oop obj, OopClosureType* closure, Contains& contains) {
50 T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr_raw(obj);
51 if (contains(discovered_addr)) {
52 Devirtualizer<nv>::do_oop(closure, discovered_addr);
53 }
54 }
55
56 template <typename T, class OopClosureType>
57 bool InstanceRefKlass::try_discover(oop obj, ReferenceType type, OopClosureType* closure) {
58 ReferenceDiscoverer* rd = closure->ref_discoverer();
59 if (rd != NULL) {
60 T referent_oop = RawAccess<>::oop_load((T*)java_lang_ref_Reference::referent_addr_raw(obj));
61 if (!CompressedOops::is_null(referent_oop)) {
62 oop referent = CompressedOops::decode_not_null(referent_oop);
63 if (!referent->is_gc_marked()) {
64 // Only try to discover if not yet marked.
65 return rd->discover_reference(obj, type);
66 }
67 }
68 }
69 return false;
70 }
71
72 template <bool nv, typename T, class OopClosureType, class Contains>
73 void InstanceRefKlass::oop_oop_iterate_discovery(oop obj, ReferenceType type, OopClosureType* closure, Contains& contains) {
74 // Try to discover reference and return if it succeeds.
75 if (try_discover<T>(obj, type, closure)) {
76 return;
77 }
78
79 // Treat referent and discovered as normal oops.
80 do_referent<nv, T>(obj, closure, contains);
81 do_discovered<nv, T>(obj, closure, contains);
82 }
83
84 template <bool nv, typename T, class OopClosureType, class Contains>
85 void InstanceRefKlass::oop_oop_iterate_fields(oop obj, OopClosureType* closure, Contains& contains) {
86 do_referent<nv, T>(obj, closure, contains);
87 do_discovered<nv, T>(obj, closure, contains);
88 }
89
90 template <bool nv, typename T, class OopClosureType, class Contains>
91 void InstanceRefKlass::oop_oop_iterate_discovered_and_discovery(oop obj, ReferenceType type, OopClosureType* closure, Contains& contains) {
92 // Explicitly apply closure to the discovered field.
93 do_discovered<nv, T>(obj, closure, contains);
94 // Then do normal reference processing with discovery.
95 oop_oop_iterate_discovery<nv, T>(obj, type, closure, contains);
96 }
97
98 template <bool nv, typename T, class OopClosureType, class Contains>
99 void InstanceRefKlass::oop_oop_iterate_ref_processing_specialized(oop obj, OopClosureType* closure, Contains& contains) {
100 switch (closure->reference_iteration_mode()) {
101 case ExtendedOopClosure::DO_DISCOVERY:
102 trace_reference_gc<T>("do_discovery", obj);
103 oop_oop_iterate_discovery<nv, T>(obj, reference_type(), closure, contains);
104 break;
105 case ExtendedOopClosure::DO_DISCOVERED_AND_DISCOVERY:
106 trace_reference_gc<T>("do_discovered_and_discovery", obj);
107 oop_oop_iterate_discovered_and_discovery<nv, T>(obj, reference_type(), closure, contains);
158 template <bool nv, class OopClosureType>
159 void InstanceRefKlass::oop_oop_iterate_reverse(oop obj, OopClosureType* closure) {
160 InstanceKlass::oop_oop_iterate_reverse<nv>(obj, closure);
161
162 oop_oop_iterate_ref_processing<nv>(obj, closure);
163 }
164 #endif // INCLUDE_OOP_OOP_ITERATE_BACKWARDS
165
166
167 template <bool nv, class OopClosureType>
168 void InstanceRefKlass::oop_oop_iterate_bounded(oop obj, OopClosureType* closure, MemRegion mr) {
169 InstanceKlass::oop_oop_iterate_bounded<nv>(obj, closure, mr);
170
171 oop_oop_iterate_ref_processing_bounded<nv>(obj, closure, mr);
172 }
173
174 #ifdef ASSERT
175 template <typename T>
176 void InstanceRefKlass::trace_reference_gc(const char *s, oop obj) {
177 T* referent_addr = (T*) java_lang_ref_Reference::referent_addr_raw(obj);
178 T* discovered_addr = (T*) java_lang_ref_Reference::discovered_addr_raw(obj);
179
180 log_develop_trace(gc, ref)("InstanceRefKlass %s for obj " PTR_FORMAT, s, p2i(obj));
181 log_develop_trace(gc, ref)(" referent_addr/* " PTR_FORMAT " / " PTR_FORMAT,
182 p2i(referent_addr), p2i(referent_addr ? RawAccess<>::oop_load(referent_addr) : (oop)NULL));
183 log_develop_trace(gc, ref)(" discovered_addr/* " PTR_FORMAT " / " PTR_FORMAT,
184 p2i(discovered_addr), p2i(discovered_addr ? RawAccess<>::oop_load(discovered_addr) : (oop)NULL));
185 }
186 #endif
187
188 // Macro to define InstanceRefKlass::oop_oop_iterate for virtual/nonvirtual for
189 // all closures. Macros calling macros above for each oop size.
190 #define ALL_INSTANCE_REF_KLASS_OOP_OOP_ITERATE_DEFN(OopClosureType, nv_suffix) \
191 OOP_OOP_ITERATE_DEFN( InstanceRefKlass, OopClosureType, nv_suffix) \
192 OOP_OOP_ITERATE_DEFN_BOUNDED( InstanceRefKlass, OopClosureType, nv_suffix) \
193 OOP_OOP_ITERATE_DEFN_BACKWARDS(InstanceRefKlass, OopClosureType, nv_suffix)
194
195 #endif // SHARE_VM_OOPS_INSTANCEREFKLASS_INLINE_HPP
|