Skip to content
Permalink
Browse files
8270059: Remove KVHashtable
Reviewed-by: dholmes, coleenp
  • Loading branch information
iklam committed Jul 9, 2021
1 parent 7bfa39f commit d6c0f5fa22d2fc07a4d8957d7ad005c03df9f8d2
@@ -160,7 +160,7 @@ ArchiveBuilder::ArchiveBuilder() :
_ro_region("ro", MAX_SHARED_DELTA),
_rw_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_obj_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);
SourceObjInfo src_info(ref, read_only, follow_mode);
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 (_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());
}
}
@@ -662,7 +662,7 @@ void ArchiveBuilder::make_shallow_copy(DumpRegion *dump_region, SourceObjInfo* s
}

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");

return p->dumped_addr();
@@ -33,7 +33,7 @@
#include "runtime/os.hpp"
#include "utilities/bitMap.hpp"
#include "utilities/growableArray.hpp"
#include "utilities/hashtable.hpp"
#include "utilities/resizeableResourceHash.hpp"
#include "utilities/resourceHash.hpp"

struct ArchiveHeapOopmapInfo;
@@ -179,8 +179,8 @@ class ArchiveBuilder : public StackObj {

class SrcObjTableCleaner {
public:
bool do_entry(address key, const SourceObjInfo* value) {
delete value->ref();
bool do_entry(address key, const SourceObjInfo& value) {
delete value.ref();
return true;
}
};
@@ -199,7 +199,7 @@ class ArchiveBuilder : public StackObj {

SourceObjList _rw_src_objs; // objs to put in rw 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<Symbol*>* _symbols;
GrowableArray<SpecialRefInfo>* _special_refs;
@@ -43,7 +43,7 @@ class AsyncLogWriter::AsyncLogLocker : public StackObj {
void AsyncLogWriter::enqueue_locked(const AsyncLogMessage& msg) {
if (_buffer.size() >= _buffer_max_size) {
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;
// drop the enqueueing message.
os::free(msg.message());
@@ -77,7 +77,7 @@ void AsyncLogWriter::enqueue(LogFileOutput& output, LogMessageBuffer::Iterator m
AsyncLogWriter::AsyncLogWriter()
: _lock(1), _sem(0), _flush_sem(0),
_initialized(false),
_stats(17 /*table_size*/) {
_stats() {
if (os::create_thread(this, os::asynclog_thread)) {
_initialized = true;
} else {
@@ -93,16 +93,16 @@ class AsyncLogMapIterator {

public:
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>;

if (*counter > 0) {
if (counter > 0) {
LogDecorations decorations(LogLevel::Warning, none::tagset(), LogDecorators::All);
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*/));
_logs.push_back(msg);
*counter = 0;
counter = 0;
}

return true;
@@ -29,7 +29,7 @@
#include "logging/logMessageBuffer.hpp"
#include "memory/resourceArea.hpp"
#include "runtime/nonJavaThread.hpp"
#include "utilities/hashtable.hpp"
#include "utilities/resourceHash.hpp"
#include "utilities/linkedlist.hpp"

template <typename E, MEMFLAGS F>
@@ -108,7 +108,13 @@ class AsyncLogMessage {
};

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
@@ -1198,7 +1198,7 @@ typedef const char* ccstr;
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) {
unsigned hash = (unsigned)((uintptr_t)k);
@@ -220,114 +220,4 @@ template <class T, MEMFLAGS F> class Hashtable : public BasicHashtable<F> {
}
};

// 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

1 comment on commit d6c0f5f

@openjdk-notifier

This comment has been minimized.

Copy link

@openjdk-notifier openjdk-notifier bot commented on d6c0f5f Jul 9, 2021

Please sign in to comment.