95 static traceid artifact_id(const T* ptr) { |
95 static traceid artifact_id(const T* ptr) { |
96 assert(ptr != NULL, "invariant"); |
96 assert(ptr != NULL, "invariant"); |
97 return TRACE_ID(ptr); |
97 return TRACE_ID(ptr); |
98 } |
98 } |
99 |
99 |
100 static traceid package_id(KlassPtr klass) { |
100 static traceid package_id(KlassPtr klass, bool leakp) { |
101 assert(klass != NULL, "invariant"); |
101 assert(klass != NULL, "invariant"); |
102 PkgPtr pkg_entry = klass->package(); |
102 PkgPtr pkg_entry = klass->package(); |
103 return pkg_entry != NULL ? artifact_id(pkg_entry) : 0; |
103 if (pkg_entry == NULL) { |
|
104 return 0; |
|
105 } |
|
106 if (leakp) { |
|
107 SET_LEAKP(pkg_entry); |
|
108 } |
|
109 // package implicitly tagged already |
|
110 return artifact_id(pkg_entry); |
104 } |
111 } |
105 |
112 |
106 static traceid module_id(PkgPtr pkg, bool leakp) { |
113 static traceid module_id(PkgPtr pkg, bool leakp) { |
107 assert(pkg != NULL, "invariant"); |
114 assert(pkg != NULL, "invariant"); |
108 ModPtr module_entry = pkg->module(); |
115 ModPtr module_entry = pkg->module(); |
109 if (module_entry != NULL && module_entry->is_named()) { |
116 if (module_entry == NULL || !module_entry->is_named()) { |
110 if (leakp) { |
117 return 0; |
111 SET_LEAKP(module_entry); |
118 } |
112 } else { |
119 if (leakp) { |
113 SET_TRANSIENT(module_entry); |
120 SET_LEAKP(module_entry); |
114 } |
121 } else { |
115 return artifact_id(module_entry); |
122 SET_TRANSIENT(module_entry); |
116 } |
123 } |
117 return 0; |
124 return artifact_id(module_entry); |
118 } |
125 } |
119 |
126 |
120 static traceid method_id(KlassPtr klass, MethodPtr method) { |
127 static traceid method_id(KlassPtr klass, MethodPtr method) { |
121 assert(klass != NULL, "invariant"); |
128 assert(klass != NULL, "invariant"); |
122 assert(method != NULL, "invariant"); |
129 assert(method != NULL, "invariant"); |
146 static void set_serialized(const T* ptr) { |
153 static void set_serialized(const T* ptr) { |
147 assert(ptr != NULL, "invariant"); |
154 assert(ptr != NULL, "invariant"); |
148 SET_SERIALIZED(ptr); |
155 SET_SERIALIZED(ptr); |
149 assert(IS_SERIALIZED(ptr), "invariant"); |
156 assert(IS_SERIALIZED(ptr), "invariant"); |
150 } |
157 } |
151 |
|
152 template <typename T> |
|
153 void tag_leakp_artifact(T const& value) { |
|
154 assert(value != NULL, "invariant"); |
|
155 SET_LEAKP(value); |
|
156 assert(IS_LEAKP(value), "invariant"); |
|
157 } |
|
158 |
|
159 static void tag_leakp_klass_artifacts(KlassPtr k) { |
|
160 assert(k != NULL, "invariant"); |
|
161 PkgPtr pkg = k->package(); |
|
162 if (pkg != NULL) { |
|
163 tag_leakp_artifact(pkg); |
|
164 ModPtr module = pkg->module(); |
|
165 if (module != NULL) { |
|
166 tag_leakp_artifact(module); |
|
167 } |
|
168 } |
|
169 CldPtr cld = k->class_loader_data(); |
|
170 assert(cld != NULL, "invariant"); |
|
171 if (!cld->is_unsafe_anonymous()) { |
|
172 tag_leakp_artifact(cld); |
|
173 } |
|
174 } |
|
175 |
|
176 class TagLeakpKlassArtifact { |
|
177 public: |
|
178 TagLeakpKlassArtifact(bool class_unload) {} |
|
179 bool operator()(KlassPtr klass) { |
|
180 if (IS_LEAKP(klass)) { |
|
181 tag_leakp_klass_artifacts(klass); |
|
182 } |
|
183 return true; |
|
184 } |
|
185 }; |
|
186 |
158 |
187 /* |
159 /* |
188 * In C++03, functions used as template parameters must have external linkage; |
160 * In C++03, functions used as template parameters must have external linkage; |
189 * this restriction was removed in C++11. Change back to "static" and |
161 * this restriction was removed in C++11. Change back to "static" and |
190 * rename functions when C++11 becomes available. |
162 * rename functions when C++11 becomes available. |
201 if (theklass->is_objArray_klass()) { |
173 if (theklass->is_objArray_klass()) { |
202 const ObjArrayKlass* obj_arr_klass = ObjArrayKlass::cast(klass); |
174 const ObjArrayKlass* obj_arr_klass = ObjArrayKlass::cast(klass); |
203 theklass = obj_arr_klass->bottom_klass(); |
175 theklass = obj_arr_klass->bottom_klass(); |
204 } |
176 } |
205 if (theklass->is_instance_klass()) { |
177 if (theklass->is_instance_klass()) { |
206 pkg_id = package_id(theklass); |
178 pkg_id = package_id(theklass, leakp); |
207 } else { |
179 } else { |
208 assert(theklass->is_typeArray_klass(), "invariant"); |
180 assert(theklass->is_typeArray_klass(), "invariant"); |
209 } |
181 } |
210 writer->write(artifact_id(klass)); |
182 writer->write(artifact_id(klass)); |
211 writer->write(cld_id(klass->class_loader_data(), leakp)); |
183 writer->write(cld_id(klass->class_loader_data(), leakp)); |
284 typedef JfrArtifactCallbackHost<KlassPtr, KlassWriterRegistration> KlassCallback; |
256 typedef JfrArtifactCallbackHost<KlassPtr, KlassWriterRegistration> KlassCallback; |
285 |
257 |
286 typedef LeakPredicate<KlassPtr> LeakKlassPredicate; |
258 typedef LeakPredicate<KlassPtr> LeakKlassPredicate; |
287 typedef JfrPredicatedTypeWriterImplHost<KlassPtr, LeakKlassPredicate, write__klass__leakp> LeakKlassWriterImpl; |
259 typedef JfrPredicatedTypeWriterImplHost<KlassPtr, LeakKlassPredicate, write__klass__leakp> LeakKlassWriterImpl; |
288 typedef JfrTypeWriterHost<LeakKlassWriterImpl, TYPE_CLASS> LeakKlassWriter; |
260 typedef JfrTypeWriterHost<LeakKlassWriterImpl, TYPE_CLASS> LeakKlassWriter; |
289 typedef CompositeFunctor<KlassPtr, TagLeakpKlassArtifact, LeakKlassWriter> LeakpKlassArtifactTagging; |
261 |
290 |
262 typedef CompositeFunctor<KlassPtr, LeakKlassWriter, KlassWriter> CompositeKlassWriter; |
291 typedef CompositeFunctor<KlassPtr, LeakpKlassArtifactTagging, KlassWriter> CompositeKlassWriter; |
|
292 typedef CompositeFunctor<KlassPtr, CompositeKlassWriter, KlassArtifactRegistrator> CompositeKlassWriterRegistration; |
263 typedef CompositeFunctor<KlassPtr, CompositeKlassWriter, KlassArtifactRegistrator> CompositeKlassWriterRegistration; |
293 typedef JfrArtifactCallbackHost<KlassPtr, CompositeKlassWriterRegistration> CompositeKlassCallback; |
264 typedef JfrArtifactCallbackHost<KlassPtr, CompositeKlassWriterRegistration> CompositeKlassCallback; |
294 |
265 |
295 static bool write_klasses() { |
266 static bool write_klasses() { |
296 assert(!_artifacts->has_klass_entries(), "invariant"); |
267 assert(!_artifacts->has_klass_entries(), "invariant"); |
301 if (_leakp_writer == NULL) { |
272 if (_leakp_writer == NULL) { |
302 KlassCallback callback(&kwr); |
273 KlassCallback callback(&kwr); |
303 _subsystem_callback = &callback; |
274 _subsystem_callback = &callback; |
304 do_klasses(); |
275 do_klasses(); |
305 } else { |
276 } else { |
306 TagLeakpKlassArtifact tagging(_class_unload); |
|
307 LeakKlassWriter lkw(_leakp_writer, _artifacts, _class_unload); |
277 LeakKlassWriter lkw(_leakp_writer, _artifacts, _class_unload); |
308 LeakpKlassArtifactTagging lpkat(&tagging, &lkw); |
278 CompositeKlassWriter ckw(&lkw, &kw); |
309 CompositeKlassWriter ckw(&lpkat, &kw); |
|
310 CompositeKlassWriterRegistration ckwr(&ckw, ®); |
279 CompositeKlassWriterRegistration ckwr(&ckw, ®); |
311 CompositeKlassCallback callback(&ckwr); |
280 CompositeKlassCallback callback(&ckwr); |
312 _subsystem_callback = &callback; |
281 _subsystem_callback = &callback; |
313 do_klasses(); |
282 do_klasses(); |
314 } |
283 } |