6863023: need non-perm oops in code cache for JSR 292

Make a special root-list for those few nmethods which might contain non-perm oops.

Reviewed-by: twisti, kvn, never, jmasa, ysr
This commit is contained in:
John R Rose 2009-09-15 21:53:47 -07:00
parent 1cf5b7ae11
commit e261aecad8
74 changed files with 979 additions and 279 deletions

View file

@ -125,6 +125,7 @@ class xmlStream;
class nmethod : public CodeBlob {
friend class VMStructs;
friend class NMethodSweeper;
friend class CodeCache; // non-perm oops
private:
// Shared fields for all nmethod's
static int _zombie_instruction_size;
@ -132,7 +133,12 @@ class nmethod : public CodeBlob {
methodOop _method;
int _entry_bci; // != InvocationEntryBci if this nmethod is an on-stack replacement method
nmethod* _link; // To support simple linked-list chaining of nmethods
// 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
static nmethod* volatile _oops_do_mark_nmethods;
nmethod* volatile _oops_do_mark_link;
AbstractCompiler* _compiler; // The compiler which compiled this nmethod
@ -174,6 +180,8 @@ class nmethod : public CodeBlob {
// used by jvmti to track if an unload event has been posted for this nmethod.
bool _unload_reported;
jbyte _scavenge_root_state;
NOT_PRODUCT(bool _has_debug_info; )
// Nmethod Flushing lock (if non-zero, then the nmethod is not removed)
@ -242,7 +250,6 @@ class nmethod : public CodeBlob {
// helper methods
void* operator new(size_t size, int nmethod_size);
void check_store();
const char* reloc_string_for(u_char* begin, u_char* end);
void make_not_entrant_or_zombie(int state);
@ -407,6 +414,24 @@ class nmethod : public CodeBlob {
int version() const { return flags.version; }
void set_version(int v);
// Non-perm oop support
bool on_scavenge_root_list() const { return (_scavenge_root_state & 1) != 0; }
protected:
enum { npl_on_list = 0x01, npl_marked = 0x10 };
void set_on_scavenge_root_list() { _scavenge_root_state = npl_on_list; }
void clear_on_scavenge_root_list() { _scavenge_root_state = 0; }
// assertion-checking and pruning logic uses the bits of _scavenge_root_state
#ifndef PRODUCT
void set_scavenge_root_marked() { _scavenge_root_state |= npl_marked; }
void clear_scavenge_root_marked() { _scavenge_root_state &= ~npl_marked; }
bool scavenge_root_not_marked() { return (_scavenge_root_state &~ npl_on_list) == 0; }
// N.B. there is no positive marked query, and we only use the not_marked query for asserts.
#endif //PRODUCT
nmethod* scavenge_root_link() const { return _scavenge_root_link; }
void set_scavenge_root_link(nmethod *n) { _scavenge_root_link = n; }
public:
// Sweeper support
long stack_traversal_mark() { return _stack_traversal_mark; }
void set_stack_traversal_mark(long l) { _stack_traversal_mark = l; }
@ -425,8 +450,8 @@ class nmethod : public CodeBlob {
int osr_entry_bci() const { assert(_entry_bci != InvocationEntryBci, "wrong kind of nmethod"); return _entry_bci; }
address osr_entry() const { assert(_entry_bci != InvocationEntryBci, "wrong kind of nmethod"); return _osr_entry_point; }
void invalidate_osr_method();
nmethod* link() const { return _link; }
void set_link(nmethod *n) { _link = n; }
nmethod* osr_link() const { return _osr_link; }
void set_osr_link(nmethod *n) { _osr_link = n; }
// tells whether frames described by this nmethod can be deoptimized
// note: native wrappers cannot be deoptimized.
@ -467,6 +492,14 @@ class nmethod : public CodeBlob {
void preserve_callee_argument_oops(frame fr, const RegisterMap *reg_map,
OopClosure* f);
void oops_do(OopClosure* f);
bool detect_scavenge_root_oops();
void verify_scavenge_root_oops() PRODUCT_RETURN;
bool test_set_oops_do_mark();
static void oops_do_marking_prologue();
static void oops_do_marking_epilogue();
static bool oops_do_marking_is_active() { return _oops_do_mark_nmethods != NULL; }
DEBUG_ONLY(bool test_oops_do_mark() { return _oops_do_mark_link != NULL; })
// ScopeDesc for an instruction
ScopeDesc* scope_desc_at(address pc);