comparison src/share/vm/ci/ciObjectFactory.cpp @ 20670:6a528388c7da

8060147: SIGSEGV in Metadata::mark_on_stack() while marking metadata in ciEnv Reviewed-by: kvn, roland, coleenp, mgerdin
author vlivanov
date Tue, 11 Nov 2014 04:46:13 -0800
parents 833b0f92429a
children 7848fc12602b
comparison
equal deleted inserted replaced
20669:e194d26c9f4e 20670:6a528388c7da
237 // already been created, it is returned. Otherwise, a new ciObject 237 // already been created, it is returned. Otherwise, a new ciObject
238 // is created. 238 // is created.
239 ciObject* ciObjectFactory::get(oop key) { 239 ciObject* ciObjectFactory::get(oop key) {
240 ASSERT_IN_VM; 240 ASSERT_IN_VM;
241 241
242 assert(key == NULL || Universe::heap()->is_in_reserved(key), "must be"); 242 assert(Universe::heap()->is_in_reserved(key), "must be");
243 243
244 NonPermObject* &bucket = find_non_perm(key); 244 NonPermObject* &bucket = find_non_perm(key);
245 if (bucket != NULL) { 245 if (bucket != NULL) {
246 return bucket->object(); 246 return bucket->object();
247 } 247 }
258 insert_non_perm(bucket, keyHandle(), new_object); 258 insert_non_perm(bucket, keyHandle(), new_object);
259 return new_object; 259 return new_object;
260 } 260 }
261 261
262 // ------------------------------------------------------------------ 262 // ------------------------------------------------------------------
263 // ciObjectFactory::get 263 // ciObjectFactory::get_metadata
264 // 264 //
265 // Get the ciObject corresponding to some oop. If the ciObject has 265 // Get the ciMetadata corresponding to some Metadata. If the ciMetadata has
266 // already been created, it is returned. Otherwise, a new ciObject 266 // already been created, it is returned. Otherwise, a new ciMetadata
267 // is created. 267 // is created.
268 ciMetadata* ciObjectFactory::get_metadata(Metadata* key) { 268 ciMetadata* ciObjectFactory::get_metadata(Metadata* key) {
269 ASSERT_IN_VM; 269 ASSERT_IN_VM;
270 270
271 #ifdef ASSERT 271 #ifdef ASSERT
288 } 288 }
289 } 289 }
290 } 290 }
291 #endif 291 #endif
292 if (!is_found_at(index, key, _ci_metadata)) { 292 if (!is_found_at(index, key, _ci_metadata)) {
293 // The ciObject does not yet exist. Create it and insert it 293 // The ciMetadata does not yet exist. Create it and insert it
294 // into the cache. 294 // into the cache.
295 ciMetadata* new_object = create_new_object(key); 295 ciMetadata* new_object = create_new_metadata(key);
296 init_ident_of(new_object); 296 init_ident_of(new_object);
297 assert(new_object->is_metadata(), "must be"); 297 assert(new_object->is_metadata(), "must be");
298 298
299 if (len != _ci_metadata->length()) { 299 if (len != _ci_metadata->length()) {
300 // creating the new object has recursively entered new objects 300 // creating the new object has recursively entered new objects
342 ShouldNotReachHere(); 342 ShouldNotReachHere();
343 return NULL; 343 return NULL;
344 } 344 }
345 345
346 // ------------------------------------------------------------------ 346 // ------------------------------------------------------------------
347 // ciObjectFactory::create_new_object 347 // ciObjectFactory::create_new_metadata
348 // 348 //
349 // Create a new ciObject from a Metadata*. 349 // Create a new ciMetadata from a Metadata*.
350 // 350 //
351 // Implementation note: this functionality could be virtual behavior 351 // Implementation note: in order to keep Metadata live, an auxiliary ciObject
352 // of the oop itself. For now, we explicitly marshal the object. 352 // is used, which points to it's holder.
353 ciMetadata* ciObjectFactory::create_new_object(Metadata* o) { 353 ciMetadata* ciObjectFactory::create_new_metadata(Metadata* o) {
354 EXCEPTION_CONTEXT; 354 EXCEPTION_CONTEXT;
355
356 // Hold metadata from unloading by keeping it's holder alive.
357 if (_initialized && o->is_klass()) {
358 Klass* holder = ((Klass*)o);
359 if (holder->oop_is_instance() && InstanceKlass::cast(holder)->is_anonymous()) {
360 // Though ciInstanceKlass records class loader oop, it's not enough to keep
361 // VM anonymous classes alive (loader == NULL). Klass holder should be used instead.
362 // It is enough to record a ciObject, since cached elements are never removed
363 // during ciObjectFactory lifetime. ciObjectFactory itself is created for
364 // every compilation and lives for the whole duration of the compilation.
365 ciObject* h = get(holder->klass_holder());
366 }
367 }
355 368
356 if (o->is_klass()) { 369 if (o->is_klass()) {
357 KlassHandle h_k(THREAD, (Klass*)o); 370 KlassHandle h_k(THREAD, (Klass*)o);
358 Klass* k = (Klass*)o; 371 Klass* k = (Klass*)o;
359 if (k->oop_is_instance()) { 372 if (k->oop_is_instance()) {
363 } else if (k->oop_is_typeArray()) { 376 } else if (k->oop_is_typeArray()) {
364 return new (arena()) ciTypeArrayKlass(h_k); 377 return new (arena()) ciTypeArrayKlass(h_k);
365 } 378 }
366 } else if (o->is_method()) { 379 } else if (o->is_method()) {
367 methodHandle h_m(THREAD, (Method*)o); 380 methodHandle h_m(THREAD, (Method*)o);
368 return new (arena()) ciMethod(h_m); 381 ciEnv *env = CURRENT_THREAD_ENV;
382 ciInstanceKlass* holder = env->get_instance_klass(h_m()->method_holder());
383 return new (arena()) ciMethod(h_m, holder);
369 } else if (o->is_methodData()) { 384 } else if (o->is_methodData()) {
370 // Hold methodHandle alive - might not be necessary ??? 385 // Hold methodHandle alive - might not be necessary ???
371 methodHandle h_m(THREAD, ((MethodData*)o)->method()); 386 methodHandle h_m(THREAD, ((MethodData*)o)->method());
372 return new (arena()) ciMethodData((MethodData*)o); 387 return new (arena()) ciMethodData((MethodData*)o);
373 } 388 }
374 389
375 // The oop is of some type not supported by the compiler interface. 390 // The Metadata* is of some type not supported by the compiler interface.
376 ShouldNotReachHere(); 391 ShouldNotReachHere();
377 return NULL; 392 return NULL;
378 } 393 }
379 394
380 // ------------------------------------------------------------------ 395 // ------------------------------------------------------------------
699 // 714 //
700 // Use a small hash table, hashed on the klass of the key. 715 // Use a small hash table, hashed on the klass of the key.
701 // If there is no entry in the cache corresponding to this oop, return 716 // If there is no entry in the cache corresponding to this oop, return
702 // the null tail of the bucket into which the oop should be inserted. 717 // the null tail of the bucket into which the oop should be inserted.
703 ciObjectFactory::NonPermObject* &ciObjectFactory::find_non_perm(oop key) { 718 ciObjectFactory::NonPermObject* &ciObjectFactory::find_non_perm(oop key) {
704 assert(Universe::heap()->is_in_reserved_or_null(key), "must be"); 719 assert(Universe::heap()->is_in_reserved(key), "must be");
705 ciMetadata* klass = get_metadata(key->klass()); 720 ciMetadata* klass = get_metadata(key->klass());
706 NonPermObject* *bp = &_non_perm_bucket[(unsigned) klass->hash() % NON_PERM_BUCKETS]; 721 NonPermObject* *bp = &_non_perm_bucket[(unsigned) klass->hash() % NON_PERM_BUCKETS];
707 for (NonPermObject* p; (p = (*bp)) != NULL; bp = &p->next()) { 722 for (NonPermObject* p; (p = (*bp)) != NULL; bp = &p->next()) {
708 if (is_equal(p, key)) break; 723 if (is_equal(p, key)) break;
709 } 724 }