8049421: G1 Class Unloading after completing a concurrent mark cycle

Co-authored-by: Mikael Gerdin <mikael.gerdin@oracle.com>
Reviewed-by: tschatzl, ehelin, brutisso, coleenp, roland, iveresov
This commit is contained in:
Stefan Karlsson 2014-07-07 10:12:40 +02:00
parent ef1e9b3c80
commit 1b001a2afd
75 changed files with 2169 additions and 874 deletions

View file

@ -111,6 +111,11 @@ class nmethod : public CodeBlob {
friend class NMethodSweeper;
friend class CodeCache; // scavengable oops
private:
// GC support to help figure out if an nmethod has been
// cleaned/unloaded by the current GC.
static unsigned char _global_unloading_clock;
// Shared fields for all nmethod's
Method* _method;
int _entry_bci; // != InvocationEntryBci if this nmethod is an on-stack replacement method
@ -118,7 +123,13 @@ class nmethod : public CodeBlob {
// To support simple linked-list chaining of nmethods:
nmethod* _osr_link; // from InstanceKlass::osr_nmethods_head
nmethod* _scavenge_root_link; // from CodeCache::scavenge_root_nmethods
union {
// Used by G1 to chain nmethods.
nmethod* _unloading_next;
// Used by non-G1 GCs to chain nmethods.
nmethod* _scavenge_root_link; // from CodeCache::scavenge_root_nmethods
};
static nmethod* volatile _oops_do_mark_nmethods;
nmethod* volatile _oops_do_mark_link;
@ -180,6 +191,8 @@ class nmethod : public CodeBlob {
// Protected by Patching_lock
volatile unsigned char _state; // {alive, not_entrant, zombie, unloaded}
volatile unsigned char _unloading_clock; // Incremented after GC unloaded/cleaned the nmethod
#ifdef ASSERT
bool _oops_are_stale; // indicates that it's no longer safe to access oops section
#endif
@ -437,6 +450,15 @@ class nmethod : public CodeBlob {
bool unload_reported() { return _unload_reported; }
void set_unload_reported() { _unload_reported = true; }
void set_unloading_next(nmethod* next) { _unloading_next = next; }
nmethod* unloading_next() { return _unloading_next; }
static unsigned char global_unloading_clock() { return _global_unloading_clock; }
static void increase_unloading_clock();
void set_unloading_clock(unsigned char unloading_clock);
unsigned char unloading_clock();
bool is_marked_for_deoptimization() const { return _marked_for_deoptimization; }
void mark_for_deoptimization() { _marked_for_deoptimization = true; }
@ -552,6 +574,10 @@ public:
return (addr >= code_begin() && addr < verified_entry_point());
}
// Verify calls to dead methods have been cleaned.
void verify_clean_inline_caches();
// Verify and count cached icholder relocations.
int verify_icholder_relocations();
// Check that all metadata is still alive
void verify_metadata_loaders(address low_boundary, BoolObjectClosure* is_alive);
@ -577,6 +603,10 @@ public:
// GC support
void do_unloading(BoolObjectClosure* is_alive, bool unloading_occurred);
// The parallel versions are used by G1.
bool do_unloading_parallel(BoolObjectClosure* is_alive, bool unloading_occurred);
void do_unloading_parallel_postponed(BoolObjectClosure* is_alive, bool unloading_occurred);
// Unload a nmethod if the *root object is dead.
bool can_unload(BoolObjectClosure* is_alive, oop* root, bool unloading_occurred);
void preserve_callee_argument_oops(frame fr, const RegisterMap *reg_map,