src/share/vm/classfile/classLoaderData.cpp

Print this page
rev 4524 : 8013136: NPG: Parallel class loading tests fail after fix for JDK-8011802
Summary: Move initialization of dependencies to before allocation of CLD
Reviewed-by:

*** 64,84 **** #include "utilities/growableArray.hpp" #include "utilities/ostream.hpp" ClassLoaderData * ClassLoaderData::_the_null_class_loader_data = NULL; ! ClassLoaderData::ClassLoaderData(Handle h_class_loader, bool is_anonymous) : _class_loader(h_class_loader()), _is_anonymous(is_anonymous), _keep_alive(is_anonymous), // initially _metaspace(NULL), _unloading(false), _klasses(NULL), _claimed(0), _jmethod_ids(NULL), _handles(NULL), _deallocate_list(NULL), ! _next(NULL), _dependencies(), _metaspace_lock(new Mutex(Monitor::leaf+1, "Metaspace allocation lock", true)) { // empty } void ClassLoaderData::init_dependencies(TRAPS) { _dependencies.init(CHECK); } void ClassLoaderData::Dependencies::init(TRAPS) { // Create empty dependencies array to add to. CMS requires this to be --- 64,86 ---- #include "utilities/growableArray.hpp" #include "utilities/ostream.hpp" ClassLoaderData * ClassLoaderData::_the_null_class_loader_data = NULL; ! ClassLoaderData::ClassLoaderData(Handle h_class_loader, bool is_anonymous, Dependencies dependencies) : _class_loader(h_class_loader()), _is_anonymous(is_anonymous), _keep_alive(is_anonymous), // initially _metaspace(NULL), _unloading(false), _klasses(NULL), _claimed(0), _jmethod_ids(NULL), _handles(NULL), _deallocate_list(NULL), ! _next(NULL), _dependencies(dependencies), _metaspace_lock(new Mutex(Monitor::leaf+1, "Metaspace allocation lock", true)) { // empty } 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); } void ClassLoaderData::Dependencies::init(TRAPS) { // Create empty dependencies array to add to. CMS requires this to be
*** 497,531 **** ClassLoaderData* ClassLoaderDataGraph::_saved_head = NULL; // 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* ClassLoaderDataGraph::add(Handle loader, bool is_anonymous, TRAPS) { ! // Not assigned a class loader data yet. ! // Create one. ! ClassLoaderData* cld = new ClassLoaderData(loader, is_anonymous); ! cld->init_dependencies(THREAD); ! if (HAS_PENDING_EXCEPTION) { ! delete cld; ! return NULL; ! } - 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) { ClassLoaderData** cld_addr = java_lang_ClassLoader::loader_data_addr(loader()); - if (cld_addr != NULL) { // First, Atomically set it ClassLoaderData* old = (ClassLoaderData*) Atomic::cmpxchg_ptr(cld, cld_addr, NULL); if (old != NULL) { delete cld; // Returns the data. return old; } } - } // We won the race, and therefore the task of adding the data to the list of // class loader data ClassLoaderData** list_head = &_head; ClassLoaderData* next = _head; --- 499,529 ---- ClassLoaderData* ClassLoaderDataGraph::_saved_head = NULL; // 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* ClassLoaderDataGraph::add(Handle loader, bool is_anonymous, TRAPS) { ! // We need to allocate all the oops for the ClassLoaderData before allocating the ! // actual ClassLoaderData object. ! ClassLoaderData::Dependencies dependencies(CHECK_NULL); ! ! No_Safepoint_Verifier no_safepoints; // we mustn't GC until we've installed the ! // ClassLoaderData in the graph since the CLD ! // contains unhandled oops ! ! ClassLoaderData* cld = new ClassLoaderData(loader, is_anonymous, dependencies); if (!is_anonymous) { ClassLoaderData** cld_addr = java_lang_ClassLoader::loader_data_addr(loader()); // First, Atomically set it ClassLoaderData* old = (ClassLoaderData*) Atomic::cmpxchg_ptr(cld, cld_addr, NULL); if (old != NULL) { delete cld; // Returns the data. return old; } } // We won the race, and therefore the task of adding the data to the list of // class loader data ClassLoaderData** list_head = &_head; ClassLoaderData* next = _head;