Skip to content
This repository has been archived by the owner before Nov 9, 2022. It is now read-only.
Permalink
Browse files
8257140: Crash in JvmtiTagMap::flush_object_free_events()
Reviewed-by: sspitsyn, kbarrett
  • Loading branch information
coleenp committed Dec 2, 2020
1 parent cfb50a9 commit 2508bc7c58b631c41f1c2415dd9925d9d309dbe8
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 8 deletions.
@@ -256,11 +256,11 @@ JvmtiEnvBase::env_dispose() {
// Same situation as with events (see above)
set_native_method_prefixes(0, NULL);

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

_needs_clean_up = true;
@@ -97,6 +97,14 @@ JvmtiTagMap::~JvmtiTagMap() {
_hashmap = NULL;
}

// Called by env_dispose() to reclaim memory before deallocation.
// Remove all the entries but keep the empty table intact.
// This needs the table lock.
void JvmtiTagMap::clear() {
MutexLocker ml(lock(), Mutex::_no_safepoint_check_flag);
_hashmap->clear();
}

// returns the tag map for the given environments. If the tag map
// doesn't exist then it is created.
JvmtiTagMap* JvmtiTagMap::tag_map_for(JvmtiEnv* env) {
@@ -119,6 +119,7 @@ class JvmtiTagMap : public CHeapObj<mtInternal> {
static void gc_notification(size_t num_dead_entries) NOT_JVMTI_RETURN;

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

// For ServiceThread
static void flush_all_object_free_events() NOT_JVMTI_RETURN;
@@ -49,21 +49,28 @@ oop JvmtiTagMapEntry::object_no_keepalive() {
JvmtiTagMapTable::JvmtiTagMapTable()
: Hashtable<WeakHandle, mtServiceability>(_table_size, sizeof(JvmtiTagMapEntry)) {}

JvmtiTagMapTable::~JvmtiTagMapTable() {
// Delete this table
log_debug(jvmti, table)("JvmtiTagMapTable deleted");
void JvmtiTagMapTable::clear() {
// Clear this table
log_debug(jvmti, table)("JvmtiTagMapTable cleared");
for (int i = 0; i < table_size(); ++i) {
for (JvmtiTagMapEntry* m = bucket(i); m != NULL;) {
JvmtiTagMapEntry* entry = m;
// read next before freeing.
m = m->next();
free_entry(entry);
}
JvmtiTagMapEntry** p = bucket_addr(i);
*p = NULL; // clear out buckets.
}
assert(number_of_entries() == 0, "should have removed all entries");
assert(new_entry_free_list() == NULL, "entry present on JvmtiTagMapTable's free list");
}

JvmtiTagMapTable::~JvmtiTagMapTable() {
clear();
// base class ~BasicHashtable deallocates the buckets.
}

// Entries are C_Heap allocated
JvmtiTagMapEntry* JvmtiTagMapTable::new_entry(unsigned int hash, WeakHandle w, jlong tag) {
JvmtiTagMapEntry* entry = (JvmtiTagMapEntry*)Hashtable<WeakHandle, mtServiceability>::allocate_new_entry(hash, w);
@@ -90,6 +90,7 @@ class JvmtiTagMapTable : public Hashtable<WeakHandle, mtServiceability> {
// Cleanup cleared entries and post
void remove_dead_entries(JvmtiEnv* env, bool post_object_free);
void rehash();
void clear();
};

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

0 comments on commit 2508bc7

Please sign in to comment.