Mercurial > hg > graal-jvmci-8
comparison src/share/vm/classfile/symbolTable.hpp @ 2177:3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
Summary: move symbols from permgen into C heap and reference count them
Reviewed-by: never, acorn, jmasa, stefank
author | coleenp |
---|---|
date | Thu, 27 Jan 2011 16:11:27 -0800 |
parents | f95d63e2154a |
children | 924777755fad |
comparison
equal
deleted
inserted
replaced
2176:27e4ea99855d | 2177:3582bf76420e |
---|---|
24 | 24 |
25 #ifndef SHARE_VM_CLASSFILE_SYMBOLTABLE_HPP | 25 #ifndef SHARE_VM_CLASSFILE_SYMBOLTABLE_HPP |
26 #define SHARE_VM_CLASSFILE_SYMBOLTABLE_HPP | 26 #define SHARE_VM_CLASSFILE_SYMBOLTABLE_HPP |
27 | 27 |
28 #include "memory/allocation.inline.hpp" | 28 #include "memory/allocation.inline.hpp" |
29 #include "oops/symbolOop.hpp" | 29 #include "oops/symbol.hpp" |
30 #include "utilities/hashtable.hpp" | 30 #include "utilities/hashtable.hpp" |
31 | 31 |
32 // The symbol table holds all symbolOops and corresponding interned strings. | 32 // The symbol table holds all Symbol*s and corresponding interned strings. |
33 // symbolOops and literal strings should be canonicalized. | 33 // Symbol*s and literal strings should be canonicalized. |
34 // | 34 // |
35 // The interned strings are created lazily. | 35 // The interned strings are created lazily. |
36 // | 36 // |
37 // It is implemented as an open hash table with a fixed number of buckets. | 37 // It is implemented as an open hash table with a fixed number of buckets. |
38 // | 38 // |
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; |
167 string_table_size = 1009 | 221 string_table_size = 1009 |
168 }; | 222 }; |
169 | 223 |
170 oop lookup(int index, jchar* chars, int length, unsigned int hashValue); | 224 oop lookup(int index, jchar* chars, int length, unsigned int hashValue); |
171 | 225 |
172 StringTable() : Hashtable(string_table_size, sizeof (HashtableEntry)) {} | 226 StringTable() : Hashtable<oop>(string_table_size, sizeof (HashtableEntry<oop>)) {} |
173 | 227 |
174 StringTable(HashtableBucket* t, int number_of_entries) | 228 StringTable(HashtableBucket* t, int number_of_entries) |
175 : Hashtable(string_table_size, sizeof (HashtableEntry), t, | 229 : Hashtable<oop>(string_table_size, sizeof (HashtableEntry<oop>), t, |
176 number_of_entries) {} | 230 number_of_entries) {} |
177 | 231 |
178 public: | 232 public: |
179 // The string table | 233 // The string table |
180 static StringTable* the_table() { return _the_table; } | 234 static StringTable* the_table() { return _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 |