97 new_entry->set_next(ec); |
97 new_entry->set_next(ec); |
98 } |
98 } |
99 release_set_exception_cache(new_entry); |
99 release_set_exception_cache(new_entry); |
100 } |
100 } |
101 |
101 |
102 void CompiledMethod::clean_exception_cache(BoolObjectClosure* is_alive) { |
102 void CompiledMethod::clean_exception_cache() { |
103 ExceptionCache* prev = NULL; |
103 ExceptionCache* prev = NULL; |
104 ExceptionCache* curr = exception_cache(); |
104 ExceptionCache* curr = exception_cache(); |
105 |
105 |
106 while (curr != NULL) { |
106 while (curr != NULL) { |
107 ExceptionCache* next = curr->next(); |
107 ExceptionCache* next = curr->next(); |
108 |
108 |
109 Klass* ex_klass = curr->exception_type(); |
109 Klass* ex_klass = curr->exception_type(); |
110 if (ex_klass != NULL && !ex_klass->is_loader_alive(is_alive)) { |
110 if (ex_klass != NULL && !ex_klass->is_loader_alive()) { |
111 if (prev == NULL) { |
111 if (prev == NULL) { |
112 set_exception_cache(next); |
112 set_exception_cache(next); |
113 } else { |
113 } else { |
114 prev->set_next(next); |
114 prev->set_next(next); |
115 } |
115 } |
367 } |
367 } |
368 } |
368 } |
369 } |
369 } |
370 |
370 |
371 #ifdef ASSERT |
371 #ifdef ASSERT |
372 |
372 // Check class_loader is alive for this bit of metadata. |
373 class CheckClass : AllStatic { |
373 static void check_class(Metadata* md) { |
374 static BoolObjectClosure* _is_alive; |
374 Klass* klass = NULL; |
375 |
375 if (md->is_klass()) { |
376 // Check class_loader is alive for this bit of metadata. |
376 klass = ((Klass*)md); |
377 static void check_class(Metadata* md) { |
377 } else if (md->is_method()) { |
378 Klass* klass = NULL; |
378 klass = ((Method*)md)->method_holder(); |
379 if (md->is_klass()) { |
379 } else if (md->is_methodData()) { |
380 klass = ((Klass*)md); |
380 klass = ((MethodData*)md)->method()->method_holder(); |
381 } else if (md->is_method()) { |
381 } else { |
382 klass = ((Method*)md)->method_holder(); |
382 md->print(); |
383 } else if (md->is_methodData()) { |
383 ShouldNotReachHere(); |
384 klass = ((MethodData*)md)->method()->method_holder(); |
384 } |
385 } else { |
385 assert(klass->is_loader_alive(), "must be alive"); |
386 md->print(); |
386 } |
387 ShouldNotReachHere(); |
|
388 } |
|
389 assert(klass->is_loader_alive(_is_alive), "must be alive"); |
|
390 } |
|
391 public: |
|
392 static void do_check_class(BoolObjectClosure* is_alive, CompiledMethod* nm) { |
|
393 assert(SafepointSynchronize::is_at_safepoint(), "this is only ok at safepoint"); |
|
394 _is_alive = is_alive; |
|
395 nm->metadata_do(check_class); |
|
396 } |
|
397 }; |
|
398 |
|
399 // This is called during a safepoint so can use static data |
|
400 BoolObjectClosure* CheckClass::_is_alive = NULL; |
|
401 #endif // ASSERT |
387 #endif // ASSERT |
402 |
388 |
403 |
389 |
404 void CompiledMethod::clean_ic_if_metadata_is_dead(CompiledIC *ic, BoolObjectClosure *is_alive) { |
390 void CompiledMethod::clean_ic_if_metadata_is_dead(CompiledIC *ic) { |
405 if (ic->is_icholder_call()) { |
391 if (ic->is_icholder_call()) { |
406 // The only exception is compiledICHolder oops which may |
392 // The only exception is compiledICHolder oops which may |
407 // yet be marked below. (We check this further below). |
393 // yet be marked below. (We check this further below). |
408 CompiledICHolder* cichk_oop = ic->cached_icholder(); |
394 CompiledICHolder* cichk_oop = ic->cached_icholder(); |
409 |
395 |
410 if (cichk_oop->is_loader_alive(is_alive)) { |
396 if (cichk_oop->is_loader_alive()) { |
411 return; |
397 return; |
412 } |
398 } |
413 } else { |
399 } else { |
414 Metadata* ic_oop = ic->cached_metadata(); |
400 Metadata* ic_oop = ic->cached_metadata(); |
415 if (ic_oop != NULL) { |
401 if (ic_oop != NULL) { |
416 if (ic_oop->is_klass()) { |
402 if (ic_oop->is_klass()) { |
417 if (((Klass*)ic_oop)->is_loader_alive(is_alive)) { |
403 if (((Klass*)ic_oop)->is_loader_alive()) { |
418 return; |
404 return; |
419 } |
405 } |
420 } else if (ic_oop->is_method()) { |
406 } else if (ic_oop->is_method()) { |
421 if (((Method*)ic_oop)->method_holder()->is_loader_alive(is_alive)) { |
407 if (((Method*)ic_oop)->method_holder()->is_loader_alive()) { |
422 return; |
408 return; |
423 } |
409 } |
424 } else { |
410 } else { |
425 ShouldNotReachHere(); |
411 ShouldNotReachHere(); |
426 } |
412 } |
451 |
437 |
452 // Processing of oop references should have been sufficient to keep |
438 // Processing of oop references should have been sufficient to keep |
453 // all strong references alive. Any weak references should have been |
439 // all strong references alive. Any weak references should have been |
454 // cleared as well. Visit all the metadata and ensure that it's |
440 // cleared as well. Visit all the metadata and ensure that it's |
455 // really alive. |
441 // really alive. |
456 void CompiledMethod::verify_metadata_loaders(address low_boundary, BoolObjectClosure* is_alive) { |
442 void CompiledMethod::verify_metadata_loaders(address low_boundary) { |
457 #ifdef ASSERT |
443 #ifdef ASSERT |
458 RelocIterator iter(this, low_boundary); |
444 RelocIterator iter(this, low_boundary); |
459 while (iter.next()) { |
445 while (iter.next()) { |
460 // static_stub_Relocations may have dangling references to |
446 // static_stub_Relocations may have dangling references to |
461 // Method*s so trim them out here. Otherwise it looks like |
447 // Method*s so trim them out here. Otherwise it looks like |
516 // of this nmethod is reported. |
502 // of this nmethod is reported. |
517 unloading_occurred = true; |
503 unloading_occurred = true; |
518 } |
504 } |
519 |
505 |
520 // Exception cache |
506 // Exception cache |
521 clean_exception_cache(is_alive); |
507 clean_exception_cache(); |
522 |
508 |
523 // If class unloading occurred we first iterate over all inline caches and |
509 // If class unloading occurred we first iterate over all inline caches and |
524 // clear ICs where the cached oop is referring to an unloaded klass or method. |
510 // clear ICs where the cached oop is referring to an unloaded klass or method. |
525 // The remaining live cached oops will be traversed in the relocInfo::oop_type |
511 // The remaining live cached oops will be traversed in the relocInfo::oop_type |
526 // iteration below. |
512 // iteration below. |
527 if (unloading_occurred) { |
513 if (unloading_occurred) { |
528 RelocIterator iter(this, low_boundary); |
514 RelocIterator iter(this, low_boundary); |
529 while(iter.next()) { |
515 while(iter.next()) { |
530 if (iter.type() == relocInfo::virtual_call_type) { |
516 if (iter.type() == relocInfo::virtual_call_type) { |
531 CompiledIC *ic = CompiledIC_at(&iter); |
517 CompiledIC *ic = CompiledIC_at(&iter); |
532 clean_ic_if_metadata_is_dead(ic, is_alive); |
518 clean_ic_if_metadata_is_dead(ic); |
533 } |
519 } |
534 } |
520 } |
535 } |
521 } |
536 |
522 |
537 if (do_unloading_oops(low_boundary, is_alive, unloading_occurred)) { |
523 if (do_unloading_oops(low_boundary, is_alive, unloading_occurred)) { |
543 return; |
529 return; |
544 } |
530 } |
545 #endif |
531 #endif |
546 |
532 |
547 // Ensure that all metadata is still alive |
533 // Ensure that all metadata is still alive |
548 verify_metadata_loaders(low_boundary, is_alive); |
534 verify_metadata_loaders(low_boundary); |
549 } |
535 } |
550 |
536 |
551 template <class CompiledICorStaticCall> |
537 template <class CompiledICorStaticCall> |
552 static bool clean_if_nmethod_is_unloaded(CompiledICorStaticCall *ic, address addr, BoolObjectClosure *is_alive, CompiledMethod* from) { |
538 static bool clean_if_nmethod_is_unloaded(CompiledICorStaticCall *ic, address addr, BoolObjectClosure *is_alive, CompiledMethod* from) { |
553 // Ok, to lookup references to zombies here |
539 // Ok, to lookup references to zombies here |
617 |
603 |
618 case relocInfo::virtual_call_type: |
604 case relocInfo::virtual_call_type: |
619 if (unloading_occurred) { |
605 if (unloading_occurred) { |
620 // If class unloading occurred we first iterate over all inline caches and |
606 // If class unloading occurred we first iterate over all inline caches and |
621 // clear ICs where the cached oop is referring to an unloaded klass or method. |
607 // clear ICs where the cached oop is referring to an unloaded klass or method. |
622 clean_ic_if_metadata_is_dead(CompiledIC_at(&iter), is_alive); |
608 clean_ic_if_metadata_is_dead(CompiledIC_at(&iter)); |
623 } |
609 } |
624 |
610 |
625 postponed |= clean_if_nmethod_is_unloaded(CompiledIC_at(&iter), is_alive, this); |
611 postponed |= clean_if_nmethod_is_unloaded(CompiledIC_at(&iter), is_alive, this); |
626 break; |
612 break; |
627 |
613 |