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