Mercurial > hg > graal-jvmci-8
comparison src/share/vm/ci/ciObjectFactory.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 | d25d4ca69222 8033953d67ff |
comparison
equal
deleted
inserted
replaced
2176:27e4ea99855d | 2177:3582bf76420e |
---|---|
36 #include "ci/ciObjArray.hpp" | 36 #include "ci/ciObjArray.hpp" |
37 #include "ci/ciObjArrayKlass.hpp" | 37 #include "ci/ciObjArrayKlass.hpp" |
38 #include "ci/ciObjArrayKlassKlass.hpp" | 38 #include "ci/ciObjArrayKlassKlass.hpp" |
39 #include "ci/ciObjectFactory.hpp" | 39 #include "ci/ciObjectFactory.hpp" |
40 #include "ci/ciSymbol.hpp" | 40 #include "ci/ciSymbol.hpp" |
41 #include "ci/ciSymbolKlass.hpp" | |
42 #include "ci/ciTypeArray.hpp" | 41 #include "ci/ciTypeArray.hpp" |
43 #include "ci/ciTypeArrayKlass.hpp" | 42 #include "ci/ciTypeArrayKlass.hpp" |
44 #include "ci/ciTypeArrayKlassKlass.hpp" | 43 #include "ci/ciTypeArrayKlassKlass.hpp" |
45 #include "ci/ciUtilities.hpp" | 44 #include "ci/ciUtilities.hpp" |
46 #include "classfile/systemDictionary.hpp" | 45 #include "classfile/systemDictionary.hpp" |
96 _unloaded_methods = new (arena) GrowableArray<ciMethod*>(arena, 4, 0, NULL); | 95 _unloaded_methods = new (arena) GrowableArray<ciMethod*>(arena, 4, 0, NULL); |
97 _unloaded_klasses = new (arena) GrowableArray<ciKlass*>(arena, 8, 0, NULL); | 96 _unloaded_klasses = new (arena) GrowableArray<ciKlass*>(arena, 8, 0, NULL); |
98 _unloaded_instances = new (arena) GrowableArray<ciInstance*>(arena, 4, 0, NULL); | 97 _unloaded_instances = new (arena) GrowableArray<ciInstance*>(arena, 4, 0, NULL); |
99 _return_addresses = | 98 _return_addresses = |
100 new (arena) GrowableArray<ciReturnAddress*>(arena, 8, 0, NULL); | 99 new (arena) GrowableArray<ciReturnAddress*>(arena, 8, 0, NULL); |
100 | |
101 _symbols = new (arena) GrowableArray<ciSymbol*>(arena, 100, 0, NULL); | |
101 } | 102 } |
102 | 103 |
103 // ------------------------------------------------------------------ | 104 // ------------------------------------------------------------------ |
104 // ciObjectFactory::ciObjectFactory | 105 // ciObjectFactory::ciObjectFactory |
105 void ciObjectFactory::initialize() { | 106 void ciObjectFactory::initialize() { |
125 | 126 |
126 { | 127 { |
127 // Create the shared symbols, but not in _shared_ci_objects. | 128 // Create the shared symbols, but not in _shared_ci_objects. |
128 int i; | 129 int i; |
129 for (i = vmSymbols::FIRST_SID; i < vmSymbols::SID_LIMIT; i++) { | 130 for (i = vmSymbols::FIRST_SID; i < vmSymbols::SID_LIMIT; i++) { |
130 symbolHandle sym_handle = vmSymbolHandles::symbol_handle_at((vmSymbols::SID) i); | 131 Symbol* vmsym = vmSymbols::symbol_at((vmSymbols::SID) i); |
131 assert(vmSymbols::find_sid(sym_handle()) == i, "1-1 mapping"); | 132 assert(vmSymbols::find_sid(vmsym) == i, "1-1 mapping"); |
132 ciSymbol* sym = new (_arena) ciSymbol(sym_handle, (vmSymbols::SID) i); | 133 ciSymbol* sym = new (_arena) ciSymbol(vmsym, (vmSymbols::SID) i); |
133 init_ident_of(sym); | 134 init_ident_of(sym); |
134 _shared_ci_symbols[i] = sym; | 135 _shared_ci_symbols[i] = sym; |
135 } | 136 } |
136 #ifdef ASSERT | 137 #ifdef ASSERT |
137 for (i = vmSymbols::FIRST_SID; i < vmSymbols::SID_LIMIT; i++) { | 138 for (i = vmSymbols::FIRST_SID; i < vmSymbols::SID_LIMIT; i++) { |
138 symbolHandle sym_handle = vmSymbolHandles::symbol_handle_at((vmSymbols::SID) i); | 139 Symbol* vmsym = vmSymbols::symbol_at((vmSymbols::SID) i); |
139 ciSymbol* sym = vm_symbol_at((vmSymbols::SID) i); | 140 ciSymbol* sym = vm_symbol_at((vmSymbols::SID) i); |
140 assert(sym->get_oop() == sym_handle(), "oop must match"); | 141 assert(sym->get_symbol() == vmsym, "oop must match"); |
141 } | 142 } |
142 assert(ciSymbol::void_class_signature()->get_oop() == vmSymbols::void_class_signature(), "spot check"); | 143 assert(ciSymbol::void_class_signature()->get_symbol() == vmSymbols::void_class_signature(), "spot check"); |
143 #endif | 144 #endif |
144 } | 145 } |
145 | 146 |
146 _ci_objects = new (_arena) GrowableArray<ciObject*>(_arena, 64, 0, NULL); | 147 _ci_objects = new (_arena) GrowableArray<ciObject*>(_arena, 64, 0, NULL); |
147 | 148 |
155 | 156 |
156 ciEnv::_null_object_instance = new (_arena) ciNullObject(); | 157 ciEnv::_null_object_instance = new (_arena) ciNullObject(); |
157 init_ident_of(ciEnv::_null_object_instance); | 158 init_ident_of(ciEnv::_null_object_instance); |
158 ciEnv::_method_klass_instance = | 159 ciEnv::_method_klass_instance = |
159 get(Universe::methodKlassObj())->as_method_klass(); | 160 get(Universe::methodKlassObj())->as_method_klass(); |
160 ciEnv::_symbol_klass_instance = | |
161 get(Universe::symbolKlassObj())->as_symbol_klass(); | |
162 ciEnv::_klass_klass_instance = | 161 ciEnv::_klass_klass_instance = |
163 get(Universe::klassKlassObj())->as_klass_klass(); | 162 get(Universe::klassKlassObj())->as_klass_klass(); |
164 ciEnv::_instance_klass_klass_instance = | 163 ciEnv::_instance_klass_klass_instance = |
165 get(Universe::instanceKlassKlassObj()) | 164 get(Universe::instanceKlassKlassObj()) |
166 ->as_instance_klass_klass(); | 165 ->as_instance_klass_klass(); |
186 obj->as_instance_klass()->compute_nonstatic_fields(); | 185 obj->as_instance_klass()->compute_nonstatic_fields(); |
187 } | 186 } |
188 } | 187 } |
189 } | 188 } |
190 | 189 |
191 ciEnv::_unloaded_cisymbol = (ciSymbol*) ciObjectFactory::get(vmSymbols::dummy_symbol_oop()); | 190 ciEnv::_unloaded_cisymbol = ciObjectFactory::get_symbol(vmSymbols::dummy_symbol()); |
192 // Create dummy instanceKlass and objArrayKlass object and assign them idents | 191 // Create dummy instanceKlass and objArrayKlass object and assign them idents |
193 ciEnv::_unloaded_ciinstance_klass = new (_arena) ciInstanceKlass(ciEnv::_unloaded_cisymbol, NULL, NULL); | 192 ciEnv::_unloaded_ciinstance_klass = new (_arena) ciInstanceKlass(ciEnv::_unloaded_cisymbol, NULL, NULL); |
194 init_ident_of(ciEnv::_unloaded_ciinstance_klass); | 193 init_ident_of(ciEnv::_unloaded_ciinstance_klass); |
195 ciEnv::_unloaded_ciobjarrayklass = new (_arena) ciObjArrayKlass(ciEnv::_unloaded_cisymbol, ciEnv::_unloaded_ciinstance_klass, 1); | 194 ciEnv::_unloaded_ciobjarrayklass = new (_arena) ciObjArrayKlass(ciEnv::_unloaded_cisymbol, ciEnv::_unloaded_ciinstance_klass, 1); |
196 init_ident_of(ciEnv::_unloaded_ciobjarrayklass); | 195 init_ident_of(ciEnv::_unloaded_ciobjarrayklass); |
214 // this limit are permanently assigned to shared CI objects, | 213 // this limit are permanently assigned to shared CI objects, |
215 // while the higher numbers are recycled afresh by each new ciEnv. | 214 // while the higher numbers are recycled afresh by each new ciEnv. |
216 | 215 |
217 _shared_ident_limit = _next_ident; | 216 _shared_ident_limit = _next_ident; |
218 _shared_ci_objects = _ci_objects; | 217 _shared_ci_objects = _ci_objects; |
218 } | |
219 | |
220 | |
221 ciSymbol* ciObjectFactory::get_symbol(Symbol* key) { | |
222 vmSymbols::SID sid = vmSymbols::find_sid(key); | |
223 if (sid != vmSymbols::NO_SID) { | |
224 // do not pollute the main cache with it | |
225 return vm_symbol_at(sid); | |
226 } | |
227 | |
228 assert(vmSymbols::find_sid(key) == vmSymbols::NO_SID, ""); | |
229 ciSymbol* s = new (arena()) ciSymbol(key, vmSymbols::NO_SID); | |
230 _symbols->push(s); | |
231 return s; | |
232 } | |
233 | |
234 // Decrement the refcount when done on symbols referenced by this compilation. | |
235 void ciObjectFactory::remove_symbols() { | |
236 for (int i = 0; i < _symbols->length(); i++) { | |
237 ciSymbol* s = _symbols->at(i); | |
238 s->get_symbol()->decrement_refcount(); | |
239 } | |
240 // Since _symbols is resource allocated we're not allowed to delete it | |
241 // but it'll go away just the same. | |
219 } | 242 } |
220 | 243 |
221 // ------------------------------------------------------------------ | 244 // ------------------------------------------------------------------ |
222 // ciObjectFactory::get | 245 // ciObjectFactory::get |
223 // | 246 // |
251 if (!is_found_at(index, key, _ci_objects)) { | 274 if (!is_found_at(index, key, _ci_objects)) { |
252 // Check in the non-perm area before putting it in the list. | 275 // Check in the non-perm area before putting it in the list. |
253 NonPermObject* &bucket = find_non_perm(key); | 276 NonPermObject* &bucket = find_non_perm(key); |
254 if (bucket != NULL) { | 277 if (bucket != NULL) { |
255 return bucket->object(); | 278 return bucket->object(); |
256 } | |
257 | |
258 // Check in the shared symbol area before putting it in the list. | |
259 if (key->is_symbol()) { | |
260 vmSymbols::SID sid = vmSymbols::find_sid((symbolOop)key); | |
261 if (sid != vmSymbols::NO_SID) { | |
262 // do not pollute the main cache with it | |
263 return vm_symbol_at(sid); | |
264 } | |
265 } | 279 } |
266 | 280 |
267 // The ciObject does not yet exist. Create it and insert it | 281 // The ciObject does not yet exist. Create it and insert it |
268 // into the cache. | 282 // into the cache. |
269 Handle keyHandle(key); | 283 Handle keyHandle(key); |
295 // Implementation note: this functionality could be virtual behavior | 309 // Implementation note: this functionality could be virtual behavior |
296 // of the oop itself. For now, we explicitly marshal the object. | 310 // of the oop itself. For now, we explicitly marshal the object. |
297 ciObject* ciObjectFactory::create_new_object(oop o) { | 311 ciObject* ciObjectFactory::create_new_object(oop o) { |
298 EXCEPTION_CONTEXT; | 312 EXCEPTION_CONTEXT; |
299 | 313 |
300 if (o->is_symbol()) { | 314 if (o->is_klass()) { |
301 symbolHandle h_o(THREAD, (symbolOop)o); | |
302 assert(vmSymbols::find_sid(h_o()) == vmSymbols::NO_SID, ""); | |
303 return new (arena()) ciSymbol(h_o, vmSymbols::NO_SID); | |
304 } else if (o->is_klass()) { | |
305 KlassHandle h_k(THREAD, (klassOop)o); | 315 KlassHandle h_k(THREAD, (klassOop)o); |
306 Klass* k = ((klassOop)o)->klass_part(); | 316 Klass* k = ((klassOop)o)->klass_part(); |
307 if (k->oop_is_instance()) { | 317 if (k->oop_is_instance()) { |
308 return new (arena()) ciInstanceKlass(h_k); | 318 return new (arena()) ciInstanceKlass(h_k); |
309 } else if (k->oop_is_objArray()) { | 319 } else if (k->oop_is_objArray()) { |
310 return new (arena()) ciObjArrayKlass(h_k); | 320 return new (arena()) ciObjArrayKlass(h_k); |
311 } else if (k->oop_is_typeArray()) { | 321 } else if (k->oop_is_typeArray()) { |
312 return new (arena()) ciTypeArrayKlass(h_k); | 322 return new (arena()) ciTypeArrayKlass(h_k); |
313 } else if (k->oop_is_method()) { | 323 } else if (k->oop_is_method()) { |
314 return new (arena()) ciMethodKlass(h_k); | 324 return new (arena()) ciMethodKlass(h_k); |
315 } else if (k->oop_is_symbol()) { | |
316 return new (arena()) ciSymbolKlass(h_k); | |
317 } else if (k->oop_is_klass()) { | 325 } else if (k->oop_is_klass()) { |
318 if (k->oop_is_objArrayKlass()) { | 326 if (k->oop_is_objArrayKlass()) { |
319 return new (arena()) ciObjArrayKlassKlass(h_k); | 327 return new (arena()) ciObjArrayKlassKlass(h_k); |
320 } else if (k->oop_is_typeArrayKlass()) { | 328 } else if (k->oop_is_typeArrayKlass()) { |
321 return new (arena()) ciTypeArrayKlassKlass(h_k); | 329 return new (arena()) ciTypeArrayKlassKlass(h_k); |
424 | 432 |
425 // Two cases: this is an unloaded objArrayKlass or an | 433 // Two cases: this is an unloaded objArrayKlass or an |
426 // unloaded instanceKlass. Deal with both. | 434 // unloaded instanceKlass. Deal with both. |
427 if (name->byte_at(0) == '[') { | 435 if (name->byte_at(0) == '[') { |
428 // Decompose the name.' | 436 // Decompose the name.' |
429 jint dimension = 0; | 437 FieldArrayInfo fd; |
430 symbolOop element_name = NULL; | 438 BasicType element_type = FieldType::get_array_info(name->get_symbol(), |
431 BasicType element_type= FieldType::get_array_info(name->get_symbolOop(), | 439 fd, THREAD); |
432 &dimension, | |
433 &element_name, | |
434 THREAD); | |
435 if (HAS_PENDING_EXCEPTION) { | 440 if (HAS_PENDING_EXCEPTION) { |
436 CLEAR_PENDING_EXCEPTION; | 441 CLEAR_PENDING_EXCEPTION; |
437 CURRENT_THREAD_ENV->record_out_of_memory_failure(); | 442 CURRENT_THREAD_ENV->record_out_of_memory_failure(); |
438 return ciEnv::_unloaded_ciobjarrayklass; | 443 return ciEnv::_unloaded_ciobjarrayklass; |
439 } | 444 } |
445 int dimension = fd.dimension(); | |
440 assert(element_type != T_ARRAY, "unsuccessful decomposition"); | 446 assert(element_type != T_ARRAY, "unsuccessful decomposition"); |
441 ciKlass* element_klass = NULL; | 447 ciKlass* element_klass = NULL; |
442 if (element_type == T_OBJECT) { | 448 if (element_type == T_OBJECT) { |
443 ciEnv *env = CURRENT_THREAD_ENV; | 449 ciEnv *env = CURRENT_THREAD_ENV; |
444 ciSymbol* ci_name = env->get_object(element_name)->as_symbol(); | 450 ciSymbol* ci_name = env->get_symbol(fd.object_key()); |
445 element_klass = | 451 element_klass = |
446 env->get_klass_by_name(accessing_klass, ci_name, false)->as_instance_klass(); | 452 env->get_klass_by_name(accessing_klass, ci_name, false)->as_instance_klass(); |
447 } else { | 453 } else { |
448 assert(dimension > 1, "one dimensional type arrays are always loaded."); | 454 assert(dimension > 1, "one dimensional type arrays are always loaded."); |
449 | 455 |
568 } | 574 } |
569 | 575 |
570 // ------------------------------------------------------------------ | 576 // ------------------------------------------------------------------ |
571 // ciObjectFactory::init_ident_of | 577 // ciObjectFactory::init_ident_of |
572 void ciObjectFactory::init_ident_of(ciObject* obj) { | 578 void ciObjectFactory::init_ident_of(ciObject* obj) { |
579 obj->set_ident(_next_ident++); | |
580 } | |
581 | |
582 void ciObjectFactory::init_ident_of(ciSymbol* obj) { | |
573 obj->set_ident(_next_ident++); | 583 obj->set_ident(_next_ident++); |
574 } | 584 } |
575 | 585 |
576 | 586 |
577 // ------------------------------------------------------------------ | 587 // ------------------------------------------------------------------ |