symbolTable.hpp revision 2062:3582bf76420e
110723Sbae/*
213655Savstepan * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
310723Sbae * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
410723Sbae *
510723Sbae * This code is free software; you can redistribute it and/or modify it
610723Sbae * under the terms of the GNU General Public License version 2 only, as
710723Sbae * published by the Free Software Foundation.
810723Sbae *
910723Sbae * This code is distributed in the hope that it will be useful, but WITHOUT
1010723Sbae * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1110723Sbae * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1210723Sbae * version 2 for more details (a copy is included in the LICENSE file that
1310723Sbae * accompanied this code).
1410723Sbae *
1510723Sbae * You should have received a copy of the GNU General Public License version
1610723Sbae * 2 along with this work; if not, write to the Free Software Foundation,
1710723Sbae * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1810723Sbae *
1910723Sbae * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2010723Sbae * or visit www.oracle.com if you need additional information or have any
2110723Sbae * questions.
2210723Sbae *
2310723Sbae */
2410723Sbae
2510723Sbae#ifndef SHARE_VM_CLASSFILE_SYMBOLTABLE_HPP
2610723Sbae#define SHARE_VM_CLASSFILE_SYMBOLTABLE_HPP
2710723Sbae
2810723Sbae#include "memory/allocation.inline.hpp"
2910723Sbae#include "oops/symbol.hpp"
3010723Sbae#include "utilities/hashtable.hpp"
3110723Sbae
3210723Sbae// The symbol table holds all Symbol*s and corresponding interned strings.
3310723Sbae// Symbol*s and literal strings should be canonicalized.
3410723Sbae//
3510723Sbae// The interned strings are created lazily.
3610723Sbae//
3710723Sbae// It is implemented as an open hash table with a fixed number of buckets.
3810723Sbae//
3910723Sbae// %note:
4010723Sbae//  - symbolTableEntrys are allocated in blocks to reduce the space overhead.
4110723Sbae
4210723Sbaeclass BoolObjectClosure;
4310723Sbae
4410723Sbae
4510723Sbae// Class to hold a newly created or referenced Symbol* temporarily in scope.
4610723Sbae// new_symbol() and lookup() will create a Symbol* if not already in the
4710723Sbae// symbol table and add to the symbol's reference count.
4810723Sbae// probe() and lookup_only() will increment the refcount if symbol is found.
4910723Sbaeclass TempNewSymbol : public StackObj {
5010723Sbae  Symbol* _temp;
5110723Sbae
5210723Sbae public:
5310723Sbae  TempNewSymbol() : _temp(NULL) {}
5410723Sbae  // Creating or looking up a symbol increments the symbol's reference count
5513655Savstepan  TempNewSymbol(Symbol *s) : _temp(s) {}
5610723Sbae
5710723Sbae  // Operator= increments reference count.
5810723Sbae  void operator=(const TempNewSymbol &s) {
5910723Sbae    _temp = s._temp;
6010723Sbae    if (_temp !=NULL) _temp->increment_refcount();
6110723Sbae  }
6210723Sbae
6310723Sbae  // Decrement reference counter so it can go away if it's unique
6410723Sbae  ~TempNewSymbol() { if (_temp != NULL) _temp->decrement_refcount(); }
6510723Sbae
6610723Sbae  // Operators so they can be used like Symbols
6710723Sbae  Symbol* operator -> () const                   { return _temp; }
6810723Sbae  bool    operator == (Symbol* o) const          { return _temp == o; }
6910723Sbae  // Sneaky conversion function
7010723Sbae  operator Symbol*()                             { return _temp; }
7110723Sbae};
7210723Sbae
7310723Sbaeclass SymbolTable : public Hashtable<Symbol*> {
7410723Sbae  friend class VMStructs;
7510723Sbae  friend class ClassFileParser;
7610723Sbae
7710723Sbaeprivate:
7810723Sbae  // The symbol table
7910723Sbae  static SymbolTable* _the_table;
8010723Sbae
8110723Sbae  // For statistics
8210723Sbae  static int symbols_removed;
8310723Sbae  static int symbols_counted;
8410723Sbae
8510723Sbae  Symbol* allocate_symbol(const u1* name, int len, TRAPS);   // Assumes no characters larger than 0x7F
8610723Sbae  bool allocate_symbols(int names_count, const u1** names, int* lengths, Symbol** syms, TRAPS);
8710723Sbae
8810723Sbae  // Adding elements
8910723Sbae  Symbol* basic_add(int index, u1* name, int len,
9010723Sbae                      unsigned int hashValue, TRAPS);
9110723Sbae  bool basic_add(constantPoolHandle cp, int names_count,
9210723Sbae                 const char** names, int* lengths, int* cp_indices,
9310723Sbae                 unsigned int* hashValues, TRAPS);
9410723Sbae
9510723Sbae  static void new_symbols(constantPoolHandle cp, int names_count,
9610723Sbae                          const char** name, int* lengths,
9710723Sbae                          int* cp_indices, unsigned int* hashValues,
9810723Sbae                          TRAPS) {
9910723Sbae    add(cp, names_count, name, lengths, cp_indices, hashValues, THREAD);
10010723Sbae  }
10110723Sbae
10210723Sbae
10310723Sbae  // Table size
10410723Sbae  enum {
10510723Sbae    symbol_table_size = 20011
10610723Sbae  };
10710723Sbae
10810723Sbae  Symbol* lookup(int index, const char* name, int len, unsigned int hash);
10910723Sbae
11010723Sbae  SymbolTable()
11110723Sbae    : Hashtable<Symbol*>(symbol_table_size, sizeof (HashtableEntry<Symbol*>)) {}
11210723Sbae
11310723Sbae  SymbolTable(HashtableBucket* t, int number_of_entries)
11410723Sbae    : Hashtable<Symbol*>(symbol_table_size, sizeof (HashtableEntry<Symbol*>), t,
11510723Sbae                number_of_entries) {}
11610723Sbae
11710723Sbae
11810723Sbaepublic:
11910723Sbae  enum {
12010723Sbae    symbol_alloc_batch_size = 8
12110723Sbae  };
12210723Sbae
12310723Sbae  // The symbol table
12410723Sbae  static SymbolTable* the_table() { return _the_table; }
12510723Sbae
12610723Sbae  static void create_table() {
12710723Sbae    assert(_the_table == NULL, "One symbol table allowed.");
12810723Sbae    _the_table = new SymbolTable();
12910723Sbae  }
130
131  static void create_table(HashtableBucket* t, int length,
132                           int number_of_entries) {
133    assert(_the_table == NULL, "One symbol table allowed.");
134    assert(length == symbol_table_size * sizeof(HashtableBucket),
135           "bad shared symbol size.");
136    _the_table = new SymbolTable(t, number_of_entries);
137  }
138
139  static Symbol* lookup(const char* name, int len, TRAPS);
140  // lookup only, won't add. Also calculate hash.
141  static Symbol* lookup_only(const char* name, int len, unsigned int& hash);
142  // Only copy to C string to be added if lookup failed.
143  static Symbol* lookup(const Symbol* sym, int begin, int end, TRAPS);
144
145  static void release(Symbol* sym);
146
147  // jchar (utf16) version of lookups
148  static Symbol* lookup_unicode(const jchar* name, int len, TRAPS);
149  static Symbol* lookup_only_unicode(const jchar* name, int len, unsigned int& hash);
150
151  static void add(constantPoolHandle cp, int names_count,
152                  const char** names, int* lengths, int* cp_indices,
153                  unsigned int* hashValues, TRAPS);
154
155  // Release any dead symbols
156  static void unlink();
157
158  // iterate over symbols
159  static void symbols_do(SymbolClosure *cl);
160
161  // Symbol creation
162  static Symbol* new_symbol(const char* utf8_buffer, int length, TRAPS) {
163    assert(utf8_buffer != NULL, "just checking");
164    return lookup(utf8_buffer, length, THREAD);
165  }
166  static Symbol*       new_symbol(const char* name, TRAPS) {
167    return new_symbol(name, (int)strlen(name), THREAD);
168  }
169  static Symbol*       new_symbol(const Symbol* sym, int begin, int end, TRAPS) {
170    assert(begin <= end && end <= sym->utf8_length(), "just checking");
171    return lookup(sym, begin, end, THREAD);
172  }
173
174  // Symbol lookup
175  static Symbol* lookup(int index, const char* name, int len, TRAPS);
176
177  // Needed for preloading classes in signatures when compiling.
178  // Returns the symbol is already present in symbol table, otherwise
179  // NULL.  NO ALLOCATION IS GUARANTEED!
180  static Symbol* probe(const char* name, int len) {
181    unsigned int ignore_hash;
182    return lookup_only(name, len, ignore_hash);
183  }
184  static Symbol* probe_unicode(const jchar* name, int len) {
185    unsigned int ignore_hash;
186    return lookup_only_unicode(name, len, ignore_hash);
187  }
188
189  // Histogram
190  static void print_histogram()     PRODUCT_RETURN;
191  static void print()     PRODUCT_RETURN;
192
193  // Debugging
194  static void verify();
195
196  // Sharing
197  static void copy_buckets(char** top, char*end) {
198    the_table()->Hashtable<Symbol*>::copy_buckets(top, end);
199  }
200  static void copy_table(char** top, char*end) {
201    the_table()->Hashtable<Symbol*>::copy_table(top, end);
202  }
203  static void reverse(void* boundary = NULL) {
204    the_table()->Hashtable<Symbol*>::reverse(boundary);
205  }
206};
207
208class StringTable : public Hashtable<oop> {
209  friend class VMStructs;
210
211private:
212  // The string table
213  static StringTable* _the_table;
214
215  static oop intern(Handle string_or_null, jchar* chars, int length, TRAPS);
216  oop basic_add(int index, Handle string_or_null, jchar* name, int len,
217                unsigned int hashValue, TRAPS);
218
219  // Table size
220  enum {
221    string_table_size = 1009
222  };
223
224  oop lookup(int index, jchar* chars, int length, unsigned int hashValue);
225
226  StringTable() : Hashtable<oop>(string_table_size, sizeof (HashtableEntry<oop>)) {}
227
228  StringTable(HashtableBucket* t, int number_of_entries)
229    : Hashtable<oop>(string_table_size, sizeof (HashtableEntry<oop>), t,
230                number_of_entries) {}
231
232public:
233  // The string table
234  static StringTable* the_table() { return _the_table; }
235
236  static void create_table() {
237    assert(_the_table == NULL, "One string table allowed.");
238    _the_table = new StringTable();
239  }
240
241  static void create_table(HashtableBucket* t, int length,
242                           int number_of_entries) {
243    assert(_the_table == NULL, "One string table allowed.");
244    assert(length == string_table_size * sizeof(HashtableBucket),
245           "bad shared string size.");
246    _the_table = new StringTable(t, number_of_entries);
247  }
248
249  static int hash_string(jchar* s, int len);
250
251  // GC support
252  //   Delete pointers to otherwise-unreachable objects.
253  static void unlink(BoolObjectClosure* cl);
254
255  // Invoke "f->do_oop" on the locations of all oops in the table.
256  static void oops_do(OopClosure* f);
257
258  // Probing
259  static oop lookup(Symbol* symbol);
260
261  // Interning
262  static oop intern(Symbol* symbol, TRAPS);
263  static oop intern(oop string, TRAPS);
264  static oop intern(const char *utf8_string, TRAPS);
265
266  // Debugging
267  static void verify();
268
269  // Sharing
270  static void copy_buckets(char** top, char*end) {
271    the_table()->Hashtable<oop>::copy_buckets(top, end);
272  }
273  static void copy_table(char** top, char*end) {
274    the_table()->Hashtable<oop>::copy_table(top, end);
275  }
276  static void reverse() {
277    the_table()->Hashtable<oop>::reverse();
278  }
279};
280
281#endif // SHARE_VM_CLASSFILE_SYMBOLTABLE_HPP
282