src/share/vm/oops/instanceKlass.hpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File
*** old/src/share/vm/oops/instanceKlass.hpp	Tue Nov  3 19:47:03 2015
--- new/src/share/vm/oops/instanceKlass.hpp	Tue Nov  3 19:47:03 2015

*** 102,111 **** --- 102,169 ---- private: int _offset; uint _count; }; + // Utility class to manipulate nmethod dependency context. + // The context consists of nmethodBucket* (a head of a linked list) + // and a boolean flag (does the list contains stale entries). The structure is + // encoded as an intptr_t: lower bit is used for the flag. It is possible since + // nmethodBucket* is aligned - the structure is malloc'ed in C heap. + // Dependency context can be attached either to an InstanceKlass (_dep_context field) + // or CallSiteContext oop for call_site_target dependencies (see javaClasses.hpp). + // DependencyContext class operates on some location which holds a intptr_t value. + class DependencyContext : public StackObj { + friend class VMStructs; + private: + enum TagBits { _has_unloaded_bit = 1, _has_unloaded_mask = 1 }; + + intptr_t* _dependency_context_addr; + + void set_dependencies(nmethodBucket* b) { + assert((intptr_t(b) & _has_unloaded_mask) == 0, "should be aligned"); + if (has_unloaded_dependent()) { + *_dependency_context_addr = intptr_t(b) | _has_unloaded_mask; + } else { + *_dependency_context_addr = intptr_t(b); + } + } + + void set_has_unloaded_dependent(bool value) { + intptr_t b = (intptr_t)dependencies(); + *_dependency_context_addr = (b | _has_unloaded_mask); + } + + public: + DependencyContext(intptr_t* addr) : _dependency_context_addr(addr) {} + + static const intptr_t EMPTY = 0; // dependencies = NULL, has_unloaded_dependent = false + + nmethodBucket* dependencies() { + intptr_t value = *_dependency_context_addr; + return (nmethodBucket*) (value & ~_has_unloaded_mask); + } + + bool has_unloaded_dependent() const { + intptr_t value = *_dependency_context_addr; + return (value & _has_unloaded_mask) != 0; + }; + + int mark_dependent_nmethods(DepChange& changes); + void add_dependent_nmethod(nmethod* nm); + void remove_dependent_nmethod(nmethod* nm, bool delete_immediately = false); + void purge(); + int clear(); + + #ifndef PRODUCT + void print_dependent_nmethods(bool verbose); + bool is_dependent_nmethod(nmethod* nm); + bool has_stale_entries(); + void wipe(); + #endif //PRODUCT + }; + struct JvmtiCachedClassFileData; class InstanceKlass: public Klass { friend class VMStructs; friend class ClassFileParser;
*** 196,206 **** --- 254,263 ---- int _nonstatic_oop_map_size;// size in words of nonstatic oop map blocks // _is_marked_dependent can be set concurrently, thus cannot be part of the // _misc_flags. bool _is_marked_dependent; // used for marking during flushing and deoptimization bool _has_unloaded_dependent; // The low two bits of _misc_flags contains the kind field. // This can be used to quickly discriminate among the four kinds of // InstanceKlass.
*** 233,243 **** --- 290,300 ---- int _itable_len; // length of Java itable (in words) OopMapCache* volatile _oop_map_cache; // OopMapCache for all methods in the klass (allocated lazily) MemberNameTable* _member_names; // Member names JNIid* _jni_ids; // First JNI identifier for static fields in this class jmethodID* _methods_jmethod_ids; // jmethodIDs corresponding to method_idnum, or NULL if none nmethodBucket* _dependencies; // list of dependent nmethods + intptr_t _dep_context; // packed DependencyContext structure nmethod* _osr_nmethods_head; // Head of list of on-stack replacement nmethods for this class BreakpointInfo* _breakpoints; // bpt lists, managed by Method* // Linked instanceKlasses of previous versions InstanceKlass* _previous_versions; // JVMTI fields can be moved to their own structure - see 6315920
*** 466,478 **** --- 523,532 ---- // marking bool is_marked_dependent() const { return _is_marked_dependent; } void set_is_marked_dependent(bool value) { _is_marked_dependent = value; } bool has_unloaded_dependent() const { return _has_unloaded_dependent; } void set_has_unloaded_dependent(bool value) { _has_unloaded_dependent = value; } // initialization (virtuals from Klass) bool should_be_initialized() const; // means that initialize should be called void initialize(TRAPS); void link_class(TRAPS); bool link_class_or_fail(TRAPS); // returns false on failure
*** 836,845 **** --- 890,900 ---- // maintenance of deoptimization dependencies int mark_dependent_nmethods(DepChange& changes); void add_dependent_nmethod(nmethod* nm); void remove_dependent_nmethod(nmethod* nm, bool delete_immediately); + void clean_dependent_nmethods(); // On-stack replacement support nmethod* osr_nmethods_head() const { return _osr_nmethods_head; }; void set_osr_nmethods_head(nmethod* h) { _osr_nmethods_head = h; }; void add_osr_nmethod(nmethod* n);
*** 1022,1032 **** --- 1077,1086 ---- #endif // INCLUDE_JVMTI void clean_weak_instanceklass_links(BoolObjectClosure* is_alive); void clean_implementors_list(BoolObjectClosure* is_alive); void clean_method_data(BoolObjectClosure* is_alive); void clean_dependent_nmethods(); // Explicit metaspace deallocation of fields // For RedefineClasses and class file parsing errors, we need to deallocate // instanceKlasses and the metadata they point to. void deallocate_contents(ClassLoaderData* loader_data);
*** 1334,1364 **** --- 1388,1406 ---- nmethod* _nmethod; int _count; nmethodBucket* _next; public: ! nmethodBucket(nmethod* nmethod, nmethodBucket* next) { _nmethod = nmethod; _next = next; _count = 1; } ! nmethodBucket(nmethod* nmethod, nmethodBucket* next) : + _nmethod(nmethod), _next(next), _count(1) {} + int count() { return _count; } int increment() { _count += 1; return _count; } int decrement(); nmethodBucket* next() { return _next; } void set_next(nmethodBucket* b) { _next = b; } nmethod* get_nmethod() { return _nmethod; } static int mark_dependent_nmethods(nmethodBucket* deps, DepChange& changes); static nmethodBucket* add_dependent_nmethod(nmethodBucket* deps, nmethod* nm); static bool remove_dependent_nmethod(nmethodBucket** deps, nmethod* nm, bool delete_immediately); static bool remove_dependent_nmethod(nmethodBucket* deps, nmethod* nm); static nmethodBucket* clean_dependent_nmethods(nmethodBucket* deps); #ifndef PRODUCT static void print_dependent_nmethods(nmethodBucket* deps, bool verbose); static bool is_dependent_nmethod(nmethodBucket* deps, nmethod* nm); #endif //PRODUCT }; // An iterator that's used to access the inner classes indices in the // InstanceKlass::_inner_classes array. class InnerClassesIterator : public StackObj {

src/share/vm/oops/instanceKlass.hpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File