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 // ------------------------------------------------------------------