< prev index next >
src/hotspot/share/classfile/classLoaderData.cpp
Print this page
@@ -1075,37 +1075,42 @@
// 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_to_graph(Handle loader, bool is_unsafe_anonymous) {
+ assert_lock_strong(ClassLoaderDataGraph_lock);
ClassLoaderData* cld;
- {
- NoSafepointVerifier no_safepoints; // we mustn't GC until we've installed the
- // ClassLoaderData in the loader since the CLD
- // contains oops in _handles that must be walked.
- // GC will find the CLD through the loader after this.
- cld = new ClassLoaderData(loader, is_unsafe_anonymous);
-
- if (!is_unsafe_anonymous) {
- // First, Atomically set it
- ClassLoaderData* old = java_lang_ClassLoader::cmpxchg_loader_data(cld, loader(), NULL);
- if (old != NULL) {
- delete cld;
- // Returns the data.
- return old;
- }
+ // First check if another thread beat us to creating the CLD and installing
+ // it into the loader while we were waiting for the lock.
+ if (!is_unsafe_anonymous && loader.not_null()) {
+ cld = java_lang_ClassLoader::loader_data_acquire(loader());
+ if (cld != NULL) {
+ return cld;
}
}
- MutexLocker ml(ClassLoaderDataGraph_lock);
+ // We mustn't GC until we've installed the ClassLoaderData in the Graph since the CLD
+ // contains oops in _handles that must be walked. GC doesn't walk CLD from the
+ // loader oop in all collections, particularly young collections.
+ NoSafepointVerifier no_safepoints;
- // We won the race, and therefore the task of adding the data to the list of
- // class loader data
+ cld = new ClassLoaderData(loader, is_unsafe_anonymous);
+
+ // First install the new CLD to the Graph.
cld->set_next(_head);
_head = cld;
+
+ // Next associate with the class_loader.
+ if (!is_unsafe_anonymous) {
+ // Use OrderAccess, since readers need to get the loader_data only after
+ // it's added to the Graph
+ java_lang_ClassLoader::release_set_loader_data(loader(), cld);
+ }
+
+ // Lastly log, if requested
LogTarget(Trace, class, loader, data) lt;
if (lt.is_enabled()) {
ResourceMark rm;
LogStream ls(lt);
ls.print("create ");
@@ -1114,13 +1119,14 @@
}
return cld;
}
ClassLoaderData* ClassLoaderDataGraph::add(Handle loader, bool is_unsafe_anonymous) {
+ MutexLocker ml(ClassLoaderDataGraph_lock);
ClassLoaderData* loader_data = add_to_graph(loader, is_unsafe_anonymous);
// Initialize _name and _name_and_id after the loader data is added to the
- // CLDG because adding the Symbol for _name and _name_and_id might safepoint.
+ // CLDG.
if (loader.not_null()) {
loader_data->initialize_name(loader);
}
return loader_data;
}
< prev index next >