< prev index next >
src/hotspot/share/classfile/compactHashtable.hpp
Print this page
*** 27,37 ****
#include "oops/array.hpp"
#include "oops/symbol.hpp"
#include "utilities/hashtable.hpp"
! template <class T, class N> class CompactHashtable;
class NumberSeq;
class SimpleCompactHashtable;
class SerializeClosure;
// Stats for symbol tables in the CDS archive
--- 27,44 ----
#include "oops/array.hpp"
#include "oops/symbol.hpp"
#include "utilities/hashtable.hpp"
!
! template <
! typename K,
! typename V,
! V (*DECODE)(address base_address, u4 offset),
! bool (*EQUALS)(V value, K key, int len)
! >
! class CompactHashtable;
class NumberSeq;
class SimpleCompactHashtable;
class SerializeClosure;
// Stats for symbol tables in the CDS archive
*** 106,142 ****
// This is called at dump-time only
CompactHashtableWriter(int num_buckets, CompactHashtableStats* stats);
~CompactHashtableWriter();
void add(unsigned int hash, u4 value);
- void add(u4 value) {
- add((unsigned int)value, value);
- }
private:
void allocate_table();
void dump_table(NumberSeq* summary);
public:
void dump(SimpleCompactHashtable *cht, const char* table_name);
- const char* table_name();
- };
-
- class CompactSymbolTableWriter: public CompactHashtableWriter {
- public:
- CompactSymbolTableWriter(int num_buckets, CompactHashtableStats* stats) :
- CompactHashtableWriter(num_buckets, stats) {}
- void add(unsigned int hash, Symbol *symbol);
- void dump(CompactHashtable<Symbol*, char> *cht);
- };
-
- class CompactStringTableWriter: public CompactHashtableWriter {
- public:
- CompactStringTableWriter(int num_entries, CompactHashtableStats* stats) :
- CompactHashtableWriter(num_entries, stats) {}
- void add(unsigned int hash, oop string);
- void dump(CompactHashtable<oop, char> *cht);
};
#define REGULAR_BUCKET_TYPE 0
#define VALUE_ONLY_BUCKET_TYPE 1
#define TABLEEND_BUCKET_TYPE 3
--- 113,129 ----
*** 146,157 ****
#define BUCKET_TYPE(info) (((info) & ~BUCKET_OFFSET_MASK) >> BUCKET_TYPE_SHIFT)
#define BUCKET_INFO(offset, type) (((type) << BUCKET_TYPE_SHIFT) | ((offset) & BUCKET_OFFSET_MASK))
/////////////////////////////////////////////////////////////////////////////
//
! // CompactHashtable is used to stored the CDS archive's symbol/string table. Used
! // at runtime only to access the compact table from the archive.
//
// Because these tables are read-only (no entries can be added/deleted) at run-time
// and tend to have large number of entries, we try to minimize the footprint
// cost per entry.
//
--- 133,143 ----
#define BUCKET_TYPE(info) (((info) & ~BUCKET_OFFSET_MASK) >> BUCKET_TYPE_SHIFT)
#define BUCKET_INFO(offset, type) (((type) << BUCKET_TYPE_SHIFT) | ((offset) & BUCKET_OFFSET_MASK))
/////////////////////////////////////////////////////////////////////////////
//
! // CompactHashtable is used to stored the CDS archive's symbol/string tables.
//
// Because these tables are read-only (no entries can be added/deleted) at run-time
// and tend to have large number of entries, we try to minimize the footprint
// cost per entry.
//
*** 223,282 ****
_entry_count = entry_count;
_buckets = buckets;
_entries = entries;
}
- template <class I> inline void iterate(const I& iterator);
-
bool exists(u4 value);
// For reading from/writing to the CDS archive
void serialize(SerializeClosure* soc);
inline bool empty() {
return (_entry_count == 0);
}
};
! template <class T, class N> class CompactHashtable : public SimpleCompactHashtable {
friend class VMStructs;
! public:
! enum CompactHashtableType {
! _symbol_table = 0,
! _string_table = 1
! };
!
! private:
! u4 _type;
!
! inline Symbol* decode_entry(CompactHashtable<Symbol*, char>* const t,
! u4 offset, const char* name, int len);
- inline oop decode_entry(CompactHashtable<oop, char>* const t,
- u4 offset, const char* name, int len);
public:
CompactHashtable() : SimpleCompactHashtable() {}
! void set_type(CompactHashtableType type) {
! _type = (u4)type;
}
! // Lookup an entry from the compact table
! inline T lookup(const N* name, unsigned int hash, int len);
!
! // iterate over symbols
! void symbols_do(SymbolClosure *cl);
!
! // iterate over strings
! void oops_do(OopClosure* f);
!
! // For reading from/writing to the CDS archive
! void serialize(SerializeClosure* soc);
!
! uintx base_address() {
! return (uintx) _base_address;
}
};
////////////////////////////////////////////////////////////////////////
//
--- 209,301 ----
_entry_count = entry_count;
_buckets = buckets;
_entries = entries;
}
bool exists(u4 value);
// For reading from/writing to the CDS archive
void serialize(SerializeClosure* soc);
inline bool empty() {
return (_entry_count == 0);
}
};
! template <
! typename K,
! typename V,
! V (*DECODE)(address base_address, u4 offset),
! bool (*EQUALS)(V value, K key, int len)
! >
! class CompactHashtable : public SimpleCompactHashtable {
friend class VMStructs;
! V if_equals(const K key, int len, u4 offset) const {
! V value = DECODE(_base_address, offset);
! if (EQUALS(value, key, len)) {
! return value;
! } else {
! return NULL;
! }
! }
public:
CompactHashtable() : SimpleCompactHashtable() {}
! // Lookup a value V from the compact table using key K
! inline V lookup(K key, unsigned int hash, int len) const {
! if (_entry_count > 0) {
! int index = hash % _bucket_count;
! u4 bucket_info = _buckets[index];
! u4 bucket_offset = BUCKET_OFFSET(bucket_info);
! int bucket_type = BUCKET_TYPE(bucket_info);
! u4* entry = _entries + bucket_offset;
!
! if (bucket_type == VALUE_ONLY_BUCKET_TYPE) {
! V res = if_equals(key, len, entry[0]);
! if (res != NULL) {
! return res;
! }
! } else {
! // This is a regular bucket, which has more than one
! // entries. Each entry is a pair of entry (hash, offset).
! // Seek until the end of the bucket.
! u4* entry_max = _entries + BUCKET_OFFSET(_buckets[index + 1]);
! while (entry < entry_max) {
! unsigned int h = (unsigned int)(entry[0]);
! if (h == hash) {
! V res = if_equals(key, len, entry[1]);
! if (res != NULL) {
! return res;
! }
! }
! entry += 2;
! }
! }
! }
! return NULL;
}
! template <class ITER>
! inline void iterate(ITER* iter) const {
! for (u4 i = 0; i < _bucket_count; i++) {
! u4 bucket_info = _buckets[i];
! u4 bucket_offset = BUCKET_OFFSET(bucket_info);
! int bucket_type = BUCKET_TYPE(bucket_info);
! u4* entry = _entries + bucket_offset;
!
! if (bucket_type == VALUE_ONLY_BUCKET_TYPE) {
! iter->do_value(DECODE(_base_address, entry[0]));
! } else {
! u4*entry_max = _entries + BUCKET_OFFSET(_buckets[i + 1]);
! while (entry < entry_max) {
! iter->do_value(DECODE(_base_address, entry[1]));
! entry += 2;
! }
! }
! }
}
};
////////////////////////////////////////////////////////////////////////
//
< prev index next >