149 |
148 |
150 template <typename T> |
149 template <typename T> |
151 static s4 get_flags(const T* ptr) { |
150 static s4 get_flags(const T* ptr) { |
152 assert(ptr != NULL, "invariant"); |
151 assert(ptr != NULL, "invariant"); |
153 return ptr->access_flags().get_flags(); |
152 return ptr->access_flags().get_flags(); |
|
153 } |
|
154 |
|
155 static bool is_unsafe_anonymous(const Klass* klass) { |
|
156 assert(klass != NULL, "invariant"); |
|
157 return klass->is_instance_klass() && ((const InstanceKlass*)klass)->is_unsafe_anonymous(); |
|
158 } |
|
159 |
|
160 static ClassLoaderData* get_cld(const Klass* klass) { |
|
161 assert(klass != NULL, "invariant"); |
|
162 return is_unsafe_anonymous(klass) ? |
|
163 InstanceKlass::cast(klass)->unsafe_anonymous_host()->class_loader_data() : klass->class_loader_data(); |
154 } |
164 } |
155 |
165 |
156 template <typename T> |
166 template <typename T> |
157 static void set_serialized(const T* ptr) { |
167 static void set_serialized(const T* ptr) { |
158 assert(ptr != NULL, "invariant"); |
168 assert(ptr != NULL, "invariant"); |
536 |
546 |
537 static void do_class_loader_data(ClassLoaderData* cld) { |
547 static void do_class_loader_data(ClassLoaderData* cld) { |
538 do_previous_epoch_artifact(_subsystem_callback, cld); |
548 do_previous_epoch_artifact(_subsystem_callback, cld); |
539 } |
549 } |
540 |
550 |
541 class CldFieldSelector { |
551 class KlassCldFieldSelector { |
542 public: |
552 public: |
543 typedef CldPtr TypePtr; |
553 typedef CldPtr TypePtr; |
544 static TypePtr select(KlassPtr klass) { |
554 static TypePtr select(KlassPtr klass) { |
545 assert(klass != NULL, "invariant"); |
555 assert(klass != NULL, "invariant"); |
546 CldPtr cld = klass->class_loader_data(); |
556 return get_cld(klass); |
547 return cld->is_unsafe_anonymous() ? NULL : cld; |
557 } |
|
558 }; |
|
559 |
|
560 class ModuleCldFieldSelector { |
|
561 public: |
|
562 typedef CldPtr TypePtr; |
|
563 static TypePtr select(KlassPtr klass) { |
|
564 assert(klass != NULL, "invariant"); |
|
565 ModPtr mod = ModuleFieldSelector::select(klass); |
|
566 return mod != NULL ? mod->loader_data() : NULL; |
548 } |
567 } |
549 }; |
568 }; |
550 |
569 |
551 class CLDCallback : public CLDClosure { |
570 class CLDCallback : public CLDClosure { |
552 public: |
571 public: |
568 typedef SerializePredicate<CldPtr> CldPredicate; |
587 typedef SerializePredicate<CldPtr> CldPredicate; |
569 typedef JfrPredicatedTypeWriterImplHost<CldPtr, CldPredicate, write__classloader> CldWriterImpl; |
588 typedef JfrPredicatedTypeWriterImplHost<CldPtr, CldPredicate, write__classloader> CldWriterImpl; |
570 typedef JfrTypeWriterHost<CldWriterImpl, TYPE_CLASSLOADER> CldWriter; |
589 typedef JfrTypeWriterHost<CldWriterImpl, TYPE_CLASSLOADER> CldWriter; |
571 typedef CompositeFunctor<CldPtr, CldWriter, ClearArtifact<CldPtr> > CldWriterWithClear; |
590 typedef CompositeFunctor<CldPtr, CldWriter, ClearArtifact<CldPtr> > CldWriterWithClear; |
572 typedef JfrArtifactCallbackHost<CldPtr, CldWriterWithClear> CldCallback; |
591 typedef JfrArtifactCallbackHost<CldPtr, CldWriterWithClear> CldCallback; |
573 typedef KlassToFieldEnvelope<CldFieldSelector, CldWriter> KlassCldWriter; |
592 typedef KlassToFieldEnvelope<KlassCldFieldSelector, CldWriter> KlassCldWriter; |
|
593 typedef KlassToFieldEnvelope<ModuleCldFieldSelector, CldWriter> ModuleCldWriter; |
|
594 typedef CompositeFunctor<KlassPtr, KlassCldWriter, ModuleCldWriter> KlassAndModuleCldWriter; |
574 |
595 |
575 typedef LeakPredicate<CldPtr> LeakCldPredicate; |
596 typedef LeakPredicate<CldPtr> LeakCldPredicate; |
576 typedef JfrPredicatedTypeWriterImplHost<CldPtr, LeakCldPredicate, write__classloader__leakp> LeakCldWriterImpl; |
597 typedef JfrPredicatedTypeWriterImplHost<CldPtr, LeakCldPredicate, write__classloader__leakp> LeakCldWriterImpl; |
577 typedef JfrTypeWriterHost<LeakCldWriterImpl, TYPE_CLASSLOADER> LeakCldWriter; |
598 typedef JfrTypeWriterHost<LeakCldWriterImpl, TYPE_CLASSLOADER> LeakCldWriter; |
578 |
599 |
579 typedef CompositeFunctor<CldPtr, LeakCldWriter, CldWriter> CompositeCldWriter; |
600 typedef CompositeFunctor<CldPtr, LeakCldWriter, CldWriter> CompositeCldWriter; |
580 typedef KlassToFieldEnvelope<CldFieldSelector, CompositeCldWriter> KlassCompositeCldWriter; |
601 typedef KlassToFieldEnvelope<KlassCldFieldSelector, CompositeCldWriter> KlassCompositeCldWriter; |
|
602 typedef KlassToFieldEnvelope<ModuleCldFieldSelector, CompositeCldWriter> ModuleCompositeCldWriter; |
|
603 typedef CompositeFunctor<KlassPtr, KlassCompositeCldWriter, ModuleCompositeCldWriter> KlassAndModuleCompositeCldWriter; |
581 typedef CompositeFunctor<CldPtr, CompositeCldWriter, ClearArtifact<CldPtr> > CompositeCldWriterWithClear; |
604 typedef CompositeFunctor<CldPtr, CompositeCldWriter, ClearArtifact<CldPtr> > CompositeCldWriterWithClear; |
582 typedef JfrArtifactCallbackHost<CldPtr, CompositeCldWriterWithClear> CompositeCldCallback; |
605 typedef JfrArtifactCallbackHost<CldPtr, CompositeCldWriterWithClear> CompositeCldCallback; |
583 |
606 |
584 static void write_classloaders() { |
607 static void write_classloaders() { |
585 assert(_writer != NULL, "invariant"); |
608 assert(_writer != NULL, "invariant"); |
586 CldWriter cldw(_writer, _class_unload); |
609 CldWriter cldw(_writer, _class_unload); |
587 KlassCldWriter kcw(&cldw); |
610 KlassCldWriter kcw(&cldw); |
|
611 ModuleCldWriter mcw(&cldw); |
|
612 KlassAndModuleCldWriter kmcw(&kcw, &mcw); |
588 if (current_epoch()) { |
613 if (current_epoch()) { |
589 _artifacts->iterate_klasses(kcw); |
614 _artifacts->iterate_klasses(kmcw); |
590 _artifacts->tally(cldw); |
615 _artifacts->tally(cldw); |
591 return; |
616 return; |
592 } |
617 } |
593 assert(previous_epoch(), "invariant"); |
618 assert(previous_epoch(), "invariant"); |
594 if (_leakp_writer == NULL) { |
619 if (_leakp_writer == NULL) { |
595 _artifacts->iterate_klasses(kcw); |
620 _artifacts->iterate_klasses(kmcw); |
596 ClearArtifact<CldPtr> clear; |
621 ClearArtifact<CldPtr> clear; |
597 CldWriterWithClear cldwwc(&cldw, &clear); |
622 CldWriterWithClear cldwwc(&cldw, &clear); |
598 CldCallback callback(&cldwwc); |
623 CldCallback callback(&cldwwc); |
599 _subsystem_callback = &callback; |
624 _subsystem_callback = &callback; |
600 do_class_loaders(); |
625 do_class_loaders(); |
601 } else { |
626 } else { |
602 LeakCldWriter lcldw(_leakp_writer, _class_unload); |
627 LeakCldWriter lcldw(_leakp_writer, _class_unload); |
603 CompositeCldWriter ccldw(&lcldw, &cldw); |
628 CompositeCldWriter ccldw(&lcldw, &cldw); |
604 KlassCompositeCldWriter kccldw(&ccldw); |
629 KlassCompositeCldWriter kccldw(&ccldw); |
605 _artifacts->iterate_klasses(kccldw); |
630 ModuleCompositeCldWriter mccldw(&ccldw); |
|
631 KlassAndModuleCompositeCldWriter kmccldw(&kccldw, &mccldw); |
|
632 _artifacts->iterate_klasses(kmccldw); |
606 ClearArtifact<CldPtr> clear; |
633 ClearArtifact<CldPtr> clear; |
607 CompositeCldWriterWithClear ccldwwc(&ccldw, &clear); |
634 CompositeCldWriterWithClear ccldwwc(&ccldw, &clear); |
608 CompositeCldCallback callback(&ccldwwc); |
635 CompositeCldCallback callback(&ccldwwc); |
609 _subsystem_callback = &callback; |
636 _subsystem_callback = &callback; |
610 do_class_loaders(); |
637 do_class_loaders(); |
650 assert(m != NULL, "invariant"); |
677 assert(m != NULL, "invariant"); |
651 MethodPtr method = (MethodPtr)m; |
678 MethodPtr method = (MethodPtr)m; |
652 return write_method(writer, method, true); |
679 return write_method(writer, method, true); |
653 } |
680 } |
654 |
681 |
655 template <typename MethodCallback, typename KlassCallback, bool leakp> |
682 class BitMapFilter { |
|
683 ResourceBitMap _bitmap; |
|
684 public: |
|
685 explicit BitMapFilter(int length = 0) : _bitmap((size_t)length) {} |
|
686 bool operator()(size_t idx) { |
|
687 if (_bitmap.size() == 0) { |
|
688 return true; |
|
689 } |
|
690 if (_bitmap.at(idx)) { |
|
691 return false; |
|
692 } |
|
693 _bitmap.set_bit(idx); |
|
694 return true; |
|
695 } |
|
696 }; |
|
697 |
|
698 class AlwaysTrue { |
|
699 public: |
|
700 explicit AlwaysTrue(int length = 0) {} |
|
701 bool operator()(size_t idx) { |
|
702 return true; |
|
703 } |
|
704 }; |
|
705 |
|
706 template <typename MethodCallback, typename KlassCallback, class Filter, bool leakp> |
656 class MethodIteratorHost { |
707 class MethodIteratorHost { |
657 private: |
708 private: |
658 MethodCallback _method_cb; |
709 MethodCallback _method_cb; |
659 KlassCallback _klass_cb; |
710 KlassCallback _klass_cb; |
660 MethodUsedPredicate<leakp> _method_used_predicate; |
711 MethodUsedPredicate<leakp> _method_used_predicate; |
669 _method_used_predicate(current_epoch), |
720 _method_used_predicate(current_epoch), |
670 _method_flag_predicate(current_epoch) {} |
721 _method_flag_predicate(current_epoch) {} |
671 |
722 |
672 bool operator()(KlassPtr klass) { |
723 bool operator()(KlassPtr klass) { |
673 if (_method_used_predicate(klass)) { |
724 if (_method_used_predicate(klass)) { |
674 const InstanceKlass* const ik = InstanceKlass::cast(klass); |
725 const InstanceKlass* ik = InstanceKlass::cast(klass); |
675 const int len = ik->methods()->length(); |
726 const int len = ik->methods()->length(); |
676 for (int i = 0; i < len; ++i) { |
727 Filter filter(ik->previous_versions() != NULL ? len : 0); |
677 MethodPtr method = ik->methods()->at(i); |
728 while (ik != NULL) { |
678 if (_method_flag_predicate(method)) { |
729 for (int i = 0; i < len; ++i) { |
679 _method_cb(method); |
730 MethodPtr method = ik->methods()->at(i); |
|
731 if (_method_flag_predicate(method) && filter(i)) { |
|
732 _method_cb(method); |
|
733 } |
680 } |
734 } |
|
735 // There can be multiple versions of the same method running |
|
736 // due to redefinition. Need to inspect the complete set of methods. |
|
737 ik = ik->previous_versions(); |
681 } |
738 } |
682 } |
739 } |
683 return _klass_cb(klass); |
740 return _klass_cb(klass); |
684 } |
741 } |
685 |
742 |
695 bool operator()(T const& value) { |
752 bool operator()(T const& value) { |
696 return _t(value); |
753 return _t(value); |
697 } |
754 } |
698 }; |
755 }; |
699 |
756 |
|
757 template <typename T> |
|
758 class EmptyStub { |
|
759 public: |
|
760 bool operator()(T const& value) { return true; } |
|
761 }; |
|
762 |
700 typedef SerializePredicate<MethodPtr> MethodPredicate; |
763 typedef SerializePredicate<MethodPtr> MethodPredicate; |
701 typedef JfrPredicatedTypeWriterImplHost<MethodPtr, MethodPredicate, write__method> MethodWriterImplTarget; |
764 typedef JfrPredicatedTypeWriterImplHost<MethodPtr, MethodPredicate, write__method> MethodWriterImplTarget; |
702 typedef Wrapper<KlassPtr, Stub> KlassCallbackStub; |
765 typedef Wrapper<KlassPtr, EmptyStub> KlassCallbackStub; |
703 typedef JfrTypeWriterHost<MethodWriterImplTarget, TYPE_METHOD> MethodWriterImpl; |
766 typedef JfrTypeWriterHost<MethodWriterImplTarget, TYPE_METHOD> MethodWriterImpl; |
704 typedef MethodIteratorHost<MethodWriterImpl, KlassCallbackStub, false> MethodWriter; |
767 typedef MethodIteratorHost<MethodWriterImpl, KlassCallbackStub, BitMapFilter, false> MethodWriter; |
705 |
768 |
706 typedef LeakPredicate<MethodPtr> LeakMethodPredicate; |
769 typedef LeakPredicate<MethodPtr> LeakMethodPredicate; |
707 typedef JfrPredicatedTypeWriterImplHost<MethodPtr, LeakMethodPredicate, write__method__leakp> LeakMethodWriterImplTarget; |
770 typedef JfrPredicatedTypeWriterImplHost<MethodPtr, LeakMethodPredicate, write__method__leakp> LeakMethodWriterImplTarget; |
708 typedef JfrTypeWriterHost<LeakMethodWriterImplTarget, TYPE_METHOD> LeakMethodWriterImpl; |
771 typedef JfrTypeWriterHost<LeakMethodWriterImplTarget, TYPE_METHOD> LeakMethodWriterImpl; |
709 typedef MethodIteratorHost<LeakMethodWriterImpl, KlassCallbackStub, true> LeakMethodWriter; |
772 typedef MethodIteratorHost<LeakMethodWriterImpl, KlassCallbackStub, BitMapFilter, true> LeakMethodWriter; |
|
773 typedef MethodIteratorHost<LeakMethodWriterImpl, KlassCallbackStub, BitMapFilter, true> LeakMethodWriter; |
710 typedef CompositeFunctor<KlassPtr, LeakMethodWriter, MethodWriter> CompositeMethodWriter; |
774 typedef CompositeFunctor<KlassPtr, LeakMethodWriter, MethodWriter> CompositeMethodWriter; |
711 |
775 |
712 static void write_methods() { |
776 static void write_methods() { |
713 assert(_writer != NULL, "invariant"); |
777 assert(_writer != NULL, "invariant"); |
714 MethodWriter mw(_writer, current_epoch(), _class_unload); |
778 MethodWriter mw(_writer, current_epoch(), _class_unload); |