From c6607dbc2946589935a9ad0de2d5362a29e7f7f2 Mon Sep 17 00:00:00 2001 From: Denghui Dong Date: Fri, 14 Feb 2020 22:42:04 +0800 Subject: [PATCH] [Backport] 8231081: TestMetadataRetention fails due to missing symbol id Summary: Test Plan: jdk/jfr Reviewed-by: yuleil Issue: https://github.com/alibaba/dragonwell8/issues/112 --- .../checkpoint/jfrCheckpointManager.cpp | 37 ++++++- .../jfr/recorder/checkpoint/types/jfrType.cpp | 25 ----- .../jfr/recorder/checkpoint/types/jfrType.hpp | 13 --- .../checkpoint/types/jfrTypeManager.cpp | 39 +------ .../checkpoint/types/jfrTypeManager.hpp | 4 +- .../recorder/checkpoint/types/jfrTypeSet.cpp | 37 +++++-- .../recorder/checkpoint/types/jfrTypeSet.hpp | 1 + .../checkpoint/types/jfrTypeSetUtils.cpp | 103 +++++++----------- .../checkpoint/types/jfrTypeSetUtils.hpp | 6 +- 9 files changed, 108 insertions(+), 157 deletions(-) diff --git a/src/share/vm/jfr/recorder/checkpoint/jfrCheckpointManager.cpp b/src/share/vm/jfr/recorder/checkpoint/jfrCheckpointManager.cpp index 28c9a9402..f1457a9d3 100644 --- a/src/share/vm/jfr/recorder/checkpoint/jfrCheckpointManager.cpp +++ b/src/share/vm/jfr/recorder/checkpoint/jfrCheckpointManager.cpp @@ -24,15 +24,18 @@ #include "precompiled.hpp" #include "classfile/javaClasses.hpp" -#include "jfr/recorder/jfrRecorder.hpp" +#include "jfr/leakprofiler/checkpoint/objectSampleCheckpoint.hpp" +#include "jfr/leakprofiler/leakProfiler.hpp" #include "jfr/recorder/checkpoint/jfrCheckpointManager.hpp" #include "jfr/recorder/checkpoint/jfrCheckpointWriter.hpp" #include "jfr/recorder/checkpoint/types/jfrTypeManager.hpp" +#include "jfr/recorder/checkpoint/types/jfrTypeSet.hpp" #include "jfr/recorder/checkpoint/types/traceid/jfrTraceIdEpoch.hpp" +#include "jfr/recorder/jfrRecorder.hpp" +#include "jfr/recorder/repository/jfrChunkWriter.hpp" #include "jfr/recorder/service/jfrOptionSet.hpp" #include "jfr/recorder/storage/jfrMemorySpace.inline.hpp" #include "jfr/recorder/storage/jfrStorageUtils.inline.hpp" -#include "jfr/recorder/repository/jfrChunkWriter.hpp" #include "jfr/utilities/jfrBigEndian.hpp" #include "jfr/utilities/jfrTypes.hpp" #include "memory/resourceArea.hpp" @@ -80,7 +83,7 @@ JfrCheckpointManager::~JfrCheckpointManager() { if (_lock != NULL) { delete _lock; } - JfrTypeManager::clear(); + JfrTypeManager::destroy(); } static const size_t unlimited_mspace_size = 0; @@ -332,6 +335,7 @@ size_t JfrCheckpointManager::write_epoch_transition_mspace() { typedef DiscardOp > DiscardOperation; size_t JfrCheckpointManager::clear() { + JfrTypeSet::clear(); DiscardOperation discarder(mutexed); // mutexed discard mode process_free_list(discarder, _free_list_mspace); process_free_list(discarder, _epoch_transition_mspace); @@ -353,12 +357,35 @@ size_t JfrCheckpointManager::write_safepoint_types() { } void JfrCheckpointManager::write_type_set() { - JfrTypeManager::write_type_set(); + assert(!SafepointSynchronize::is_at_safepoint(), "invariant"); + // can safepoint here + // TODO: CLDG lock does not exist in 11 - what shall we do? + // MutexLocker cld_lock(ClassLoaderDataGraph_lock); + MutexLocker package_table_lock(PackageTable_lock); + if (!LeakProfiler::is_running()) { + JfrCheckpointWriter writer(true, true, Thread::current()); + JfrTypeSet::serialize(&writer, NULL, false); + return; + } + Thread* const t = Thread::current(); + JfrCheckpointWriter leakp_writer(false, true, t); + JfrCheckpointWriter writer(false, true, t); + JfrTypeSet::serialize(&writer, &leakp_writer, false); + ObjectSampleCheckpoint::on_type_set(leakp_writer); } void JfrCheckpointManager::write_type_set_for_unloaded_classes() { assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint!"); - JfrTypeManager::write_type_set_for_unloaded_classes(); + JfrCheckpointWriter writer(false, true, Thread::current()); + const JfrCheckpointContext ctx = writer.context(); + JfrTypeSet::serialize(&writer, NULL, true); + if (LeakProfiler::is_running()) { + ObjectSampleCheckpoint::on_type_set_unload(writer); + } + if (!JfrRecorder::is_recording()) { + // discard by rewind + writer.set_context(ctx); + } } void JfrCheckpointManager::create_thread_blob(JavaThread* jt) { diff --git a/src/share/vm/jfr/recorder/checkpoint/types/jfrType.cpp b/src/share/vm/jfr/recorder/checkpoint/types/jfrType.cpp index e513abc63..f717ae6fb 100644 --- a/src/share/vm/jfr/recorder/checkpoint/types/jfrType.cpp +++ b/src/share/vm/jfr/recorder/checkpoint/types/jfrType.cpp @@ -36,7 +36,6 @@ #include "jfr/recorder/jfrRecorder.hpp" #include "jfr/recorder/checkpoint/types/jfrThreadGroup.hpp" #include "jfr/recorder/checkpoint/types/jfrThreadState.hpp" -#include "jfr/recorder/checkpoint/types/jfrTypeSet.hpp" #include "jfr/support/jfrThreadLocal.hpp" #include "jfr/writers/jfrJavaEventWriter.hpp" #include "memory/metaspaceGCThresholdUpdater.hpp" @@ -292,30 +291,6 @@ void VMOperationTypeConstant::serialize(JfrCheckpointWriter& writer) { } } -class TypeSetSerialization { - private: - JfrCheckpointWriter* _leakp_writer; - bool _class_unload; - public: - TypeSetSerialization(bool class_unload, JfrCheckpointWriter* leakp_writer = NULL) : - _leakp_writer(leakp_writer), _class_unload(class_unload) {} - void write(JfrCheckpointWriter& writer) { - JfrTypeSet::serialize(&writer, _leakp_writer, _class_unload); - } -}; - -void ClassUnloadTypeSet::serialize(JfrCheckpointWriter& writer) { - TypeSetSerialization type_set(true); - type_set.write(writer); -}; - -TypeSet::TypeSet(JfrCheckpointWriter* leakp_writer) : _leakp_writer(leakp_writer) {} - -void TypeSet::serialize(JfrCheckpointWriter& writer) { - TypeSetSerialization type_set(false, _leakp_writer); - type_set.write(writer); -}; - void ThreadStateConstant::serialize(JfrCheckpointWriter& writer) { JfrThreadState::serialize(writer); } diff --git a/src/share/vm/jfr/recorder/checkpoint/types/jfrType.hpp b/src/share/vm/jfr/recorder/checkpoint/types/jfrType.hpp index a33fe3981..cddbc43aa 100644 --- a/src/share/vm/jfr/recorder/checkpoint/types/jfrType.hpp +++ b/src/share/vm/jfr/recorder/checkpoint/types/jfrType.hpp @@ -37,11 +37,6 @@ class JfrThreadGroupConstant : public JfrSerializer { void serialize(JfrCheckpointWriter& writer); }; -class ClassUnloadTypeSet : public JfrSerializer { - public: - void serialize(JfrCheckpointWriter& writer); -}; - class FlagValueOriginConstant : public JfrSerializer { public: void serialize(JfrCheckpointWriter& writer); @@ -117,14 +112,6 @@ class VMOperationTypeConstant : public JfrSerializer { void serialize(JfrCheckpointWriter& writer); }; -class TypeSet : public JfrSerializer { - private: - JfrCheckpointWriter* _leakp_writer; - public: - explicit TypeSet(JfrCheckpointWriter* leakp_writer = NULL); - void serialize(JfrCheckpointWriter& writer); -}; - class ThreadStateConstant : public JfrSerializer { public: void serialize(JfrCheckpointWriter& writer); diff --git a/src/share/vm/jfr/recorder/checkpoint/types/jfrTypeManager.cpp b/src/share/vm/jfr/recorder/checkpoint/types/jfrTypeManager.cpp index 916956457..135491dd9 100644 --- a/src/share/vm/jfr/recorder/checkpoint/types/jfrTypeManager.cpp +++ b/src/share/vm/jfr/recorder/checkpoint/types/jfrTypeManager.cpp @@ -23,9 +23,6 @@ */ #include "precompiled.hpp" -#include "jfr/jfr.hpp" -#include "jfr/leakprofiler/leakProfiler.hpp" -#include "jfr/leakprofiler/checkpoint/objectSampleCheckpoint.hpp" #include "jfr/metadata/jfrSerializer.hpp" #include "jfr/recorder/checkpoint/jfrCheckpointWriter.hpp" #include "jfr/recorder/checkpoint/types/jfrType.hpp" @@ -35,9 +32,9 @@ #include "memory/resourceArea.hpp" #include "runtime/handles.inline.hpp" #include "runtime/safepoint.hpp" +#include "runtime/semaphore.hpp" #include "runtime/thread.inline.hpp" #include "utilities/exceptions.hpp" -#include "runtime/semaphore.hpp" class JfrSerializerRegistration : public JfrCHeapObj { private: @@ -120,7 +117,7 @@ typedef StopOnNullIterator Iterator; static List types; static List safepoint_types; -void JfrTypeManager::clear() { +void JfrTypeManager::destroy() { SerializerRegistrationGuard guard; Iterator iter(types); JfrSerializerRegistration* registration; @@ -152,38 +149,6 @@ void JfrTypeManager::write_safepoint_types(JfrCheckpointWriter& writer) { } } -void JfrTypeManager::write_type_set() { - assert(!SafepointSynchronize::is_at_safepoint(), "invariant"); - // can safepoint here - MutexLocker module_lock(PackageTable_lock); - if (!LeakProfiler::is_running()) { - JfrCheckpointWriter writer(true, true, Thread::current()); - TypeSet set; - set.serialize(writer); - return; - } - JfrCheckpointWriter leakp_writer(false, true, Thread::current()); - JfrCheckpointWriter writer(false, true, Thread::current()); - TypeSet set(&leakp_writer); - set.serialize(writer); - ObjectSampleCheckpoint::on_type_set(leakp_writer); -} - -void JfrTypeManager::write_type_set_for_unloaded_classes() { - assert(SafepointSynchronize::is_at_safepoint(), "invariant"); - JfrCheckpointWriter writer(false, true, Thread::current()); - const JfrCheckpointContext ctx = writer.context(); - ClassUnloadTypeSet class_unload_set; - class_unload_set.serialize(writer); - if (LeakProfiler::is_running()) { - ObjectSampleCheckpoint::on_type_set_unload(writer); - } - if (!Jfr::is_recording()) { - // discard anything written - writer.set_context(ctx); - } -} - void JfrTypeManager::create_thread_blob(JavaThread* jt) { assert(jt != NULL, "invariant"); ResourceMark rm(jt); diff --git a/src/share/vm/jfr/recorder/checkpoint/types/jfrTypeManager.hpp b/src/share/vm/jfr/recorder/checkpoint/types/jfrTypeManager.hpp index 0bd195d72..50b01024b 100644 --- a/src/share/vm/jfr/recorder/checkpoint/types/jfrTypeManager.hpp +++ b/src/share/vm/jfr/recorder/checkpoint/types/jfrTypeManager.hpp @@ -32,11 +32,9 @@ class JfrCheckpointWriter; class JfrTypeManager : public AllStatic { public: static bool initialize(); - static void clear(); + static void destroy(); static void write_types(JfrCheckpointWriter& writer); static void write_safepoint_types(JfrCheckpointWriter& writer); - static void write_type_set(); - static void write_type_set_for_unloaded_classes(); static void create_thread_blob(JavaThread* jt); static void write_thread_checkpoint(JavaThread* jt); }; diff --git a/src/share/vm/jfr/recorder/checkpoint/types/jfrTypeSet.cpp b/src/share/vm/jfr/recorder/checkpoint/types/jfrTypeSet.cpp index 81bb4107f..6eff9c222 100644 --- a/src/share/vm/jfr/recorder/checkpoint/types/jfrTypeSet.cpp +++ b/src/share/vm/jfr/recorder/checkpoint/types/jfrTypeSet.cpp @@ -108,7 +108,6 @@ inline uintptr_t package_name_hash(const char *s) { return val; } -/** static traceid package_id(KlassPtr klass, JfrArtifactSet* artifacts) { assert(klass != NULL, "invariant"); char* klass_name = klass->name()->as_C_string(); // uses ResourceMark declared in JfrTypeSet::serialize() @@ -118,7 +117,6 @@ static traceid package_id(KlassPtr klass, JfrArtifactSet* artifacts) { } return CREATE_PACKAGE_ID(artifacts->markPackage(pkg_name, package_name_hash(pkg_name))); } -*/ static traceid method_id(KlassPtr klass, MethodPtr method) { assert(klass != NULL, "invariant"); @@ -170,8 +168,7 @@ static int write_klass(JfrCheckpointWriter* writer, KlassPtr klass, bool leakp) theklass = obj_arr_klass->bottom_klass(); } if (theklass->oop_is_instance()) { - // pkg_id = package_id(theklass, _artifacts); - pkg_id = 0; + pkg_id = package_id(theklass, _artifacts); } else { assert(theklass->oop_is_typeArray(), "invariant"); } @@ -206,9 +203,14 @@ int write__klass__leakp(JfrCheckpointWriter* writer, const void* k) { return write_klass(writer, klass, true); } +static bool is_implied(const Klass* klass) { + assert(klass != NULL, "invariant"); + return klass->is_subclass_of(SystemDictionary::ClassLoader_klass()) || klass == SystemDictionary::Object_klass(); +} + static void do_implied(Klass* klass) { assert(klass != NULL, "invariant"); - if (klass->is_subclass_of(SystemDictionary::ClassLoader_klass()) || klass == SystemDictionary::Object_klass()) { + if (is_implied(klass)) { if (_leakp_writer != NULL) { SET_LEAKP(klass); } @@ -261,6 +263,16 @@ typedef JfrTypeWriterHost KlassWriter; typedef CompositeFunctor KlassWriterRegistration; typedef JfrArtifactCallbackHost KlassCallback; +template <> +class LeakPredicate { +public: + LeakPredicate(bool class_unload) {} + bool operator()(const Klass* klass) { + assert(klass != NULL, "invariant"); + return IS_LEAKP(klass) || is_implied(klass); + } +}; + typedef LeakPredicate LeakKlassPredicate; typedef JfrPredicatedTypeWriterImplHost LeakKlassWriterImpl; typedef JfrTypeWriterHost LeakKlassWriter; @@ -308,7 +320,6 @@ int write__artifact__package(JfrCheckpointWriter* writer, const void* p) { return 1; } -/** typedef JfrTypeWriterImplHost PackageEntryWriterImpl; typedef JfrTypeWriterHost PackageEntryWriter; @@ -318,7 +329,6 @@ void write_packages() { PackageEntryWriter pw(_writer, _class_unload); _artifacts->iterate_packages(pw); } -*/ template static void do_previous_epoch_artifact(JfrArtifactClosure* callback, T* value) { @@ -657,6 +667,12 @@ static void write_symbols() { _artifacts->tally(sw); } +static bool clear_artifacts = false; + +void JfrTypeSet::clear() { + clear_artifacts = true; +} + typedef Wrapper ClearKlassBits; typedef Wrapper ClearMethodFlag; typedef MethodIteratorHost ClearKlassAndMethods; @@ -668,7 +684,7 @@ static size_t teardown() { assert(_writer != NULL, "invariant"); ClearKlassAndMethods clear(_writer); _artifacts->iterate_klasses(clear); - _artifacts->clear(); + JfrTypeSet::clear(); ++checkpoint_id; } return total_count; @@ -681,8 +697,9 @@ static void setup(JfrCheckpointWriter* writer, JfrCheckpointWriter* leakp_writer if (_artifacts == NULL) { _artifacts = new JfrArtifactSet(class_unload); } else { - _artifacts->initialize(class_unload); + _artifacts->initialize(class_unload, clear_artifacts); } + clear_artifacts = false; assert(_artifacts != NULL, "invariant"); assert(!_artifacts->has_klass_entries(), "invariant"); } @@ -699,7 +716,7 @@ size_t JfrTypeSet::serialize(JfrCheckpointWriter* writer, JfrCheckpointWriter* l if (!write_klasses()) { return 0; } - // write_packages(); + write_packages(); write_classloaders(); write_methods(); write_symbols(); diff --git a/src/share/vm/jfr/recorder/checkpoint/types/jfrTypeSet.hpp b/src/share/vm/jfr/recorder/checkpoint/types/jfrTypeSet.hpp index 4c512b916..949380271 100644 --- a/src/share/vm/jfr/recorder/checkpoint/types/jfrTypeSet.hpp +++ b/src/share/vm/jfr/recorder/checkpoint/types/jfrTypeSet.hpp @@ -31,6 +31,7 @@ class JfrCheckpointWriter; class JfrTypeSet : AllStatic { public: + static void clear(); static size_t serialize(JfrCheckpointWriter* writer, JfrCheckpointWriter* leakp_writer, bool class_unload); }; diff --git a/src/share/vm/jfr/recorder/checkpoint/types/jfrTypeSetUtils.cpp b/src/share/vm/jfr/recorder/checkpoint/types/jfrTypeSetUtils.cpp index c73fc52d5..4e0318d2c 100644 --- a/src/share/vm/jfr/recorder/checkpoint/types/jfrTypeSetUtils.cpp +++ b/src/share/vm/jfr/recorder/checkpoint/types/jfrTypeSetUtils.cpp @@ -36,6 +36,8 @@ JfrSymbolId::JfrSymbolId() : _pkg_table(new CStringTable(this)), _sym_list(NULL), _cstring_list(NULL), + _sym_query(NULL), + _cstring_query(NULL), _symbol_id_counter(1), _class_unload(false) { assert(_sym_table != NULL, "invariant"); @@ -74,9 +76,11 @@ void JfrSymbolId::clear() { assert(!_pkg_table->has_entries(), "invariant"); _sym_list = NULL; - _cstring_list = NULL; _symbol_id_counter = 1; + _sym_query = NULL; + _cstring_query = NULL; + assert(bootstrap != NULL, "invariant"); bootstrap->reset(); _cstring_list = bootstrap; @@ -96,10 +100,10 @@ void JfrSymbolId::on_link(const SymbolEntry* entry) { } bool JfrSymbolId::on_equals(uintptr_t hash, const SymbolEntry* entry) { - // query might be NULL assert(entry != NULL, "invariant"); assert(entry->hash() == hash, "invariant"); - return true; + assert(_sym_query != NULL, "invariant"); + return _sym_query == entry->literal(); } void JfrSymbolId::on_unlink(const SymbolEntry* entry) { @@ -107,18 +111,36 @@ void JfrSymbolId::on_unlink(const SymbolEntry* entry) { const_cast(entry->literal())->decrement_refcount(); } +static const char* resource_to_cstring(const char* resource_str) { + assert(resource_str != NULL, "invariant"); + const size_t length = strlen(resource_str); + char* const c_string = JfrCHeapObj::new_array(length + 1); + assert(c_string != NULL, "invariant"); + strncpy(c_string, resource_str, length + 1); + return c_string; +} + void JfrSymbolId::on_link(const CStringEntry* entry) { assert(entry != NULL, "invariant"); assert(entry->id() == 0, "invariant"); entry->set_id(++_symbol_id_counter); + const_cast(entry)->set_literal(resource_to_cstring(entry->literal())); entry->set_list_next(_cstring_list); _cstring_list = entry; } +static bool string_compare(const char* query, const char* candidate) { + assert(query != NULL, "invariant"); + assert(candidate != NULL, "invariant"); + const size_t length = strlen(query); + return strncmp(query, candidate, length) == 0; +} + bool JfrSymbolId::on_equals(uintptr_t hash, const CStringEntry* entry) { assert(entry != NULL, "invariant"); assert(entry->hash() == hash, "invariant"); - return true; + assert(_cstring_query != NULL, "invariant"); + return string_compare(_cstring_query, entry->literal()); } void JfrSymbolId::on_unlink(const CStringEntry* entry) { @@ -139,16 +161,10 @@ traceid JfrSymbolId::mark(const Symbol* symbol, bool leakp) { return mark((uintptr_t)((Symbol*)symbol)->identity_hash(), symbol, leakp); } -static unsigned int last_symbol_hash = 0; -static traceid last_symbol_id = 0; - traceid JfrSymbolId::mark(uintptr_t hash, const Symbol* data, bool leakp) { assert(data != NULL, "invariant"); assert(_sym_table != NULL, "invariant"); - if (hash == last_symbol_hash) { - assert(last_symbol_id != 0, "invariant"); - return last_symbol_id; - } + _sym_query = data; const SymbolEntry& entry = _sym_table->lookup_put(hash, data); if (_class_unload) { entry.set_unloading(); @@ -156,39 +172,24 @@ traceid JfrSymbolId::mark(uintptr_t hash, const Symbol* data, bool leakp) { if (leakp) { entry.set_leakp(); } - last_symbol_hash = hash; - last_symbol_id = entry.id(); - return last_symbol_id; + return entry.id(); } -static unsigned int last_cstring_hash_for_pkg = 0; -static traceid last_cstring_id_for_pkg = 0; -static unsigned int last_cstring_hash = 0; -static traceid last_cstring_id = 0; - traceid JfrSymbolId::markPackage(const char* name, uintptr_t hash) { assert(name != NULL, "invariant"); assert(_pkg_table != NULL, "invariant"); - if (hash == last_cstring_hash_for_pkg) { - assert(last_cstring_id_for_pkg != 0, "invariant"); - return last_cstring_id_for_pkg; - } + _cstring_query = name; const CStringEntry& entry = _pkg_table->lookup_put(hash, name); if (_class_unload) { entry.set_unloading(); } - last_cstring_hash_for_pkg = hash; - last_cstring_id_for_pkg = entry.id(); - return last_cstring_id_for_pkg; + return entry.id(); } traceid JfrSymbolId::mark(uintptr_t hash, const char* str, bool leakp) { assert(str != NULL, "invariant"); assert(_cstring_table != NULL, "invariant"); - if (hash == last_cstring_hash) { - assert(last_cstring_id != 0, "invariant"); - return last_cstring_id; - } + _cstring_query = str; const CStringEntry& entry = _cstring_table->lookup_put(hash, str); if (_class_unload) { entry.set_unloading(); @@ -196,9 +197,7 @@ traceid JfrSymbolId::mark(uintptr_t hash, const char* str, bool leakp) { if (leakp) { entry.set_leakp(); } - last_cstring_hash = hash; - last_cstring_id = entry.id(); - return last_cstring_id; + return entry.id(); } /* @@ -228,7 +227,7 @@ static const char* create_unsafe_anonymous_klass_symbol(const InstanceKlass* ik, sprintf(hash_buf, "/" UINTX_FORMAT, hash); const size_t hash_len = strlen(hash_buf); const size_t result_len = ik->name()->utf8_length(); - anonymous_symbol = JfrCHeapObj::new_array(result_len + hash_len + 1); + anonymous_symbol = NEW_RESOURCE_ARRAY(char, result_len + hash_len + 1); ik->name()->as_klass_external_name(anonymous_symbol, (int)result_len + 1); assert(strlen(anonymous_symbol) == result_len, "invariant"); strcpy(anonymous_symbol + result_len, hash_buf); @@ -241,21 +240,12 @@ bool JfrSymbolId::is_unsafe_anonymous_klass(const Klass* k) { return k->oop_is_instance() && ((const InstanceKlass*)k)->is_anonymous(); } -static unsigned int last_anonymous_hash = 0; -static traceid last_anonymous_id = 0; - traceid JfrSymbolId::mark_unsafe_anonymous_klass_name(const InstanceKlass* ik, bool leakp) { assert(ik != NULL, "invariant"); assert(ik->is_anonymous(), "invariant"); const uintptr_t hash = unsafe_anonymous_klass_name_hash(ik); - if (hash == last_anonymous_hash) { - assert(last_anonymous_id != 0, "invariant"); - return last_anonymous_id; - } - last_anonymous_hash = hash; - const CStringEntry* const entry = _cstring_table->lookup_only(hash); - last_anonymous_id = entry != NULL ? entry->id() : mark(hash, create_unsafe_anonymous_klass_symbol(ik, hash), leakp); - return last_anonymous_id; + const char* const anonymous_klass_symbol = create_unsafe_anonymous_klass_symbol(ik, hash); + return mark(hash, anonymous_klass_symbol, leakp); } traceid JfrSymbolId::mark(const Klass* k, bool leakp) { @@ -275,24 +265,20 @@ traceid JfrSymbolId::mark(const Klass* k, bool leakp) { return symbol_id; } -static void reset_symbol_caches() { - last_anonymous_hash = 0; - last_symbol_hash = 0; - last_cstring_hash = 0; - last_cstring_hash_for_pkg = 0; -} - JfrArtifactSet::JfrArtifactSet(bool class_unload) : _symbol_id(new JfrSymbolId()), - _klass_list(NULL), - _total_count(0) { + _klass_list(NULL), + _total_count(0) { initialize(class_unload); assert(_klass_list != NULL, "invariant"); } static const size_t initial_class_list_size = 200; -void JfrArtifactSet::initialize(bool class_unload) { +void JfrArtifactSet::initialize(bool class_unload, bool clear /* false */) { assert(_symbol_id != NULL, "invariant"); + if (clear) { + _symbol_id->clear(); + } _symbol_id->set_class_unload(class_unload); _total_count = 0; // resource allocation @@ -300,13 +286,8 @@ void JfrArtifactSet::initialize(bool class_unload) { } JfrArtifactSet::~JfrArtifactSet() { - clear(); - delete _symbol_id; -} - -void JfrArtifactSet::clear() { - reset_symbol_caches(); _symbol_id->clear(); + delete _symbol_id; // _klass_list will be cleared by a ResourceMark } diff --git a/src/share/vm/jfr/recorder/checkpoint/types/jfrTypeSetUtils.hpp b/src/share/vm/jfr/recorder/checkpoint/types/jfrTypeSetUtils.hpp index 61287bfab..5634ccc9d 100644 --- a/src/share/vm/jfr/recorder/checkpoint/types/jfrTypeSetUtils.hpp +++ b/src/share/vm/jfr/recorder/checkpoint/types/jfrTypeSetUtils.hpp @@ -228,6 +228,8 @@ class JfrSymbolId : public JfrCHeapObj { CStringTable* _pkg_table; const SymbolEntry* _sym_list; const CStringEntry* _cstring_list; + const Symbol* _sym_query; + const char* _cstring_query; traceid _symbol_id_counter; bool _class_unload; @@ -313,9 +315,7 @@ class JfrArtifactSet : public JfrCHeapObj { ~JfrArtifactSet(); // caller needs ResourceMark - void initialize(bool class_unload); - void clear(); - + void initialize(bool class_unload, bool clear = false); traceid mark(uintptr_t hash, const Symbol* sym, bool leakp); traceid mark(const Klass* klass, bool leakp); -- GitLab