Skip to content

Commit 2508bc7

Browse files
committedDec 2, 2020
8257140: Crash in JvmtiTagMap::flush_object_free_events()
Reviewed-by: sspitsyn, kbarrett
1 parent cfb50a9 commit 2508bc7

File tree

5 files changed

+25
-8
lines changed

5 files changed

+25
-8
lines changed
 

‎src/hotspot/share/prims/jvmtiEnvBase.cpp

+5-5
Original file line numberDiff line numberDiff line change
@@ -256,11 +256,11 @@ JvmtiEnvBase::env_dispose() {
256256
// Same situation as with events (see above)
257257
set_native_method_prefixes(0, NULL);
258258

259-
JvmtiTagMap* tag_map_to_deallocate = _tag_map;
260-
set_tag_map(NULL);
261-
// A tag map can be big, deallocate it now
262-
if (tag_map_to_deallocate != NULL) {
263-
delete tag_map_to_deallocate;
259+
JvmtiTagMap* tag_map_to_clear = tag_map_acquire();
260+
// A tag map can be big, clear it now to save memory until
261+
// the destructor runs.
262+
if (tag_map_to_clear != NULL) {
263+
tag_map_to_clear->clear();
264264
}
265265

266266
_needs_clean_up = true;

‎src/hotspot/share/prims/jvmtiTagMap.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,14 @@ JvmtiTagMap::~JvmtiTagMap() {
9797
_hashmap = NULL;
9898
}
9999

100+
// Called by env_dispose() to reclaim memory before deallocation.
101+
// Remove all the entries but keep the empty table intact.
102+
// This needs the table lock.
103+
void JvmtiTagMap::clear() {
104+
MutexLocker ml(lock(), Mutex::_no_safepoint_check_flag);
105+
_hashmap->clear();
106+
}
107+
100108
// returns the tag map for the given environments. If the tag map
101109
// doesn't exist then it is created.
102110
JvmtiTagMap* JvmtiTagMap::tag_map_for(JvmtiEnv* env) {

‎src/hotspot/share/prims/jvmtiTagMap.hpp

+1
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ class JvmtiTagMap : public CHeapObj<mtInternal> {
119119
static void gc_notification(size_t num_dead_entries) NOT_JVMTI_RETURN;
120120

121121
void flush_object_free_events();
122+
void clear(); // Clear tagmap table after the env is disposed.
122123

123124
// For ServiceThread
124125
static void flush_all_object_free_events() NOT_JVMTI_RETURN;

‎src/hotspot/share/prims/jvmtiTagMapTable.cpp

+10-3
Original file line numberDiff line numberDiff line change
@@ -49,21 +49,28 @@ oop JvmtiTagMapEntry::object_no_keepalive() {
4949
JvmtiTagMapTable::JvmtiTagMapTable()
5050
: Hashtable<WeakHandle, mtServiceability>(_table_size, sizeof(JvmtiTagMapEntry)) {}
5151

52-
JvmtiTagMapTable::~JvmtiTagMapTable() {
53-
// Delete this table
54-
log_debug(jvmti, table)("JvmtiTagMapTable deleted");
52+
void JvmtiTagMapTable::clear() {
53+
// Clear this table
54+
log_debug(jvmti, table)("JvmtiTagMapTable cleared");
5555
for (int i = 0; i < table_size(); ++i) {
5656
for (JvmtiTagMapEntry* m = bucket(i); m != NULL;) {
5757
JvmtiTagMapEntry* entry = m;
5858
// read next before freeing.
5959
m = m->next();
6060
free_entry(entry);
6161
}
62+
JvmtiTagMapEntry** p = bucket_addr(i);
63+
*p = NULL; // clear out buckets.
6264
}
6365
assert(number_of_entries() == 0, "should have removed all entries");
6466
assert(new_entry_free_list() == NULL, "entry present on JvmtiTagMapTable's free list");
6567
}
6668

69+
JvmtiTagMapTable::~JvmtiTagMapTable() {
70+
clear();
71+
// base class ~BasicHashtable deallocates the buckets.
72+
}
73+
6774
// Entries are C_Heap allocated
6875
JvmtiTagMapEntry* JvmtiTagMapTable::new_entry(unsigned int hash, WeakHandle w, jlong tag) {
6976
JvmtiTagMapEntry* entry = (JvmtiTagMapEntry*)Hashtable<WeakHandle, mtServiceability>::allocate_new_entry(hash, w);

‎src/hotspot/share/prims/jvmtiTagMapTable.hpp

+1
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ class JvmtiTagMapTable : public Hashtable<WeakHandle, mtServiceability> {
9090
// Cleanup cleared entries and post
9191
void remove_dead_entries(JvmtiEnv* env, bool post_object_free);
9292
void rehash();
93+
void clear();
9394
};
9495

9596
// A supporting class for iterating over all entries in Hashmap

0 commit comments

Comments
 (0)
Please sign in to comment.