136 if (theklass->is_instance_klass()) { |
162 if (theklass->is_instance_klass()) { |
137 pkg_id = package_id(theklass); |
163 pkg_id = package_id(theklass); |
138 } else { |
164 } else { |
139 assert(theklass->is_typeArray_klass(), "invariant"); |
165 assert(theklass->is_typeArray_klass(), "invariant"); |
140 } |
166 } |
141 const traceid symbol_id = artifacts->mark(klass); |
167 writer->write(artifact_id(klass)); |
142 assert(symbol_id > 0, "need to have an address for symbol!"); |
|
143 writer->write(TRACE_ID(klass)); |
|
144 writer->write(cld_id(klass->class_loader_data())); |
168 writer->write(cld_id(klass->class_loader_data())); |
145 writer->write((traceid)CREATE_SYMBOL_ID(symbol_id)); |
169 writer->write(mark_symbol(klass)); |
146 writer->write(pkg_id); |
170 writer->write(pkg_id); |
147 writer->write((s4)klass->access_flags().get_flags()); |
171 writer->write(get_flags(klass)); |
|
172 set_serialized(klass); |
148 return 1; |
173 return 1; |
149 } |
174 } |
150 |
175 |
151 int write__artifact__klass__leakp(JfrCheckpointWriter* writer, JfrArtifactSet* artifacts, const void* k) { |
176 static void do_implied(Klass* klass) { |
152 assert(k != NULL, "invariant"); |
|
153 KlassPtr klass = (KlassPtr)k; |
|
154 return write__artifact__klass(writer, artifacts, klass); |
|
155 } |
|
156 |
|
157 int write__artifact__klass__serialize(JfrCheckpointWriter* writer, JfrArtifactSet* artifacts, const void* k) { |
|
158 assert(k != NULL, "invariant"); |
|
159 KlassPtr klass = (KlassPtr)k; |
|
160 int result = write__artifact__klass(writer, artifacts, klass); |
|
161 if (IS_NOT_SERIALIZED(klass)) { |
|
162 SET_SERIALIZED(klass); |
|
163 } |
|
164 assert(IS_SERIALIZED(klass), "invariant"); |
|
165 return result; |
|
166 } |
|
167 |
|
168 typedef LeakPredicate<KlassPtr> LeakKlassPredicate; |
|
169 typedef SerializePredicate<KlassPtr> KlassPredicate; |
|
170 typedef JfrPredicatedArtifactWriterImplHost<KlassPtr, LeakKlassPredicate, write__artifact__klass__leakp> LeakKlassWriterImpl; |
|
171 typedef JfrArtifactWriterHost<LeakKlassWriterImpl, TYPE_CLASS> LeakKlassWriter; |
|
172 typedef JfrPredicatedArtifactWriterImplHost<KlassPtr, KlassPredicate, write__artifact__klass__serialize> KlassWriterImpl; |
|
173 typedef JfrArtifactWriterHost<KlassWriterImpl, TYPE_CLASS> KlassWriter; |
|
174 |
|
175 int write__artifact__method(JfrCheckpointWriter* writer, JfrArtifactSet* artifacts, MethodPtr method) { |
|
176 assert(writer != NULL, "invariant"); |
|
177 assert(artifacts != NULL, "invariant"); |
|
178 const traceid method_name_symbol_id = artifacts->mark(method->name()); |
|
179 assert(method_name_symbol_id > 0, "invariant"); |
|
180 const traceid method_sig_symbol_id = artifacts->mark(method->signature()); |
|
181 assert(method_sig_symbol_id > 0, "invariant"); |
|
182 KlassPtr klass = method->method_holder(); |
|
183 assert(klass != NULL, "invariant"); |
177 assert(klass != NULL, "invariant"); |
184 assert(METHOD_USED_ANY_EPOCH(klass), "invariant"); |
178 if (klass->is_subclass_of(SystemDictionary::ClassLoader_klass()) || klass == SystemDictionary::Object_klass()) { |
185 writer->write((u8)METHOD_ID(klass, method)); |
179 _subsystem_callback->do_artifact(klass); |
186 writer->write((u8)TRACE_ID(klass)); |
180 } |
187 writer->write((u8)CREATE_SYMBOL_ID(method_name_symbol_id)); |
181 } |
188 writer->write((u8)CREATE_SYMBOL_ID(method_sig_symbol_id)); |
182 |
189 writer->write((u2)method->access_flags().get_flags()); |
183 static void do_unloaded_klass(Klass* klass) { |
190 writer->write(const_cast<Method*>(method)->is_hidden() ? (u1)1 : (u1)0); |
|
191 return 1; |
|
192 } |
|
193 |
|
194 int write__artifact__method__leakp(JfrCheckpointWriter* writer, JfrArtifactSet* artifacts, const void* m) { |
|
195 assert(m != NULL, "invariant"); |
|
196 MethodPtr method = (MethodPtr)m; |
|
197 return write__artifact__method(writer, artifacts, method); |
|
198 } |
|
199 |
|
200 int write__artifact__method__serialize(JfrCheckpointWriter* writer, JfrArtifactSet* artifacts, const void* m) { |
|
201 assert(m != NULL, "invariant"); |
|
202 MethodPtr method = (MethodPtr)m; |
|
203 int result = write__artifact__method(writer, artifacts, method); |
|
204 if (METHOD_NOT_SERIALIZED(method)) { |
|
205 SET_METHOD_SERIALIZED(method); |
|
206 } |
|
207 assert(IS_METHOD_SERIALIZED(method), "invariant"); |
|
208 return result; |
|
209 } |
|
210 |
|
211 typedef JfrArtifactWriterImplHost<MethodPtr, write__artifact__method__leakp> LeakpMethodWriterImplTarget; |
|
212 typedef JfrArtifactWriterHost<LeakpMethodWriterImplTarget, TYPE_METHOD> LeakpMethodWriterImpl; |
|
213 typedef SerializePredicate<MethodPtr> MethodPredicate; |
|
214 typedef JfrPredicatedArtifactWriterImplHost<MethodPtr, MethodPredicate, write__artifact__method__serialize> MethodWriterImplTarget; |
|
215 typedef JfrArtifactWriterHost<MethodWriterImplTarget, TYPE_METHOD> MethodWriterImpl; |
|
216 |
|
217 int write__artifact__package(JfrCheckpointWriter* writer, JfrArtifactSet* artifacts, PkgPtr pkg) { |
|
218 assert(writer != NULL, "invariant"); |
|
219 assert(artifacts != NULL, "invariant"); |
|
220 assert(pkg != NULL, "invariant"); |
|
221 Symbol* const pkg_name = pkg->name(); |
|
222 const traceid package_name_symbol_id = pkg_name != NULL ? artifacts->mark(pkg_name) : 0; |
|
223 assert(package_name_symbol_id > 0, "invariant"); |
|
224 writer->write((traceid)TRACE_ID(pkg)); |
|
225 writer->write((traceid)CREATE_SYMBOL_ID(package_name_symbol_id)); |
|
226 writer->write(module_id(pkg)); |
|
227 writer->write((bool)pkg->is_exported()); |
|
228 return 1; |
|
229 } |
|
230 |
|
231 int write__artifact__package__leakp(JfrCheckpointWriter* writer, JfrArtifactSet* artifacts, const void* p) { |
|
232 assert(p != NULL, "invariant"); |
|
233 PkgPtr pkg = (PkgPtr)p; |
|
234 return write__artifact__package(writer, artifacts, pkg); |
|
235 } |
|
236 |
|
237 int write__artifact__package__serialize(JfrCheckpointWriter* writer, JfrArtifactSet* artifacts, const void* p) { |
|
238 assert(p != NULL, "invariant"); |
|
239 PkgPtr pkg = (PkgPtr)p; |
|
240 int result = write__artifact__package(writer, artifacts, pkg); |
|
241 if (IS_NOT_SERIALIZED(pkg)) { |
|
242 SET_SERIALIZED(pkg); |
|
243 } |
|
244 assert(IS_SERIALIZED(pkg), "invariant"); |
|
245 return result; |
|
246 } |
|
247 |
|
248 typedef LeakPredicate<PkgPtr> LeakPackagePredicate; |
|
249 //int _compare_pkg_ptr_(PkgPtr const& lhs, PkgPtr const& rhs) { return lhs > rhs ? 1 : (lhs < rhs) ? -1 : 0; } |
|
250 //typedef UniquePredicate<PkgPtr, _compare_pkg_ptr_> PackagePredicate; |
|
251 typedef SerializePredicate<PkgPtr> PackagePredicate; |
|
252 typedef JfrPredicatedArtifactWriterImplHost<PkgPtr, LeakPackagePredicate, write__artifact__package__leakp> LeakPackageWriterImpl; |
|
253 typedef JfrPredicatedArtifactWriterImplHost<PkgPtr, PackagePredicate, write__artifact__package__serialize> PackageWriterImpl; |
|
254 typedef JfrArtifactWriterHost<LeakPackageWriterImpl, TYPE_PACKAGE> LeakPackageWriter; |
|
255 typedef JfrArtifactWriterHost<PackageWriterImpl, TYPE_PACKAGE> PackageWriter; |
|
256 |
|
257 int write__artifact__module(JfrCheckpointWriter* writer, JfrArtifactSet* artifacts, ModPtr entry) { |
|
258 assert(entry != NULL, "invariant"); |
|
259 Symbol* const module_name = entry->name(); |
|
260 const traceid module_name_symbol_id = module_name != NULL ? artifacts->mark(module_name) : 0; |
|
261 Symbol* const module_version = entry->version(); |
|
262 const traceid module_version_symbol_id = module_version != NULL ? artifacts->mark(module_version) : 0; |
|
263 Symbol* const module_location = entry->location(); |
|
264 const traceid module_location_symbol_id = module_location != NULL ? artifacts->mark(module_location) : 0; |
|
265 writer->write((traceid)TRACE_ID(entry)); |
|
266 writer->write(module_name_symbol_id == 0 ? (traceid)0 : (traceid)CREATE_SYMBOL_ID(module_name_symbol_id)); |
|
267 writer->write(module_version_symbol_id == 0 ? (traceid)0 : (traceid)CREATE_SYMBOL_ID(module_version_symbol_id)); |
|
268 writer->write(module_location_symbol_id == 0 ? (traceid)0 : (traceid)CREATE_SYMBOL_ID(module_location_symbol_id)); |
|
269 writer->write(cld_id(entry->loader_data())); |
|
270 return 1; |
|
271 } |
|
272 |
|
273 int write__artifact__module__leakp(JfrCheckpointWriter* writer, JfrArtifactSet* artifacts, const void* m) { |
|
274 assert(m != NULL, "invariant"); |
|
275 ModPtr entry = (ModPtr)m; |
|
276 return write__artifact__module(writer, artifacts, entry); |
|
277 } |
|
278 |
|
279 int write__artifact__module__serialize(JfrCheckpointWriter* writer, JfrArtifactSet* artifacts, const void* m) { |
|
280 assert(m != NULL, "invariant"); |
|
281 ModPtr entry = (ModPtr)m; |
|
282 int result = write__artifact__module(writer, artifacts, entry); |
|
283 CldPtr cld = entry->loader_data(); |
|
284 assert(cld != NULL, "invariant"); |
|
285 if (IS_NOT_SERIALIZED(cld)) { |
|
286 if (!cld->is_unsafe_anonymous()) { |
|
287 SET_USED_PREV_EPOCH(cld); |
|
288 } |
|
289 } |
|
290 if (IS_NOT_SERIALIZED(entry)) { |
|
291 SET_SERIALIZED(entry); |
|
292 } |
|
293 assert(IS_SERIALIZED(entry), "invariant"); |
|
294 return result; |
|
295 } |
|
296 |
|
297 typedef LeakPredicate<ModPtr> LeakModulePredicate; |
|
298 //int _compare_mod_ptr_(ModPtr const& lhs, ModPtr const& rhs) { return lhs > rhs ? 1 : (lhs < rhs) ? -1 : 0; } |
|
299 //typedef UniquePredicate<ModPtr, _compare_mod_ptr_> ModulePredicate; |
|
300 typedef SerializePredicate<ModPtr> ModulePredicate; |
|
301 typedef JfrPredicatedArtifactWriterImplHost<ModPtr, LeakModulePredicate, write__artifact__module__leakp> LeakModuleWriterImpl; |
|
302 typedef JfrPredicatedArtifactWriterImplHost<ModPtr, ModulePredicate, write__artifact__module__serialize> ModuleWriterImpl; |
|
303 typedef JfrArtifactWriterHost<LeakModuleWriterImpl, TYPE_MODULE> LeakModuleWriter; |
|
304 typedef JfrArtifactWriterHost<ModuleWriterImpl, TYPE_MODULE> ModuleWriter; |
|
305 |
|
306 int write__artifact__classloader(JfrCheckpointWriter* writer, JfrArtifactSet* artifacts, CldPtr cld) { |
|
307 assert(cld != NULL, "invariant"); |
|
308 assert(!cld->is_unsafe_anonymous(), "invariant"); |
|
309 const traceid cld_id = TRACE_ID(cld); |
|
310 // class loader type |
|
311 const Klass* class_loader_klass = cld->class_loader_klass(); |
|
312 if (class_loader_klass == NULL) { |
|
313 // (primordial) boot class loader |
|
314 writer->write(cld_id); // class loader instance id |
|
315 writer->write((traceid)0); // class loader type id (absence of) |
|
316 writer->write((traceid)CREATE_SYMBOL_ID(1)); // 1 maps to synthetic name -> "bootstrap" |
|
317 } else { |
|
318 Symbol* symbol_name = cld->name(); |
|
319 const traceid symbol_name_id = symbol_name != NULL ? artifacts->mark(symbol_name) : 0; |
|
320 writer->write(cld_id); // class loader instance id |
|
321 writer->write(TRACE_ID(class_loader_klass)); // class loader type id |
|
322 writer->write(symbol_name_id == 0 ? (traceid)0 : |
|
323 (traceid)CREATE_SYMBOL_ID(symbol_name_id)); // class loader instance name |
|
324 } |
|
325 return 1; |
|
326 } |
|
327 |
|
328 int write__artifact__classloader__leakp(JfrCheckpointWriter* writer, JfrArtifactSet* artifacts, const void* c) { |
|
329 assert(c != NULL, "invariant"); |
|
330 CldPtr cld = (CldPtr)c; |
|
331 int result = write__artifact__classloader(writer, artifacts, cld); |
|
332 if (IS_NOT_LEAKP_SERIALIZED(cld)) { |
|
333 SET_LEAKP_SERIALIZED(cld); |
|
334 } |
|
335 assert(IS_LEAKP_SERIALIZED(cld), "invariant"); |
|
336 return result; |
|
337 } |
|
338 |
|
339 int write__artifact__classloader__serialize(JfrCheckpointWriter* writer, JfrArtifactSet* artifacts, const void* c) { |
|
340 assert(c != NULL, "invariant"); |
|
341 CldPtr cld = (CldPtr)c; |
|
342 int result = write__artifact__classloader(writer, artifacts, cld); |
|
343 if (IS_NOT_SERIALIZED(cld)) { |
|
344 SET_SERIALIZED(cld); |
|
345 } |
|
346 assert(IS_SERIALIZED(cld), "invariant"); |
|
347 return result; |
|
348 } |
|
349 |
|
350 typedef LeakSerializePredicate<CldPtr> LeakCldPredicate; |
|
351 //int _compare_cld_ptr_(CldPtr const& lhs, CldPtr const& rhs) { return lhs > rhs ? 1 : (lhs < rhs) ? -1 : 0; } |
|
352 //typedef UniquePredicate<CldPtr, _compare_cld_ptr_> CldPredicate; |
|
353 typedef SerializePredicate<CldPtr> CldPredicate; |
|
354 typedef JfrPredicatedArtifactWriterImplHost<CldPtr, LeakCldPredicate, write__artifact__classloader__leakp> LeakCldWriterImpl; |
|
355 typedef JfrPredicatedArtifactWriterImplHost<CldPtr, CldPredicate, write__artifact__classloader__serialize> CldWriterImpl; |
|
356 typedef JfrArtifactWriterHost<LeakCldWriterImpl, TYPE_CLASSLOADER> LeakCldWriter; |
|
357 typedef JfrArtifactWriterHost<CldWriterImpl, TYPE_CLASSLOADER> CldWriter; |
|
358 |
|
359 typedef const JfrSymbolId::SymbolEntry* SymbolEntryPtr; |
|
360 |
|
361 static int write__artifact__symbol__entry__(JfrCheckpointWriter* writer, SymbolEntryPtr entry) { |
|
362 assert(writer != NULL, "invariant"); |
|
363 assert(entry != NULL, "invariant"); |
|
364 ResourceMark rm; |
|
365 writer->write(CREATE_SYMBOL_ID(entry->id())); |
|
366 writer->write(entry->value()->as_C_string()); |
|
367 return 1; |
|
368 } |
|
369 |
|
370 int write__artifact__symbol__entry(JfrCheckpointWriter* writer, JfrArtifactSet* artifacts, const void* e) { |
|
371 assert(e != NULL, "invariant"); |
|
372 return write__artifact__symbol__entry__(writer, (SymbolEntryPtr)e); |
|
373 } |
|
374 |
|
375 typedef JfrArtifactWriterImplHost<SymbolEntryPtr, write__artifact__symbol__entry> SymbolEntryWriterImpl; |
|
376 typedef JfrArtifactWriterHost<SymbolEntryWriterImpl, TYPE_SYMBOL> SymbolEntryWriter; |
|
377 |
|
378 typedef const JfrSymbolId::CStringEntry* CStringEntryPtr; |
|
379 |
|
380 static int write__artifact__cstring__entry__(JfrCheckpointWriter* writer, CStringEntryPtr entry) { |
|
381 assert(writer != NULL, "invariant"); |
|
382 assert(entry != NULL, "invariant"); |
|
383 writer->write(CREATE_SYMBOL_ID(entry->id())); |
|
384 writer->write(entry->value()); |
|
385 return 1; |
|
386 } |
|
387 |
|
388 int write__artifact__cstring__entry(JfrCheckpointWriter* writer, JfrArtifactSet* artifacts, const void* e) { |
|
389 assert(e != NULL, "invariant"); |
|
390 return write__artifact__cstring__entry__(writer, (CStringEntryPtr)e); |
|
391 } |
|
392 |
|
393 typedef JfrArtifactWriterImplHost<CStringEntryPtr, write__artifact__cstring__entry> CStringEntryWriterImpl; |
|
394 typedef JfrArtifactWriterHost<CStringEntryWriterImpl, TYPE_SYMBOL> CStringEntryWriter; |
|
395 |
|
396 int write__artifact__klass__symbol(JfrCheckpointWriter* writer, JfrArtifactSet* artifacts, const void* k) { |
|
397 assert(writer != NULL, "invariant"); |
|
398 assert(artifacts != NULL, "invaiant"); |
|
399 assert(k != NULL, "invariant"); |
|
400 const InstanceKlass* const ik = (const InstanceKlass*)k; |
|
401 if (ik->is_unsafe_anonymous()) { |
|
402 CStringEntryPtr entry = |
|
403 artifacts->map_cstring(JfrSymbolId::unsafe_anonymous_klass_name_hash_code(ik)); |
|
404 assert(entry != NULL, "invariant"); |
|
405 return write__artifact__cstring__entry__(writer, entry); |
|
406 } |
|
407 |
|
408 SymbolEntryPtr entry = artifacts->map_symbol(JfrSymbolId::regular_klass_name_hash_code(ik)); |
|
409 return write__artifact__symbol__entry__(writer, entry); |
|
410 } |
|
411 |
|
412 int _compare_traceid_(const traceid& lhs, const traceid& rhs) { |
|
413 return lhs > rhs ? 1 : (lhs < rhs) ? -1 : 0; |
|
414 } |
|
415 |
|
416 template <template <typename> class Predicate> |
|
417 class KlassSymbolWriterImpl { |
|
418 private: |
|
419 JfrCheckpointWriter* _writer; |
|
420 JfrArtifactSet* _artifacts; |
|
421 Predicate<KlassPtr> _predicate; |
|
422 MethodUsedPredicate<true> _method_used_predicate; |
|
423 MethodFlagPredicate _method_flag_predicate; |
|
424 UniquePredicate<traceid, _compare_traceid_> _unique_predicate; |
|
425 |
|
426 int klass_symbols(KlassPtr klass); |
|
427 int package_symbols(PkgPtr pkg); |
|
428 int module_symbols(ModPtr module); |
|
429 int class_loader_symbols(CldPtr cld); |
|
430 int method_symbols(KlassPtr klass); |
|
431 |
|
432 public: |
|
433 typedef KlassPtr Type; |
|
434 KlassSymbolWriterImpl(JfrCheckpointWriter* writer, |
|
435 JfrArtifactSet* artifacts, |
|
436 bool current_epoch) : _writer(writer), |
|
437 _artifacts(artifacts), |
|
438 _predicate(current_epoch), |
|
439 _method_used_predicate(current_epoch), |
|
440 _method_flag_predicate(current_epoch), |
|
441 _unique_predicate(current_epoch) {} |
|
442 |
|
443 int operator()(KlassPtr klass) { |
|
444 assert(klass != NULL, "invariant"); |
|
445 int count = 0; |
|
446 if (_predicate(klass)) { |
|
447 count += klass_symbols(klass); |
|
448 PkgPtr pkg = klass->package(); |
|
449 if (pkg != NULL) { |
|
450 count += package_symbols(pkg); |
|
451 ModPtr module = pkg->module(); |
|
452 if (module != NULL && module->is_named()) { |
|
453 count += module_symbols(module); |
|
454 } |
|
455 } |
|
456 CldPtr cld = klass->class_loader_data(); |
|
457 assert(cld != NULL, "invariant"); |
|
458 if (!cld->is_unsafe_anonymous()) { |
|
459 count += class_loader_symbols(cld); |
|
460 } |
|
461 if (_method_used_predicate(klass)) { |
|
462 count += method_symbols(klass); |
|
463 } |
|
464 } |
|
465 return count; |
|
466 } |
|
467 }; |
|
468 |
|
469 template <template <typename> class Predicate> |
|
470 int KlassSymbolWriterImpl<Predicate>::klass_symbols(KlassPtr klass) { |
|
471 assert(klass != NULL, "invariant"); |
|
472 assert(_predicate(klass), "invariant"); |
|
473 const InstanceKlass* const ik = (const InstanceKlass*)klass; |
|
474 if (ik->is_unsafe_anonymous()) { |
|
475 CStringEntryPtr entry = |
|
476 this->_artifacts->map_cstring(JfrSymbolId::unsafe_anonymous_klass_name_hash_code(ik)); |
|
477 assert(entry != NULL, "invariant"); |
|
478 return _unique_predicate(entry->id()) ? write__artifact__cstring__entry__(this->_writer, entry) : 0; |
|
479 } |
|
480 SymbolEntryPtr entry = this->_artifacts->map_symbol(ik->name()); |
|
481 assert(entry != NULL, "invariant"); |
|
482 return _unique_predicate(entry->id()) ? write__artifact__symbol__entry__(this->_writer, entry) : 0; |
|
483 } |
|
484 |
|
485 template <template <typename> class Predicate> |
|
486 int KlassSymbolWriterImpl<Predicate>::package_symbols(PkgPtr pkg) { |
|
487 assert(pkg != NULL, "invariant"); |
|
488 SymbolPtr pkg_name = pkg->name(); |
|
489 assert(pkg_name != NULL, "invariant"); |
|
490 SymbolEntryPtr package_symbol = this->_artifacts->map_symbol(pkg_name); |
|
491 assert(package_symbol != NULL, "invariant"); |
|
492 return _unique_predicate(package_symbol->id()) ? write__artifact__symbol__entry__(this->_writer, package_symbol) : 0; |
|
493 } |
|
494 |
|
495 template <template <typename> class Predicate> |
|
496 int KlassSymbolWriterImpl<Predicate>::module_symbols(ModPtr module) { |
|
497 assert(module != NULL, "invariant"); |
|
498 assert(module->is_named(), "invariant"); |
|
499 int count = 0; |
|
500 SymbolPtr sym = module->name(); |
|
501 SymbolEntryPtr entry = NULL; |
|
502 if (sym != NULL) { |
|
503 entry = this->_artifacts->map_symbol(sym); |
|
504 assert(entry != NULL, "invariant"); |
|
505 if (_unique_predicate(entry->id())) { |
|
506 count += write__artifact__symbol__entry__(this->_writer, entry); |
|
507 } |
|
508 } |
|
509 sym = module->version(); |
|
510 if (sym != NULL) { |
|
511 entry = this->_artifacts->map_symbol(sym); |
|
512 assert(entry != NULL, "invariant"); |
|
513 if (_unique_predicate(entry->id())) { |
|
514 count += write__artifact__symbol__entry__(this->_writer, entry); |
|
515 } |
|
516 } |
|
517 sym = module->location(); |
|
518 if (sym != NULL) { |
|
519 entry = this->_artifacts->map_symbol(sym); |
|
520 assert(entry != NULL, "invariant"); |
|
521 if (_unique_predicate(entry->id())) { |
|
522 count += write__artifact__symbol__entry__(this->_writer, entry); |
|
523 } |
|
524 } |
|
525 return count; |
|
526 } |
|
527 |
|
528 template <template <typename> class Predicate> |
|
529 int KlassSymbolWriterImpl<Predicate>::class_loader_symbols(CldPtr cld) { |
|
530 assert(cld != NULL, "invariant"); |
|
531 assert(!cld->is_unsafe_anonymous(), "invariant"); |
|
532 int count = 0; |
|
533 // class loader type |
|
534 const Klass* class_loader_klass = cld->class_loader_klass(); |
|
535 if (class_loader_klass == NULL) { |
|
536 // (primordial) boot class loader |
|
537 CStringEntryPtr entry = this->_artifacts->map_cstring(0); |
|
538 assert(entry != NULL, "invariant"); |
|
539 assert(strncmp(entry->literal(), |
|
540 BOOTSTRAP_LOADER_NAME, |
|
541 BOOTSTRAP_LOADER_NAME_LEN) == 0, "invariant"); |
|
542 if (_unique_predicate(entry->id())) { |
|
543 count += write__artifact__cstring__entry__(this->_writer, entry); |
|
544 } |
|
545 } else { |
|
546 const Symbol* class_loader_name = cld->name(); |
|
547 if (class_loader_name != NULL) { |
|
548 SymbolEntryPtr entry = this->_artifacts->map_symbol(class_loader_name); |
|
549 assert(entry != NULL, "invariant"); |
|
550 if (_unique_predicate(entry->id())) { |
|
551 count += write__artifact__symbol__entry__(this->_writer, entry); |
|
552 } |
|
553 } |
|
554 } |
|
555 return count; |
|
556 } |
|
557 |
|
558 template <template <typename> class Predicate> |
|
559 int KlassSymbolWriterImpl<Predicate>::method_symbols(KlassPtr klass) { |
|
560 assert(_predicate(klass), "invariant"); |
|
561 assert(_method_used_predicate(klass), "invariant"); |
|
562 assert(METHOD_AND_CLASS_USED_ANY_EPOCH(klass), "invariant"); |
|
563 int count = 0; |
|
564 const InstanceKlass* const ik = InstanceKlass::cast(klass); |
|
565 const int len = ik->methods()->length(); |
|
566 for (int i = 0; i < len; ++i) { |
|
567 MethodPtr method = ik->methods()->at(i); |
|
568 if (_method_flag_predicate(method)) { |
|
569 SymbolEntryPtr entry = this->_artifacts->map_symbol(method->name()); |
|
570 assert(entry != NULL, "invariant"); |
|
571 if (_unique_predicate(entry->id())) { |
|
572 count += write__artifact__symbol__entry__(this->_writer, entry); |
|
573 } |
|
574 entry = this->_artifacts->map_symbol(method->signature()); |
|
575 assert(entry != NULL, "invariant"); |
|
576 if (_unique_predicate(entry->id())) { |
|
577 count += write__artifact__symbol__entry__(this->_writer, entry); |
|
578 } |
|
579 } |
|
580 } |
|
581 return count; |
|
582 } |
|
583 |
|
584 typedef KlassSymbolWriterImpl<LeakPredicate> LeakKlassSymbolWriterImpl; |
|
585 typedef JfrArtifactWriterHost<LeakKlassSymbolWriterImpl, TYPE_SYMBOL> LeakKlassSymbolWriter; |
|
586 |
|
587 class ClearKlassAndMethods { |
|
588 private: |
|
589 ClearArtifact<KlassPtr> _clear_klass_tag_bits; |
|
590 ClearArtifact<MethodPtr> _clear_method_flag; |
|
591 MethodUsedPredicate<false> _method_used_predicate; |
|
592 |
|
593 public: |
|
594 ClearKlassAndMethods(bool current_epoch) : _method_used_predicate(current_epoch) {} |
|
595 bool operator()(KlassPtr klass) { |
|
596 if (_method_used_predicate(klass)) { |
|
597 const InstanceKlass* ik = InstanceKlass::cast(klass); |
|
598 const int len = ik->methods()->length(); |
|
599 for (int i = 0; i < len; ++i) { |
|
600 MethodPtr method = ik->methods()->at(i); |
|
601 _clear_method_flag(method); |
|
602 } |
|
603 } |
|
604 _clear_klass_tag_bits(klass); |
|
605 return true; |
|
606 } |
|
607 }; |
|
608 |
|
609 typedef CompositeFunctor<KlassPtr, |
|
610 TagLeakpKlassArtifact, |
|
611 LeakKlassWriter> LeakpKlassArtifactTagging; |
|
612 |
|
613 typedef CompositeFunctor<KlassPtr, |
|
614 LeakpKlassArtifactTagging, |
|
615 KlassWriter> CompositeKlassWriter; |
|
616 |
|
617 typedef CompositeFunctor<KlassPtr, |
|
618 CompositeKlassWriter, |
|
619 KlassArtifactRegistrator> CompositeKlassWriterRegistration; |
|
620 |
|
621 typedef CompositeFunctor<KlassPtr, |
|
622 KlassWriter, |
|
623 KlassArtifactRegistrator> KlassWriterRegistration; |
|
624 |
|
625 typedef JfrArtifactCallbackHost<KlassPtr, KlassWriterRegistration> KlassCallback; |
|
626 typedef JfrArtifactCallbackHost<KlassPtr, CompositeKlassWriterRegistration> CompositeKlassCallback; |
|
627 |
|
628 /* |
|
629 * Composite operation |
|
630 * |
|
631 * TagLeakpKlassArtifact -> |
|
632 * LeakpPredicate -> |
|
633 * LeakpKlassWriter -> |
|
634 * KlassPredicate -> |
|
635 * KlassWriter -> |
|
636 * KlassWriterRegistration |
|
637 */ |
|
638 void JfrTypeSet::write_klass_constants(JfrCheckpointWriter* writer, JfrCheckpointWriter* leakp_writer) { |
|
639 assert(!_artifacts->has_klass_entries(), "invariant"); |
|
640 KlassArtifactRegistrator reg(_artifacts); |
|
641 KlassWriter kw(writer, _artifacts, current_epoch()); |
|
642 KlassWriterRegistration kwr(&kw, ®); |
|
643 if (leakp_writer == NULL) { |
|
644 KlassCallback callback(&kwr); |
|
645 _subsystem_callback = &callback; |
|
646 do_klasses(); |
|
647 _artifacts->tally(kw); |
|
648 return; |
|
649 } |
|
650 TagLeakpKlassArtifact tagging(current_epoch()); |
|
651 LeakKlassWriter lkw(leakp_writer, _artifacts, current_epoch()); |
|
652 LeakpKlassArtifactTagging lpkat(&tagging, &lkw); |
|
653 CompositeKlassWriter ckw(&lpkat, &kw); |
|
654 CompositeKlassWriterRegistration ckwr(&ckw, ®); |
|
655 CompositeKlassCallback callback(&ckwr); |
|
656 _subsystem_callback = &callback; |
|
657 do_klasses(); |
|
658 } |
|
659 |
|
660 typedef CompositeFunctor<PkgPtr, |
|
661 PackageWriter, |
|
662 ClearArtifact<PkgPtr> > PackageWriterWithClear; |
|
663 |
|
664 typedef CompositeFunctor<PkgPtr, |
|
665 PackageWriter, |
|
666 UnTagArtifact<PkgPtr> > PackageWriterWithUnTag; |
|
667 typedef CompositeFunctor<PkgPtr, |
|
668 LeakPackageWriter, |
|
669 PackageWriter> CompositePackageWriter; |
|
670 |
|
671 typedef CompositeFunctor<PkgPtr, |
|
672 CompositePackageWriter, |
|
673 ClearArtifact<PkgPtr> > CompositePackageWriterWithClear; |
|
674 typedef CompositeFunctor<PkgPtr, |
|
675 CompositePackageWriter, |
|
676 UnTagArtifact<PkgPtr> > CompositePackageWriterWithUnTag; |
|
677 |
|
678 class PackageFieldSelector { |
|
679 public: |
|
680 typedef PkgPtr TypePtr; |
|
681 static TypePtr select(KlassPtr klass) { |
|
682 assert(klass != NULL, "invariant"); |
|
683 return ((InstanceKlass*)klass)->package(); |
|
684 } |
|
685 }; |
|
686 |
|
687 typedef KlassToFieldEnvelope<PackageFieldSelector, |
|
688 PackageWriterWithClear> KlassPackageWriterWithClear; |
|
689 |
|
690 typedef KlassToFieldEnvelope<PackageFieldSelector, |
|
691 PackageWriterWithUnTag> KlassPackageWriterWithUnTag; |
|
692 typedef KlassToFieldEnvelope<PackageFieldSelector, PackageWriter> KlassPackageWriter; |
|
693 typedef KlassToFieldEnvelope<PackageFieldSelector, CompositePackageWriter> KlassCompositePackageWriter; |
|
694 typedef KlassToFieldEnvelope<PackageFieldSelector, |
|
695 CompositePackageWriterWithClear> KlassCompositePackageWriterWithClear; |
|
696 |
|
697 typedef KlassToFieldEnvelope<PackageFieldSelector, |
|
698 CompositePackageWriterWithUnTag> KlassCompositePackageWriterWithUnTag; |
|
699 typedef JfrArtifactCallbackHost<PkgPtr, PackageWriterWithClear> PackageCallback; |
|
700 typedef JfrArtifactCallbackHost<PkgPtr, CompositePackageWriterWithClear> CompositePackageCallback; |
|
701 |
|
702 static void write_package_constants_current_epoch(JfrArtifactSet* artifacts, JfrCheckpointWriter* writer, JfrCheckpointWriter* leakp_writer) { |
|
703 assert(artifacts != NULL, "invariant"); |
|
704 assert(artifacts->has_klass_entries(), "invariant"); |
|
705 PackageWriter pw(writer, artifacts, true); |
|
706 if (leakp_writer == NULL) { |
|
707 KlassPackageWriter kpw(&pw); |
|
708 artifacts->iterate_klasses(kpw); |
|
709 artifacts->tally(pw); |
|
710 } else { |
|
711 LeakPackageWriter lpw(leakp_writer, artifacts, true); |
|
712 CompositePackageWriter cpw(&lpw, &pw); |
|
713 KlassCompositePackageWriter kcpw(&cpw); |
|
714 artifacts->iterate_klasses(kcpw); |
|
715 } |
|
716 } |
|
717 |
|
718 /* |
|
719 * Composite operation |
|
720 * |
|
721 * LeakpPackageWriter -> |
|
722 * PackageWriter -> |
|
723 * ClearArtifact<PackageEntry> |
|
724 * |
|
725 */ |
|
726 void JfrTypeSet::write_package_constants(JfrCheckpointWriter* writer, JfrCheckpointWriter* leakp_writer) { |
|
727 assert(_artifacts->has_klass_entries(), "invariant"); |
|
728 if (current_epoch()) { |
|
729 write_package_constants_current_epoch(_artifacts, writer, leakp_writer); |
|
730 return; |
|
731 } |
|
732 assert(is_rotating(), "invariant"); |
|
733 PackageWriter pw(writer, _artifacts, false); |
|
734 ClearArtifact<PkgPtr> clear; |
|
735 UnTagArtifact<PkgPtr> untag; |
|
736 if (leakp_writer == NULL) { |
|
737 PackageWriterWithUnTag kpw(&pw, &untag); |
|
738 KlassPackageWriterWithUnTag kpwwut(&kpw); |
|
739 _artifacts->iterate_klasses(kpwwut); |
|
740 PackageWriterWithClear pwwc(&pw, &clear); |
|
741 PackageCallback callback(&pwwc); |
|
742 _subsystem_callback = &callback; |
|
743 do_packages(); |
|
744 return; |
|
745 } |
|
746 LeakPackageWriter lpw(leakp_writer, _artifacts, false); |
|
747 CompositePackageWriter cpw(&lpw, &pw); |
|
748 CompositePackageWriterWithUnTag cpwwut(&cpw, &untag); |
|
749 KlassCompositePackageWriterWithUnTag kcpw(&cpwwut); |
|
750 _artifacts->iterate_klasses(kcpw); |
|
751 CompositePackageWriterWithClear cpwwc(&cpw, &clear); |
|
752 CompositePackageCallback callback(&cpwwc); |
|
753 _subsystem_callback = &callback; |
|
754 do_packages(); |
|
755 } |
|
756 |
|
757 typedef CompositeFunctor<ModPtr, |
|
758 ModuleWriter, |
|
759 ClearArtifact<ModPtr> > ModuleWriterWithClear; |
|
760 |
|
761 typedef CompositeFunctor<ModPtr, |
|
762 ModuleWriter, |
|
763 UnTagArtifact<ModPtr> > ModuleWriterWithUnTag; |
|
764 typedef CompositeFunctor<ModPtr, |
|
765 LeakModuleWriter, |
|
766 ModuleWriter> CompositeModuleWriter; |
|
767 |
|
768 typedef CompositeFunctor<ModPtr, |
|
769 CompositeModuleWriter, |
|
770 ClearArtifact<ModPtr> > CompositeModuleWriterWithClear; |
|
771 typedef CompositeFunctor<ModPtr, |
|
772 CompositeModuleWriter, |
|
773 UnTagArtifact<ModPtr> > CompositeModuleWriterWithUnTag; |
|
774 |
|
775 typedef JfrArtifactCallbackHost<ModPtr, ModuleWriterWithClear> ModuleCallback; |
|
776 typedef JfrArtifactCallbackHost<ModPtr, CompositeModuleWriterWithClear> CompositeModuleCallback; |
|
777 |
|
778 class ModuleFieldSelector { |
|
779 public: |
|
780 typedef ModPtr TypePtr; |
|
781 static TypePtr select(KlassPtr klass) { |
|
782 assert(klass != NULL, "invariant"); |
|
783 PkgPtr pkg = klass->package(); |
|
784 return pkg != NULL ? pkg->module() : NULL; |
|
785 } |
|
786 }; |
|
787 |
|
788 typedef KlassToFieldEnvelope<ModuleFieldSelector, |
|
789 ModuleWriterWithClear> KlassModuleWriterWithClear; |
|
790 |
|
791 typedef KlassToFieldEnvelope<ModuleFieldSelector, |
|
792 ModuleWriterWithUnTag> KlassModuleWriterWithUnTag; |
|
793 typedef KlassToFieldEnvelope<ModuleFieldSelector, ModuleWriter> KlassModuleWriter; |
|
794 typedef KlassToFieldEnvelope<ModuleFieldSelector, CompositeModuleWriter> KlassCompositeModuleWriter; |
|
795 typedef KlassToFieldEnvelope<ModuleFieldSelector, |
|
796 CompositeModuleWriterWithClear> KlassCompositeModuleWriterWithClear; |
|
797 |
|
798 typedef KlassToFieldEnvelope<ModuleFieldSelector, |
|
799 CompositeModuleWriterWithUnTag> KlassCompositeModuleWriterWithUnTag; |
|
800 |
|
801 static void write_module_constants_current_epoch(JfrArtifactSet* artifacts, JfrCheckpointWriter* writer, JfrCheckpointWriter* leakp_writer) { |
|
802 assert(artifacts != NULL, "invariant"); |
|
803 assert(artifacts->has_klass_entries(), "invariant"); |
|
804 ModuleWriter mw(writer, artifacts, true); |
|
805 if (leakp_writer == NULL) { |
|
806 KlassModuleWriter kmw(&mw); |
|
807 artifacts->iterate_klasses(kmw); |
|
808 artifacts->tally(mw); |
|
809 } else { |
|
810 LeakModuleWriter lmw(leakp_writer, artifacts, true); |
|
811 CompositeModuleWriter cmw(&lmw, &mw); |
|
812 KlassCompositeModuleWriter kcmw(&cmw); |
|
813 artifacts->iterate_klasses(kcmw); |
|
814 } |
|
815 } |
|
816 |
|
817 /* |
|
818 * Composite operation |
|
819 * |
|
820 * LeakpModuleWriter -> |
|
821 * ModuleWriter -> |
|
822 * ClearArtifact<ModuleEntry> |
|
823 */ |
|
824 void JfrTypeSet::write_module_constants(JfrCheckpointWriter* writer, JfrCheckpointWriter* leakp_writer) { |
|
825 assert(_artifacts->has_klass_entries(), "invariant"); |
|
826 if (current_epoch()) { |
|
827 write_module_constants_current_epoch(_artifacts, writer, leakp_writer); |
|
828 return; |
|
829 } |
|
830 assert(is_rotating(), "invariant"); |
|
831 ClearArtifact<ModPtr> clear; |
|
832 UnTagArtifact<ModPtr> untag; |
|
833 ModuleWriter mw(writer, _artifacts, false); |
|
834 if (leakp_writer == NULL) { |
|
835 ModuleWriterWithUnTag kpw(&mw, &untag); |
|
836 KlassModuleWriterWithUnTag kmwwut(&kpw); |
|
837 _artifacts->iterate_klasses(kmwwut); |
|
838 ModuleWriterWithClear mwwc(&mw, &clear); |
|
839 ModuleCallback callback(&mwwc); |
|
840 _subsystem_callback = &callback; |
|
841 do_modules(); |
|
842 return; |
|
843 } |
|
844 LeakModuleWriter lmw(leakp_writer, _artifacts, false); |
|
845 CompositeModuleWriter cmw(&lmw, &mw); |
|
846 CompositeModuleWriterWithUnTag cmwwut(&cmw, &untag); |
|
847 KlassCompositeModuleWriterWithUnTag kcmw(&cmwwut); |
|
848 _artifacts->iterate_klasses(kcmw); |
|
849 CompositeModuleWriterWithClear cmwwc(&cmw, &clear); |
|
850 CompositeModuleCallback callback(&cmwwc); |
|
851 _subsystem_callback = &callback; |
|
852 do_modules(); |
|
853 } |
|
854 |
|
855 typedef CompositeFunctor<CldPtr, CldWriter, ClearArtifact<CldPtr> > CldWriterWithClear; |
|
856 typedef CompositeFunctor<CldPtr, CldWriter, UnTagArtifact<CldPtr> > CldWriterWithUnTag; |
|
857 typedef CompositeFunctor<CldPtr, LeakCldWriter, CldWriter> CompositeCldWriter; |
|
858 typedef CompositeFunctor<CldPtr, CompositeCldWriter, ClearArtifact<CldPtr> > CompositeCldWriterWithClear; |
|
859 typedef CompositeFunctor<CldPtr, CompositeCldWriter, UnTagArtifact<CldPtr> > CompositeCldWriterWithUnTag; |
|
860 typedef JfrArtifactCallbackHost<CldPtr, CldWriterWithClear> CldCallback; |
|
861 typedef JfrArtifactCallbackHost<CldPtr, CompositeCldWriterWithClear> CompositeCldCallback; |
|
862 |
|
863 class CldFieldSelector { |
|
864 public: |
|
865 typedef CldPtr TypePtr; |
|
866 static TypePtr select(KlassPtr klass) { |
|
867 assert(klass != NULL, "invariant"); |
|
868 CldPtr cld = klass->class_loader_data(); |
|
869 return cld->is_unsafe_anonymous() ? NULL : cld; |
|
870 } |
|
871 }; |
|
872 |
|
873 typedef KlassToFieldEnvelope<CldFieldSelector, CldWriter> KlassCldWriter; |
|
874 typedef KlassToFieldEnvelope<CldFieldSelector, CldWriterWithClear> KlassCldWriterWithClear; |
|
875 typedef KlassToFieldEnvelope<CldFieldSelector, CldWriterWithUnTag> KlassCldWriterWithUnTag; |
|
876 typedef KlassToFieldEnvelope<CldFieldSelector, CompositeCldWriter> KlassCompositeCldWriter; |
|
877 typedef KlassToFieldEnvelope<CldFieldSelector, CompositeCldWriterWithClear> KlassCompositeCldWriterWithClear; |
|
878 typedef KlassToFieldEnvelope<CldFieldSelector, CompositeCldWriterWithUnTag> KlassCompositeCldWriterWithUnTag; |
|
879 |
|
880 static void write_class_loader_constants_current_epoch(JfrArtifactSet* artifacts, JfrCheckpointWriter* writer, JfrCheckpointWriter* leakp_writer) { |
|
881 assert(artifacts != NULL, "invariant"); |
|
882 assert(artifacts->has_klass_entries(), "invariant"); |
|
883 CldWriter cldw(writer, artifacts, true); |
|
884 if (leakp_writer == NULL) { |
|
885 KlassCldWriter kcw(&cldw); |
|
886 artifacts->iterate_klasses(kcw); |
|
887 artifacts->tally(cldw); |
|
888 } else { |
|
889 LeakCldWriter lcldw(leakp_writer, artifacts, true); |
|
890 CompositeCldWriter ccldw(&lcldw, &cldw); |
|
891 KlassCompositeCldWriter kccldw(&ccldw); |
|
892 artifacts->iterate_klasses(kccldw); |
|
893 } |
|
894 } |
|
895 |
|
896 /* |
|
897 * Composite operation |
|
898 * |
|
899 * LeakpClassLoaderWriter -> |
|
900 * ClassLoaderWriter -> |
|
901 * ClearArtifact<ClassLoaderData> |
|
902 */ |
|
903 void JfrTypeSet::write_class_loader_constants(JfrCheckpointWriter* writer, JfrCheckpointWriter* leakp_writer) { |
|
904 assert(_artifacts->has_klass_entries(), "invariant"); |
|
905 if (current_epoch()) { |
|
906 write_class_loader_constants_current_epoch(_artifacts, writer, leakp_writer); |
|
907 return; |
|
908 } |
|
909 assert(is_rotating(), "invariant"); |
|
910 ClearArtifact<CldPtr> clear; |
|
911 UnTagArtifact<CldPtr> untag; |
|
912 CldWriter cldw(writer, _artifacts, false); |
|
913 if (leakp_writer == NULL) { |
|
914 CldWriterWithUnTag cldwut(&cldw, &untag); |
|
915 KlassCldWriterWithUnTag kcldwut(&cldwut); |
|
916 _artifacts->iterate_klasses(kcldwut); |
|
917 CldWriterWithClear cldwwc(&cldw, &clear); |
|
918 CldCallback callback(&cldwwc); |
|
919 _subsystem_callback = &callback; |
|
920 do_class_loaders(); |
|
921 return; |
|
922 } |
|
923 LeakCldWriter lcldw(leakp_writer, _artifacts, false); |
|
924 CompositeCldWriter ccldw(&lcldw, &cldw); |
|
925 CompositeCldWriterWithUnTag cldwwut(&ccldw, &untag); |
|
926 KlassCompositeCldWriterWithUnTag kccldw(&cldwwut); |
|
927 _artifacts->iterate_klasses(kccldw); |
|
928 CompositeCldWriterWithClear ccldwwc(&ccldw, &clear); |
|
929 CompositeCldCallback callback(&ccldwwc); |
|
930 _subsystem_callback = &callback; |
|
931 do_class_loaders(); |
|
932 } |
|
933 |
|
934 template <bool predicate_bool, typename MethodFunctor> |
|
935 class MethodIteratorHost { |
|
936 private: |
|
937 MethodFunctor _method_functor; |
|
938 MethodUsedPredicate<predicate_bool> _method_used_predicate; |
|
939 MethodFlagPredicate _method_flag_predicate; |
|
940 |
|
941 public: |
|
942 MethodIteratorHost(JfrCheckpointWriter* writer, |
|
943 JfrArtifactSet* artifacts, |
|
944 bool current_epoch, |
|
945 bool skip_header = false) : |
|
946 _method_functor(writer, artifacts, current_epoch, skip_header), |
|
947 _method_used_predicate(current_epoch), |
|
948 _method_flag_predicate(current_epoch) {} |
|
949 |
|
950 bool operator()(KlassPtr klass) { |
|
951 if (_method_used_predicate(klass)) { |
|
952 assert(METHOD_AND_CLASS_USED_ANY_EPOCH(klass), "invariant"); |
|
953 const InstanceKlass* ik = InstanceKlass::cast(klass); |
|
954 const int len = ik->methods()->length(); |
|
955 for (int i = 0; i < len; ++i) { |
|
956 MethodPtr method = ik->methods()->at(i); |
|
957 if (_method_flag_predicate(method)) { |
|
958 _method_functor(method); |
|
959 } |
|
960 } |
|
961 } |
|
962 return true; |
|
963 } |
|
964 |
|
965 int count() const { return _method_functor.count(); } |
|
966 void add(int count) { _method_functor.add(count); } |
|
967 }; |
|
968 |
|
969 typedef MethodIteratorHost<true /*leakp */, LeakpMethodWriterImpl> LeakMethodWriter; |
|
970 typedef MethodIteratorHost<false, MethodWriterImpl> MethodWriter; |
|
971 typedef CompositeFunctor<KlassPtr, LeakMethodWriter, MethodWriter> CompositeMethodWriter; |
|
972 |
|
973 /* |
|
974 * Composite operation |
|
975 * |
|
976 * LeakpMethodWriter -> |
|
977 * MethodWriter |
|
978 */ |
|
979 void JfrTypeSet::write_method_constants(JfrCheckpointWriter* writer, JfrCheckpointWriter* leakp_writer) { |
|
980 assert(_artifacts->has_klass_entries(), "invariant"); |
|
981 MethodWriter mw(writer, _artifacts, is_not_rotating()); |
|
982 if (leakp_writer == NULL) { |
|
983 _artifacts->iterate_klasses(mw); |
|
984 _artifacts->tally(mw); |
|
985 return; |
|
986 } |
|
987 LeakMethodWriter lpmw(leakp_writer, _artifacts, is_not_rotating()); |
|
988 CompositeMethodWriter cmw(&lpmw, &mw); |
|
989 _artifacts->iterate_klasses(cmw); |
|
990 } |
|
991 |
|
992 static void write_symbols_leakp(JfrCheckpointWriter* leakp_writer, JfrArtifactSet* artifacts, bool current_epoch) { |
|
993 assert(leakp_writer != NULL, "invariant"); |
|
994 assert(artifacts != NULL, "invariant"); |
|
995 LeakKlassSymbolWriter lpksw(leakp_writer, artifacts, current_epoch); |
|
996 artifacts->iterate_klasses(lpksw); |
|
997 } |
|
998 |
|
999 static void write_symbols(JfrCheckpointWriter* writer, JfrCheckpointWriter* leakp_writer, JfrArtifactSet* artifacts, bool current_epoch) { |
|
1000 assert(writer != NULL, "invariant"); |
|
1001 assert(artifacts != NULL, "invariant"); |
|
1002 if (leakp_writer != NULL) { |
|
1003 write_symbols_leakp(leakp_writer, artifacts, current_epoch); |
|
1004 } |
|
1005 // iterate all registered symbols |
|
1006 SymbolEntryWriter symbol_writer(writer, artifacts, current_epoch); |
|
1007 artifacts->iterate_symbols(symbol_writer); |
|
1008 CStringEntryWriter cstring_writer(writer, artifacts, current_epoch, true); // skip header |
|
1009 artifacts->iterate_cstrings(cstring_writer); |
|
1010 symbol_writer.add(cstring_writer.count()); |
|
1011 artifacts->tally(symbol_writer); |
|
1012 } |
|
1013 |
|
1014 bool JfrTypeSet::_class_unload = false; |
|
1015 bool JfrTypeSet::_flushpoint = false; |
|
1016 JfrArtifactSet* JfrTypeSet::_artifacts = NULL; |
|
1017 JfrArtifactClosure* JfrTypeSet::_subsystem_callback = NULL; |
|
1018 |
|
1019 bool JfrTypeSet::is_rotating() { |
|
1020 return !(_class_unload || _flushpoint); |
|
1021 } |
|
1022 |
|
1023 bool JfrTypeSet::is_not_rotating() { |
|
1024 return !is_rotating(); |
|
1025 } |
|
1026 |
|
1027 bool JfrTypeSet::current_epoch() { |
|
1028 return is_not_rotating(); |
|
1029 } |
|
1030 |
|
1031 void JfrTypeSet::write_symbol_constants(JfrCheckpointWriter* writer, JfrCheckpointWriter* leakp_writer) { |
|
1032 assert(writer != NULL, "invariant"); |
|
1033 assert(_artifacts->has_klass_entries(), "invariant"); |
|
1034 write_symbols(writer, leakp_writer, _artifacts, _class_unload); |
|
1035 } |
|
1036 |
|
1037 void JfrTypeSet::do_unloaded_klass(Klass* klass) { |
|
1038 assert(klass != NULL, "invariant"); |
184 assert(klass != NULL, "invariant"); |
1039 assert(_subsystem_callback != NULL, "invariant"); |
185 assert(_subsystem_callback != NULL, "invariant"); |
1040 if (IS_JDK_JFR_EVENT_SUBKLASS(klass)) { |
186 if (IS_JDK_JFR_EVENT_SUBKLASS(klass)) { |
1041 JfrEventClasses::increment_unloaded_event_class(); |
187 JfrEventClasses::increment_unloaded_event_class(); |
1042 } |
188 } |
1043 if (USED_THIS_EPOCH(klass)) { // includes leakp subset |
189 if (USED_THIS_EPOCH(klass)) { |
|
190 ObjectSampleCheckpoint::on_klass_unload(klass); |
1044 _subsystem_callback->do_artifact(klass); |
191 _subsystem_callback->do_artifact(klass); |
1045 return; |
192 return; |
1046 } |
193 } |
1047 if (klass->is_subclass_of(SystemDictionary::ClassLoader_klass()) || klass == SystemDictionary::Object_klass()) { |
194 do_implied(klass); |
1048 SET_LEAKP_USED_THIS_EPOCH(klass); // tag leakp "safe byte" for subset inclusion |
195 } |
1049 _subsystem_callback->do_artifact(klass); |
196 |
1050 } |
197 static void do_klass(Klass* klass) { |
1051 } |
|
1052 |
|
1053 void JfrTypeSet::do_klass(Klass* klass) { |
|
1054 assert(klass != NULL, "invariant"); |
198 assert(klass != NULL, "invariant"); |
1055 assert(_subsystem_callback != NULL, "invariant"); |
199 assert(_subsystem_callback != NULL, "invariant"); |
1056 if (_flushpoint) { |
200 if (_flushpoint) { |
1057 if (USED_THIS_EPOCH(klass)) { |
201 if (USED_THIS_EPOCH(klass)) { |
1058 _subsystem_callback->do_artifact(klass); |
202 _subsystem_callback->do_artifact(klass); |
1059 return; |
203 return; |
1060 } |
204 } |
1061 } else { |
205 } else { |
1062 if (USED_PREV_EPOCH(klass)) { // includes leakp subset |
206 if (USED_PREV_EPOCH(klass)) { |
1063 _subsystem_callback->do_artifact(klass); |
207 _subsystem_callback->do_artifact(klass); |
1064 return; |
208 return; |
1065 } |
209 } |
1066 } |
210 } |
1067 if (klass->is_subclass_of(SystemDictionary::ClassLoader_klass()) || klass == SystemDictionary::Object_klass()) { |
211 do_implied(klass); |
1068 if (_flushpoint) { |
212 } |
1069 SET_LEAKP_USED_THIS_EPOCH(klass); |
213 |
1070 } else { |
214 static void do_klasses() { |
1071 SET_LEAKP_USED_PREV_EPOCH(klass); // tag leakp "safe byte" for subset inclusion |
|
1072 } |
|
1073 _subsystem_callback->do_artifact(klass); |
|
1074 } |
|
1075 } |
|
1076 |
|
1077 void JfrTypeSet::do_klasses() { |
|
1078 if (_class_unload) { |
215 if (_class_unload) { |
1079 ClassLoaderDataGraph::classes_unloading_do(&do_unloaded_klass); |
216 ClassLoaderDataGraph::classes_unloading_do(&do_unloaded_klass); |
1080 return; |
217 return; |
1081 } |
218 } |
1082 ClassLoaderDataGraph::classes_do(&do_klass); |
219 ClassLoaderDataGraph::classes_do(&do_klass); |
1083 } |
220 } |
1084 |
221 |
1085 template <typename T> |
222 typedef SerializePredicate<KlassPtr> KlassPredicate; |
1086 static void do_current_epoch_artifact(JfrArtifactClosure* callback, T* value) { |
223 typedef JfrPredicatedTypeWriterImplHost<KlassPtr, KlassPredicate, write__klass> KlassWriterImpl; |
1087 assert(callback != NULL, "invariant"); |
224 typedef JfrTypeWriterHost<KlassWriterImpl, TYPE_CLASS> KlassWriter; |
1088 assert(value != NULL, "invariant"); |
225 typedef CompositeFunctor<KlassPtr, KlassWriter, KlassArtifactRegistrator> KlassWriterRegistration; |
1089 if (ANY_USED_THIS_EPOCH(value)) { // includes leakp subset |
226 typedef JfrArtifactCallbackHost<KlassPtr, KlassWriterRegistration> KlassCallback; |
1090 callback->do_artifact(value); |
227 |
1091 } |
228 static bool write_klasses() { |
|
229 assert(!_artifacts->has_klass_entries(), "invariant"); |
|
230 assert(_writer != NULL, "invariant"); |
|
231 KlassArtifactRegistrator reg(_artifacts); |
|
232 KlassWriter kw(_writer, _class_unload); |
|
233 KlassWriterRegistration kwr(&kw, ®); |
|
234 KlassCallback callback(&kwr); |
|
235 _subsystem_callback = &callback; |
|
236 do_klasses(); |
|
237 if (is_complete()) { |
|
238 return false; |
|
239 } |
|
240 _artifacts->tally(kw); |
|
241 return true; |
1092 } |
242 } |
1093 |
243 |
1094 template <typename T> |
244 template <typename T> |
1095 static void do_previous_epoch_artifact(JfrArtifactClosure* callback, T* value) { |
245 static void do_previous_epoch_artifact(JfrArtifactClosure* callback, T* value) { |
1096 assert(callback != NULL, "invariant"); |
246 assert(callback != NULL, "invariant"); |
1097 assert(value != NULL, "invariant"); |
247 assert(value != NULL, "invariant"); |
1098 if (ANY_USED_PREV_EPOCH(value)) { // includes leakp subset |
248 if (USED_PREV_EPOCH(value)) { |
1099 callback->do_artifact(value); |
249 callback->do_artifact(value); |
1100 assert(IS_NOT_SERIALIZED(value), "invariant"); |
250 assert(IS_NOT_SERIALIZED(value), "invariant"); |
1101 return; |
251 return; |
1102 } |
252 } |
1103 if (IS_SERIALIZED(value)) { |
253 if (IS_SERIALIZED(value)) { |
1104 UNSERIALIZE(value); |
254 CLEAR_SERIALIZED(value); |
1105 } |
255 } |
1106 assert(IS_NOT_SERIALIZED(value), "invariant"); |
256 assert(IS_NOT_SERIALIZED(value), "invariant"); |
1107 } |
257 } |
1108 void JfrTypeSet::do_unloaded_package(PackageEntry* entry) { |
258 |
1109 do_current_epoch_artifact(_subsystem_callback, entry); |
259 int write__package(JfrCheckpointWriter* writer, const void* p) { |
1110 } |
260 assert(writer != NULL, "invariant"); |
1111 |
261 assert(_artifacts != NULL, "invariant"); |
1112 void JfrTypeSet::do_package(PackageEntry* entry) { |
262 assert(p != NULL, "invariant"); |
|
263 PkgPtr pkg = (PkgPtr)p; |
|
264 writer->write(artifact_id(pkg)); |
|
265 writer->write(mark_symbol(pkg->name())); |
|
266 writer->write(module_id(pkg)); |
|
267 writer->write((bool)pkg->is_exported()); |
|
268 set_serialized(pkg); |
|
269 return 1; |
|
270 } |
|
271 |
|
272 static void do_package(PackageEntry* entry) { |
1113 do_previous_epoch_artifact(_subsystem_callback, entry); |
273 do_previous_epoch_artifact(_subsystem_callback, entry); |
1114 } |
274 } |
1115 |
275 |
1116 void JfrTypeSet::do_packages() { |
276 static void do_packages() { |
1117 if (_class_unload) { |
|
1118 ClassLoaderDataGraph::packages_unloading_do(&do_unloaded_package); |
|
1119 return; |
|
1120 } |
|
1121 ClassLoaderDataGraph::packages_do(&do_package); |
277 ClassLoaderDataGraph::packages_do(&do_package); |
1122 } |
278 } |
1123 |
279 |
1124 void JfrTypeSet::do_unloaded_module(ModuleEntry* entry) { |
280 class PackageFieldSelector { |
1125 do_current_epoch_artifact(_subsystem_callback, entry); |
281 public: |
1126 } |
282 typedef PkgPtr TypePtr; |
1127 |
283 static TypePtr select(KlassPtr klass) { |
1128 void JfrTypeSet::do_module(ModuleEntry* entry) { |
284 assert(klass != NULL, "invariant"); |
|
285 return ((InstanceKlass*)klass)->package(); |
|
286 } |
|
287 }; |
|
288 |
|
289 typedef SerializePredicate<PkgPtr> PackagePredicate; |
|
290 typedef JfrPredicatedTypeWriterImplHost<PkgPtr, PackagePredicate, write__package> PackageWriterImpl; |
|
291 typedef JfrTypeWriterHost<PackageWriterImpl, TYPE_PACKAGE> PackageWriter; |
|
292 typedef CompositeFunctor<PkgPtr, PackageWriter, ClearArtifact<PkgPtr> > PackageWriterWithClear; |
|
293 typedef KlassToFieldEnvelope<PackageFieldSelector, PackageWriter> KlassPackageWriter; |
|
294 typedef JfrArtifactCallbackHost<PkgPtr, PackageWriterWithClear> PackageCallback; |
|
295 |
|
296 static void write_packages() { |
|
297 assert(_writer != NULL, "invariant"); |
|
298 PackageWriter pw(_writer, _class_unload); |
|
299 KlassPackageWriter kpw(&pw); |
|
300 _artifacts->iterate_klasses(kpw); |
|
301 if (previous_epoch()) { |
|
302 ClearArtifact<PkgPtr> clear; |
|
303 PackageWriterWithClear pwwc(&pw, &clear); |
|
304 PackageCallback callback(&pwwc); |
|
305 _subsystem_callback = &callback; |
|
306 do_packages(); |
|
307 } |
|
308 _artifacts->tally(pw); |
|
309 } |
|
310 |
|
311 int write__module(JfrCheckpointWriter* writer, const void* m) { |
|
312 assert(m != NULL, "invariant"); |
|
313 assert(_artifacts != NULL, "invariant"); |
|
314 ModPtr mod = (ModPtr)m; |
|
315 writer->write(artifact_id(mod)); |
|
316 writer->write(mark_symbol(mod->name())); |
|
317 writer->write(mark_symbol(mod->version())); |
|
318 writer->write(mark_symbol(mod->location())); |
|
319 writer->write(cld_id(mod->loader_data())); |
|
320 set_serialized(mod); |
|
321 return 1; |
|
322 } |
|
323 |
|
324 static void do_module(ModuleEntry* entry) { |
1129 do_previous_epoch_artifact(_subsystem_callback, entry); |
325 do_previous_epoch_artifact(_subsystem_callback, entry); |
1130 } |
326 } |
1131 |
327 |
1132 void JfrTypeSet::do_modules() { |
328 static void do_modules() { |
1133 if (_class_unload) { |
|
1134 ClassLoaderDataGraph::modules_unloading_do(&do_unloaded_module); |
|
1135 return; |
|
1136 } |
|
1137 ClassLoaderDataGraph::modules_do(&do_module); |
329 ClassLoaderDataGraph::modules_do(&do_module); |
1138 } |
330 } |
1139 |
331 |
1140 void JfrTypeSet::do_unloaded_class_loader_data(ClassLoaderData* cld) { |
332 class ModuleFieldSelector { |
1141 do_current_epoch_artifact(_subsystem_callback, cld); |
333 public: |
1142 } |
334 typedef ModPtr TypePtr; |
1143 |
335 static TypePtr select(KlassPtr klass) { |
1144 void JfrTypeSet::do_class_loader_data(ClassLoaderData* cld) { |
336 assert(klass != NULL, "invariant"); |
|
337 PkgPtr pkg = klass->package(); |
|
338 return pkg != NULL ? pkg->module() : NULL; |
|
339 } |
|
340 }; |
|
341 |
|
342 typedef SerializePredicate<ModPtr> ModulePredicate; |
|
343 typedef JfrPredicatedTypeWriterImplHost<ModPtr, ModulePredicate, write__module> ModuleWriterImpl; |
|
344 typedef JfrTypeWriterHost<ModuleWriterImpl, TYPE_MODULE> ModuleWriter; |
|
345 typedef CompositeFunctor<ModPtr, ModuleWriter, ClearArtifact<ModPtr> > ModuleWriterWithClear; |
|
346 typedef JfrArtifactCallbackHost<ModPtr, ModuleWriterWithClear> ModuleCallback; |
|
347 typedef KlassToFieldEnvelope<ModuleFieldSelector, ModuleWriter> KlassModuleWriter; |
|
348 |
|
349 static void write_modules() { |
|
350 assert(_writer != NULL, "invariant"); |
|
351 ModuleWriter mw(_writer, _class_unload); |
|
352 KlassModuleWriter kmw(&mw); |
|
353 _artifacts->iterate_klasses(kmw); |
|
354 if (previous_epoch()) { |
|
355 ClearArtifact<ModPtr> clear; |
|
356 ModuleWriterWithClear mwwc(&mw, &clear); |
|
357 ModuleCallback callback(&mwwc); |
|
358 _subsystem_callback = &callback; |
|
359 do_modules(); |
|
360 } |
|
361 _artifacts->tally(mw); |
|
362 } |
|
363 |
|
364 int write__classloader(JfrCheckpointWriter* writer, const void* c) { |
|
365 assert(c != NULL, "invariant"); |
|
366 CldPtr cld = (CldPtr)c; |
|
367 assert(!cld->is_unsafe_anonymous(), "invariant"); |
|
368 // class loader type |
|
369 const Klass* class_loader_klass = cld->class_loader_klass(); |
|
370 if (class_loader_klass == NULL) { |
|
371 // (primordial) boot class loader |
|
372 writer->write(artifact_id(cld)); // class loader instance id |
|
373 writer->write((traceid)0); // class loader type id (absence of) |
|
374 writer->write(create_symbol_id(1)); // 1 maps to synthetic name -> "bootstrap" |
|
375 } else { |
|
376 writer->write(artifact_id(cld)); // class loader instance id |
|
377 writer->write(artifact_id(class_loader_klass)); // class loader type id |
|
378 writer->write(mark_symbol(cld->name())); // class loader instance name |
|
379 } |
|
380 set_serialized(cld); |
|
381 return 1; |
|
382 } |
|
383 |
|
384 static void do_class_loader_data(ClassLoaderData* cld) { |
1145 do_previous_epoch_artifact(_subsystem_callback, cld); |
385 do_previous_epoch_artifact(_subsystem_callback, cld); |
1146 } |
386 } |
1147 |
387 |
|
388 class CldFieldSelector { |
|
389 public: |
|
390 typedef CldPtr TypePtr; |
|
391 static TypePtr select(KlassPtr klass) { |
|
392 assert(klass != NULL, "invariant"); |
|
393 CldPtr cld = klass->class_loader_data(); |
|
394 return cld->is_unsafe_anonymous() ? NULL : cld; |
|
395 } |
|
396 }; |
|
397 |
1148 class CLDCallback : public CLDClosure { |
398 class CLDCallback : public CLDClosure { |
1149 private: |
|
1150 bool _class_unload; |
|
1151 public: |
399 public: |
1152 CLDCallback(bool class_unload) : _class_unload(class_unload) {} |
400 CLDCallback() {} |
1153 void do_cld(ClassLoaderData* cld) { |
401 void do_cld(ClassLoaderData* cld) { |
1154 assert(cld != NULL, "invariant"); |
402 assert(cld != NULL, "invariant"); |
1155 if (cld->is_unsafe_anonymous()) { |
403 if (cld->is_unsafe_anonymous()) { |
1156 return; |
404 return; |
1157 } |
405 } |
1158 if (_class_unload) { |
406 do_class_loader_data(cld); |
1159 JfrTypeSet::do_unloaded_class_loader_data(cld); |
407 } |
1160 return; |
408 }; |
|
409 |
|
410 static void do_class_loaders() { |
|
411 CLDCallback cld_cb; |
|
412 ClassLoaderDataGraph::loaded_cld_do(&cld_cb); |
|
413 } |
|
414 |
|
415 typedef SerializePredicate<CldPtr> CldPredicate; |
|
416 typedef JfrPredicatedTypeWriterImplHost<CldPtr, CldPredicate, write__classloader> CldWriterImpl; |
|
417 typedef JfrTypeWriterHost<CldWriterImpl, TYPE_CLASSLOADER> CldWriter; |
|
418 typedef CompositeFunctor<CldPtr, CldWriter, ClearArtifact<CldPtr> > CldWriterWithClear; |
|
419 typedef JfrArtifactCallbackHost<CldPtr, CldWriterWithClear> CldCallback; |
|
420 typedef KlassToFieldEnvelope<CldFieldSelector, CldWriter> KlassCldWriter; |
|
421 |
|
422 static void write_classloaders() { |
|
423 assert(_writer != NULL, "invariant"); |
|
424 CldWriter cldw(_writer, _class_unload); |
|
425 KlassCldWriter kcw(&cldw); |
|
426 _artifacts->iterate_klasses(kcw); |
|
427 if (previous_epoch()) { |
|
428 ClearArtifact<CldPtr> clear; |
|
429 CldWriterWithClear cldwwc(&cldw, &clear); |
|
430 CldCallback callback(&cldwwc); |
|
431 _subsystem_callback = &callback; |
|
432 do_class_loaders(); |
|
433 } |
|
434 _artifacts->tally(cldw); |
|
435 } |
|
436 |
|
437 static u1 get_visibility(MethodPtr method) { |
|
438 assert(method != NULL, "invariant"); |
|
439 return const_cast<Method*>(method)->is_hidden() ? (u1)1 : (u1)0; |
|
440 } |
|
441 |
|
442 template <> |
|
443 void set_serialized<Method>(MethodPtr method) { |
|
444 assert(method != NULL, "invariant"); |
|
445 SET_METHOD_SERIALIZED(method); |
|
446 assert(IS_METHOD_SERIALIZED(method), "invariant"); |
|
447 } |
|
448 |
|
449 int write__method(JfrCheckpointWriter* writer, const void* m) { |
|
450 assert(writer != NULL, "invariant"); |
|
451 assert(_artifacts != NULL, "invariant"); |
|
452 assert(m != NULL, "invariant"); |
|
453 MethodPtr method = (MethodPtr)m; |
|
454 KlassPtr klass = method->method_holder(); |
|
455 assert(klass != NULL, "invariant"); |
|
456 assert(METHOD_USED_ANY_EPOCH(klass), "invariant"); |
|
457 writer->write(method_id(klass, method)); |
|
458 writer->write(artifact_id(klass)); |
|
459 writer->write(mark_symbol(method->name())); |
|
460 writer->write(mark_symbol(method->signature())); |
|
461 writer->write((u2)get_flags(method)); |
|
462 writer->write(get_visibility(method)); |
|
463 set_serialized(method); |
|
464 return 1; |
|
465 } |
|
466 |
|
467 template <typename MethodCallback, typename KlassCallback> |
|
468 class MethodIteratorHost { |
|
469 private: |
|
470 MethodCallback _method_cb; |
|
471 KlassCallback _klass_cb; |
|
472 MethodUsedPredicate _method_used_predicate; |
|
473 MethodFlagPredicate _method_flag_predicate; |
|
474 public: |
|
475 MethodIteratorHost(JfrCheckpointWriter* writer, |
|
476 bool current_epoch = false, |
|
477 bool class_unload = false, |
|
478 bool skip_header = false) : |
|
479 _method_cb(writer, class_unload, skip_header), |
|
480 _klass_cb(writer, class_unload, skip_header), |
|
481 _method_used_predicate(current_epoch), |
|
482 _method_flag_predicate(current_epoch) {} |
|
483 |
|
484 bool operator()(KlassPtr klass) { |
|
485 if (_method_used_predicate(klass)) { |
|
486 assert(METHOD_AND_CLASS_USED_ANY_EPOCH(klass), "invariant"); |
|
487 const InstanceKlass* const ik = InstanceKlass::cast(klass); |
|
488 const int len = ik->methods()->length(); |
|
489 for (int i = 0; i < len; ++i) { |
|
490 MethodPtr method = ik->methods()->at(i); |
|
491 if (_method_flag_predicate(method)) { |
|
492 _method_cb(method); |
|
493 } |
|
494 } |
1161 } |
495 } |
1162 JfrTypeSet::do_class_loader_data(cld); |
496 return _klass_cb(klass); |
1163 } |
497 } |
|
498 |
|
499 int count() const { return _method_cb.count(); } |
|
500 void add(int count) { _method_cb.add(count); } |
1164 }; |
501 }; |
1165 |
502 |
1166 void JfrTypeSet::do_class_loaders() { |
503 template <typename T, template <typename> class Impl> |
1167 CLDCallback cld_cb(_class_unload); |
504 class Wrapper { |
1168 if (_class_unload) { |
505 Impl<T> _t; |
1169 ClassLoaderDataGraph::cld_unloading_do(&cld_cb); |
506 public: |
1170 return; |
507 Wrapper(JfrCheckpointWriter*, bool, bool) : _t() {} |
1171 } |
508 bool operator()(T const& value) { |
1172 ClassLoaderDataGraph::loaded_cld_do(&cld_cb); |
509 return _t(value); |
1173 } |
510 } |
1174 |
511 }; |
1175 static void clear_artifacts(JfrArtifactSet* artifacts, bool current_epoch) { |
512 |
1176 assert(artifacts != NULL, "invariant"); |
513 typedef SerializePredicate<MethodPtr> MethodPredicate; |
1177 assert(artifacts->has_klass_entries(), "invariant"); |
514 typedef JfrPredicatedTypeWriterImplHost<MethodPtr, MethodPredicate, write__method> MethodWriterImplTarget; |
1178 |
515 typedef JfrTypeWriterHost<MethodWriterImplTarget, TYPE_METHOD> MethodWriterImpl; |
1179 // untag |
516 typedef Wrapper<KlassPtr, Stub> KlassCallbackStub; |
1180 ClearKlassAndMethods clear(current_epoch); |
517 typedef MethodIteratorHost<MethodWriterImpl, KlassCallbackStub> MethodWriter; |
1181 artifacts->iterate_klasses(clear); |
518 |
|
519 static void write_methods() { |
|
520 assert(_writer != NULL, "invariant"); |
|
521 MethodWriter mw(_writer, current_epoch(), _class_unload); |
|
522 _artifacts->iterate_klasses(mw); |
|
523 _artifacts->tally(mw); |
|
524 } |
|
525 |
|
526 template <> |
|
527 void set_serialized<JfrSymbolId::SymbolEntry>(SymbolEntryPtr ptr) { |
|
528 assert(ptr != NULL, "invariant"); |
|
529 ptr->set_serialized(); |
|
530 assert(ptr->is_serialized(), "invariant"); |
|
531 } |
|
532 |
|
533 template <> |
|
534 void set_serialized<JfrSymbolId::CStringEntry>(CStringEntryPtr ptr) { |
|
535 assert(ptr != NULL, "invariant"); |
|
536 ptr->set_serialized(); |
|
537 assert(ptr->is_serialized(), "invariant"); |
|
538 } |
|
539 |
|
540 int write__symbol(JfrCheckpointWriter* writer, const void* e) { |
|
541 assert(writer != NULL, "invariant"); |
|
542 assert(e != NULL, "invariant"); |
|
543 ResourceMark rm; |
|
544 SymbolEntryPtr entry = (SymbolEntryPtr)e; |
|
545 writer->write(create_symbol_id(entry->id())); |
|
546 writer->write(entry->value()->as_C_string()); |
|
547 set_serialized(entry); |
|
548 return 1; |
|
549 } |
|
550 |
|
551 int write__cstring(JfrCheckpointWriter* writer, const void* e) { |
|
552 assert(writer != NULL, "invariant"); |
|
553 assert(e != NULL, "invariant"); |
|
554 CStringEntryPtr entry = (CStringEntryPtr)e; |
|
555 writer->write(create_symbol_id(entry->id())); |
|
556 writer->write(entry->value()); |
|
557 set_serialized(entry); |
|
558 return 1; |
|
559 } |
|
560 |
|
561 typedef SymbolPredicate<SymbolEntryPtr> SymPredicate; |
|
562 typedef JfrPredicatedTypeWriterImplHost<SymbolEntryPtr, SymPredicate, write__symbol> SymbolEntryWriterImpl; |
|
563 typedef JfrTypeWriterHost<SymbolEntryWriterImpl, TYPE_SYMBOL> SymbolEntryWriter; |
|
564 typedef SymbolPredicate<CStringEntryPtr> CStringPredicate; |
|
565 typedef JfrPredicatedTypeWriterImplHost<CStringEntryPtr, CStringPredicate, write__cstring> CStringEntryWriterImpl; |
|
566 typedef JfrTypeWriterHost<CStringEntryWriterImpl, TYPE_SYMBOL> CStringEntryWriter; |
|
567 |
|
568 static void write_symbols() { |
|
569 assert(_writer != NULL, "invariant"); |
|
570 SymbolEntryWriter symbol_writer(_writer, _class_unload); |
|
571 _artifacts->iterate_symbols(symbol_writer); |
|
572 CStringEntryWriter cstring_writer(_writer, _class_unload, true); // skip header |
|
573 _artifacts->iterate_cstrings(cstring_writer); |
|
574 symbol_writer.add(cstring_writer.count()); |
|
575 _artifacts->tally(symbol_writer); |
|
576 } |
|
577 |
|
578 typedef Wrapper<KlassPtr, ClearArtifact> ClearKlassBits; |
|
579 typedef Wrapper<MethodPtr, ClearArtifact> ClearMethodFlag; |
|
580 typedef MethodIteratorHost<ClearMethodFlag, ClearKlassBits> ClearKlassAndMethods; |
|
581 |
|
582 static size_t teardown() { |
|
583 assert(_artifacts != NULL, "invariant"); |
|
584 const size_t total_count = _artifacts->total_count(); |
|
585 if (previous_epoch()) { |
|
586 assert(_writer != NULL, "invariant"); |
|
587 ClearKlassAndMethods clear(_writer); |
|
588 _artifacts->iterate_klasses(clear); |
|
589 _artifacts->clear(); |
|
590 ++checkpoint_id; |
|
591 } |
|
592 return total_count; |
|
593 } |
|
594 |
|
595 static void setup(JfrCheckpointWriter* writer, bool class_unload, bool flushpoint) { |
|
596 _writer = writer; |
|
597 _class_unload = class_unload; |
|
598 _flushpoint = flushpoint; |
|
599 if (_artifacts == NULL) { |
|
600 _artifacts = new JfrArtifactSet(class_unload); |
|
601 } else { |
|
602 _artifacts->initialize(class_unload); |
|
603 } |
|
604 assert(_artifacts != NULL, "invariant"); |
|
605 assert(!_artifacts->has_klass_entries(), "invariant"); |
1182 } |
606 } |
1183 |
607 |
1184 /** |
608 /** |
1185 * Write all "tagged" (in-use) constant artifacts and their dependencies. |
609 * Write all "tagged" (in-use) constant artifacts and their dependencies. |
1186 */ |
610 */ |
1187 size_t JfrTypeSet::serialize(JfrCheckpointWriter* writer, JfrCheckpointWriter* leakp_writer, bool class_unload, bool flushpoint) { |
611 size_t JfrTypeSet::serialize(JfrCheckpointWriter* writer, bool class_unload, bool flushpoint) { |
1188 assert(writer != NULL, "invariant"); |
612 assert(writer != NULL, "invariant"); |
1189 ResourceMark rm; |
613 ResourceMark rm; |
1190 // initialization begin |
614 setup(writer, class_unload, flushpoint); |
1191 _class_unload = class_unload; |
|
1192 _flushpoint = flushpoint; |
|
1193 ++checkpoint_id; |
|
1194 if (_artifacts == NULL) { |
|
1195 _artifacts = new JfrArtifactSet(current_epoch()); |
|
1196 } else { |
|
1197 _artifacts->initialize(current_epoch()); |
|
1198 } |
|
1199 assert(_artifacts != NULL, "invariant"); |
|
1200 assert(!_artifacts->has_klass_entries(), "invariant"); |
|
1201 // initialization complete |
|
1202 |
|
1203 // write order is important because an individual write step |
615 // write order is important because an individual write step |
1204 // might tag an artifact to be written in a subsequent step |
616 // might tag an artifact to be written in a subsequent step |
1205 write_klass_constants(writer, leakp_writer); |
617 if (!write_klasses()) { |
1206 if (!_artifacts->has_klass_entries()) { |
|
1207 return 0; |
618 return 0; |
1208 } |
619 } |
1209 write_package_constants(writer, leakp_writer); |
620 write_packages(); |
1210 write_module_constants(writer, leakp_writer); |
621 write_modules(); |
1211 write_class_loader_constants(writer, leakp_writer); |
622 write_classloaders(); |
1212 write_method_constants(writer, leakp_writer); |
623 write_methods(); |
1213 write_symbol_constants(writer, leakp_writer); |
624 write_symbols(); |
1214 const size_t total_count = _artifacts->total_count(); |
625 return teardown(); |
1215 if (!flushpoint) { |
626 } |
1216 clear_artifacts(_artifacts, class_unload); |
|
1217 } |
|
1218 return total_count; |
|
1219 } |
|