symbolTable.hpp revision 1472:c18cbe5936b8
1/*
2 * Copyright (c) 1997, 2009, 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// The symbol table holds all symbolOops and corresponding interned strings.
26// symbolOops and literal strings should be canonicalized.
27//
28// The interned strings are created lazily.
29//
30// It is implemented as an open hash table with a fixed number of buckets.
31//
32// %note:
33//  - symbolTableEntrys are allocated in blocks to reduce the space overhead.
34
35class BoolObjectClosure;
36
37
38class SymbolTable : public Hashtable {
39  friend class VMStructs;
40
41private:
42  // The symbol table
43  static SymbolTable* _the_table;
44
45  // Adding elements
46  symbolOop basic_add(int index, u1* name, int len,
47                      unsigned int hashValue, TRAPS);
48  bool basic_add(constantPoolHandle cp, int names_count,
49                 const char** names, int* lengths, int* cp_indices,
50                 unsigned int* hashValues, TRAPS);
51
52  // Table size
53  enum {
54    symbol_table_size = 20011
55  };
56
57  symbolOop lookup(int index, const char* name, int len, unsigned int hash);
58
59  SymbolTable()
60    : Hashtable(symbol_table_size, sizeof (HashtableEntry)) {}
61
62  SymbolTable(HashtableBucket* t, int number_of_entries)
63    : Hashtable(symbol_table_size, sizeof (HashtableEntry), t,
64                number_of_entries) {}
65
66
67public:
68  enum {
69    symbol_alloc_batch_size = 8
70  };
71
72  // The symbol table
73  static SymbolTable* the_table() { return _the_table; }
74
75  static void create_table() {
76    assert(_the_table == NULL, "One symbol table allowed.");
77    _the_table = new SymbolTable();
78  }
79
80  static void create_table(HashtableBucket* t, int length,
81                           int number_of_entries) {
82    assert(_the_table == NULL, "One symbol table allowed.");
83    assert(length == symbol_table_size * sizeof(HashtableBucket),
84           "bad shared symbol size.");
85    _the_table = new SymbolTable(t, number_of_entries);
86  }
87
88  static symbolOop lookup(const char* name, int len, TRAPS);
89  // lookup only, won't add. Also calculate hash.
90  static symbolOop lookup_only(const char* name, int len, unsigned int& hash);
91  // Only copy to C string to be added if lookup failed.
92  static symbolOop lookup(symbolHandle sym, int begin, int end, TRAPS);
93
94  // jchar (utf16) version of lookups
95  static symbolOop lookup_unicode(const jchar* name, int len, TRAPS);
96  static symbolOop lookup_only_unicode(const jchar* name, int len, unsigned int& hash);
97
98  static void add(constantPoolHandle cp, int names_count,
99                  const char** names, int* lengths, int* cp_indices,
100                  unsigned int* hashValues, TRAPS);
101
102  // GC support
103  //   Delete pointers to otherwise-unreachable objects.
104  static void unlink(BoolObjectClosure* cl) {
105    the_table()->Hashtable::unlink(cl);
106  }
107
108  // Invoke "f->do_oop" on the locations of all oops in the table.
109  static void oops_do(OopClosure* f) {
110    the_table()->Hashtable::oops_do(f);
111  }
112
113  // Symbol lookup
114  static symbolOop lookup(int index, const char* name, int len, TRAPS);
115
116  // Needed for preloading classes in signatures when compiling.
117  // Returns the symbol is already present in symbol table, otherwise
118  // NULL.  NO ALLOCATION IS GUARANTEED!
119  static symbolOop probe(const char* name, int len) {
120    unsigned int ignore_hash;
121    return lookup_only(name, len, ignore_hash);
122  }
123  static symbolOop probe_unicode(const jchar* name, int len) {
124    unsigned int ignore_hash;
125    return lookup_only_unicode(name, len, ignore_hash);
126  }
127
128  // Histogram
129  static void print_histogram()     PRODUCT_RETURN;
130
131  // Debugging
132  static void verify();
133
134  // Sharing
135  static void copy_buckets(char** top, char*end) {
136    the_table()->Hashtable::copy_buckets(top, end);
137  }
138  static void copy_table(char** top, char*end) {
139    the_table()->Hashtable::copy_table(top, end);
140  }
141  static void reverse(void* boundary = NULL) {
142    ((Hashtable*)the_table())->reverse(boundary);
143  }
144};
145
146
147class StringTable : public Hashtable {
148  friend class VMStructs;
149
150private:
151  // The string table
152  static StringTable* _the_table;
153
154  static oop intern(Handle string_or_null, jchar* chars, int length, TRAPS);
155  oop basic_add(int index, Handle string_or_null, jchar* name, int len,
156                unsigned int hashValue, TRAPS);
157
158  // Table size
159  enum {
160    string_table_size = 1009
161  };
162
163  oop lookup(int index, jchar* chars, int length, unsigned int hashValue);
164
165  StringTable() : Hashtable(string_table_size, sizeof (HashtableEntry)) {}
166
167  StringTable(HashtableBucket* t, int number_of_entries)
168    : Hashtable(string_table_size, sizeof (HashtableEntry), t,
169                number_of_entries) {}
170
171public:
172  // The string table
173  static StringTable* the_table() { return _the_table; }
174
175  static void create_table() {
176    assert(_the_table == NULL, "One string table allowed.");
177    _the_table = new StringTable();
178  }
179
180  static void create_table(HashtableBucket* t, int length,
181                           int number_of_entries) {
182    assert(_the_table == NULL, "One string table allowed.");
183    assert(length == string_table_size * sizeof(HashtableBucket),
184           "bad shared string size.");
185    _the_table = new StringTable(t, number_of_entries);
186  }
187
188
189  static int hash_string(jchar* s, int len);
190
191
192  // GC support
193  //   Delete pointers to otherwise-unreachable objects.
194  static void unlink(BoolObjectClosure* cl) {
195    the_table()->Hashtable::unlink(cl);
196  }
197
198  // Invoke "f->do_oop" on the locations of all oops in the table.
199  static void oops_do(OopClosure* f) {
200    the_table()->Hashtable::oops_do(f);
201  }
202
203  // Probing
204  static oop lookup(symbolOop symbol);
205
206  // Interning
207  static oop intern(symbolOop symbol, TRAPS);
208  static oop intern(oop string, TRAPS);
209  static oop intern(const char *utf8_string, TRAPS);
210
211  // Debugging
212  static void verify();
213
214  // Sharing
215  static void copy_buckets(char** top, char*end) {
216    the_table()->Hashtable::copy_buckets(top, end);
217  }
218  static void copy_table(char** top, char*end) {
219    the_table()->Hashtable::copy_table(top, end);
220  }
221  static void reverse() {
222    ((BasicHashtable*)the_table())->reverse();
223  }
224};
225