1/*
2 * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
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_CLASSFILE_STRINGTABLE_HPP
26#define SHARE_CLASSFILE_STRINGTABLE_HPP
27
28#include "gc/shared/oopStorage.hpp"
29#include "memory/allocation.hpp"
30#include "memory/padded.hpp"
31#include "oops/oop.hpp"
32#include "oops/weakHandle.hpp"
33#include "utilities/tableStatistics.hpp"
34
35class CompactHashtableWriter;
36class SerializeClosure;
37
38class StringTable;
39class StringTableConfig;
40class StringTableCreateEntry;
41
42class StringTable : public CHeapObj<mtSymbol>{
43 friend class VMStructs;
44 friend class Symbol;
45 friend class StringTableConfig;
46 friend class StringTableCreateEntry;
47
48 static volatile bool _has_work;
49 static volatile size_t _uncleaned_items_count;
50
51 // Set if one bucket is out of balance due to hash algorithm deficiency
52 static volatile bool _needs_rehashing;
53
54 static OopStorage* _weak_handles;
55
56 static void grow(JavaThread* jt);
57 static void clean_dead_entries(JavaThread* jt);
58
59 static double get_load_factor();
60 static double get_dead_factor();
61
62 static void check_concurrent_work();
63 static void trigger_concurrent_work();
64
65 static size_t item_added();
66 static void item_removed();
67 static size_t add_items_to_clean(size_t ndead);
68
69 static oop intern(Handle string_or_null_h, const jchar* name, int len, TRAPS);
70 static oop do_intern(Handle string_or_null, const jchar* name, int len, uintx hash, TRAPS);
71 static oop do_lookup(const jchar* name, int len, uintx hash);
72
73 static void print_table_statistics(outputStream* st, const char* table_name);
74
75 static bool do_rehash();
76
77 public:
78 static size_t table_size();
79 static TableStatistics get_table_statistics();
80
81 static OopStorage* weak_storage() { return _weak_handles; }
82
83 static void create_table();
84
85 static void do_concurrent_work(JavaThread* jt);
86 static bool has_work() { return _has_work; }
87
88 // GC support
89
90 // Must be called before a parallel walk where strings might die.
91 static void reset_dead_counter() { _uncleaned_items_count = 0; }
92
93 // After the parallel walk this method must be called to trigger
94 // cleaning. Note it might trigger a resize instead.
95 static void finish_dead_counter() { check_concurrent_work(); }
96
97 // If GC uses ParState directly it should add the number of cleared
98 // strings to this method.
99 static void inc_dead_counter(size_t ndead) { add_items_to_clean(ndead); }
100
101 // Serially invoke "f->do_oop" on the locations of all oops in the table.
102 // Used by JFR leak profiler. TODO: it should find these oops through
103 // the WeakProcessor.
104 static void oops_do(OopClosure* f);
105
106 // Probing
107 static oop lookup(Symbol* symbol);
108 static oop lookup(const jchar* chars, int length);
109
110 // Interning
111 static oop intern(Symbol* symbol, TRAPS);
112 static oop intern(oop string, TRAPS);
113 static oop intern(const char *utf8_string, TRAPS);
114
115 // Rehash the string table if it gets out of balance
116 static void rehash_table();
117 static bool needs_rehashing() { return _needs_rehashing; }
118 static inline void update_needs_rehash(bool rehash) {
119 if (rehash) {
120 _needs_rehashing = true;
121 }
122 }
123
124 // Sharing
125 private:
126 static oop lookup_shared(const jchar* name, int len, unsigned int hash) NOT_CDS_JAVA_HEAP_RETURN_(NULL);
127 static void copy_shared_string_table(CompactHashtableWriter* ch_table) NOT_CDS_JAVA_HEAP_RETURN;
128 public:
129 static oop create_archived_string(oop s, Thread* THREAD) NOT_CDS_JAVA_HEAP_RETURN_(NULL);
130 static void shared_oops_do(OopClosure* f) NOT_CDS_JAVA_HEAP_RETURN;
131 static void write_to_archive() NOT_CDS_JAVA_HEAP_RETURN;
132 static void serialize_shared_table_header(SerializeClosure* soc) NOT_CDS_JAVA_HEAP_RETURN;
133
134 // Jcmd
135 static void dump(outputStream* st, bool verbose=false);
136 // Debugging
137 static size_t verify_and_compare_entries();
138 static void verify();
139};
140
141#endif // SHARE_CLASSFILE_STRINGTABLE_HPP
142