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_SYMBOLTABLE_HPP
26#define SHARE_CLASSFILE_SYMBOLTABLE_HPP
27
28#include "memory/allocation.hpp"
29#include "memory/padded.hpp"
30#include "oops/symbol.hpp"
31#include "utilities/tableStatistics.hpp"
32
33class JavaThread;
34
35// TempNewSymbol acts as a handle class in a handle/body idiom and is
36// responsible for proper resource management of the body (which is a Symbol*).
37// The body is resource managed by a reference counting scheme.
38// TempNewSymbol can therefore be used to properly hold a newly created or referenced
39// Symbol* temporarily in scope.
40//
41// Routines in SymbolTable will initialize the reference count of a Symbol* before
42// it becomes "managed" by TempNewSymbol instances. As a handle class, TempNewSymbol
43// needs to maintain proper reference counting in context of copy semantics.
44//
45// In SymbolTable, new_symbol() will create a Symbol* if not already in the
46// symbol table and add to the symbol's reference count.
47// probe() and lookup_only() will increment the refcount if symbol is found.
48class TempNewSymbol : public StackObj {
49 Symbol* _temp;
50
51public:
52 TempNewSymbol() : _temp(NULL) {}
53
54 // Conversion from a Symbol* to a TempNewSymbol.
55 // Does not increment the current reference count.
56 TempNewSymbol(Symbol *s) : _temp(s) {}
57
58 // Copy constructor increments reference count.
59 TempNewSymbol(const TempNewSymbol& rhs) : _temp(rhs._temp) {
60 if (_temp != NULL) {
61 _temp->increment_refcount();
62 }
63 }
64
65 // Assignment operator uses a c++ trick called copy and swap idiom.
66 // rhs is passed by value so within the scope of this method it is a copy.
67 // At method exit it contains the former value of _temp, triggering the correct refcount
68 // decrement upon destruction.
69 void operator=(TempNewSymbol rhs) {
70 Symbol* tmp = rhs._temp;
71 rhs._temp = _temp;
72 _temp = tmp;
73 }
74
75 // Decrement reference counter so it can go away if it's unused
76 ~TempNewSymbol() {
77 if (_temp != NULL) {
78 _temp->decrement_refcount();
79 }
80 }
81
82 // Symbol* conversion operators
83 Symbol* operator -> () const { return _temp; }
84 bool operator == (Symbol* o) const { return _temp == o; }
85 operator Symbol*() { return _temp; }
86};
87
88class CompactHashtableWriter;
89class SerializeClosure;
90
91class SymbolTableConfig;
92class SymbolTableCreateEntry;
93
94class constantPoolHandle;
95class SymbolClosure;
96
97class SymbolTable : public AllStatic {
98 friend class VMStructs;
99 friend class Symbol;
100 friend class ClassFileParser;
101 friend class SymbolTableConfig;
102 friend class SymbolTableCreateEntry;
103
104 private:
105 static volatile bool _has_work;
106
107 // Set if one bucket is out of balance due to hash algorithm deficiency
108 static volatile bool _needs_rehashing;
109
110 static void delete_symbol(Symbol* sym);
111 static void grow(JavaThread* jt);
112 static void clean_dead_entries(JavaThread* jt);
113
114 static double get_load_factor();
115
116 static void check_concurrent_work();
117
118 static void item_added();
119 static void item_removed();
120
121 // For cleaning
122 static void reset_has_items_to_clean();
123 static void mark_has_items_to_clean();
124 static bool has_items_to_clean();
125
126 static Symbol* allocate_symbol(const char* name, int len, bool c_heap); // Assumes no characters larger than 0x7F
127 static Symbol* do_lookup(const char* name, int len, uintx hash);
128 static Symbol* do_add_if_needed(const char* name, int len, uintx hash, bool heap);
129
130 // lookup only, won't add. Also calculate hash. Used by the ClassfileParser.
131 static Symbol* lookup_only(const char* name, int len, unsigned int& hash);
132 static Symbol* lookup_only_unicode(const jchar* name, int len, unsigned int& hash);
133
134 // Adding elements
135 static void new_symbols(ClassLoaderData* loader_data,
136 const constantPoolHandle& cp, int names_count,
137 const char** name, int* lengths,
138 int* cp_indices, unsigned int* hashValues);
139
140 static Symbol* lookup_shared(const char* name, int len, unsigned int hash) NOT_CDS_RETURN_(NULL);
141 static Symbol* lookup_dynamic(const char* name, int len, unsigned int hash);
142 static Symbol* lookup_common(const char* name, int len, unsigned int hash);
143
144 // Arena for permanent symbols (null class loader) that are never unloaded
145 static Arena* _arena;
146 static Arena* arena() { return _arena; } // called for statistics
147
148 static void print_table_statistics(outputStream* st, const char* table_name);
149
150 static void try_rehash_table();
151 static bool do_rehash();
152
153public:
154 // The symbol table
155 static size_t table_size();
156 static TableStatistics get_table_statistics();
157
158 enum {
159 symbol_alloc_batch_size = 8,
160 // Pick initial size based on java -version size measurements
161 symbol_alloc_arena_size = 360*K // TODO (revisit)
162 };
163
164 static void create_table();
165
166 static void do_concurrent_work(JavaThread* jt);
167 static bool has_work() { return _has_work; }
168 static void trigger_cleanup();
169
170 // Probing
171 // Needed for preloading classes in signatures when compiling.
172 // Returns the symbol is already present in symbol table, otherwise
173 // NULL. NO ALLOCATION IS GUARANTEED!
174 static Symbol* probe(const char* name, int len) {
175 unsigned int ignore_hash;
176 return lookup_only(name, len, ignore_hash);
177 }
178 static Symbol* probe_unicode(const jchar* name, int len) {
179 unsigned int ignore_hash;
180 return lookup_only_unicode(name, len, ignore_hash);
181 }
182
183 // Symbol lookup and create if not found.
184 // jchar (UTF16) version of lookup
185 static Symbol* new_symbol(const jchar* name, int len);
186 // char (UTF8) versions
187 static Symbol* new_symbol(const Symbol* sym, int begin, int end);
188 static Symbol* new_symbol(const char* utf8_buffer, int length);
189 static Symbol* new_symbol(const char* name) {
190 return new_symbol(name, (int)strlen(name));
191 }
192
193 // Create a symbol in the arena for symbols that are not deleted
194 static Symbol* new_permanent_symbol(const char* name);
195
196 // Rehash the string table if it gets out of balance
197 static void rehash_table();
198 static bool needs_rehashing() { return _needs_rehashing; }
199 static inline void update_needs_rehash(bool rehash) {
200 if (rehash) {
201 _needs_rehashing = true;
202 }
203 }
204
205 // Heap dumper and CDS
206 static void symbols_do(SymbolClosure *cl);
207
208 // Sharing
209private:
210 static void copy_shared_symbol_table(CompactHashtableWriter* ch_table);
211public:
212 static size_t estimate_size_for_archive() NOT_CDS_RETURN_(0);
213 static void write_to_archive(bool is_static_archive = true) NOT_CDS_RETURN;
214 static void serialize_shared_table_header(SerializeClosure* soc,
215 bool is_static_archive = true) NOT_CDS_RETURN;
216 static void metaspace_pointers_do(MetaspaceClosure* it);
217
218 // Jcmd
219 static void dump(outputStream* st, bool verbose=false);
220 // Debugging
221 static void verify();
222
223 // Histogram
224 static void print_histogram() PRODUCT_RETURN;
225};
226
227#endif // SHARE_CLASSFILE_SYMBOLTABLE_HPP
228