Mercurial > hg > truffle
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 } |