18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #ifndef SHARE_VM_CLASSFILE_COMPACTHASHTABLE_HPP
26 #define SHARE_VM_CLASSFILE_COMPACTHASHTABLE_HPP
27
28 #include "oops/array.hpp"
29 #include "oops/symbol.hpp"
30 #include "utilities/hashtable.hpp"
31
32 template <class T, class N> class CompactHashtable;
33 class NumberSeq;
34 class SimpleCompactHashtable;
35 class SerializeClosure;
36
37 // Stats for symbol tables in the CDS archive
38 class CompactHashtableStats VALUE_OBJ_CLASS_SPEC {
39 public:
40 int hashentry_count;
41 int hashentry_bytes;
42 int bucket_count;
43 int bucket_bytes;
44 };
45
46 /////////////////////////////////////////////////////////////////////////
47 //
48 // The compact hash table writer. Used at dump time for writing out
49 // the compact table to the shared archive.
50 //
51 // At dump time, the CompactHashtableWriter obtains all entries from the
52 // symbol/string table and adds them to a new temporary hash table. The hash
53 // table size (number of buckets) is calculated using
54 // '(num_entries + bucket_size - 1) / bucket_size'. The default bucket
55 // size is 4 and can be changed by -XX:SharedSymbolTableBucketSize option.
56 // 4 is chosen because it produces smaller sized bucket on average for
57 // faster lookup. It also has relatively small number of empty buckets and
58 // good distribution of the entries.
59 //
60 // We use a simple hash function (hash % num_bucket) for the table.
61 // The new table is compacted when written out. Please see comments
62 // above the CompactHashtable class for the table layout detail. The bucket
63 // offsets are written to the archive as part of the compact table. The
64 // bucket offset is encoded in the low 30-bit (0-29) and the bucket type
65 // (regular or compact) are encoded in bit[31, 30]. For buckets with more
66 // than one entry, both hash and entry offset are written to the
67 // table. For buckets with only one entry, only the entry offset is written
68 // to the table and the buckets are tagged as compact in their type bits.
69 // Buckets without entry are skipped from the table. Their offsets are
70 // still written out for faster lookup.
71 //
72 class CompactHashtableWriter: public StackObj {
73 public:
74 class Entry VALUE_OBJ_CLASS_SPEC {
75 unsigned int _hash;
76 u4 _value;
77
78 public:
79 Entry() {}
80 Entry(unsigned int hash, u4 val) : _hash(hash), _value(val) {}
81
82 u4 value() {
83 return _value;
84 }
85 unsigned int hash() {
86 return _hash;
87 }
88
89 bool operator==(const CompactHashtableWriter::Entry& other) {
90 return (_value == other._value && _hash == other._hash);
91 }
92 }; // class CompactHashtableWriter::Entry
93
94 private:
177 // narrowOop str; /* String narrowOop encoding */
178 // }
179 //
180 //
181 // For value_only buckets, each entry has only the 4-byte 'offset' in the entries[].
182 //
183 // Example -- note that the second bucket is a VALUE_ONLY_BUCKET_TYPE so the hash code
184 // is skipped.
185 // buckets[0, 4, 5, ....]
186 // | | |
187 // | | +---+
188 // | | |
189 // | +----+ |
190 // v v v
191 // entries[H,O,H,O,O,H,O,H,O.....]
192 //
193 // See CompactHashtable::lookup() for how the table is searched at runtime.
194 // See CompactHashtableWriter::dump() for how the table is written at CDS
195 // dump time.
196 //
197 class SimpleCompactHashtable VALUE_OBJ_CLASS_SPEC {
198 protected:
199 address _base_address;
200 u4 _bucket_count;
201 u4 _entry_count;
202 u4* _buckets;
203 u4* _entries;
204
205 public:
206 SimpleCompactHashtable() {
207 _entry_count = 0;
208 _bucket_count = 0;
209 _buckets = 0;
210 _entries = 0;
211 }
212
213 void reset() {
214 _bucket_count = 0;
215 _entry_count = 0;
216 _buckets = 0;
217 _entries = 0;
264 void symbols_do(SymbolClosure *cl);
265
266 // iterate over strings
267 void oops_do(OopClosure* f);
268
269 // For reading from/writing to the CDS archive
270 void serialize(SerializeClosure* soc);
271
272 uintx base_address() {
273 return (uintx) _base_address;
274 }
275 };
276
277 ////////////////////////////////////////////////////////////////////////
278 //
279 // Read/Write the contents of a hashtable textual dump (created by
280 // SymbolTable::dump and StringTable::dump).
281 // Because the dump file may be big (hundred of MB in extreme cases),
282 // we use mmap for fast access when reading it.
283 //
284 class HashtableTextDump VALUE_OBJ_CLASS_SPEC {
285 int _fd;
286 const char* _base;
287 const char* _p;
288 const char* _end;
289 const char* _filename;
290 size_t _size;
291 int _prefix_type;
292 int _line_no;
293 public:
294 HashtableTextDump(const char* filename);
295 ~HashtableTextDump();
296
297 enum {
298 SymbolPrefix = 1 << 0,
299 StringPrefix = 1 << 1,
300 Unknown = 1 << 2
301 };
302
303 void quit(const char* err, const char* msg);
304
|
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #ifndef SHARE_VM_CLASSFILE_COMPACTHASHTABLE_HPP
26 #define SHARE_VM_CLASSFILE_COMPACTHASHTABLE_HPP
27
28 #include "oops/array.hpp"
29 #include "oops/symbol.hpp"
30 #include "utilities/hashtable.hpp"
31
32 template <class T, class N> class CompactHashtable;
33 class NumberSeq;
34 class SimpleCompactHashtable;
35 class SerializeClosure;
36
37 // Stats for symbol tables in the CDS archive
38 class CompactHashtableStats {
39 public:
40 int hashentry_count;
41 int hashentry_bytes;
42 int bucket_count;
43 int bucket_bytes;
44 };
45
46 /////////////////////////////////////////////////////////////////////////
47 //
48 // The compact hash table writer. Used at dump time for writing out
49 // the compact table to the shared archive.
50 //
51 // At dump time, the CompactHashtableWriter obtains all entries from the
52 // symbol/string table and adds them to a new temporary hash table. The hash
53 // table size (number of buckets) is calculated using
54 // '(num_entries + bucket_size - 1) / bucket_size'. The default bucket
55 // size is 4 and can be changed by -XX:SharedSymbolTableBucketSize option.
56 // 4 is chosen because it produces smaller sized bucket on average for
57 // faster lookup. It also has relatively small number of empty buckets and
58 // good distribution of the entries.
59 //
60 // We use a simple hash function (hash % num_bucket) for the table.
61 // The new table is compacted when written out. Please see comments
62 // above the CompactHashtable class for the table layout detail. The bucket
63 // offsets are written to the archive as part of the compact table. The
64 // bucket offset is encoded in the low 30-bit (0-29) and the bucket type
65 // (regular or compact) are encoded in bit[31, 30]. For buckets with more
66 // than one entry, both hash and entry offset are written to the
67 // table. For buckets with only one entry, only the entry offset is written
68 // to the table and the buckets are tagged as compact in their type bits.
69 // Buckets without entry are skipped from the table. Their offsets are
70 // still written out for faster lookup.
71 //
72 class CompactHashtableWriter: public StackObj {
73 public:
74 class Entry {
75 unsigned int _hash;
76 u4 _value;
77
78 public:
79 Entry() {}
80 Entry(unsigned int hash, u4 val) : _hash(hash), _value(val) {}
81
82 u4 value() {
83 return _value;
84 }
85 unsigned int hash() {
86 return _hash;
87 }
88
89 bool operator==(const CompactHashtableWriter::Entry& other) {
90 return (_value == other._value && _hash == other._hash);
91 }
92 }; // class CompactHashtableWriter::Entry
93
94 private:
177 // narrowOop str; /* String narrowOop encoding */
178 // }
179 //
180 //
181 // For value_only buckets, each entry has only the 4-byte 'offset' in the entries[].
182 //
183 // Example -- note that the second bucket is a VALUE_ONLY_BUCKET_TYPE so the hash code
184 // is skipped.
185 // buckets[0, 4, 5, ....]
186 // | | |
187 // | | +---+
188 // | | |
189 // | +----+ |
190 // v v v
191 // entries[H,O,H,O,O,H,O,H,O.....]
192 //
193 // See CompactHashtable::lookup() for how the table is searched at runtime.
194 // See CompactHashtableWriter::dump() for how the table is written at CDS
195 // dump time.
196 //
197 class SimpleCompactHashtable {
198 protected:
199 address _base_address;
200 u4 _bucket_count;
201 u4 _entry_count;
202 u4* _buckets;
203 u4* _entries;
204
205 public:
206 SimpleCompactHashtable() {
207 _entry_count = 0;
208 _bucket_count = 0;
209 _buckets = 0;
210 _entries = 0;
211 }
212
213 void reset() {
214 _bucket_count = 0;
215 _entry_count = 0;
216 _buckets = 0;
217 _entries = 0;
264 void symbols_do(SymbolClosure *cl);
265
266 // iterate over strings
267 void oops_do(OopClosure* f);
268
269 // For reading from/writing to the CDS archive
270 void serialize(SerializeClosure* soc);
271
272 uintx base_address() {
273 return (uintx) _base_address;
274 }
275 };
276
277 ////////////////////////////////////////////////////////////////////////
278 //
279 // Read/Write the contents of a hashtable textual dump (created by
280 // SymbolTable::dump and StringTable::dump).
281 // Because the dump file may be big (hundred of MB in extreme cases),
282 // we use mmap for fast access when reading it.
283 //
284 class HashtableTextDump {
285 int _fd;
286 const char* _base;
287 const char* _p;
288 const char* _end;
289 const char* _filename;
290 size_t _size;
291 int _prefix_type;
292 int _line_no;
293 public:
294 HashtableTextDump(const char* filename);
295 ~HashtableTextDump();
296
297 enum {
298 SymbolPrefix = 1 << 0,
299 StringPrefix = 1 << 1,
300 Unknown = 1 << 2
301 };
302
303 void quit(const char* err, const char* msg);
304
|