comparison src/share/vm/classfile/vmSymbols.cpp @ 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 72dee110246f
comparison
equal deleted inserted replaced
2176:27e4ea99855d 2177:3582bf76420e
28 #include "oops/oop.inline.hpp" 28 #include "oops/oop.inline.hpp"
29 #include "runtime/handles.inline.hpp" 29 #include "runtime/handles.inline.hpp"
30 #include "utilities/xmlstream.hpp" 30 #include "utilities/xmlstream.hpp"
31 31
32 32
33 symbolOop vmSymbols::_symbols[vmSymbols::SID_LIMIT]; 33 Symbol* vmSymbols::_symbols[vmSymbols::SID_LIMIT];
34 34
35 symbolOop vmSymbols::_type_signatures[T_VOID+1] = { NULL /*, NULL...*/ }; 35 Symbol* vmSymbols::_type_signatures[T_VOID+1] = { NULL /*, NULL...*/ };
36 36
37 inline int compare_symbol(symbolOop a, symbolOop b) { 37 inline int compare_symbol(Symbol* a, Symbol* b) {
38 if (a == b) return 0; 38 if (a == b) return 0;
39 // follow the natural address order: 39 // follow the natural address order:
40 return (address)a > (address)b ? +1 : -1; 40 return (address)a > (address)b ? +1 : -1;
41 } 41 }
42 42
43 static vmSymbols::SID vm_symbol_index[vmSymbols::SID_LIMIT]; 43 static vmSymbols::SID vm_symbol_index[vmSymbols::SID_LIMIT];
44 extern "C" { 44 extern "C" {
45 static int compare_vmsymbol_sid(const void* void_a, const void* void_b) { 45 static int compare_vmsymbol_sid(const void* void_a, const void* void_b) {
46 symbolOop a = vmSymbols::symbol_at(*((vmSymbols::SID*) void_a)); 46 Symbol* a = vmSymbols::symbol_at(*((vmSymbols::SID*) void_a));
47 symbolOop b = vmSymbols::symbol_at(*((vmSymbols::SID*) void_b)); 47 Symbol* b = vmSymbols::symbol_at(*((vmSymbols::SID*) void_b));
48 return compare_symbol(a, b); 48 return compare_symbol(a, b);
49 } 49 }
50 } 50 }
51 51
52 #ifndef PRODUCT 52 #ifndef PRODUCT
77 assert(vmIntrinsics::FLAG_LIMIT <= (1 << vmIntrinsics::log2_FLAG_LIMIT), "must fit in this bitfield"); 77 assert(vmIntrinsics::FLAG_LIMIT <= (1 << vmIntrinsics::log2_FLAG_LIMIT), "must fit in this bitfield");
78 78
79 if (!UseSharedSpaces) { 79 if (!UseSharedSpaces) {
80 const char* string = &vm_symbol_bodies[0]; 80 const char* string = &vm_symbol_bodies[0];
81 for (int index = (int)FIRST_SID; index < (int)SID_LIMIT; index++) { 81 for (int index = (int)FIRST_SID; index < (int)SID_LIMIT; index++) {
82 symbolOop sym = oopFactory::new_symbol(string, CHECK); 82 Symbol* sym = SymbolTable::new_symbol(string, CHECK);
83 _symbols[index] = sym; 83 _symbols[index] = sym;
84 string += strlen(string); // skip string body 84 string += strlen(string); // skip string body
85 string += 1; // skip trailing null 85 string += 1; // skip trailing null
86 } 86 }
87 87
98 } 98 }
99 99
100 #ifdef ASSERT 100 #ifdef ASSERT
101 // Check for duplicates: 101 // Check for duplicates:
102 for (int i1 = (int)FIRST_SID; i1 < (int)SID_LIMIT; i1++) { 102 for (int i1 = (int)FIRST_SID; i1 < (int)SID_LIMIT; i1++) {
103 symbolOop sym = symbol_at((SID)i1); 103 Symbol* sym = symbol_at((SID)i1);
104 for (int i2 = (int)FIRST_SID; i2 < i1; i2++) { 104 for (int i2 = (int)FIRST_SID; i2 < i1; i2++) {
105 if (symbol_at((SID)i2) == sym) { 105 if (symbol_at((SID)i2) == sym) {
106 tty->print("*** Duplicate VM symbol SIDs %s(%d) and %s(%d): \"", 106 tty->print("*** Duplicate VM symbol SIDs %s(%d) and %s(%d): \"",
107 vm_symbol_enum_name((SID)i2), i2, 107 vm_symbol_enum_name((SID)i2), i2,
108 vm_symbol_enum_name((SID)i1), i1); 108 vm_symbol_enum_name((SID)i1), i1);
126 #ifdef ASSERT 126 #ifdef ASSERT
127 { 127 {
128 // Spot-check correspondence between strings, symbols, and enums: 128 // Spot-check correspondence between strings, symbols, and enums:
129 assert(_symbols[NO_SID] == NULL, "must be"); 129 assert(_symbols[NO_SID] == NULL, "must be");
130 const char* str = "java/lang/Object"; 130 const char* str = "java/lang/Object";
131 symbolOop sym = oopFactory::new_symbol(str, CHECK); 131 TempNewSymbol jlo = SymbolTable::new_symbol(str, CHECK);
132 assert(strcmp(str, (char*)sym->base()) == 0, ""); 132 assert(strncmp(str, (char*)jlo->base(), jlo->utf8_length()) == 0, "");
133 assert(sym == java_lang_Object(), ""); 133 assert(jlo == java_lang_Object(), "");
134 SID sid = VM_SYMBOL_ENUM_NAME(java_lang_Object); 134 SID sid = VM_SYMBOL_ENUM_NAME(java_lang_Object);
135 assert(find_sid(sym) == sid, ""); 135 assert(find_sid(jlo) == sid, "");
136 assert(symbol_at(sid) == sym, ""); 136 assert(symbol_at(sid) == jlo, "");
137 137
138 // Make sure find_sid produces the right answer in each case. 138 // Make sure find_sid produces the right answer in each case.
139 for (int index = (int)FIRST_SID; index < (int)SID_LIMIT; index++) { 139 for (int index = (int)FIRST_SID; index < (int)SID_LIMIT; index++) {
140 sym = symbol_at((SID)index); 140 Symbol* sym = symbol_at((SID)index);
141 sid = find_sid(sym); 141 sid = find_sid(sym);
142 assert(sid == (SID)index, "symbol index works"); 142 assert(sid == (SID)index, "symbol index works");
143 // Note: If there are duplicates, this assert will fail. 143 // Note: If there are duplicates, this assert will fail.
144 // A "Duplicate VM symbol" message will have already been printed. 144 // A "Duplicate VM symbol" message will have already been printed.
145 } 145 }
146 146
147 // The string "format" happens (at the moment) not to be a vmSymbol, 147 // The string "format" happens (at the moment) not to be a vmSymbol,
148 // though it is a method name in java.lang.String. 148 // though it is a method name in java.lang.String.
149 str = "format"; 149 str = "format";
150 sym = oopFactory::new_symbol(str, CHECK); 150 TempNewSymbol fmt = SymbolTable::new_symbol(str, CHECK);
151 sid = find_sid(sym); 151 sid = find_sid(fmt);
152 assert(sid == NO_SID, "symbol index works (negative test)"); 152 assert(sid == NO_SID, "symbol index works (negative test)");
153 } 153 }
154 #endif 154 #endif
155 } 155 }
156 156
170 } 170 }
171 #endif 171 #endif
172 172
173 173
174 174
175 void vmSymbols::oops_do(OopClosure* f, bool do_all) { 175 void vmSymbols::symbols_do(SymbolClosure* f) {
176 for (int index = (int)FIRST_SID; index < (int)SID_LIMIT; index++) { 176 for (int index = (int)FIRST_SID; index < (int)SID_LIMIT; index++) {
177 f->do_oop((oop*) &_symbols[index]); 177 f->do_symbol(&_symbols[index]);
178 } 178 }
179 for (int i = 0; i < T_VOID+1; i++) { 179 for (int i = 0; i < T_VOID+1; i++) {
180 if (_type_signatures[i] != NULL) { 180 f->do_symbol(&_type_signatures[i]);
181 assert(i >= T_BOOLEAN, "checking"); 181 }
182 f->do_oop((oop*)&_type_signatures[i]); 182 }
183 } else if (do_all) { 183
184 f->do_oop((oop*)&_type_signatures[i]); 184 void vmSymbols::serialize(SerializeOopClosure* soc) {
185 } 185 soc->do_region((u_char*)&_symbols[FIRST_SID],
186 } 186 (SID_LIMIT - FIRST_SID) * sizeof(_symbols[0]));
187 } 187 soc->do_region((u_char*)_type_signatures, sizeof(_type_signatures));
188 188 }
189 189
190 BasicType vmSymbols::signature_type(symbolOop s) { 190
191 BasicType vmSymbols::signature_type(Symbol* s) {
191 assert(s != NULL, "checking"); 192 assert(s != NULL, "checking");
192 for (int i = T_BOOLEAN; i < T_VOID+1; i++) { 193 for (int i = T_BOOLEAN; i < T_VOID+1; i++) {
193 if (s == _type_signatures[i]) { 194 if (s == _type_signatures[i]) {
194 return (BasicType)i; 195 return (BasicType)i;
195 } 196 }
203 #ifndef PRODUCT 204 #ifndef PRODUCT
204 static int find_sid_calls, find_sid_probes; 205 static int find_sid_calls, find_sid_probes;
205 // (Typical counts are calls=7000 and probes=17000.) 206 // (Typical counts are calls=7000 and probes=17000.)
206 #endif 207 #endif
207 208
208 vmSymbols::SID vmSymbols::find_sid(symbolOop symbol) { 209 vmSymbols::SID vmSymbols::find_sid(Symbol* symbol) {
209 // Handle the majority of misses by a bounds check. 210 // Handle the majority of misses by a bounds check.
210 // Then, use a binary search over the index. 211 // Then, use a binary search over the index.
211 // Expected trip count is less than log2_SID_LIMIT, about eight. 212 // Expected trip count is less than log2_SID_LIMIT, about eight.
212 // This is slow but acceptable, given that calls are not 213 // This is slow but acceptable, given that calls are not
213 // dynamically common. (methodOop::intrinsic_id has a cache.) 214 // dynamically common. (methodOop::intrinsic_id has a cache.)
258 259
259 // Make sure this is the right answer, using linear search. 260 // Make sure this is the right answer, using linear search.
260 // (We have already proven that there are no duplicates in the list.) 261 // (We have already proven that there are no duplicates in the list.)
261 SID sid2 = NO_SID; 262 SID sid2 = NO_SID;
262 for (int index = (int)FIRST_SID; index < (int)SID_LIMIT; index++) { 263 for (int index = (int)FIRST_SID; index < (int)SID_LIMIT; index++) {
263 symbolOop sym2 = symbol_at((SID)index); 264 Symbol* sym2 = symbol_at((SID)index);
264 if (sym2 == symbol) { 265 if (sym2 == symbol) {
265 sid2 = (SID)index; 266 sid2 = (SID)index;
266 break; 267 break;
267 } 268 }
268 } 269 }
317 return vmIntrinsics::_none; 318 return vmIntrinsics::_none;
318 } 319 }
319 320
320 methodOop vmIntrinsics::method_for(vmIntrinsics::ID id) { 321 methodOop vmIntrinsics::method_for(vmIntrinsics::ID id) {
321 if (id == _none) return NULL; 322 if (id == _none) return NULL;
322 symbolOop cname = vmSymbols::symbol_at(class_for(id)); 323 Symbol* cname = vmSymbols::symbol_at(class_for(id));
323 symbolOop mname = vmSymbols::symbol_at(name_for(id)); 324 Symbol* mname = vmSymbols::symbol_at(name_for(id));
324 symbolOop msig = vmSymbols::symbol_at(signature_for(id)); 325 Symbol* msig = vmSymbols::symbol_at(signature_for(id));
325 if (cname == NULL || mname == NULL || msig == NULL) return NULL; 326 if (cname == NULL || mname == NULL || msig == NULL) return NULL;
326 klassOop k = SystemDictionary::find_well_known_klass(cname); 327 klassOop k = SystemDictionary::find_well_known_klass(cname);
327 if (k == NULL) return NULL; 328 if (k == NULL) return NULL;
328 return instanceKlass::cast(k)->find_method(mname, msig); 329 return instanceKlass::cast(k)->find_method(mname, msig);
329 } 330 }
488 489
489 490
490 #ifndef PRODUCT 491 #ifndef PRODUCT
491 // verify_method performs an extra check on a matched intrinsic method 492 // verify_method performs an extra check on a matched intrinsic method
492 493
493 static bool match_method(methodOop m, symbolOop n, symbolOop s) { 494 static bool match_method(methodOop m, Symbol* n, Symbol* s) {
494 return (m->name() == n && 495 return (m->name() == n &&
495 m->signature() == s); 496 m->signature() == s);
496 } 497 }
497 498
498 static vmIntrinsics::ID match_method_with_klass(methodOop m, symbolOop mk) { 499 static vmIntrinsics::ID match_method_with_klass(methodOop m, Symbol* mk) {
499 #define VM_INTRINSIC_MATCH(id, klassname, namepart, sigpart, flags) \ 500 #define VM_INTRINSIC_MATCH(id, klassname, namepart, sigpart, flags) \
500 { symbolOop k = vmSymbols::klassname(); \ 501 { Symbol* k = vmSymbols::klassname(); \
501 if (mk == k) { \ 502 if (mk == k) { \
502 symbolOop n = vmSymbols::namepart(); \ 503 Symbol* n = vmSymbols::namepart(); \
503 symbolOop s = vmSymbols::sigpart(); \ 504 Symbol* s = vmSymbols::sigpart(); \
504 if (match_method(m, n, s)) \ 505 if (match_method(m, n, s)) \
505 return vmIntrinsics::id; \ 506 return vmIntrinsics::id; \
506 } } 507 } }
507 VM_INTRINSICS_DO(VM_INTRINSIC_MATCH, 508 VM_INTRINSICS_DO(VM_INTRINSIC_MATCH,
508 VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_ALIAS_IGNORE); 509 VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_ALIAS_IGNORE);
509 return vmIntrinsics::_none; 510 return vmIntrinsics::_none;
510 #undef VM_INTRINSIC_MATCH 511 #undef VM_INTRINSIC_MATCH
511 } 512 }
512 513
513 void vmIntrinsics::verify_method(ID actual_id, methodOop m) { 514 void vmIntrinsics::verify_method(ID actual_id, methodOop m) {
514 symbolOop mk = Klass::cast(m->method_holder())->name(); 515 Symbol* mk = Klass::cast(m->method_holder())->name();
515 ID declared_id = match_method_with_klass(m, mk); 516 ID declared_id = match_method_with_klass(m, mk);
516 517
517 if (declared_id == actual_id) return; // success 518 if (declared_id == actual_id) return; // success
518 519
519 if (declared_id == _none && actual_id != _none && mk == vmSymbols::java_lang_StrictMath()) { 520 if (declared_id == _none && actual_id != _none && mk == vmSymbols::java_lang_StrictMath()) {