40 // - symbolTableEntrys are allocated in blocks to reduce the space overhead. |
40 // - symbolTableEntrys are allocated in blocks to reduce the space overhead. |
41 |
41 |
42 class BoolObjectClosure; |
42 class BoolObjectClosure; |
43 |
43 |
44 |
44 |
45 class SymbolTable : public Hashtable { |
45 // Class to hold a newly created or referenced Symbol* temporarily in scope. |
|
46 // new_symbol() and lookup() will create a Symbol* if not already in the |
|
47 // symbol table and add to the symbol's reference count. |
|
48 // probe() and lookup_only() will increment the refcount if symbol is found. |
|
49 class TempNewSymbol : public StackObj { |
|
50 Symbol* _temp; |
|
51 |
|
52 public: |
|
53 TempNewSymbol() : _temp(NULL) {} |
|
54 // Creating or looking up a symbol increments the symbol's reference count |
|
55 TempNewSymbol(Symbol *s) : _temp(s) {} |
|
56 |
|
57 // Operator= increments reference count. |
|
58 void operator=(const TempNewSymbol &s) { |
|
59 _temp = s._temp; |
|
60 if (_temp !=NULL) _temp->increment_refcount(); |
|
61 } |
|
62 |
|
63 // Decrement reference counter so it can go away if it's unique |
|
64 ~TempNewSymbol() { if (_temp != NULL) _temp->decrement_refcount(); } |
|
65 |
|
66 // Operators so they can be used like Symbols |
|
67 Symbol* operator -> () const { return _temp; } |
|
68 bool operator == (Symbol* o) const { return _temp == o; } |
|
69 // Sneaky conversion function |
|
70 operator Symbol*() { return _temp; } |
|
71 }; |
|
72 |
|
73 class SymbolTable : public Hashtable<Symbol*> { |
46 friend class VMStructs; |
74 friend class VMStructs; |
|
75 friend class ClassFileParser; |
47 |
76 |
48 private: |
77 private: |
49 // The symbol table |
78 // The symbol table |
50 static SymbolTable* _the_table; |
79 static SymbolTable* _the_table; |
51 |
80 |
|
81 // For statistics |
|
82 static int symbols_removed; |
|
83 static int symbols_counted; |
|
84 |
|
85 Symbol* allocate_symbol(const u1* name, int len, TRAPS); // Assumes no characters larger than 0x7F |
|
86 bool allocate_symbols(int names_count, const u1** names, int* lengths, Symbol** syms, TRAPS); |
|
87 |
52 // Adding elements |
88 // Adding elements |
53 symbolOop basic_add(int index, u1* name, int len, |
89 Symbol* basic_add(int index, u1* name, int len, |
54 unsigned int hashValue, TRAPS); |
90 unsigned int hashValue, TRAPS); |
55 bool basic_add(constantPoolHandle cp, int names_count, |
91 bool basic_add(constantPoolHandle cp, int names_count, |
56 const char** names, int* lengths, int* cp_indices, |
92 const char** names, int* lengths, int* cp_indices, |
57 unsigned int* hashValues, TRAPS); |
93 unsigned int* hashValues, TRAPS); |
58 |
94 |
|
95 static void new_symbols(constantPoolHandle cp, int names_count, |
|
96 const char** name, int* lengths, |
|
97 int* cp_indices, unsigned int* hashValues, |
|
98 TRAPS) { |
|
99 add(cp, names_count, name, lengths, cp_indices, hashValues, THREAD); |
|
100 } |
|
101 |
|
102 |
59 // Table size |
103 // Table size |
60 enum { |
104 enum { |
61 symbol_table_size = 20011 |
105 symbol_table_size = 20011 |
62 }; |
106 }; |
63 |
107 |
64 symbolOop lookup(int index, const char* name, int len, unsigned int hash); |
108 Symbol* lookup(int index, const char* name, int len, unsigned int hash); |
65 |
109 |
66 SymbolTable() |
110 SymbolTable() |
67 : Hashtable(symbol_table_size, sizeof (HashtableEntry)) {} |
111 : Hashtable<Symbol*>(symbol_table_size, sizeof (HashtableEntry<Symbol*>)) {} |
68 |
112 |
69 SymbolTable(HashtableBucket* t, int number_of_entries) |
113 SymbolTable(HashtableBucket* t, int number_of_entries) |
70 : Hashtable(symbol_table_size, sizeof (HashtableEntry), t, |
114 : Hashtable<Symbol*>(symbol_table_size, sizeof (HashtableEntry<Symbol*>), t, |
71 number_of_entries) {} |
115 number_of_entries) {} |
72 |
116 |
73 |
117 |
74 public: |
118 public: |
75 enum { |
119 enum { |
90 assert(length == symbol_table_size * sizeof(HashtableBucket), |
134 assert(length == symbol_table_size * sizeof(HashtableBucket), |
91 "bad shared symbol size."); |
135 "bad shared symbol size."); |
92 _the_table = new SymbolTable(t, number_of_entries); |
136 _the_table = new SymbolTable(t, number_of_entries); |
93 } |
137 } |
94 |
138 |
95 static symbolOop lookup(const char* name, int len, TRAPS); |
139 static Symbol* lookup(const char* name, int len, TRAPS); |
96 // lookup only, won't add. Also calculate hash. |
140 // lookup only, won't add. Also calculate hash. |
97 static symbolOop lookup_only(const char* name, int len, unsigned int& hash); |
141 static Symbol* lookup_only(const char* name, int len, unsigned int& hash); |
98 // Only copy to C string to be added if lookup failed. |
142 // Only copy to C string to be added if lookup failed. |
99 static symbolOop lookup(symbolHandle sym, int begin, int end, TRAPS); |
143 static Symbol* lookup(const Symbol* sym, int begin, int end, TRAPS); |
|
144 |
|
145 static void release(Symbol* sym); |
100 |
146 |
101 // jchar (utf16) version of lookups |
147 // jchar (utf16) version of lookups |
102 static symbolOop lookup_unicode(const jchar* name, int len, TRAPS); |
148 static Symbol* lookup_unicode(const jchar* name, int len, TRAPS); |
103 static symbolOop lookup_only_unicode(const jchar* name, int len, unsigned int& hash); |
149 static Symbol* lookup_only_unicode(const jchar* name, int len, unsigned int& hash); |
104 |
150 |
105 static void add(constantPoolHandle cp, int names_count, |
151 static void add(constantPoolHandle cp, int names_count, |
106 const char** names, int* lengths, int* cp_indices, |
152 const char** names, int* lengths, int* cp_indices, |
107 unsigned int* hashValues, TRAPS); |
153 unsigned int* hashValues, TRAPS); |
108 |
154 |
109 // GC support |
155 // Release any dead symbols |
110 // Delete pointers to otherwise-unreachable objects. |
156 static void unlink(); |
111 static void unlink(BoolObjectClosure* cl) { |
157 |
112 the_table()->Hashtable::unlink(cl); |
158 // iterate over symbols |
113 } |
159 static void symbols_do(SymbolClosure *cl); |
114 |
160 |
115 // Invoke "f->do_oop" on the locations of all oops in the table. |
161 // Symbol creation |
116 static void oops_do(OopClosure* f) { |
162 static Symbol* new_symbol(const char* utf8_buffer, int length, TRAPS) { |
117 the_table()->Hashtable::oops_do(f); |
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); |
118 } |
172 } |
119 |
173 |
120 // Symbol lookup |
174 // Symbol lookup |
121 static symbolOop lookup(int index, const char* name, int len, TRAPS); |
175 static Symbol* lookup(int index, const char* name, int len, TRAPS); |
122 |
176 |
123 // Needed for preloading classes in signatures when compiling. |
177 // Needed for preloading classes in signatures when compiling. |
124 // Returns the symbol is already present in symbol table, otherwise |
178 // Returns the symbol is already present in symbol table, otherwise |
125 // NULL. NO ALLOCATION IS GUARANTEED! |
179 // NULL. NO ALLOCATION IS GUARANTEED! |
126 static symbolOop probe(const char* name, int len) { |
180 static Symbol* probe(const char* name, int len) { |
127 unsigned int ignore_hash; |
181 unsigned int ignore_hash; |
128 return lookup_only(name, len, ignore_hash); |
182 return lookup_only(name, len, ignore_hash); |
129 } |
183 } |
130 static symbolOop probe_unicode(const jchar* name, int len) { |
184 static Symbol* probe_unicode(const jchar* name, int len) { |
131 unsigned int ignore_hash; |
185 unsigned int ignore_hash; |
132 return lookup_only_unicode(name, len, ignore_hash); |
186 return lookup_only_unicode(name, len, ignore_hash); |
133 } |
187 } |
134 |
188 |
135 // Histogram |
189 // Histogram |
136 static void print_histogram() PRODUCT_RETURN; |
190 static void print_histogram() PRODUCT_RETURN; |
|
191 static void print() PRODUCT_RETURN; |
137 |
192 |
138 // Debugging |
193 // Debugging |
139 static void verify(); |
194 static void verify(); |
140 |
195 |
141 // Sharing |
196 // Sharing |
142 static void copy_buckets(char** top, char*end) { |
197 static void copy_buckets(char** top, char*end) { |
143 the_table()->Hashtable::copy_buckets(top, end); |
198 the_table()->Hashtable<Symbol*>::copy_buckets(top, end); |
144 } |
199 } |
145 static void copy_table(char** top, char*end) { |
200 static void copy_table(char** top, char*end) { |
146 the_table()->Hashtable::copy_table(top, end); |
201 the_table()->Hashtable<Symbol*>::copy_table(top, end); |
147 } |
202 } |
148 static void reverse(void* boundary = NULL) { |
203 static void reverse(void* boundary = NULL) { |
149 ((Hashtable*)the_table())->reverse(boundary); |
204 the_table()->Hashtable<Symbol*>::reverse(boundary); |
150 } |
205 } |
151 }; |
206 }; |
152 |
207 |
153 |
208 class StringTable : public Hashtable<oop> { |
154 class StringTable : public Hashtable { |
|
155 friend class VMStructs; |
209 friend class VMStructs; |
156 |
210 |
157 private: |
211 private: |
158 // The string table |
212 // The string table |
159 static StringTable* _the_table; |
213 static StringTable* _the_table; |
190 assert(length == string_table_size * sizeof(HashtableBucket), |
244 assert(length == string_table_size * sizeof(HashtableBucket), |
191 "bad shared string size."); |
245 "bad shared string size."); |
192 _the_table = new StringTable(t, number_of_entries); |
246 _the_table = new StringTable(t, number_of_entries); |
193 } |
247 } |
194 |
248 |
195 |
|
196 static int hash_string(jchar* s, int len); |
249 static int hash_string(jchar* s, int len); |
197 |
|
198 |
250 |
199 // GC support |
251 // GC support |
200 // Delete pointers to otherwise-unreachable objects. |
252 // Delete pointers to otherwise-unreachable objects. |
201 static void unlink(BoolObjectClosure* cl) { |
253 static void unlink(BoolObjectClosure* cl); |
202 the_table()->Hashtable::unlink(cl); |
|
203 } |
|
204 |
254 |
205 // Invoke "f->do_oop" on the locations of all oops in the table. |
255 // Invoke "f->do_oop" on the locations of all oops in the table. |
206 static void oops_do(OopClosure* f) { |
256 static void oops_do(OopClosure* f); |
207 the_table()->Hashtable::oops_do(f); |
|
208 } |
|
209 |
257 |
210 // Probing |
258 // Probing |
211 static oop lookup(symbolOop symbol); |
259 static oop lookup(Symbol* symbol); |
212 |
260 |
213 // Interning |
261 // Interning |
214 static oop intern(symbolOop symbol, TRAPS); |
262 static oop intern(Symbol* symbol, TRAPS); |
215 static oop intern(oop string, TRAPS); |
263 static oop intern(oop string, TRAPS); |
216 static oop intern(const char *utf8_string, TRAPS); |
264 static oop intern(const char *utf8_string, TRAPS); |
217 |
265 |
218 // Debugging |
266 // Debugging |
219 static void verify(); |
267 static void verify(); |
220 |
268 |
221 // Sharing |
269 // Sharing |
222 static void copy_buckets(char** top, char*end) { |
270 static void copy_buckets(char** top, char*end) { |
223 the_table()->Hashtable::copy_buckets(top, end); |
271 the_table()->Hashtable<oop>::copy_buckets(top, end); |
224 } |
272 } |
225 static void copy_table(char** top, char*end) { |
273 static void copy_table(char** top, char*end) { |
226 the_table()->Hashtable::copy_table(top, end); |
274 the_table()->Hashtable<oop>::copy_table(top, end); |
227 } |
275 } |
228 static void reverse() { |
276 static void reverse() { |
229 ((BasicHashtable*)the_table())->reverse(); |
277 the_table()->Hashtable<oop>::reverse(); |
230 } |
278 } |
231 }; |
279 }; |
232 |
280 |
233 #endif // SHARE_VM_CLASSFILE_SYMBOLTABLE_HPP |
281 #endif // SHARE_VM_CLASSFILE_SYMBOLTABLE_HPP |