8270059: Remove KVHashtable

Reviewed-by: dholmes, coleenp
This commit is contained in:
Ioi Lam 2021-07-09 19:29:13 +00:00
parent 7bfa39f59a
commit d6c0f5fa22
6 changed files with 23 additions and 127 deletions

View file

@ -160,7 +160,7 @@ ArchiveBuilder::ArchiveBuilder() :
_ro_region("ro", MAX_SHARED_DELTA), _ro_region("ro", MAX_SHARED_DELTA),
_rw_src_objs(), _rw_src_objs(),
_ro_src_objs(), _ro_src_objs(),
_src_obj_table(INITIAL_TABLE_SIZE), _src_obj_table(INITIAL_TABLE_SIZE, MAX_TABLE_SIZE),
_num_instance_klasses(0), _num_instance_klasses(0),
_num_obj_array_klasses(0), _num_obj_array_klasses(0),
_num_type_array_klasses(0), _num_type_array_klasses(0),
@ -466,9 +466,9 @@ bool ArchiveBuilder::gather_one_source_obj(MetaspaceClosure::Ref* enclosing_ref,
FollowMode follow_mode = get_follow_mode(ref); FollowMode follow_mode = get_follow_mode(ref);
SourceObjInfo src_info(ref, read_only, follow_mode); SourceObjInfo src_info(ref, read_only, follow_mode);
bool created; bool created;
SourceObjInfo* p = _src_obj_table.add_if_absent(src_obj, src_info, &created); SourceObjInfo* p = _src_obj_table.put_if_absent(src_obj, src_info, &created);
if (created) { if (created) {
if (_src_obj_table.maybe_grow(MAX_TABLE_SIZE)) { if (_src_obj_table.maybe_grow()) {
log_info(cds, hashtables)("Expanded _src_obj_table table to %d", _src_obj_table.table_size()); log_info(cds, hashtables)("Expanded _src_obj_table table to %d", _src_obj_table.table_size());
} }
} }
@ -662,7 +662,7 @@ void ArchiveBuilder::make_shallow_copy(DumpRegion *dump_region, SourceObjInfo* s
} }
address ArchiveBuilder::get_dumped_addr(address src_obj) const { address ArchiveBuilder::get_dumped_addr(address src_obj) const {
SourceObjInfo* p = _src_obj_table.lookup(src_obj); SourceObjInfo* p = _src_obj_table.get(src_obj);
assert(p != NULL, "must be"); assert(p != NULL, "must be");
return p->dumped_addr(); return p->dumped_addr();

View file

@ -33,7 +33,7 @@
#include "runtime/os.hpp" #include "runtime/os.hpp"
#include "utilities/bitMap.hpp" #include "utilities/bitMap.hpp"
#include "utilities/growableArray.hpp" #include "utilities/growableArray.hpp"
#include "utilities/hashtable.hpp" #include "utilities/resizeableResourceHash.hpp"
#include "utilities/resourceHash.hpp" #include "utilities/resourceHash.hpp"
struct ArchiveHeapOopmapInfo; struct ArchiveHeapOopmapInfo;
@ -179,8 +179,8 @@ private:
class SrcObjTableCleaner { class SrcObjTableCleaner {
public: public:
bool do_entry(address key, const SourceObjInfo* value) { bool do_entry(address key, const SourceObjInfo& value) {
delete value->ref(); delete value.ref();
return true; return true;
} }
}; };
@ -199,7 +199,7 @@ private:
SourceObjList _rw_src_objs; // objs to put in rw region SourceObjList _rw_src_objs; // objs to put in rw region
SourceObjList _ro_src_objs; // objs to put in ro region SourceObjList _ro_src_objs; // objs to put in ro region
KVHashtable<address, SourceObjInfo, mtClassShared> _src_obj_table; ResizeableResourceHashtable<address, SourceObjInfo, ResourceObj::C_HEAP, mtClassShared> _src_obj_table;
GrowableArray<Klass*>* _klasses; GrowableArray<Klass*>* _klasses;
GrowableArray<Symbol*>* _symbols; GrowableArray<Symbol*>* _symbols;
GrowableArray<SpecialRefInfo>* _special_refs; GrowableArray<SpecialRefInfo>* _special_refs;

View file

@ -43,7 +43,7 @@ class AsyncLogWriter::AsyncLogLocker : public StackObj {
void AsyncLogWriter::enqueue_locked(const AsyncLogMessage& msg) { void AsyncLogWriter::enqueue_locked(const AsyncLogMessage& msg) {
if (_buffer.size() >= _buffer_max_size) { if (_buffer.size() >= _buffer_max_size) {
bool p_created; bool p_created;
uint32_t* counter = _stats.add_if_absent(msg.output(), 0, &p_created); uint32_t* counter = _stats.put_if_absent(msg.output(), 0, &p_created);
*counter = *counter + 1; *counter = *counter + 1;
// drop the enqueueing message. // drop the enqueueing message.
os::free(msg.message()); os::free(msg.message());
@ -77,7 +77,7 @@ void AsyncLogWriter::enqueue(LogFileOutput& output, LogMessageBuffer::Iterator m
AsyncLogWriter::AsyncLogWriter() AsyncLogWriter::AsyncLogWriter()
: _lock(1), _sem(0), _flush_sem(0), : _lock(1), _sem(0), _flush_sem(0),
_initialized(false), _initialized(false),
_stats(17 /*table_size*/) { _stats() {
if (os::create_thread(this, os::asynclog_thread)) { if (os::create_thread(this, os::asynclog_thread)) {
_initialized = true; _initialized = true;
} else { } else {
@ -93,16 +93,16 @@ class AsyncLogMapIterator {
public: public:
AsyncLogMapIterator(AsyncLogBuffer& logs) :_logs(logs) {} AsyncLogMapIterator(AsyncLogBuffer& logs) :_logs(logs) {}
bool do_entry(LogFileOutput* output, uint32_t* counter) { bool do_entry(LogFileOutput* output, uint32_t& counter) {
using none = LogTagSetMapping<LogTag::__NO_TAG>; using none = LogTagSetMapping<LogTag::__NO_TAG>;
if (*counter > 0) { if (counter > 0) {
LogDecorations decorations(LogLevel::Warning, none::tagset(), LogDecorators::All); LogDecorations decorations(LogLevel::Warning, none::tagset(), LogDecorators::All);
stringStream ss; stringStream ss;
ss.print(UINT32_FORMAT_W(6) " messages dropped due to async logging", *counter); ss.print(UINT32_FORMAT_W(6) " messages dropped due to async logging", counter);
AsyncLogMessage msg(output, decorations, ss.as_string(true /*c_heap*/)); AsyncLogMessage msg(output, decorations, ss.as_string(true /*c_heap*/));
_logs.push_back(msg); _logs.push_back(msg);
*counter = 0; counter = 0;
} }
return true; return true;

View file

@ -29,7 +29,7 @@
#include "logging/logMessageBuffer.hpp" #include "logging/logMessageBuffer.hpp"
#include "memory/resourceArea.hpp" #include "memory/resourceArea.hpp"
#include "runtime/nonJavaThread.hpp" #include "runtime/nonJavaThread.hpp"
#include "utilities/hashtable.hpp" #include "utilities/resourceHash.hpp"
#include "utilities/linkedlist.hpp" #include "utilities/linkedlist.hpp"
template <typename E, MEMFLAGS F> template <typename E, MEMFLAGS F>
@ -108,7 +108,13 @@ public:
}; };
typedef LinkedListDeque<AsyncLogMessage, mtLogging> AsyncLogBuffer; typedef LinkedListDeque<AsyncLogMessage, mtLogging> AsyncLogBuffer;
typedef KVHashtable<LogFileOutput*, uint32_t, mtLogging> AsyncLogMap; typedef ResourceHashtable<LogFileOutput*,
uint32_t,
primitive_hash<LogFileOutput*>,
primitive_equals<LogFileOutput*>,
17, /*table_size*/
ResourceObj::C_HEAP,
mtLogging> AsyncLogMap;
// //
// ASYNC LOGGING SUPPORT // ASYNC LOGGING SUPPORT

View file

@ -1198,7 +1198,7 @@ typedef const char* ccstr;
typedef const char* ccstrlist; // represents string arguments which accumulate typedef const char* ccstrlist; // represents string arguments which accumulate
//---------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------
// Default hash/equals functions used by ResourceHashtable and KVHashtable // Default hash/equals functions used by ResourceHashtable
template<typename K> unsigned primitive_hash(const K& k) { template<typename K> unsigned primitive_hash(const K& k) {
unsigned hash = (unsigned)((uintptr_t)k); unsigned hash = (unsigned)((uintptr_t)k);

View file

@ -220,114 +220,4 @@ public:
} }
}; };
// A subclass of BasicHashtable that allows you to do a simple K -> V mapping
// without using tons of boilerplate code.
template<
typename K, typename V, MEMFLAGS F,
unsigned (*HASH) (K const&) = primitive_hash<K>,
bool (*EQUALS)(K const&, K const&) = primitive_equals<K>
>
class KVHashtable : public BasicHashtable<F> {
class KVHashtableEntry : public BasicHashtableEntry<F> {
public:
K _key;
V _value;
KVHashtableEntry* next() {
return (KVHashtableEntry*)BasicHashtableEntry<F>::next();
}
};
protected:
KVHashtableEntry* bucket(int i) const {
return (KVHashtableEntry*)BasicHashtable<F>::bucket(i);
}
// The following method is not MT-safe and must be done under lock.
KVHashtableEntry** bucket_addr(int i) {
return (KVHashtableEntry**)BasicHashtable<F>::bucket_addr(i);
}
KVHashtableEntry* new_entry(unsigned int hashValue, K key, V value) {
KVHashtableEntry* entry = (KVHashtableEntry*)BasicHashtable<F>::new_entry(hashValue);
entry->_key = key;
entry->_value = value;
return entry;
}
void free_entry(KVHashtableEntry* entry) {
BasicHashtable<F>::free_entry(entry);
}
public:
KVHashtable(int table_size) : BasicHashtable<F>(table_size, sizeof(KVHashtableEntry)) {}
~KVHashtable() {
KVHashtableEntry* probe = NULL;
for (int index = 0; index < table_size(); index++) {
for (KVHashtableEntry** p = bucket_addr(index); *p != NULL; ) {
probe = *p;
*p = probe->next();
free_entry(probe);
}
}
assert(BasicHashtable<F>::number_of_entries() == 0, "should have removed all entries");
}
V* add(K key, V value) {
unsigned int hash = HASH(key);
KVHashtableEntry* entry = new_entry(hash, key, value);
BasicHashtable<F>::add_entry(BasicHashtable<F>::hash_to_index(hash), entry);
return &(entry->_value);
}
V* lookup(K key) const {
unsigned int hash = HASH(key);
int index = BasicHashtable<F>::hash_to_index(hash);
for (KVHashtableEntry* e = bucket(index); e != NULL; e = e->next()) {
if (e->hash() == hash && EQUALS(e->_key, key)) {
return &(e->_value);
}
}
return NULL;
}
// Look up the key.
// If an entry for the key exists, leave map unchanged and return a pointer to its value.
// If no entry for the key exists, create a new entry from key and value and return a
// pointer to the value.
// *p_created is true if entry was created, false if entry pre-existed.
V* add_if_absent(K key, V value, bool* p_created) {
unsigned int hash = HASH(key);
int index = BasicHashtable<F>::hash_to_index(hash);
for (KVHashtableEntry* e = bucket(index); e != NULL; e = e->next()) {
if (e->hash() == hash && EQUALS(e->_key, key)) {
*p_created = false;
return &(e->_value);
}
}
KVHashtableEntry* entry = new_entry(hash, key, value);
BasicHashtable<F>::add_entry(BasicHashtable<F>::hash_to_index(hash), entry);
*p_created = true;
return &(entry->_value);
}
int table_size() const {
return BasicHashtable<F>::table_size();
}
// ITER contains bool do_entry(K, V const&), which will be
// called for each entry in the table. If do_entry() returns false,
// the iteration is cancelled.
template<class ITER>
void iterate(ITER* iter) const {
for (int index = 0; index < table_size(); index++) {
for (KVHashtableEntry* e = bucket(index); e != NULL; e = e->next()) {
bool cont = iter->do_entry(e->_key, &e->_value);
if (!cont) { return; }
}
}
}
};
#endif // SHARE_UTILITIES_HASHTABLE_HPP #endif // SHARE_UTILITIES_HASHTABLE_HPP