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