< prev index next >

src/hotspot/share/classfile/compactHashtable.hpp

Print this page

@@ -27,11 +27,18 @@
 
 #include "oops/array.hpp"
 #include "oops/symbol.hpp"
 #include "utilities/hashtable.hpp"
 
-template <class T, class N> class CompactHashtable;
+
+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,37 +113,17 @@
   // 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

@@ -146,12 +133,11 @@
 #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.
+// 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,60 +209,93 @@
     _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 {
+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;
 
-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);
+  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;
+    }
+  }
 
-  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 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;
   }
 
-  // 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;
+  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 >