Mercurial > hg > truffle
comparison src/share/vm/prims/jvmtiTagMap.cpp @ 6725:da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
Summary: Remove PermGen, allocate meta-data in metaspace linked to class loaders, rewrite GC walking, rewrite and rename metadata to be C++ classes
Reviewed-by: jmasa, stefank, never, coleenp, kvn, brutisso, mgerdin, dholmes, jrose, twisti, roland
Contributed-by: jmasa <jon.masamitsu@oracle.com>, stefank <stefan.karlsson@oracle.com>, mgerdin <mikael.gerdin@oracle.com>, never <tom.rodriguez@oracle.com>
author | coleenp |
---|---|
date | Sat, 01 Sep 2012 13:25:18 -0400 |
parents | 1d7922586cf6 |
children | aed758eda82a |
comparison
equal
deleted
inserted
replaced
6724:36d1d483d5d6 | 6725:da91efe96a93 |
---|---|
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. |
565 JvmtiTagHashmap* _hashmap; | 554 JvmtiTagHashmap* _hashmap; |
566 JvmtiTagHashmapEntry* _entry; | 555 JvmtiTagHashmapEntry* _entry; |
567 oop _o; | 556 oop _o; |
568 jlong _obj_size; | 557 jlong _obj_size; |
569 jlong _obj_tag; | 558 jlong _obj_tag; |
570 klassOop _klass; // the object's class | |
571 jlong _klass_tag; | 559 jlong _klass_tag; |
572 | 560 |
573 protected: | 561 protected: |
574 JvmtiTagMap* tag_map() const { return _tag_map; } | 562 JvmtiTagMap* tag_map() const { return _tag_map; } |
575 | 563 |
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 } |