8013136: NPG: Parallel class loading tests fail after fix for JDK-8011802
Move initialization of dependencies to before allocation of CLD Reviewed-by: stefank, coleenp
This commit is contained in:
parent
d72b516201
commit
316993b3db
@ -66,17 +66,19 @@
|
|||||||
|
|
||||||
ClassLoaderData * ClassLoaderData::_the_null_class_loader_data = NULL;
|
ClassLoaderData * ClassLoaderData::_the_null_class_loader_data = NULL;
|
||||||
|
|
||||||
ClassLoaderData::ClassLoaderData(Handle h_class_loader, bool is_anonymous) :
|
ClassLoaderData::ClassLoaderData(Handle h_class_loader, bool is_anonymous, Dependencies dependencies) :
|
||||||
_class_loader(h_class_loader()),
|
_class_loader(h_class_loader()),
|
||||||
_is_anonymous(is_anonymous), _keep_alive(is_anonymous), // initially
|
_is_anonymous(is_anonymous), _keep_alive(is_anonymous), // initially
|
||||||
_metaspace(NULL), _unloading(false), _klasses(NULL),
|
_metaspace(NULL), _unloading(false), _klasses(NULL),
|
||||||
_claimed(0), _jmethod_ids(NULL), _handles(NULL), _deallocate_list(NULL),
|
_claimed(0), _jmethod_ids(NULL), _handles(NULL), _deallocate_list(NULL),
|
||||||
_next(NULL), _dependencies(),
|
_next(NULL), _dependencies(dependencies),
|
||||||
_metaspace_lock(new Mutex(Monitor::leaf+1, "Metaspace allocation lock", true)) {
|
_metaspace_lock(new Mutex(Monitor::leaf+1, "Metaspace allocation lock", true)) {
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassLoaderData::init_dependencies(TRAPS) {
|
void ClassLoaderData::init_dependencies(TRAPS) {
|
||||||
|
assert(!Universe::is_fully_initialized(), "should only be called when initializing");
|
||||||
|
assert(is_the_null_class_loader_data(), "should only call this for the null class loader");
|
||||||
_dependencies.init(CHECK);
|
_dependencies.init(CHECK);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -499,22 +501,19 @@ ClassLoaderData* ClassLoaderDataGraph::_saved_head = NULL;
|
|||||||
// Add a new class loader data node to the list. Assign the newly created
|
// Add a new class loader data node to the list. Assign the newly created
|
||||||
// ClassLoaderData into the java/lang/ClassLoader object as a hidden field
|
// ClassLoaderData into the java/lang/ClassLoader object as a hidden field
|
||||||
ClassLoaderData* ClassLoaderDataGraph::add(Handle loader, bool is_anonymous, TRAPS) {
|
ClassLoaderData* ClassLoaderDataGraph::add(Handle loader, bool is_anonymous, TRAPS) {
|
||||||
// Not assigned a class loader data yet.
|
// We need to allocate all the oops for the ClassLoaderData before allocating the
|
||||||
// Create one.
|
// actual ClassLoaderData object.
|
||||||
ClassLoaderData* cld = new ClassLoaderData(loader, is_anonymous);
|
ClassLoaderData::Dependencies dependencies(CHECK_NULL);
|
||||||
cld->init_dependencies(THREAD);
|
|
||||||
if (HAS_PENDING_EXCEPTION) {
|
No_Safepoint_Verifier no_safepoints; // we mustn't GC until we've installed the
|
||||||
delete cld;
|
// ClassLoaderData in the graph since the CLD
|
||||||
return NULL;
|
// contains unhandled oops
|
||||||
}
|
|
||||||
|
ClassLoaderData* cld = new ClassLoaderData(loader, is_anonymous, dependencies);
|
||||||
|
|
||||||
No_Safepoint_Verifier no_safepoints; // nothing is keeping the dependencies array in cld alive
|
|
||||||
// make sure we don't encounter a GC until we've inserted
|
|
||||||
// cld into the CLDG
|
|
||||||
|
|
||||||
if (!is_anonymous) {
|
if (!is_anonymous) {
|
||||||
ClassLoaderData** cld_addr = java_lang_ClassLoader::loader_data_addr(loader());
|
ClassLoaderData** cld_addr = java_lang_ClassLoader::loader_data_addr(loader());
|
||||||
if (cld_addr != NULL) {
|
|
||||||
// First, Atomically set it
|
// First, Atomically set it
|
||||||
ClassLoaderData* old = (ClassLoaderData*) Atomic::cmpxchg_ptr(cld, cld_addr, NULL);
|
ClassLoaderData* old = (ClassLoaderData*) Atomic::cmpxchg_ptr(cld, cld_addr, NULL);
|
||||||
if (old != NULL) {
|
if (old != NULL) {
|
||||||
@ -523,7 +522,6 @@ ClassLoaderData* ClassLoaderDataGraph::add(Handle loader, bool is_anonymous, TRA
|
|||||||
return old;
|
return old;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// We won the race, and therefore the task of adding the data to the list of
|
// We won the race, and therefore the task of adding the data to the list of
|
||||||
// class loader data
|
// class loader data
|
||||||
|
@ -100,6 +100,9 @@ class ClassLoaderData : public CHeapObj<mtClass> {
|
|||||||
Thread* THREAD);
|
Thread* THREAD);
|
||||||
public:
|
public:
|
||||||
Dependencies() : _list_head(NULL) {}
|
Dependencies() : _list_head(NULL) {}
|
||||||
|
Dependencies(TRAPS) : _list_head(NULL) {
|
||||||
|
init(CHECK);
|
||||||
|
}
|
||||||
void add(Handle dependency, TRAPS);
|
void add(Handle dependency, TRAPS);
|
||||||
void init(TRAPS);
|
void init(TRAPS);
|
||||||
void oops_do(OopClosure* f);
|
void oops_do(OopClosure* f);
|
||||||
@ -150,7 +153,7 @@ class ClassLoaderData : public CHeapObj<mtClass> {
|
|||||||
void set_next(ClassLoaderData* next) { _next = next; }
|
void set_next(ClassLoaderData* next) { _next = next; }
|
||||||
ClassLoaderData* next() const { return _next; }
|
ClassLoaderData* next() const { return _next; }
|
||||||
|
|
||||||
ClassLoaderData(Handle h_class_loader, bool is_anonymous);
|
ClassLoaderData(Handle h_class_loader, bool is_anonymous, Dependencies dependencies);
|
||||||
~ClassLoaderData();
|
~ClassLoaderData();
|
||||||
|
|
||||||
void set_metaspace(Metaspace* m) { _metaspace = m; }
|
void set_metaspace(Metaspace* m) { _metaspace = m; }
|
||||||
@ -190,7 +193,9 @@ class ClassLoaderData : public CHeapObj<mtClass> {
|
|||||||
static void init_null_class_loader_data() {
|
static void init_null_class_loader_data() {
|
||||||
assert(_the_null_class_loader_data == NULL, "cannot initialize twice");
|
assert(_the_null_class_loader_data == NULL, "cannot initialize twice");
|
||||||
assert(ClassLoaderDataGraph::_head == NULL, "cannot initialize twice");
|
assert(ClassLoaderDataGraph::_head == NULL, "cannot initialize twice");
|
||||||
_the_null_class_loader_data = new ClassLoaderData((oop)NULL, false);
|
|
||||||
|
// We explicitly initialize the Dependencies object at a later phase in the initialization
|
||||||
|
_the_null_class_loader_data = new ClassLoaderData((oop)NULL, false, Dependencies());
|
||||||
ClassLoaderDataGraph::_head = _the_null_class_loader_data;
|
ClassLoaderDataGraph::_head = _the_null_class_loader_data;
|
||||||
assert(_the_null_class_loader_data->is_the_null_class_loader_data(), "Must be");
|
assert(_the_null_class_loader_data->is_the_null_class_loader_data(), "Must be");
|
||||||
if (DumpSharedSpaces) {
|
if (DumpSharedSpaces) {
|
||||||
|
Loading…
Reference in New Issue
Block a user