531 } else { |
531 } else { |
532 return entry->tag(); |
532 return entry->tag(); |
533 } |
533 } |
534 } |
534 } |
535 |
535 |
536 // If the object is a java.lang.Class then return the klassOop, |
|
537 // otherwise return the original object |
|
538 static inline oop klassOop_if_java_lang_Class(oop o) { |
|
539 if (o->klass() == SystemDictionary::Class_klass()) { |
|
540 if (!java_lang_Class::is_primitive(o)) { |
|
541 o = (oop)java_lang_Class::as_klassOop(o); |
|
542 assert(o != NULL, "class for non-primitive mirror must exist"); |
|
543 } |
|
544 } |
|
545 return o; |
|
546 } |
|
547 |
536 |
548 // A CallbackWrapper is a support class for querying and tagging an object |
537 // A CallbackWrapper is a support class for querying and tagging an object |
549 // around a callback to a profiler. The constructor does pre-callback |
538 // around a callback to a profiler. The constructor does pre-callback |
550 // work to get the tag value, klass tag value, ... and the destructor |
539 // work to get the tag value, klass tag value, ... and the destructor |
551 // does the post-callback work of tagging or untagging the object. |
540 // does the post-callback work of tagging or untagging the object. |
579 public: |
567 public: |
580 CallbackWrapper(JvmtiTagMap* tag_map, oop o) { |
568 CallbackWrapper(JvmtiTagMap* tag_map, oop o) { |
581 assert(Thread::current()->is_VM_thread() || tag_map->is_locked(), |
569 assert(Thread::current()->is_VM_thread() || tag_map->is_locked(), |
582 "MT unsafe or must be VM thread"); |
570 "MT unsafe or must be VM thread"); |
583 |
571 |
584 // for Classes the klassOop is tagged |
572 // object to tag |
585 _o = klassOop_if_java_lang_Class(o); |
573 _o = o; |
586 |
574 |
587 // object size |
575 // object size |
588 _obj_size = (jlong)_o->size() * wordSize; |
576 _obj_size = (jlong)_o->size() * wordSize; |
589 |
577 |
590 // record the context |
578 // record the context |
594 |
582 |
595 // get object tag |
583 // get object tag |
596 _obj_tag = (_entry == NULL) ? 0 : _entry->tag(); |
584 _obj_tag = (_entry == NULL) ? 0 : _entry->tag(); |
597 |
585 |
598 // get the class and the class's tag value |
586 // get the class and the class's tag value |
599 if (_o == o) { |
587 assert(SystemDictionary::Class_klass()->oop_is_instanceMirror(), "Is not?"); |
600 _klass = _o->klass(); |
588 |
601 } else { |
589 _klass_tag = tag_for(tag_map, _o->klass()->java_mirror()); |
602 // if the object represents a runtime class then use the |
|
603 // tag for java.lang.Class |
|
604 _klass = SystemDictionary::Class_klass(); |
|
605 } |
|
606 _klass_tag = tag_for(tag_map, _klass); |
|
607 } |
590 } |
608 |
591 |
609 ~CallbackWrapper() { |
592 ~CallbackWrapper() { |
610 post_callback_tag_update(_o, _hashmap, _entry, _obj_tag); |
593 post_callback_tag_update(_o, _hashmap, _entry, _obj_tag); |
611 } |
594 } |
612 |
595 |
613 inline jlong* obj_tag_p() { return &_obj_tag; } |
596 inline jlong* obj_tag_p() { return &_obj_tag; } |
614 inline jlong obj_size() const { return _obj_size; } |
597 inline jlong obj_size() const { return _obj_size; } |
615 inline jlong obj_tag() const { return _obj_tag; } |
598 inline jlong obj_tag() const { return _obj_tag; } |
616 inline klassOop klass() const { return _klass; } |
|
617 inline jlong klass_tag() const { return _klass_tag; } |
599 inline jlong klass_tag() const { return _klass_tag; } |
618 }; |
600 }; |
619 |
601 |
620 |
602 |
621 |
603 |
684 |
666 |
685 if (_is_reference_to_self) { |
667 if (_is_reference_to_self) { |
686 _referrer_klass_tag = klass_tag(); |
668 _referrer_klass_tag = klass_tag(); |
687 _referrer_tag_p = obj_tag_p(); |
669 _referrer_tag_p = obj_tag_p(); |
688 } else { |
670 } else { |
689 // for Classes the klassOop is tagged |
671 _referrer = referrer; |
690 _referrer = klassOop_if_java_lang_Class(referrer); |
|
691 // record the context |
672 // record the context |
692 _referrer_hashmap = tag_map->hashmap(); |
673 _referrer_hashmap = tag_map->hashmap(); |
693 _referrer_entry = _referrer_hashmap->find(_referrer); |
674 _referrer_entry = _referrer_hashmap->find(_referrer); |
694 |
675 |
695 // get object tag |
676 // get object tag |
696 _referrer_obj_tag = (_referrer_entry == NULL) ? 0 : _referrer_entry->tag(); |
677 _referrer_obj_tag = (_referrer_entry == NULL) ? 0 : _referrer_entry->tag(); |
697 _referrer_tag_p = &_referrer_obj_tag; |
678 _referrer_tag_p = &_referrer_obj_tag; |
698 |
679 |
699 // get referrer class tag. |
680 // get referrer class tag. |
700 klassOop k = (_referrer == referrer) ? // Check if referrer is a class... |
681 _referrer_klass_tag = tag_for(tag_map, _referrer->klass()->java_mirror()); |
701 _referrer->klass() // No, just get its class |
|
702 : SystemDictionary::Class_klass(); // Yes, its class is Class |
|
703 _referrer_klass_tag = tag_for(tag_map, k); |
|
704 } |
682 } |
705 } |
683 } |
706 |
684 |
707 ~TwoOopCallbackWrapper() { |
685 ~TwoOopCallbackWrapper() { |
708 if (!is_reference_to_self()){ |
686 if (!is_reference_to_self()){ |
729 void JvmtiTagMap::set_tag(jobject object, jlong tag) { |
707 void JvmtiTagMap::set_tag(jobject object, jlong tag) { |
730 MutexLocker ml(lock()); |
708 MutexLocker ml(lock()); |
731 |
709 |
732 // resolve the object |
710 // resolve the object |
733 oop o = JNIHandles::resolve_non_null(object); |
711 oop o = JNIHandles::resolve_non_null(object); |
734 |
|
735 // for Classes we tag the klassOop |
|
736 o = klassOop_if_java_lang_Class(o); |
|
737 |
712 |
738 // see if the object is already tagged |
713 // see if the object is already tagged |
739 JvmtiTagHashmap* hashmap = _hashmap; |
714 JvmtiTagHashmap* hashmap = _hashmap; |
740 JvmtiTagHashmapEntry* entry = hashmap->find(o); |
715 JvmtiTagHashmapEntry* entry = hashmap->find(o); |
741 |
716 |
765 MutexLocker ml(lock()); |
740 MutexLocker ml(lock()); |
766 |
741 |
767 // resolve the object |
742 // resolve the object |
768 oop o = JNIHandles::resolve_non_null(object); |
743 oop o = JNIHandles::resolve_non_null(object); |
769 |
744 |
770 // for Classes get the tag from the klassOop |
745 return tag_for(this, o); |
771 return tag_for(this, klassOop_if_java_lang_Class(o)); |
|
772 } |
746 } |
773 |
747 |
774 |
748 |
775 // Helper class used to describe the static or instance fields of a class. |
749 // Helper class used to describe the static or instance fields of a class. |
776 // For each field it holds the field index (as defined by the JVMTI specification), |
750 // For each field it holds the field index (as defined by the JVMTI specification), |
814 // access |
788 // access |
815 int field_count() { return _fields->length(); } |
789 int field_count() { return _fields->length(); } |
816 ClassFieldDescriptor* field_at(int i) { return _fields->at(i); } |
790 ClassFieldDescriptor* field_at(int i) { return _fields->at(i); } |
817 |
791 |
818 // functions to create maps of static or instance fields |
792 // functions to create maps of static or instance fields |
819 static ClassFieldMap* create_map_of_static_fields(klassOop k); |
793 static ClassFieldMap* create_map_of_static_fields(Klass* k); |
820 static ClassFieldMap* create_map_of_instance_fields(oop obj); |
794 static ClassFieldMap* create_map_of_instance_fields(oop obj); |
821 }; |
795 }; |
822 |
796 |
823 ClassFieldMap::ClassFieldMap() { |
797 ClassFieldMap::ClassFieldMap() { |
824 _fields = new (ResourceObj::C_HEAP, mtInternal) |
798 _fields = new (ResourceObj::C_HEAP, mtInternal) |
838 } |
812 } |
839 |
813 |
840 // Returns a heap allocated ClassFieldMap to describe the static fields |
814 // Returns a heap allocated ClassFieldMap to describe the static fields |
841 // of the given class. |
815 // of the given class. |
842 // |
816 // |
843 ClassFieldMap* ClassFieldMap::create_map_of_static_fields(klassOop k) { |
817 ClassFieldMap* ClassFieldMap::create_map_of_static_fields(Klass* k) { |
844 HandleMark hm; |
818 HandleMark hm; |
845 instanceKlassHandle ikh = instanceKlassHandle(Thread::current(), k); |
819 instanceKlassHandle ikh = instanceKlassHandle(Thread::current(), k); |
846 |
820 |
847 // create the field map |
821 // create the field map |
848 ClassFieldMap* field_map = new ClassFieldMap(); |
822 ClassFieldMap* field_map = new ClassFieldMap(); |
887 |
861 |
888 return field_map; |
862 return field_map; |
889 } |
863 } |
890 |
864 |
891 // Helper class used to cache a ClassFileMap for the instance fields of |
865 // Helper class used to cache a ClassFileMap for the instance fields of |
892 // a cache. A JvmtiCachedClassFieldMap can be cached by an instanceKlass during |
866 // a cache. A JvmtiCachedClassFieldMap can be cached by an InstanceKlass during |
893 // heap iteration and avoid creating a field map for each object in the heap |
867 // heap iteration and avoid creating a field map for each object in the heap |
894 // (only need to create the map when the first instance of a class is encountered). |
868 // (only need to create the map when the first instance of a class is encountered). |
895 // |
869 // |
896 class JvmtiCachedClassFieldMap : public CHeapObj<mtInternal> { |
870 class JvmtiCachedClassFieldMap : public CHeapObj<mtInternal> { |
897 private: |
871 private: |
903 ClassFieldMap* field_map() const { return _field_map; } |
877 ClassFieldMap* field_map() const { return _field_map; } |
904 |
878 |
905 JvmtiCachedClassFieldMap(ClassFieldMap* field_map); |
879 JvmtiCachedClassFieldMap(ClassFieldMap* field_map); |
906 ~JvmtiCachedClassFieldMap(); |
880 ~JvmtiCachedClassFieldMap(); |
907 |
881 |
908 static GrowableArray<instanceKlass*>* _class_list; |
882 static GrowableArray<InstanceKlass*>* _class_list; |
909 static void add_to_class_list(instanceKlass* ik); |
883 static void add_to_class_list(InstanceKlass* ik); |
910 |
884 |
911 public: |
885 public: |
912 // returns the field map for a given object (returning map cached |
886 // returns the field map for a given object (returning map cached |
913 // by instanceKlass if possible |
887 // by InstanceKlass if possible |
914 static ClassFieldMap* get_map_of_instance_fields(oop obj); |
888 static ClassFieldMap* get_map_of_instance_fields(oop obj); |
915 |
889 |
916 // removes the field map from all instanceKlasses - should be |
890 // removes the field map from all instanceKlasses - should be |
917 // called before VM operation completes |
891 // called before VM operation completes |
918 static void clear_cache(); |
892 static void clear_cache(); |
919 |
893 |
920 // returns the number of ClassFieldMap cached by instanceKlasses |
894 // returns the number of ClassFieldMap cached by instanceKlasses |
921 static int cached_field_map_count(); |
895 static int cached_field_map_count(); |
922 }; |
896 }; |
923 |
897 |
924 GrowableArray<instanceKlass*>* JvmtiCachedClassFieldMap::_class_list; |
898 GrowableArray<InstanceKlass*>* JvmtiCachedClassFieldMap::_class_list; |
925 |
899 |
926 JvmtiCachedClassFieldMap::JvmtiCachedClassFieldMap(ClassFieldMap* field_map) { |
900 JvmtiCachedClassFieldMap::JvmtiCachedClassFieldMap(ClassFieldMap* field_map) { |
927 _field_map = field_map; |
901 _field_map = field_map; |
928 } |
902 } |
929 |
903 |
953 }; |
927 }; |
954 |
928 |
955 bool ClassFieldMapCacheMark::_is_active; |
929 bool ClassFieldMapCacheMark::_is_active; |
956 |
930 |
957 |
931 |
958 // record that the given instanceKlass is caching a field map |
932 // record that the given InstanceKlass is caching a field map |
959 void JvmtiCachedClassFieldMap::add_to_class_list(instanceKlass* ik) { |
933 void JvmtiCachedClassFieldMap::add_to_class_list(InstanceKlass* ik) { |
960 if (_class_list == NULL) { |
934 if (_class_list == NULL) { |
961 _class_list = new (ResourceObj::C_HEAP, mtInternal) |
935 _class_list = new (ResourceObj::C_HEAP, mtInternal) |
962 GrowableArray<instanceKlass*>(initial_class_count, true); |
936 GrowableArray<InstanceKlass*>(initial_class_count, true); |
963 } |
937 } |
964 _class_list->push(ik); |
938 _class_list->push(ik); |
965 } |
939 } |
966 |
940 |
967 // returns the instance field map for the given object |
941 // returns the instance field map for the given object |
968 // (returns field map cached by the instanceKlass if possible) |
942 // (returns field map cached by the InstanceKlass if possible) |
969 ClassFieldMap* JvmtiCachedClassFieldMap::get_map_of_instance_fields(oop obj) { |
943 ClassFieldMap* JvmtiCachedClassFieldMap::get_map_of_instance_fields(oop obj) { |
970 assert(Thread::current()->is_VM_thread(), "must be VMThread"); |
944 assert(Thread::current()->is_VM_thread(), "must be VMThread"); |
971 assert(ClassFieldMapCacheMark::is_active(), "ClassFieldMapCacheMark not active"); |
945 assert(ClassFieldMapCacheMark::is_active(), "ClassFieldMapCacheMark not active"); |
972 |
946 |
973 klassOop k = obj->klass(); |
947 Klass* k = obj->klass(); |
974 instanceKlass* ik = instanceKlass::cast(k); |
948 InstanceKlass* ik = InstanceKlass::cast(k); |
975 |
949 |
976 // return cached map if possible |
950 // return cached map if possible |
977 JvmtiCachedClassFieldMap* cached_map = ik->jvmti_cached_class_field_map(); |
951 JvmtiCachedClassFieldMap* cached_map = ik->jvmti_cached_class_field_map(); |
978 if (cached_map != NULL) { |
952 if (cached_map != NULL) { |
979 assert(cached_map->field_map() != NULL, "missing field list"); |
953 assert(cached_map->field_map() != NULL, "missing field list"); |
990 // remove the fields maps cached from all instanceKlasses |
964 // remove the fields maps cached from all instanceKlasses |
991 void JvmtiCachedClassFieldMap::clear_cache() { |
965 void JvmtiCachedClassFieldMap::clear_cache() { |
992 assert(Thread::current()->is_VM_thread(), "must be VMThread"); |
966 assert(Thread::current()->is_VM_thread(), "must be VMThread"); |
993 if (_class_list != NULL) { |
967 if (_class_list != NULL) { |
994 for (int i = 0; i < _class_list->length(); i++) { |
968 for (int i = 0; i < _class_list->length(); i++) { |
995 instanceKlass* ik = _class_list->at(i); |
969 InstanceKlass* ik = _class_list->at(i); |
996 JvmtiCachedClassFieldMap* cached_map = ik->jvmti_cached_class_field_map(); |
970 JvmtiCachedClassFieldMap* cached_map = ik->jvmti_cached_class_field_map(); |
997 assert(cached_map != NULL, "should not be NULL"); |
971 assert(cached_map != NULL, "should not be NULL"); |
998 ik->set_jvmti_cached_class_field_map(NULL); |
972 ik->set_jvmti_cached_class_field_map(NULL); |
999 delete cached_map; // deletes the encapsulated field map |
973 delete cached_map; // deletes the encapsulated field map |
1000 } |
974 } |
1129 |
1103 |
1130 assert(obj->klass() == SystemDictionary::Class_klass(), "not a class"); |
1104 assert(obj->klass() == SystemDictionary::Class_klass(), "not a class"); |
1131 if (java_lang_Class::is_primitive(obj)) { |
1105 if (java_lang_Class::is_primitive(obj)) { |
1132 return 0; |
1106 return 0; |
1133 } |
1107 } |
1134 klassOop k = java_lang_Class::as_klassOop(obj); |
1108 Klass* klass = java_lang_Class::as_Klass(obj); |
1135 Klass* klass = k->klass_part(); |
|
1136 |
1109 |
1137 // ignore classes for object and type arrays |
1110 // ignore classes for object and type arrays |
1138 if (!klass->oop_is_instance()) { |
1111 if (!klass->oop_is_instance()) { |
1139 return 0; |
1112 return 0; |
1140 } |
1113 } |
1141 |
1114 |
1142 // ignore classes which aren't linked yet |
1115 // ignore classes which aren't linked yet |
1143 instanceKlass* ik = instanceKlass::cast(k); |
1116 InstanceKlass* ik = InstanceKlass::cast(klass); |
1144 if (!ik->is_linked()) { |
1117 if (!ik->is_linked()) { |
1145 return 0; |
1118 return 0; |
1146 } |
1119 } |
1147 |
1120 |
1148 // get the field map |
1121 // get the field map |
1149 ClassFieldMap* field_map = ClassFieldMap::create_map_of_static_fields(k); |
1122 ClassFieldMap* field_map = ClassFieldMap::create_map_of_static_fields(klass); |
1150 |
1123 |
1151 // invoke the callback for each static primitive field |
1124 // invoke the callback for each static primitive field |
1152 for (int i=0; i<field_map->field_count(); i++) { |
1125 for (int i=0; i<field_map->field_count(); i++) { |
1153 ClassFieldDescriptor* field = field_map->field_at(i); |
1126 ClassFieldDescriptor* field = field_map->field_at(i); |
1154 |
1127 |
1160 // one-to-one mapping |
1133 // one-to-one mapping |
1161 jvmtiPrimitiveType value_type = (jvmtiPrimitiveType)type; |
1134 jvmtiPrimitiveType value_type = (jvmtiPrimitiveType)type; |
1162 |
1135 |
1163 // get offset and field value |
1136 // get offset and field value |
1164 int offset = field->field_offset(); |
1137 int offset = field->field_offset(); |
1165 address addr = (address)k + offset; |
1138 address addr = (address)klass + offset; |
1166 jvalue value; |
1139 jvalue value; |
1167 copy_to_jvalue(&value, addr, value_type); |
1140 copy_to_jvalue(&value, addr, value_type); |
1168 |
1141 |
1169 // field index |
1142 // field index |
1170 reference_info.field.index = field->field_index(); |
1143 reference_info.field.index = field->field_index(); |
1263 // do the iteration |
1236 // do the iteration |
1264 // If this operation encounters a bad object when using CMS, |
1237 // If this operation encounters a bad object when using CMS, |
1265 // consider using safe_object_iterate() which avoids perm gen |
1238 // consider using safe_object_iterate() which avoids perm gen |
1266 // objects that may contain bad references. |
1239 // objects that may contain bad references. |
1267 Universe::heap()->object_iterate(_blk); |
1240 Universe::heap()->object_iterate(_blk); |
1268 |
|
1269 // when sharing is enabled we must iterate over the shared spaces |
|
1270 if (UseSharedSpaces) { |
|
1271 GenCollectedHeap* gch = GenCollectedHeap::heap(); |
|
1272 CompactingPermGenGen* gen = (CompactingPermGenGen*)gch->perm_gen(); |
|
1273 gen->ro_space()->object_iterate(_blk); |
|
1274 gen->rw_space()->object_iterate(_blk); |
|
1275 } |
|
1276 } |
1241 } |
1277 |
1242 |
1278 }; |
1243 }; |
1279 |
1244 |
1280 |
1245 |
1543 // |
1508 // |
1544 void do_entry(JvmtiTagHashmapEntry* entry) { |
1509 void do_entry(JvmtiTagHashmapEntry* entry) { |
1545 for (int i=0; i<_tag_count; i++) { |
1510 for (int i=0; i<_tag_count; i++) { |
1546 if (_tags[i] == entry->tag()) { |
1511 if (_tags[i] == entry->tag()) { |
1547 oop o = entry->object(); |
1512 oop o = entry->object(); |
1548 assert(o != NULL, "sanity check"); |
1513 assert(o != NULL && Universe::heap()->is_in_reserved(o), "sanity check"); |
1549 |
|
1550 // the mirror is tagged |
|
1551 if (o->is_klass()) { |
|
1552 klassOop k = (klassOop)o; |
|
1553 o = Klass::cast(k)->java_mirror(); |
|
1554 } |
|
1555 |
|
1556 jobject ref = JNIHandles::make_local(JavaThread::current(), o); |
1514 jobject ref = JNIHandles::make_local(JavaThread::current(), o); |
1557 _object_results->append(ref); |
1515 _object_results->append(ref); |
1558 _tag_results->append((uint64_t)entry->tag()); |
1516 _tag_results->append((uint64_t)entry->tag()); |
1559 } |
1517 } |
1560 } |
1518 } |
1693 // We don't need to reset mark bits on this call, but reset the |
1651 // We don't need to reset mark bits on this call, but reset the |
1694 // flag to the default for the next call. |
1652 // flag to the default for the next call. |
1695 set_needs_reset(true); |
1653 set_needs_reset(true); |
1696 } |
1654 } |
1697 |
1655 |
1698 // When sharing is enabled we need to restore the headers of the objects |
|
1699 // in the readwrite space too. |
|
1700 if (UseSharedSpaces) { |
|
1701 GenCollectedHeap* gch = GenCollectedHeap::heap(); |
|
1702 CompactingPermGenGen* gen = (CompactingPermGenGen*)gch->perm_gen(); |
|
1703 gen->rw_space()->object_iterate(&blk); |
|
1704 } |
|
1705 |
|
1706 // now restore the interesting headers |
1656 // now restore the interesting headers |
1707 for (int i = 0; i < _saved_oop_stack->length(); i++) { |
1657 for (int i = 0; i < _saved_oop_stack->length(); i++) { |
1708 oop o = _saved_oop_stack->at(i); |
1658 oop o = _saved_oop_stack->at(i); |
1709 markOop mark = _saved_mark_stack->at(i); |
1659 markOop mark = _saved_mark_stack->at(i); |
1710 o->set_mark(mark); |
1660 o->set_mark(mark); |
2067 // as the last call then we use the cached value. |
2017 // as the last call then we use the cached value. |
2068 jlong referrer_tag; |
2018 jlong referrer_tag; |
2069 if (referrer == context->last_referrer()) { |
2019 if (referrer == context->last_referrer()) { |
2070 referrer_tag = context->last_referrer_tag(); |
2020 referrer_tag = context->last_referrer_tag(); |
2071 } else { |
2021 } else { |
2072 referrer_tag = tag_for(tag_map(), klassOop_if_java_lang_Class(referrer)); |
2022 referrer_tag = tag_for(tag_map(), referrer); |
2073 } |
2023 } |
2074 |
2024 |
2075 // do the callback |
2025 // do the callback |
2076 CallbackWrapper wrapper(tag_map(), referree); |
2026 CallbackWrapper wrapper(tag_map(), referree); |
2077 jvmtiObjectReferenceCallback cb = context->object_ref_callback(); |
2027 jvmtiObjectReferenceCallback cb = context->object_ref_callback(); |
2602 return; |
2552 return; |
2603 } |
2553 } |
2604 |
2554 |
2605 jvmtiHeapReferenceKind kind = root_kind(); |
2555 jvmtiHeapReferenceKind kind = root_kind(); |
2606 |
2556 |
2607 // many roots are Klasses so we use the java mirror |
2557 assert(Universe::heap()->is_in_reserved(o), "should be impossible"); |
2608 if (o->is_klass()) { |
|
2609 klassOop k = (klassOop)o; |
|
2610 o = Klass::cast(k)->java_mirror(); |
|
2611 if (o == NULL) { |
|
2612 // Classes without mirrors don't correspond to real Java |
|
2613 // classes so just ignore them. |
|
2614 return; |
|
2615 } |
|
2616 } else { |
|
2617 |
|
2618 // SystemDictionary::always_strong_oops_do reports the application |
2558 // SystemDictionary::always_strong_oops_do reports the application |
2619 // class loader as a root. We want this root to be reported as |
2559 // class loader as a root. We want this root to be reported as |
2620 // a root kind of "OTHER" rather than "SYSTEM_CLASS". |
2560 // a root kind of "OTHER" rather than "SYSTEM_CLASS". |
2621 if (o->is_instance() && root_kind() == JVMTI_HEAP_REFERENCE_SYSTEM_CLASS) { |
2561 if (o->is_instance() && root_kind() == JVMTI_HEAP_REFERENCE_SYSTEM_CLASS) { |
2622 kind = JVMTI_HEAP_REFERENCE_OTHER; |
2562 kind = JVMTI_HEAP_REFERENCE_OTHER; |
2623 } |
2563 } |
2624 } |
|
2625 |
2564 |
2626 // some objects are ignored - in the case of simple |
2565 // some objects are ignored - in the case of simple |
2627 // roots it's mostly Symbol*s that we are skipping |
2566 // roots it's mostly Symbol*s that we are skipping |
2628 // here. |
2567 // here. |
2629 if (!ServiceUtil::visible_oop(o)) { |
2568 if (!ServiceUtil::visible_oop(o)) { |
2731 GrowableArray<oop>* visit_stack() const { return _visit_stack; } |
2670 GrowableArray<oop>* visit_stack() const { return _visit_stack; } |
2732 |
2671 |
2733 // iterate over the various object types |
2672 // iterate over the various object types |
2734 inline bool iterate_over_array(oop o); |
2673 inline bool iterate_over_array(oop o); |
2735 inline bool iterate_over_type_array(oop o); |
2674 inline bool iterate_over_type_array(oop o); |
2736 inline bool iterate_over_class(klassOop o); |
2675 inline bool iterate_over_class(oop o); |
2737 inline bool iterate_over_object(oop o); |
2676 inline bool iterate_over_object(oop o); |
2738 |
2677 |
2739 // root collection |
2678 // root collection |
2740 inline bool collect_simple_roots(); |
2679 inline bool collect_simple_roots(); |
2741 inline bool collect_stack_roots(); |
2680 inline bool collect_stack_roots(); |
2805 |
2744 |
2806 // an array references its class and has a reference to |
2745 // an array references its class and has a reference to |
2807 // each element in the array |
2746 // each element in the array |
2808 inline bool VM_HeapWalkOperation::iterate_over_array(oop o) { |
2747 inline bool VM_HeapWalkOperation::iterate_over_array(oop o) { |
2809 objArrayOop array = objArrayOop(o); |
2748 objArrayOop array = objArrayOop(o); |
2810 if (array->klass() == Universe::systemObjArrayKlassObj()) { |
|
2811 // filtered out |
|
2812 return true; |
|
2813 } |
|
2814 |
2749 |
2815 // array reference to its class |
2750 // array reference to its class |
2816 oop mirror = objArrayKlass::cast(array->klass())->java_mirror(); |
2751 oop mirror = objArrayKlass::cast(array->klass())->java_mirror(); |
2817 if (!CallbackInvoker::report_class_reference(o, mirror)) { |
2752 if (!CallbackInvoker::report_class_reference(o, mirror)) { |
2818 return false; |
2753 return false; |
2834 return true; |
2769 return true; |
2835 } |
2770 } |
2836 |
2771 |
2837 // a type array references its class |
2772 // a type array references its class |
2838 inline bool VM_HeapWalkOperation::iterate_over_type_array(oop o) { |
2773 inline bool VM_HeapWalkOperation::iterate_over_type_array(oop o) { |
2839 klassOop k = o->klass(); |
2774 Klass* k = o->klass(); |
2840 oop mirror = Klass::cast(k)->java_mirror(); |
2775 oop mirror = Klass::cast(k)->java_mirror(); |
2841 if (!CallbackInvoker::report_class_reference(o, mirror)) { |
2776 if (!CallbackInvoker::report_class_reference(o, mirror)) { |
2842 return false; |
2777 return false; |
2843 } |
2778 } |
2844 |
2779 |
2850 } |
2785 } |
2851 return true; |
2786 return true; |
2852 } |
2787 } |
2853 |
2788 |
2854 // verify that a static oop field is in range |
2789 // verify that a static oop field is in range |
2855 static inline bool verify_static_oop(instanceKlass* ik, |
2790 static inline bool verify_static_oop(InstanceKlass* ik, |
2856 oop mirror, int offset) { |
2791 oop mirror, int offset) { |
2857 address obj_p = (address)mirror + offset; |
2792 address obj_p = (address)mirror + offset; |
2858 address start = (address)instanceMirrorKlass::start_of_static_fields(mirror); |
2793 address start = (address)instanceMirrorKlass::start_of_static_fields(mirror); |
2859 address end = start + (java_lang_Class::static_oop_field_count(mirror) * heapOopSize); |
2794 address end = start + (java_lang_Class::static_oop_field_count(mirror) * heapOopSize); |
2860 assert(end >= start, "sanity check"); |
2795 assert(end >= start, "sanity check"); |
2866 } |
2801 } |
2867 } |
2802 } |
2868 |
2803 |
2869 // a class references its super class, interfaces, class loader, ... |
2804 // a class references its super class, interfaces, class loader, ... |
2870 // and finally its static fields |
2805 // and finally its static fields |
2871 inline bool VM_HeapWalkOperation::iterate_over_class(klassOop k) { |
2806 inline bool VM_HeapWalkOperation::iterate_over_class(oop java_class) { |
2872 int i; |
2807 int i; |
2873 Klass* klass = klassOop(k)->klass_part(); |
2808 Klass* klass = java_lang_Class::as_Klass(java_class); |
2874 |
2809 |
2875 if (klass->oop_is_instance()) { |
2810 if (klass->oop_is_instance()) { |
2876 instanceKlass* ik = instanceKlass::cast(k); |
2811 InstanceKlass* ik = InstanceKlass::cast(klass); |
2877 |
2812 |
2878 // ignore the class if it's has been initialized yet |
2813 // ignore the class if it's has been initialized yet |
2879 if (!ik->is_linked()) { |
2814 if (!ik->is_linked()) { |
2880 return true; |
2815 return true; |
2881 } |
2816 } |
2882 |
2817 |
2883 // get the java mirror |
2818 // get the java mirror |
2884 oop mirror = klass->java_mirror(); |
2819 oop mirror = klass->java_mirror(); |
2885 |
2820 |
2886 // super (only if something more interesting than java.lang.Object) |
2821 // super (only if something more interesting than java.lang.Object) |
2887 klassOop java_super = ik->java_super(); |
2822 Klass* java_super = ik->java_super(); |
2888 if (java_super != NULL && java_super != SystemDictionary::Object_klass()) { |
2823 if (java_super != NULL && java_super != SystemDictionary::Object_klass()) { |
2889 oop super = Klass::cast(java_super)->java_mirror(); |
2824 oop super = Klass::cast(java_super)->java_mirror(); |
2890 if (!CallbackInvoker::report_superclass_reference(mirror, super)) { |
2825 if (!CallbackInvoker::report_superclass_reference(mirror, super)) { |
2891 return false; |
2826 return false; |
2892 } |
2827 } |
2916 } |
2851 } |
2917 } |
2852 } |
2918 |
2853 |
2919 // references from the constant pool |
2854 // references from the constant pool |
2920 { |
2855 { |
2921 const constantPoolOop pool = ik->constants(); |
2856 ConstantPool* const pool = ik->constants(); |
2922 for (int i = 1; i < pool->length(); i++) { |
2857 for (int i = 1; i < pool->length(); i++) { |
2923 constantTag tag = pool->tag_at(i).value(); |
2858 constantTag tag = pool->tag_at(i).value(); |
2924 if (tag.is_string() || tag.is_klass()) { |
2859 if (tag.is_string() || tag.is_klass()) { |
2925 oop entry; |
2860 oop entry; |
2926 if (tag.is_string()) { |
2861 if (tag.is_string()) { |
2927 entry = pool->resolved_string_at(i); |
2862 entry = pool->resolved_string_at(i); |
|
2863 // If the entry is non-null it it resolved. |
|
2864 if (entry == NULL) continue; |
2928 assert(java_lang_String::is_instance(entry), "must be string"); |
2865 assert(java_lang_String::is_instance(entry), "must be string"); |
2929 } else { |
2866 } else { |
2930 entry = Klass::cast(pool->resolved_klass_at(i))->java_mirror(); |
2867 entry = Klass::cast(pool->resolved_klass_at(i))->java_mirror(); |
2931 } |
2868 } |
2932 if (!CallbackInvoker::report_constant_pool_reference(mirror, entry, (jint)i)) { |
2869 if (!CallbackInvoker::report_constant_pool_reference(mirror, entry, (jint)i)) { |
2937 } |
2874 } |
2938 |
2875 |
2939 // interfaces |
2876 // interfaces |
2940 // (These will already have been reported as references from the constant pool |
2877 // (These will already have been reported as references from the constant pool |
2941 // but are specified by IterateOverReachableObjects and must be reported). |
2878 // but are specified by IterateOverReachableObjects and must be reported). |
2942 objArrayOop interfaces = ik->local_interfaces(); |
2879 Array<Klass*>* interfaces = ik->local_interfaces(); |
2943 for (i = 0; i < interfaces->length(); i++) { |
2880 for (i = 0; i < interfaces->length(); i++) { |
2944 oop interf = Klass::cast((klassOop)interfaces->obj_at(i))->java_mirror(); |
2881 oop interf = Klass::cast((Klass*)interfaces->at(i))->java_mirror(); |
2945 if (interf == NULL) { |
2882 if (interf == NULL) { |
2946 continue; |
2883 continue; |
2947 } |
2884 } |
2948 if (!CallbackInvoker::report_interface_reference(mirror, interf)) { |
2885 if (!CallbackInvoker::report_interface_reference(mirror, interf)) { |
2949 return false; |
2886 return false; |
2950 } |
2887 } |
2951 } |
2888 } |
2952 |
2889 |
2953 // iterate over the static fields |
2890 // iterate over the static fields |
2954 |
2891 |
2955 ClassFieldMap* field_map = ClassFieldMap::create_map_of_static_fields(k); |
2892 ClassFieldMap* field_map = ClassFieldMap::create_map_of_static_fields(klass); |
2956 for (i=0; i<field_map->field_count(); i++) { |
2893 for (i=0; i<field_map->field_count(); i++) { |
2957 ClassFieldDescriptor* field = field_map->field_at(i); |
2894 ClassFieldDescriptor* field = field_map->field_at(i); |
2958 char type = field->field_type(); |
2895 char type = field->field_type(); |
2959 if (!is_primitive_field_type(type)) { |
2896 if (!is_primitive_field_type(type)) { |
2960 oop fld_o = mirror->obj_field(field->field_offset()); |
2897 oop fld_o = mirror->obj_field(field->field_offset()); |
3001 char type = field->field_type(); |
2938 char type = field->field_type(); |
3002 if (!is_primitive_field_type(type)) { |
2939 if (!is_primitive_field_type(type)) { |
3003 oop fld_o = o->obj_field(field->field_offset()); |
2940 oop fld_o = o->obj_field(field->field_offset()); |
3004 // ignore any objects that aren't visible to profiler |
2941 // ignore any objects that aren't visible to profiler |
3005 if (fld_o != NULL && ServiceUtil::visible_oop(fld_o)) { |
2942 if (fld_o != NULL && ServiceUtil::visible_oop(fld_o)) { |
3006 // reflection code may have a reference to a klassOop. |
2943 assert(Universe::heap()->is_in_reserved(fld_o), "unsafe code should not " |
3007 // - see sun.reflect.UnsafeStaticFieldAccessorImpl and sun.misc.Unsafe |
2944 "have references to Klass* anymore"); |
3008 if (fld_o->is_klass()) { |
|
3009 klassOop k = (klassOop)fld_o; |
|
3010 fld_o = Klass::cast(k)->java_mirror(); |
|
3011 } |
|
3012 int slot = field->field_index(); |
2945 int slot = field->field_index(); |
3013 if (!CallbackInvoker::report_field_reference(o, fld_o, slot)) { |
2946 if (!CallbackInvoker::report_field_reference(o, fld_o, slot)) { |
3014 return false; |
2947 return false; |
3015 } |
2948 } |
3016 } |
2949 } |
3056 } |
2989 } |
3057 |
2990 |
3058 // Preloaded classes and loader from the system dictionary |
2991 // Preloaded classes and loader from the system dictionary |
3059 blk.set_kind(JVMTI_HEAP_REFERENCE_SYSTEM_CLASS); |
2992 blk.set_kind(JVMTI_HEAP_REFERENCE_SYSTEM_CLASS); |
3060 SystemDictionary::always_strong_oops_do(&blk); |
2993 SystemDictionary::always_strong_oops_do(&blk); |
|
2994 ClassLoaderDataGraph::always_strong_oops_do(&blk, NULL, false); |
3061 if (blk.stopped()) { |
2995 if (blk.stopped()) { |
3062 return false; |
2996 return false; |
3063 } |
2997 } |
3064 |
2998 |
3065 // Inflated monitors |
2999 // Inflated monitors |
3211 ObjectMarker::mark(o); |
3145 ObjectMarker::mark(o); |
3212 |
3146 |
3213 // instance |
3147 // instance |
3214 if (o->is_instance()) { |
3148 if (o->is_instance()) { |
3215 if (o->klass() == SystemDictionary::Class_klass()) { |
3149 if (o->klass() == SystemDictionary::Class_klass()) { |
3216 o = klassOop_if_java_lang_Class(o); |
3150 if (!java_lang_Class::is_primitive(o)) { |
3217 if (o->is_klass()) { |
|
3218 // a java.lang.Class |
3151 // a java.lang.Class |
3219 return iterate_over_class(klassOop(o)); |
3152 return iterate_over_class(o); |
3220 } |
3153 } |
3221 } else { |
3154 } else { |
3222 return iterate_over_object(o); |
3155 return iterate_over_object(o); |
3223 } |
3156 } |
3224 } |
3157 } |