提交 450f5790 编写于 作者: M mgerdin

8013136: NPG: Parallel class loading tests fail after fix for JDK-8011802

Summary: Move initialization of dependencies to before allocation of CLD
Reviewed-by: stefank, coleenp
上级 6fe0e0c8
...@@ -66,17 +66,19 @@ ...@@ -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,29 +501,25 @@ ClassLoaderData* ClassLoaderDataGraph::_saved_head = NULL; ...@@ -499,29 +501,25 @@ 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) { delete cld;
delete cld; // Returns the data.
// Returns the data. return old;
return old;
}
} }
} }
......
...@@ -100,6 +100,9 @@ class ClassLoaderData : public CHeapObj<mtClass> { ...@@ -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> { ...@@ -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> { ...@@ -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) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册