53 // |
53 // |
54 // Each entry encapsulates a reference to the tagged object |
54 // Each entry encapsulates a reference to the tagged object |
55 // and the tag value. In addition an entry includes a next pointer which |
55 // and the tag value. In addition an entry includes a next pointer which |
56 // is used to chain entries together. |
56 // is used to chain entries together. |
57 |
57 |
58 class JvmtiTagHashmapEntry : public CHeapObj { |
58 class JvmtiTagHashmapEntry : public CHeapObj<mtInternal> { |
59 private: |
59 private: |
60 friend class JvmtiTagMap; |
60 friend class JvmtiTagMap; |
61 |
61 |
62 oop _object; // tagged object |
62 oop _object; // tagged object |
63 jlong _tag; // the tag |
63 jlong _tag; // the tag |
104 // |
104 // |
105 // A hashmap provides functions for adding, removing, and finding |
105 // A hashmap provides functions for adding, removing, and finding |
106 // entries. It also provides a function to iterate over all entries |
106 // entries. It also provides a function to iterate over all entries |
107 // in the hashmap. |
107 // in the hashmap. |
108 |
108 |
109 class JvmtiTagHashmap : public CHeapObj { |
109 class JvmtiTagHashmap : public CHeapObj<mtInternal> { |
110 private: |
110 private: |
111 friend class JvmtiTagMap; |
111 friend class JvmtiTagMap; |
112 |
112 |
113 enum { |
113 enum { |
114 small_trace_threshold = 10000, // threshold for tracing |
114 small_trace_threshold = 10000, // threshold for tracing |
148 } |
148 } |
149 _load_factor = load_factor; |
149 _load_factor = load_factor; |
150 _resize_threshold = (int)(_load_factor * _size); |
150 _resize_threshold = (int)(_load_factor * _size); |
151 _resizing_enabled = true; |
151 _resizing_enabled = true; |
152 size_t s = initial_size * sizeof(JvmtiTagHashmapEntry*); |
152 size_t s = initial_size * sizeof(JvmtiTagHashmapEntry*); |
153 _table = (JvmtiTagHashmapEntry**)os::malloc(s); |
153 _table = (JvmtiTagHashmapEntry**)os::malloc(s, mtInternal); |
154 if (_table == NULL) { |
154 if (_table == NULL) { |
155 vm_exit_out_of_memory(s, "unable to allocate initial hashtable for jvmti object tags"); |
155 vm_exit_out_of_memory(s, "unable to allocate initial hashtable for jvmti object tags"); |
156 } |
156 } |
157 for (int i=0; i<initial_size; i++) { |
157 for (int i=0; i<initial_size; i++) { |
158 _table[i] = NULL; |
158 _table[i] = NULL; |
186 return; |
186 return; |
187 } |
187 } |
188 |
188 |
189 // allocate new table |
189 // allocate new table |
190 size_t s = new_size * sizeof(JvmtiTagHashmapEntry*); |
190 size_t s = new_size * sizeof(JvmtiTagHashmapEntry*); |
191 JvmtiTagHashmapEntry** new_table = (JvmtiTagHashmapEntry**)os::malloc(s); |
191 JvmtiTagHashmapEntry** new_table = (JvmtiTagHashmapEntry**)os::malloc(s, mtInternal); |
192 if (new_table == NULL) { |
192 if (new_table == NULL) { |
193 warning("unable to allocate larger hashtable for jvmti object tags"); |
193 warning("unable to allocate larger hashtable for jvmti object tags"); |
194 set_resizing_enabled(false); |
194 set_resizing_enabled(false); |
195 return; |
195 return; |
196 } |
196 } |
774 |
774 |
775 // Helper class used to describe the static or instance fields of a class. |
775 // 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), |
776 // For each field it holds the field index (as defined by the JVMTI specification), |
777 // the field type, and the offset. |
777 // the field type, and the offset. |
778 |
778 |
779 class ClassFieldDescriptor: public CHeapObj { |
779 class ClassFieldDescriptor: public CHeapObj<mtInternal> { |
780 private: |
780 private: |
781 int _field_index; |
781 int _field_index; |
782 int _field_offset; |
782 int _field_offset; |
783 char _field_type; |
783 char _field_type; |
784 public: |
784 public: |
788 int field_index() const { return _field_index; } |
788 int field_index() const { return _field_index; } |
789 char field_type() const { return _field_type; } |
789 char field_type() const { return _field_type; } |
790 int field_offset() const { return _field_offset; } |
790 int field_offset() const { return _field_offset; } |
791 }; |
791 }; |
792 |
792 |
793 class ClassFieldMap: public CHeapObj { |
793 class ClassFieldMap: public CHeapObj<mtInternal> { |
794 private: |
794 private: |
795 enum { |
795 enum { |
796 initial_field_count = 5 |
796 initial_field_count = 5 |
797 }; |
797 }; |
798 |
798 |
819 static ClassFieldMap* create_map_of_static_fields(klassOop k); |
819 static ClassFieldMap* create_map_of_static_fields(klassOop k); |
820 static ClassFieldMap* create_map_of_instance_fields(oop obj); |
820 static ClassFieldMap* create_map_of_instance_fields(oop obj); |
821 }; |
821 }; |
822 |
822 |
823 ClassFieldMap::ClassFieldMap() { |
823 ClassFieldMap::ClassFieldMap() { |
824 _fields = new (ResourceObj::C_HEAP) GrowableArray<ClassFieldDescriptor*>(initial_field_count, true); |
824 _fields = new (ResourceObj::C_HEAP, mtInternal) |
|
825 GrowableArray<ClassFieldDescriptor*>(initial_field_count, true); |
825 } |
826 } |
826 |
827 |
827 ClassFieldMap::~ClassFieldMap() { |
828 ClassFieldMap::~ClassFieldMap() { |
828 for (int i=0; i<_fields->length(); i++) { |
829 for (int i=0; i<_fields->length(); i++) { |
829 delete _fields->at(i); |
830 delete _fields->at(i); |
890 // Helper class used to cache a ClassFileMap for the instance fields of |
891 // Helper class used to cache a ClassFileMap for the instance fields of |
891 // a cache. A JvmtiCachedClassFieldMap can be cached by an instanceKlass during |
892 // a cache. A JvmtiCachedClassFieldMap can be cached by an instanceKlass during |
892 // heap iteration and avoid creating a field map for each object in the heap |
893 // heap iteration and avoid creating a field map for each object in the heap |
893 // (only need to create the map when the first instance of a class is encountered). |
894 // (only need to create the map when the first instance of a class is encountered). |
894 // |
895 // |
895 class JvmtiCachedClassFieldMap : public CHeapObj { |
896 class JvmtiCachedClassFieldMap : public CHeapObj<mtInternal> { |
896 private: |
897 private: |
897 enum { |
898 enum { |
898 initial_class_count = 200 |
899 initial_class_count = 200 |
899 }; |
900 }; |
900 ClassFieldMap* _field_map; |
901 ClassFieldMap* _field_map; |
955 |
956 |
956 |
957 |
957 // record that the given instanceKlass is caching a field map |
958 // record that the given instanceKlass is caching a field map |
958 void JvmtiCachedClassFieldMap::add_to_class_list(instanceKlass* ik) { |
959 void JvmtiCachedClassFieldMap::add_to_class_list(instanceKlass* ik) { |
959 if (_class_list == NULL) { |
960 if (_class_list == NULL) { |
960 _class_list = new (ResourceObj::C_HEAP) GrowableArray<instanceKlass*>(initial_class_count, true); |
961 _class_list = new (ResourceObj::C_HEAP, mtInternal) |
|
962 GrowableArray<instanceKlass*>(initial_class_count, true); |
961 } |
963 } |
962 _class_list->push(ik); |
964 _class_list->push(ik); |
963 } |
965 } |
964 |
966 |
965 // returns the instance field map for the given object |
967 // returns the instance field map for the given object |
1524 public: |
1526 public: |
1525 TagObjectCollector(JvmtiEnv* env, const jlong* tags, jint tag_count) { |
1527 TagObjectCollector(JvmtiEnv* env, const jlong* tags, jint tag_count) { |
1526 _env = env; |
1528 _env = env; |
1527 _tags = (jlong*)tags; |
1529 _tags = (jlong*)tags; |
1528 _tag_count = tag_count; |
1530 _tag_count = tag_count; |
1529 _object_results = new (ResourceObj::C_HEAP) GrowableArray<jobject>(1,true); |
1531 _object_results = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<jobject>(1,true); |
1530 _tag_results = new (ResourceObj::C_HEAP) GrowableArray<uint64_t>(1,true); |
1532 _tag_results = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<uint64_t>(1,true); |
1531 } |
1533 } |
1532 |
1534 |
1533 ~TagObjectCollector() { |
1535 ~TagObjectCollector() { |
1534 delete _object_results; |
1536 delete _object_results; |
1535 delete _tag_results; |
1537 delete _tag_results; |
1670 |
1672 |
1671 // prepare heap for iteration |
1673 // prepare heap for iteration |
1672 Universe::heap()->ensure_parsability(false); // no need to retire TLABs |
1674 Universe::heap()->ensure_parsability(false); // no need to retire TLABs |
1673 |
1675 |
1674 // create stacks for interesting headers |
1676 // create stacks for interesting headers |
1675 _saved_mark_stack = new (ResourceObj::C_HEAP) GrowableArray<markOop>(4000, true); |
1677 _saved_mark_stack = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<markOop>(4000, true); |
1676 _saved_oop_stack = new (ResourceObj::C_HEAP) GrowableArray<oop>(4000, true); |
1678 _saved_oop_stack = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<oop>(4000, true); |
1677 |
1679 |
1678 if (UseBiasedLocking) { |
1680 if (UseBiasedLocking) { |
1679 BiasedLocking::preserve_marks(); |
1681 BiasedLocking::preserve_marks(); |
1680 } |
1682 } |
1681 } |
1683 } |
2710 bool _reporting_primitive_fields; // optional reporting |
2712 bool _reporting_primitive_fields; // optional reporting |
2711 bool _reporting_primitive_array_values; |
2713 bool _reporting_primitive_array_values; |
2712 bool _reporting_string_values; |
2714 bool _reporting_string_values; |
2713 |
2715 |
2714 GrowableArray<oop>* create_visit_stack() { |
2716 GrowableArray<oop>* create_visit_stack() { |
2715 return new (ResourceObj::C_HEAP) GrowableArray<oop>(initial_visit_stack_size, true); |
2717 return new (ResourceObj::C_HEAP, mtInternal) GrowableArray<oop>(initial_visit_stack_size, true); |
2716 } |
2718 } |
2717 |
2719 |
2718 // accessors |
2720 // accessors |
2719 bool is_advanced_heap_walk() const { return _is_advanced_heap_walk; } |
2721 bool is_advanced_heap_walk() const { return _is_advanced_heap_walk; } |
2720 JvmtiTagMap* tag_map() const { return _tag_map; } |
2722 JvmtiTagMap* tag_map() const { return _tag_map; } |