33 template <
34 typename K,
35 typename V,
36 V (*DECODE)(address base_address, u4 offset),
37 bool (*EQUALS)(V value, K key, int len)
38 >
39 class CompactHashtable;
40 class NumberSeq;
41 class SimpleCompactHashtable;
42 class SerializeClosure;
43
44 // Stats for symbol tables in the CDS archive
45 class CompactHashtableStats {
46 public:
47 int hashentry_count;
48 int hashentry_bytes;
49 int bucket_count;
50 int bucket_bytes;
51 };
52
53 /////////////////////////////////////////////////////////////////////////
54 //
55 // The compact hash table writer. Used at dump time for writing out
56 // the compact table to the shared archive.
57 //
58 // At dump time, the CompactHashtableWriter obtains all entries from the
59 // symbol/string table and adds them to a new temporary hash table. The hash
60 // table size (number of buckets) is calculated using
61 // '(num_entries + bucket_size - 1) / bucket_size'. The default bucket
62 // size is 4 and can be changed by -XX:SharedSymbolTableBucketSize option.
63 // 4 is chosen because it produces smaller sized bucket on average for
64 // faster lookup. It also has relatively small number of empty buckets and
65 // good distribution of the entries.
66 //
67 // We use a simple hash function (hash % num_bucket) for the table.
68 // The new table is compacted when written out. Please see comments
69 // above the CompactHashtable class for the table layout detail. The bucket
70 // offsets are written to the archive as part of the compact table. The
71 // bucket offset is encoded in the low 30-bit (0-29) and the bucket type
72 // (regular or compact) are encoded in bit[31, 30]. For buckets with more
106 int _num_other_buckets;
107 GrowableArray<Entry>** _buckets;
108 CompactHashtableStats* _stats;
109 Array<u4>* _compact_buckets;
110 Array<u4>* _compact_entries;
111
112 public:
113 // This is called at dump-time only
114 CompactHashtableWriter(int num_buckets, CompactHashtableStats* stats);
115 ~CompactHashtableWriter();
116
117 void add(unsigned int hash, u4 value);
118
119 private:
120 void allocate_table();
121 void dump_table(NumberSeq* summary);
122
123 public:
124 void dump(SimpleCompactHashtable *cht, const char* table_name);
125 };
126
127 #define REGULAR_BUCKET_TYPE 0
128 #define VALUE_ONLY_BUCKET_TYPE 1
129 #define TABLEEND_BUCKET_TYPE 3
130 #define BUCKET_OFFSET_MASK 0x3FFFFFFF
131 #define BUCKET_OFFSET(info) ((info) & BUCKET_OFFSET_MASK)
132 #define BUCKET_TYPE_SHIFT 30
133 #define BUCKET_TYPE(info) (((info) & ~BUCKET_OFFSET_MASK) >> BUCKET_TYPE_SHIFT)
134 #define BUCKET_INFO(offset, type) (((type) << BUCKET_TYPE_SHIFT) | ((offset) & BUCKET_OFFSET_MASK))
135
136 /////////////////////////////////////////////////////////////////////////////
137 //
138 // CompactHashtable is used to store the CDS archive's symbol/string tables.
139 //
140 // Because these tables are read-only (no entries can be added/deleted) at run-time
141 // and tend to have large number of entries, we try to minimize the footprint
142 // cost per entry.
143 //
144 // The CompactHashtable is split into two arrays
145 //
195 _buckets = 0;
196 _entries = 0;
197 }
198
199 void reset() {
200 _bucket_count = 0;
201 _entry_count = 0;
202 _buckets = 0;
203 _entries = 0;
204 }
205
206 void init(address base_address, u4 entry_count, u4 bucket_count, u4* buckets, u4* entries) {
207 _base_address = base_address;
208 _bucket_count = bucket_count;
209 _entry_count = entry_count;
210 _buckets = buckets;
211 _entries = entries;
212 }
213
214 // For reading from/writing to the CDS archive
215 void serialize(SerializeClosure* soc);
216
217 inline bool empty() {
218 return (_entry_count == 0);
219 }
220 };
221
222 template <
223 typename K,
224 typename V,
225 V (*DECODE)(address base_address, u4 offset),
226 bool (*EQUALS)(V value, K key, int len)
227 >
228 class CompactHashtable : public SimpleCompactHashtable {
229 friend class VMStructs;
230
231 V decode(u4 offset) const {
232 return DECODE(_base_address, offset);
233 }
234
235 public:
|
33 template <
34 typename K,
35 typename V,
36 V (*DECODE)(address base_address, u4 offset),
37 bool (*EQUALS)(V value, K key, int len)
38 >
39 class CompactHashtable;
40 class NumberSeq;
41 class SimpleCompactHashtable;
42 class SerializeClosure;
43
44 // Stats for symbol tables in the CDS archive
45 class CompactHashtableStats {
46 public:
47 int hashentry_count;
48 int hashentry_bytes;
49 int bucket_count;
50 int bucket_bytes;
51 };
52
53 #if INCLUDE_CDS
54 /////////////////////////////////////////////////////////////////////////
55 //
56 // The compact hash table writer. Used at dump time for writing out
57 // the compact table to the shared archive.
58 //
59 // At dump time, the CompactHashtableWriter obtains all entries from the
60 // symbol/string table and adds them to a new temporary hash table. The hash
61 // table size (number of buckets) is calculated using
62 // '(num_entries + bucket_size - 1) / bucket_size'. The default bucket
63 // size is 4 and can be changed by -XX:SharedSymbolTableBucketSize option.
64 // 4 is chosen because it produces smaller sized bucket on average for
65 // faster lookup. It also has relatively small number of empty buckets and
66 // good distribution of the entries.
67 //
68 // We use a simple hash function (hash % num_bucket) for the table.
69 // The new table is compacted when written out. Please see comments
70 // above the CompactHashtable class for the table layout detail. The bucket
71 // offsets are written to the archive as part of the compact table. The
72 // bucket offset is encoded in the low 30-bit (0-29) and the bucket type
73 // (regular or compact) are encoded in bit[31, 30]. For buckets with more
107 int _num_other_buckets;
108 GrowableArray<Entry>** _buckets;
109 CompactHashtableStats* _stats;
110 Array<u4>* _compact_buckets;
111 Array<u4>* _compact_entries;
112
113 public:
114 // This is called at dump-time only
115 CompactHashtableWriter(int num_buckets, CompactHashtableStats* stats);
116 ~CompactHashtableWriter();
117
118 void add(unsigned int hash, u4 value);
119
120 private:
121 void allocate_table();
122 void dump_table(NumberSeq* summary);
123
124 public:
125 void dump(SimpleCompactHashtable *cht, const char* table_name);
126 };
127 #endif // INCLUDE_CDS
128
129 #define REGULAR_BUCKET_TYPE 0
130 #define VALUE_ONLY_BUCKET_TYPE 1
131 #define TABLEEND_BUCKET_TYPE 3
132 #define BUCKET_OFFSET_MASK 0x3FFFFFFF
133 #define BUCKET_OFFSET(info) ((info) & BUCKET_OFFSET_MASK)
134 #define BUCKET_TYPE_SHIFT 30
135 #define BUCKET_TYPE(info) (((info) & ~BUCKET_OFFSET_MASK) >> BUCKET_TYPE_SHIFT)
136 #define BUCKET_INFO(offset, type) (((type) << BUCKET_TYPE_SHIFT) | ((offset) & BUCKET_OFFSET_MASK))
137
138 /////////////////////////////////////////////////////////////////////////////
139 //
140 // CompactHashtable is used to store the CDS archive's symbol/string tables.
141 //
142 // Because these tables are read-only (no entries can be added/deleted) at run-time
143 // and tend to have large number of entries, we try to minimize the footprint
144 // cost per entry.
145 //
146 // The CompactHashtable is split into two arrays
147 //
197 _buckets = 0;
198 _entries = 0;
199 }
200
201 void reset() {
202 _bucket_count = 0;
203 _entry_count = 0;
204 _buckets = 0;
205 _entries = 0;
206 }
207
208 void init(address base_address, u4 entry_count, u4 bucket_count, u4* buckets, u4* entries) {
209 _base_address = base_address;
210 _bucket_count = bucket_count;
211 _entry_count = entry_count;
212 _buckets = buckets;
213 _entries = entries;
214 }
215
216 // For reading from/writing to the CDS archive
217 void serialize(SerializeClosure* soc) NOT_CDS_RETURN;
218
219 inline bool empty() {
220 return (_entry_count == 0);
221 }
222 };
223
224 template <
225 typename K,
226 typename V,
227 V (*DECODE)(address base_address, u4 offset),
228 bool (*EQUALS)(V value, K key, int len)
229 >
230 class CompactHashtable : public SimpleCompactHashtable {
231 friend class VMStructs;
232
233 V decode(u4 offset) const {
234 return DECODE(_base_address, offset);
235 }
236
237 public:
|