mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-18 01:54:47 +02:00
8270059: Remove KVHashtable
Reviewed-by: dholmes, coleenp
This commit is contained in:
parent
7bfa39f59a
commit
d6c0f5fa22
6 changed files with 23 additions and 127 deletions
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue