1/*
2 * Copyright (c) 1997, 2017, 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_VM_CLASSFILE_SYMBOLTABLE_HPP
26#define SHARE_VM_CLASSFILE_SYMBOLTABLE_HPP
27
28#include "memory/allocation.inline.hpp"
29#include "oops/symbol.hpp"
30#include "utilities/hashtable.hpp"
31
32// The symbol table holds all Symbol*s and corresponding interned strings.
33// Symbol*s and literal strings should be canonicalized.
34//
35// The interned strings are created lazily.
36//
37// It is implemented as an open hash table with a fixed number of buckets.
38//
39// %note:
40//  - symbolTableEntrys are allocated in blocks to reduce the space overhead.
41
42class BoolObjectClosure;
43class outputStream;
44class SerializeClosure;
45
46// TempNewSymbol acts as a handle class in a handle/body idiom and is
47// responsible for proper resource management of the body (which is a Symbol*).
48// The body is resource managed by a reference counting scheme.
49// TempNewSymbol can therefore be used to properly hold a newly created or referenced
50// Symbol* temporarily in scope.
51//
52// Routines in SymbolTable will initialize the reference count of a Symbol* before
53// it becomes "managed" by TempNewSymbol instances. As a handle class, TempNewSymbol
54// needs to maintain proper reference counting in context of copy semantics.
55//
56// In SymbolTable, new_symbol() and lookup() will create a Symbol* if not already in the
57// symbol table and add to the symbol's reference count.
58// probe() and lookup_only() will increment the refcount if symbol is found.
59class TempNewSymbol : public StackObj {
60  Symbol* _temp;
61
62 public:
63  TempNewSymbol() : _temp(NULL) {}
64
65  // Conversion from a Symbol* to a TempNewSymbol.
66  // Does not increment the current reference count.
67  TempNewSymbol(Symbol *s) : _temp(s) {}
68
69  // Copy constructor increments reference count.
70  TempNewSymbol(const TempNewSymbol& rhs) : _temp(rhs._temp) {
71    if (_temp != NULL) {
72      _temp->increment_refcount();
73    }
74  }
75
76  // Assignment operator uses a c++ trick called copy and swap idiom.
77  // rhs is passed by value so within the scope of this method it is a copy.
78  // At method exit it contains the former value of _temp, triggering the correct refcount
79  // decrement upon destruction.
80  void operator=(TempNewSymbol rhs) {
81    Symbol* tmp = rhs._temp;
82    rhs._temp = _temp;
83    _temp = tmp;
84  }
85
86  // Decrement reference counter so it can go away if it's unused
87  ~TempNewSymbol() {
88    if (_temp != NULL) {
89      _temp->decrement_refcount();
90    }
91  }
92
93  // Symbol* conversion operators
94  Symbol* operator -> () const                   { return _temp; }
95  bool    operator == (Symbol* o) const          { return _temp == o; }
96  operator Symbol*()                             { return _temp; }
97};
98
99template <class T, class N> class CompactHashtable;
100
101class SymbolTable : public RehashableHashtable<Symbol*, mtSymbol> {
102  friend class VMStructs;
103  friend class ClassFileParser;
104
105private:
106  // The symbol table
107  static SymbolTable* _the_table;
108
109  // Set if one bucket is out of balance due to hash algorithm deficiency
110  static bool _needs_rehashing;
111  static bool _lookup_shared_first;
112
113  // For statistics
114  static int _symbols_removed;
115  static int _symbols_counted;
116
117  // shared symbol table.
118  static CompactHashtable<Symbol*, char> _shared_table;
119
120  Symbol* allocate_symbol(const u1* name, int len, bool c_heap, TRAPS); // Assumes no characters larger than 0x7F
121
122  // Adding elements
123  Symbol* basic_add(int index, u1* name, int len, unsigned int hashValue,
124                    bool c_heap, TRAPS);
125  bool basic_add(ClassLoaderData* loader_data,
126                 const constantPoolHandle& cp, int names_count,
127                 const char** names, int* lengths, int* cp_indices,
128                 unsigned int* hashValues, TRAPS);
129
130  static void new_symbols(ClassLoaderData* loader_data,
131                          const constantPoolHandle& cp, int names_count,
132                          const char** name, int* lengths,
133                          int* cp_indices, unsigned int* hashValues,
134                          TRAPS) {
135    add(loader_data, cp, names_count, name, lengths, cp_indices, hashValues, THREAD);
136  }
137
138  static Symbol* lookup_shared(const char* name, int len, unsigned int hash);
139  Symbol* lookup_dynamic(int index, const char* name, int len, unsigned int hash);
140  Symbol* lookup(int index, const char* name, int len, unsigned int hash);
141
142  SymbolTable()
143    : RehashableHashtable<Symbol*, mtSymbol>(SymbolTableSize, sizeof (HashtableEntry<Symbol*, mtSymbol>)) {}
144
145  SymbolTable(HashtableBucket<mtSymbol>* t, int number_of_entries)
146    : RehashableHashtable<Symbol*, mtSymbol>(SymbolTableSize, sizeof (HashtableEntry<Symbol*, mtSymbol>), t,
147                number_of_entries) {}
148
149  // Arena for permanent symbols (null class loader) that are never unloaded
150  static Arena*  _arena;
151  static Arena* arena() { return _arena; }  // called for statistics
152
153  static void initialize_symbols(int arena_alloc_size = 0);
154
155  static volatile int _parallel_claimed_idx;
156
157  typedef SymbolTable::BucketUnlinkContext BucketUnlinkContext;
158  // Release any dead symbols. Unlinked bucket entries are collected in the given
159  // context to be freed later.
160  // This allows multiple threads to work on the table at once.
161  static void buckets_unlink(int start_idx, int end_idx, BucketUnlinkContext* context);
162public:
163  enum {
164    symbol_alloc_batch_size = 8,
165    // Pick initial size based on java -version size measurements
166    symbol_alloc_arena_size = 360*K
167  };
168
169  // The symbol table
170  static SymbolTable* the_table() { return _the_table; }
171
172  // Size of one bucket in the string table.  Used when checking for rollover.
173  static uint bucket_size() { return sizeof(HashtableBucket<mtSymbol>); }
174
175  static void create_table() {
176    assert(_the_table == NULL, "One symbol table allowed.");
177    _the_table = new SymbolTable();
178    initialize_symbols(symbol_alloc_arena_size);
179  }
180
181  static unsigned int hash_symbol(const char* s, int len);
182  static unsigned int hash_shared_symbol(const char* s, int len);
183
184  static Symbol* lookup(const char* name, int len, TRAPS);
185  // lookup only, won't add. Also calculate hash.
186  static Symbol* lookup_only(const char* name, int len, unsigned int& hash);
187  // Only copy to C string to be added if lookup failed.
188  static Symbol* lookup(const Symbol* sym, int begin, int end, TRAPS);
189
190  static void release(Symbol* sym);
191
192  // Look up the address of the literal in the SymbolTable for this Symbol*
193  static Symbol** lookup_symbol_addr(Symbol* sym);
194
195  // jchar (UTF16) version of lookups
196  static Symbol* lookup_unicode(const jchar* name, int len, TRAPS);
197  static Symbol* lookup_only_unicode(const jchar* name, int len, unsigned int& hash);
198
199  static void add(ClassLoaderData* loader_data,
200                  const constantPoolHandle& cp, int names_count,
201                  const char** names, int* lengths, int* cp_indices,
202                  unsigned int* hashValues, TRAPS);
203
204  // Release any dead symbols
205  static void unlink() {
206    int processed = 0;
207    int removed = 0;
208    unlink(&processed, &removed);
209  }
210  static void unlink(int* processed, int* removed);
211  // Release any dead symbols, possibly parallel version
212  static void possibly_parallel_unlink(int* processed, int* removed);
213
214  // iterate over symbols
215  static void symbols_do(SymbolClosure *cl);
216  static void metaspace_pointers_do(MetaspaceClosure* it);
217
218  // Symbol creation
219  static Symbol* new_symbol(const char* utf8_buffer, int length, TRAPS) {
220    assert(utf8_buffer != NULL, "just checking");
221    return lookup(utf8_buffer, length, THREAD);
222  }
223  static Symbol*       new_symbol(const char* name, TRAPS) {
224    return new_symbol(name, (int)strlen(name), THREAD);
225  }
226  static Symbol*       new_symbol(const Symbol* sym, int begin, int end, TRAPS) {
227    assert(begin <= end && end <= sym->utf8_length(), "just checking");
228    return lookup(sym, begin, end, THREAD);
229  }
230
231  // Create a symbol in the arena for symbols that are not deleted
232  static Symbol* new_permanent_symbol(const char* name, TRAPS);
233
234  // Symbol lookup
235  static Symbol* lookup(int index, const char* name, int len, TRAPS);
236
237  // Needed for preloading classes in signatures when compiling.
238  // Returns the symbol is already present in symbol table, otherwise
239  // NULL.  NO ALLOCATION IS GUARANTEED!
240  static Symbol* probe(const char* name, int len) {
241    unsigned int ignore_hash;
242    return lookup_only(name, len, ignore_hash);
243  }
244  static Symbol* probe_unicode(const jchar* name, int len) {
245    unsigned int ignore_hash;
246    return lookup_only_unicode(name, len, ignore_hash);
247  }
248
249  // Histogram
250  static void print_histogram()     PRODUCT_RETURN;
251  static void print()     PRODUCT_RETURN;
252
253  // Debugging
254  static void verify();
255  static void dump(outputStream* st, bool verbose=false);
256  static void read(const char* filename, TRAPS);
257
258  // Sharing
259  static void write_to_archive();
260  static void serialize(SerializeClosure* soc);
261  static u4 encode_shared(Symbol* sym);
262  static Symbol* decode_shared(u4 offset);
263
264  // Rehash the symbol table if it gets out of balance
265  static void rehash_table();
266  static bool needs_rehashing()         { return _needs_rehashing; }
267  // Parallel chunked scanning
268  static void clear_parallel_claimed_index() { _parallel_claimed_idx = 0; }
269  static int parallel_claimed_index()        { return _parallel_claimed_idx; }
270};
271
272#endif // SHARE_VM_CLASSFILE_SYMBOLTABLE_HPP
273