1586 void nmethod::do_unloading(BoolObjectClosure* is_alive, 1587 OopClosure* keep_alive, bool unloading_occurred) { 1588 // Make sure the oop's ready to receive visitors 1589 assert(!is_zombie() && !is_unloaded(), 1590 "should not call follow on zombie or unloaded nmethod"); 1591 1592 // If the method is not entrant then a JMP is plastered over the 1593 // first few bytes. If an oop in the old code was there, that oop 1594 // should not get GC'd. Skip the first few bytes of oops on 1595 // not-entrant methods. 1596 address low_boundary = verified_entry_point(); 1597 if (is_not_entrant()) { 1598 low_boundary += NativeJump::instruction_size; 1599 // %%% Note: On SPARC we patch only a 4-byte trap, not a full NativeJump. 1600 // (See comment above.) 1601 } 1602 1603 // The RedefineClasses() API can cause the class unloading invariant 1604 // to no longer be true. See jvmtiExport.hpp for details. 1605 // Also, leave a debugging breadcrumb in local flag. 1606 bool a_class_was_redefined = JvmtiExport::has_redefined_a_class(); 1607 if (a_class_was_redefined) { 1608 // This set of the unloading_occurred flag is done before the 1609 // call to post_compiled_method_unload() so that the unloading 1610 // of this nmethod is reported. 1611 unloading_occurred = true; 1612 } 1613 1614 // Exception cache 1615 ExceptionCache* ec = exception_cache(); 1616 while (ec != NULL) { 1617 Klass* ex_klass = ec->exception_type(); 1618 ExceptionCache* next_ec = ec->next(); 1619 if (ex_klass != NULL && !ex_klass->is_loader_alive(is_alive)) { 1620 remove_from_exception_cache(ec); 1621 } 1622 ec = next_ec; 1623 } 1624 1625 // If class unloading occurred we first iterate over all inline caches and 1626 // clear ICs where the cached oop is referring to an unloaded klass or method. 1627 // The remaining live cached oops will be traversed in the relocInfo::oop_type 1628 // iteration below. 1629 if (unloading_occurred) { 1630 RelocIterator iter(this, low_boundary); 1631 while(iter.next()) { 1632 if (iter.type() == relocInfo::virtual_call_type) { | 1586 void nmethod::do_unloading(BoolObjectClosure* is_alive, 1587 OopClosure* keep_alive, bool unloading_occurred) { 1588 // Make sure the oop's ready to receive visitors 1589 assert(!is_zombie() && !is_unloaded(), 1590 "should not call follow on zombie or unloaded nmethod"); 1591 1592 // If the method is not entrant then a JMP is plastered over the 1593 // first few bytes. If an oop in the old code was there, that oop 1594 // should not get GC'd. Skip the first few bytes of oops on 1595 // not-entrant methods. 1596 address low_boundary = verified_entry_point(); 1597 if (is_not_entrant()) { 1598 low_boundary += NativeJump::instruction_size; 1599 // %%% Note: On SPARC we patch only a 4-byte trap, not a full NativeJump. 1600 // (See comment above.) 1601 } 1602 1603 // The RedefineClasses() API can cause the class unloading invariant 1604 // to no longer be true. See jvmtiExport.hpp for details. 1605 // Also, leave a debugging breadcrumb in local flag. 1606 #if INCLUDE_JVMTI 1607 bool a_class_was_redefined = JvmtiExport::has_redefined_a_class(); 1608 if (a_class_was_redefined) { 1609 // This set of the unloading_occurred flag is done before the 1610 // call to post_compiled_method_unload() so that the unloading 1611 // of this nmethod is reported. 1612 unloading_occurred = true; 1613 } 1614 #endif // INCLUDE_JVMTI 1615 1616 // Exception cache 1617 ExceptionCache* ec = exception_cache(); 1618 while (ec != NULL) { 1619 Klass* ex_klass = ec->exception_type(); 1620 ExceptionCache* next_ec = ec->next(); 1621 if (ex_klass != NULL && !ex_klass->is_loader_alive(is_alive)) { 1622 remove_from_exception_cache(ec); 1623 } 1624 ec = next_ec; 1625 } 1626 1627 // If class unloading occurred we first iterate over all inline caches and 1628 // clear ICs where the cached oop is referring to an unloaded klass or method. 1629 // The remaining live cached oops will be traversed in the relocInfo::oop_type 1630 // iteration below. 1631 if (unloading_occurred) { 1632 RelocIterator iter(this, low_boundary); 1633 while(iter.next()) { 1634 if (iter.type() == relocInfo::virtual_call_type) { |