< prev index next > src/hotspot/share/gc/shenandoah/shenandoahNMethod.hpp
Print this page
// Use ShenandoahReentrantLock as ShenandoahNMethodLock
typedef ShenandoahReentrantLock<ShenandoahSimpleLock> ShenandoahNMethodLock;
typedef ShenandoahLocker<ShenandoahNMethodLock> ShenandoahNMethodLocker;
// ShenandoahNMethod tuple records the internal locations of oop slots within reclocation stream in
// the nmethod. This allows us to quickly scan the oops without doing the nmethod-internal scans,
// that sometimes involves parsing the machine code. Note it does not record the oops themselves,
// because it would then require handling these tuples as the new class of roots.
class ShenandoahNMethod : public CHeapObj<mtGC> {
private:
nmethod* const _nm;
oop** _oops;
int _oops_count;
bool _has_non_immed_oops;
bool _unregistered;
ShenandoahNMethodLock _lock;
ShenandoahNMethodLock _ic_lock;
public:
! ShenandoahNMethod(nmethod *nm, GrowableArray<oop*>& oops, bool has_non_immed_oops);
~ShenandoahNMethod();
inline nmethod* nm() const;
inline ShenandoahNMethodLock* lock();
inline ShenandoahNMethodLock* ic_lock();
inline void oops_do(OopClosure* oops, bool fix_relocations = false);
// Update oops when the nmethod is re-registered
// Use ShenandoahReentrantLock as ShenandoahNMethodLock
typedef ShenandoahReentrantLock<ShenandoahSimpleLock> ShenandoahNMethodLock;
typedef ShenandoahLocker<ShenandoahNMethodLock> ShenandoahNMethodLocker;
+ struct ShenandoahNMethodBarrier {
+ int _rel_pc;
+ int _rel_target;
+ int _metadata;
+ };
+
// ShenandoahNMethod tuple records the internal locations of oop slots within reclocation stream in
// the nmethod. This allows us to quickly scan the oops without doing the nmethod-internal scans,
// that sometimes involves parsing the machine code. Note it does not record the oops themselves,
// because it would then require handling these tuples as the new class of roots.
class ShenandoahNMethod : public CHeapObj<mtGC> {
private:
nmethod* const _nm;
oop** _oops;
int _oops_count;
+ ShenandoahNMethodBarrier* _barriers;
+ int _barriers_count;
bool _has_non_immed_oops;
bool _unregistered;
ShenandoahNMethodLock _lock;
ShenandoahNMethodLock _ic_lock;
public:
! ShenandoahNMethod(nmethod *nm);
~ShenandoahNMethod();
+ static bool decode_reloc_inverted(int reloc) {
+ return (reloc & (1 << 8)) != 0;
+ }
+
+ static char decode_reloc_gc_state(int reloc) {
+ return (reloc & 0xFF);
+ }
+
+ static int encode_to_reloc(char gc_state, bool inverted) {
+ int res = (gc_state & 0xFF) | (inverted ? (1 << 8) : 0);
+ assert(decode_reloc_inverted(res) == inverted, "Round-trip");
+ assert(decode_reloc_gc_state(res) == gc_state, "Round-trip");
+ return res;
+ }
+
inline nmethod* nm() const;
inline ShenandoahNMethodLock* lock();
inline ShenandoahNMethodLock* ic_lock();
inline void oops_do(OopClosure* oops, bool fix_relocations = false);
// Update oops when the nmethod is re-registered
static ShenandoahNMethod* for_nmethod(nmethod* nm);
static inline ShenandoahNMethodLock* lock_for_nmethod(nmethod* nm);
static inline ShenandoahNMethodLock* ic_lock_for_nmethod(nmethod* nm);
static void heal_nmethod(nmethod* nm);
static inline void heal_nmethod_metadata(ShenandoahNMethod* nmethod_data);
static inline void disarm_nmethod(nmethod* nm);
static inline ShenandoahNMethod* gc_data(nmethod* nm);
static inline void attach_gc_data(nmethod* nm, ShenandoahNMethod* gc_data);
void assert_correct() NOT_DEBUG_RETURN;
void assert_same_oops() NOT_DEBUG_RETURN;
private:
! static void detect_reloc_oops(nmethod* nm, GrowableArray<oop*>& oops, bool& _has_non_immed_oops);
};
class ShenandoahNMethodTable;
// ShenandoahNMethodList holds registered nmethod data. The list is reference counted.
static ShenandoahNMethod* for_nmethod(nmethod* nm);
static inline ShenandoahNMethodLock* lock_for_nmethod(nmethod* nm);
static inline ShenandoahNMethodLock* ic_lock_for_nmethod(nmethod* nm);
static void heal_nmethod(nmethod* nm);
+ static bool update_barriers(nmethod* nm);
static inline void heal_nmethod_metadata(ShenandoahNMethod* nmethod_data);
static inline void disarm_nmethod(nmethod* nm);
static inline ShenandoahNMethod* gc_data(nmethod* nm);
static inline void attach_gc_data(nmethod* nm, ShenandoahNMethod* gc_data);
void assert_correct() NOT_DEBUG_RETURN;
void assert_same_oops() NOT_DEBUG_RETURN;
private:
! void init_from(nmethod* nm);
+ static void parse(nmethod* nm, GrowableArray<oop*>& oops, bool& _has_non_immed_oops, GrowableArray<ShenandoahNMethodBarrier>& barriers);
};
class ShenandoahNMethodTable;
// ShenandoahNMethodList holds registered nmethod data. The list is reference counted.
< prev index next >