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