< prev index next >
src/hotspot/share/classfile/classLoaderData.hpp
Print this page
@@ -24,21 +24,15 @@
#ifndef SHARE_VM_CLASSFILE_CLASSLOADERDATA_HPP
#define SHARE_VM_CLASSFILE_CLASSLOADERDATA_HPP
#include "memory/allocation.hpp"
-#include "memory/memRegion.hpp"
-#include "memory/metaspace.hpp"
-#include "memory/metaspaceCounters.hpp"
#include "oops/oopHandle.hpp"
-#include "runtime/mutex.hpp"
+#include "runtime/handles.hpp"
#include "trace/traceMacros.hpp"
#include "utilities/growableArray.hpp"
#include "utilities/macros.hpp"
-#if INCLUDE_TRACE
-#include "utilities/ticks.hpp"
-#endif
//
// A class loader represents a linkset. Conceptually, a linkset identifies
// the complete transitive closure of resolved links that a dynamic linker can
// produce.
@@ -49,26 +43,26 @@
//
// ClassLoaderData are stored in the runtime representation of classes,
// and provides iterators for root tracing and other GC operations.
class ClassLoaderData;
+class Dictionary;
class JNIMethodBlock;
-class Metadebug;
+class Metaspace;
class ModuleEntry;
-class PackageEntry;
class ModuleEntryTable;
+class Mutex;
+class PackageEntry;
class PackageEntryTable;
-class DictionaryEntry;
-class Dictionary;
// GC root for walking class loader data created
class ClassLoaderDataGraph : public AllStatic {
friend class ClassLoaderData;
- friend class ClassLoaderDataGraphMetaspaceIterator;
friend class ClassLoaderDataGraphKlassIteratorAtomic;
friend class ClassLoaderDataGraphKlassIteratorStatic;
+ friend class ClassLoaderDataGraphMetaspaceIterator;
friend class VMStructs;
private:
// All CLDs (except the null CLD) can be reached by walking _head->_next->...
static ClassLoaderData* _head;
static ClassLoaderData* _unloading;
@@ -79,11 +73,10 @@
// OOM has been seen in metaspace allocation. Used to prevent some
// allocations until class unloading
static bool _metaspace_oom;
static ClassLoaderData* add(Handle class_loader, bool anonymous, TRAPS);
- static void post_class_unload_events();
public:
static ClassLoaderData* find_or_create(Handle class_loader, TRAPS);
static void purge();
static void clear_claimed_marks();
// oops do
@@ -147,108 +140,77 @@
static bool has_metaspace_oom() { return _metaspace_oom; }
static void set_metaspace_oom(bool value) { _metaspace_oom = value; }
static void dump_on(outputStream * const out) PRODUCT_RETURN;
- static void dump() { dump_on(tty); }
- static void verify();
- static void print_creation(outputStream* out, Handle loader, ClassLoaderData* cld, TRAPS);
-
static bool unload_list_contains(const void* x);
-#ifndef PRODUCT
- static bool contains_loader_data(ClassLoaderData* loader_data);
-#endif
-#if INCLUDE_TRACE
- private:
- static Ticks _class_unload_time;
- static void class_unload_event(Klass* const k);
-#endif
+ NOT_PRODUCT(static void verify();)
+ NOT_PRODUCT(static bool contains_loader_data(ClassLoaderData* loader_data);)
};
// ClassLoaderData class
class ClassLoaderData : public CHeapObj<mtClass> {
+ friend class ClassLoaderDataGraph;
+ friend class ClassLoaderDataGraphKlassIteratorAtomic;
+ friend class ClassLoaderDataGraphKlassIteratorStatic;
+ friend class ClassLoaderDataGraphMetaspaceIterator;
+ friend class MetaDataFactory;
+ friend class Method;
+ friend class Universe;
friend class VMStructs;
private:
class Dependencies VALUE_OBJ_CLASS_SPEC {
+ friend class ClassLoaderData;
+ friend class ClassLoaderDataGraph;
+ private:
objArrayOop _list_head;
- void locked_add(objArrayHandle last,
- objArrayHandle new_dependency,
- Thread* THREAD);
- public:
Dependencies() : _list_head(NULL) {}
- Dependencies(TRAPS) : _list_head(NULL) {
- init(CHECK);
- }
- void add(Handle dependency, TRAPS);
+ Dependencies(TRAPS) : _list_head(NULL) { init(CHECK); }
void init(TRAPS);
+ void add(Handle dependency, TRAPS);
+ void locked_add(objArrayHandle last, objArrayHandle new_dependency, Thread* THREAD);
void oops_do(OopClosure* f);
};
class ChunkedHandleList VALUE_OBJ_CLASS_SPEC {
+ friend class ClassLoaderData;
+ private:
struct Chunk : public CHeapObj<mtClass> {
static const size_t CAPACITY = 32;
-
oop _data[CAPACITY];
volatile juint _size;
Chunk* _next;
-
- Chunk(Chunk* c) : _next(c), _size(0) { }
+ Chunk(Chunk* c) : _next(c), _size(0) {}
};
-
Chunk* volatile _head;
-
- void oops_do_chunk(OopClosure* f, Chunk* c, const juint size);
-
- public:
ChunkedHandleList() : _head(NULL) {}
~ChunkedHandleList();
// Only one thread at a time can add, guarded by ClassLoaderData::metaspace_lock().
// However, multiple threads can execute oops_do concurrently with add.
oop* add(oop o);
-#ifdef ASSERT
- bool contains(oop* p);
-#endif
void oops_do(OopClosure* f);
+ void oops_do_chunk(OopClosure* f, Chunk* c, const juint size);
+ DEBUG_ONLY(bool contains(oop* p);)
};
- friend class ClassLoaderDataGraph;
- friend class ClassLoaderDataGraphKlassIteratorAtomic;
- friend class ClassLoaderDataGraphKlassIteratorStatic;
- friend class ClassLoaderDataGraphMetaspaceIterator;
- friend class MetaDataFactory;
- friend class Method;
+ static ClassLoaderData* _the_null_class_loader_data;
- static ClassLoaderData * _the_null_class_loader_data;
+ Dependencies _dependencies; // holds dependencies from this class loader
+ // data to others.
+
+ ChunkedHandleList _handles; // Handles to constant pool arrays, Modules, etc, which
+ // have the same life cycle of the corresponding ClassLoader.
oop _class_loader; // oop used to uniquely identify a class loader
// class loader or a canonical class path
- Dependencies _dependencies; // holds dependencies from this class loader
- // data to others.
Metaspace * volatile _metaspace; // Meta-space where meta-data defined by the
// classes in the class loader are allocated.
Mutex* _metaspace_lock; // Locks the metaspace for allocations and setup.
- bool _unloading; // true if this class loader goes away
- bool _is_anonymous; // if this CLD is for an anonymous class
-
- // Remembered sets support for the oops in the class loader data.
- bool _modified_oops; // Card Table Equivalent (YC/CMS support)
- bool _accumulated_modified_oops; // Mod Union Equivalent (CMS support)
-
- s2 _keep_alive; // if this CLD is kept alive without a keep_alive_object().
- // Used for anonymous classes and the boot class
- // loader. _keep_alive does not need to be volatile or
- // atomic since there is one unique CLD per anonymous class.
-
- volatile int _claimed; // true if claimed, for example during GC traces.
- // To avoid applying oop closure more than once.
- // Has to be an int because we cas it.
- ChunkedHandleList _handles; // Handles to constant pool arrays, Modules, etc, which
- // have the same life cycle of the corresponding ClassLoader.
Klass* volatile _klasses; // The classes defined by the class loader.
PackageEntryTable* volatile _packages; // The packages defined by the class loader.
ModuleEntryTable* volatile _modules; // The modules defined by the class loader.
ModuleEntry* _unnamed_module; // This class loader's unnamed module.
@@ -264,169 +226,151 @@
GrowableArray<Metadata*>* _deallocate_list;
// Support for walking class loader data objects
ClassLoaderData* _next; /// Next loader_datas created
- // ReadOnly and ReadWrite metaspaces (static because only on the null
- // class loader for now).
- static Metaspace* _ro_metaspace;
- static Metaspace* _rw_metaspace;
+ s2 _keep_alive; // if this CLD is kept alive without a keep_alive_object().
+ // Used for anonymous classes and the boot class
+ // loader. _keep_alive does not need to be volatile or
+ // atomic since there is one unique CLD per anonymous class.
+
+ volatile int _claimed; // true if claimed, for example during GC traces.
+ // To avoid applying oop closure more than once.
+ // Has to be an int because we cas it.
TRACE_DEFINE_TRACE_ID_FIELD;
+ bool _unloading; // true if this class loader goes away
+ bool _is_anonymous; // if this CLD is for an anonymous class
+
+ // Remembered sets support for the oops in the class loader data.
+ bool _modified_oops; // Card Table Equivalent (YC/CMS support)
+ bool _accumulated_modified_oops; // Mod Union Equivalent (CMS support)
+
void set_next(ClassLoaderData* next) { _next = next; }
ClassLoaderData* next() const { return _next; }
ClassLoaderData(Handle h_class_loader, bool is_anonymous, Dependencies dependencies);
~ClassLoaderData();
- // GC interface.
- void clear_claimed() { _claimed = 0; }
- bool claimed() const { return _claimed == 1; }
- bool claim();
+ void init_dependencies(TRAPS);
+
+ // Deallocate free list during class unloading.
+ void free_deallocate_list();
+ void unload_deallocate_list(); // for the classes that are unloaded
+
+ void unload();
+ bool keep_alive() const { return _keep_alive > 0; }
// The CLD are not placed in the Heap, so the Card Table or
// the Mod Union Table can't be used to mark when CLD have modified oops.
// The CT and MUT bits saves this information for the whole class loader data.
void clear_modified_oops() { _modified_oops = false; }
- public:
- void record_modified_oops() { _modified_oops = true; }
- bool has_modified_oops() { return _modified_oops; }
-
- void accumulate_modified_oops() { if (has_modified_oops()) _accumulated_modified_oops = true; }
- void clear_accumulated_modified_oops() { _accumulated_modified_oops = false; }
- bool has_accumulated_modified_oops() { return _accumulated_modified_oops; }
- private:
- void unload();
- bool keep_alive() const { return _keep_alive > 0; }
void classes_do(void f(Klass*));
- void loaded_classes_do(KlassClosure* klass_closure);
void classes_do(void f(InstanceKlass*));
+ void loaded_classes_do(KlassClosure* klass_closure);
void methods_do(void f(Method*));
void modules_do(void f(ModuleEntry*));
void packages_do(void f(PackageEntry*));
- // Deallocate free list during class unloading.
- void free_deallocate_list(); // for the classes that are not unloaded
- void unload_deallocate_list(); // for the classes that are unloaded
-
- // Allocate out of this class loader data
- MetaWord* allocate(size_t size);
-
- Dictionary* create_dictionary();
public:
+ void oops_do(OopClosure* f, bool must_claim, bool clear_modified_oops = false);
+ void classes_do(KlassClosure* klass_closure);
- bool is_alive(BoolObjectClosure* is_alive_closure) const;
-
- // Accessors
- Metaspace* metaspace_or_null() const { return _metaspace; }
-
- static ClassLoaderData* the_null_class_loader_data() {
- return _the_null_class_loader_data;
- }
-
- Mutex* metaspace_lock() const { return _metaspace_lock; }
-
- bool is_anonymous() const { return _is_anonymous; }
-
- static void init_null_class_loader_data() {
- assert(_the_null_class_loader_data == NULL, "cannot initialize twice");
- assert(ClassLoaderDataGraph::_head == NULL, "cannot initialize twice");
-
- // We explicitly initialize the Dependencies object at a later phase in the initialization
- _the_null_class_loader_data = new ClassLoaderData(Handle(), false, Dependencies());
- ClassLoaderDataGraph::_head = _the_null_class_loader_data;
- assert(_the_null_class_loader_data->is_the_null_class_loader_data(), "Must be");
- }
-
- bool is_the_null_class_loader_data() const {
- return this == _the_null_class_loader_data;
- }
- bool is_system_class_loader_data() const;
- bool is_platform_class_loader_data() const;
- bool is_builtin_class_loader_data() const;
-
- // The Metaspace is created lazily so may be NULL. This
- // method will allocate a Metaspace if needed.
- Metaspace* metaspace_non_null();
+ void record_modified_oops() { _modified_oops = true; }
+ bool has_modified_oops() const { return _modified_oops; }
- oop class_loader() const { return _class_loader; }
+ void accumulate_modified_oops() { if (has_modified_oops()) _accumulated_modified_oops = true; }
+ void clear_accumulated_modified_oops() { _accumulated_modified_oops = false; }
+ bool has_accumulated_modified_oops() const { return _accumulated_modified_oops; }
+ bool is_alive(BoolObjectClosure* is_alive_closure) const;
// The object the GC is using to keep this ClassLoaderData alive.
oop keep_alive_object() const;
+ // Used to refcount an anonymous class's CLD in order to
+ // indicate their aliveness without a keep_alive_object().
+ void inc_keep_alive();
+ void dec_keep_alive();
// Returns true if this class loader data is for a loader going away.
bool is_unloading() const {
assert(!(is_the_null_class_loader_data() && _unloading), "The null class loader can never be unloaded");
return _unloading;
}
- // Used to refcount an anonymous class's CLD in order to
- // indicate their aliveness without a keep_alive_object().
- void inc_keep_alive();
- void dec_keep_alive();
+ void clear_claimed() { _claimed = 0; }
+ bool claimed() const { return _claimed == 1; }
+ bool claim();
- inline unsigned int identity_hash() const { return (unsigned int)(((intptr_t)this) >> 3); }
+ // The Metaspace is created lazily so may be NULL. This
+ // method will allocate a Metaspace if needed.
+ Metaspace* metaspace_non_null();
+ Mutex* metaspace_lock() const { return _metaspace_lock; }
+ Metaspace* metaspace_or_null() const { return _metaspace; }
- void oops_do(OopClosure* f, bool must_claim, bool clear_modified_oops = false);
+ bool is_the_null_class_loader_data() const { return this == _the_null_class_loader_data; }
+ bool is_system_class_loader_data() const;
+ bool is_platform_class_loader_data() const;
+ bool is_builtin_class_loader_data() const;
+ bool is_anonymous() const { return _is_anonymous; }
+
+ oop class_loader() const { return _class_loader; }
+ const char* loader_name();
+ unsigned int identity_hash() const { return (unsigned int)(((intptr_t)this) >> 3); }
+ // Loaded class dictionary
+ Dictionary* dictionary() { return _dictionary; }
- void classes_do(KlassClosure* klass_closure);
Klass* klasses() { return _klasses; }
+ PackageEntryTable* packages() { return _packages; }
+ ModuleEntry* unnamed_module() { return _unnamed_module; }
+ ModuleEntryTable* modules();
+ bool modules_defined() { return (_modules != NULL); }
JNIMethodBlock* jmethod_ids() const { return _jmethod_ids; }
void set_jmethod_ids(JNIMethodBlock* new_block) { _jmethod_ids = new_block; }
- void print() { print_on(tty); }
- void print_on(outputStream* out) const;
- void print_value() { print_value_on(tty); }
- void print_value_on(outputStream* out) const;
- void dump(outputStream * const out) PRODUCT_RETURN;
- void verify();
- const char* loader_name();
-
OopHandle add_handle(Handle h);
void remove_handle(OopHandle h);
void init_handle_locked(OopHandle& pd, Handle h); // used for concurrent access to ModuleEntry::_pd field
void add_class(Klass* k, bool publicize = true);
void remove_class(Klass* k);
bool contains_klass(Klass* k);
void record_dependency(const Klass* to, TRAPS);
- void init_dependencies(TRAPS);
- PackageEntryTable* packages() { return _packages; }
- ModuleEntry* unnamed_module() { return _unnamed_module; }
- ModuleEntryTable* modules();
- bool modules_defined() { return (_modules != NULL); }
+ void add_to_deallocate_list(Metadata* m);
- // Loaded class dictionary
- Dictionary* dictionary() const { return _dictionary; }
+ TRACE_DEFINE_TRACE_ID_METHODS;
- void add_to_deallocate_list(Metadata* m);
+ void print() { print_on(tty); }
+ void print_on(outputStream* out) const;
+ void print_value() { print_value_on(tty); }
+ void print_value_on(outputStream* out) const;
+ void dump(outputStream * const out) PRODUCT_RETURN;
+ NOT_PRODUCT(void verify();)
+ static void init_null_class_loader_data();
+ static ClassLoaderData* the_null_class_loader_data() { return _the_null_class_loader_data; }
static ClassLoaderData* class_loader_data(oop loader);
static ClassLoaderData* class_loader_data_or_null(oop loader);
static ClassLoaderData* anonymous_class_loader_data(oop loader, TRAPS);
- static void print_loader(ClassLoaderData *loader_data, outputStream *out);
-
- TRACE_DEFINE_TRACE_ID_METHODS;
};
// An iterator that distributes Klasses to parallel worker threads.
class ClassLoaderDataGraphKlassIteratorAtomic : public StackObj {
+ private:
Klass* volatile _next_klass;
public:
ClassLoaderDataGraphKlassIteratorAtomic();
Klass* next_klass();
- private:
static Klass* next_klass_in_cldg(Klass* klass);
};
class ClassLoaderDataGraphMetaspaceIterator : public StackObj {
+ private:
ClassLoaderData* _data;
public:
ClassLoaderDataGraphMetaspaceIterator();
- ~ClassLoaderDataGraphMetaspaceIterator();
bool repeat() { return _data != NULL; }
Metaspace* get_next() {
assert(_data != NULL, "Should not be NULL in call to the iterator");
Metaspace* result = _data->metaspace_or_null();
_data = _data->next();
@@ -435,6 +379,7 @@
// there is no guarantee that there will be a non-null result
// down the list so the caller is going to have to check.
return result;
}
};
+
#endif // SHARE_VM_CLASSFILE_CLASSLOADERDATA_HPP
< prev index next >