Mercurial > hg > graal-jvmci-8
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()) { |