225 objArrayHandle last_handle(THREAD, last);
226
227 // Create a new dependency node with fields for (class_loader or mirror, next)
228 objArrayOop deps = oopFactory::new_objectArray(2, CHECK);
229 deps->obj_at_put(0, dependency());
230
231 // Must handle over GC points
232 objArrayHandle new_dependency(THREAD, deps);
233
234 // Add the dependency under lock
235 locked_add(last_handle, new_dependency, THREAD);
236 }
237
238 void ClassLoaderData::Dependencies::locked_add(objArrayHandle last_handle,
239 objArrayHandle new_dependency,
240 Thread* THREAD) {
241
242 // Have to lock and put the new dependency on the end of the dependency
243 // array so the card mark for CMS sees that this dependency is new.
244 // Can probably do this lock free with some effort.
245 ObjectLocker ol(Handle(THREAD, _list_head), THREAD);
246
247 oop loader_or_mirror = new_dependency->obj_at(0);
248
249 // Since the dependencies are only added, add to the end.
250 objArrayOop end = last_handle();
251 objArrayOop last = NULL;
252 while (end != NULL) {
253 last = end;
254 // check again if another thread added it to the end.
255 if (end->obj_at(0) == loader_or_mirror) {
256 // Don't need to add it
257 return;
258 }
259 end = (objArrayOop)end->obj_at(1);
260 }
261 assert (last != NULL, "dependencies should be initialized");
262 // fill in the first element with the oop in new_dependency.
263 if (last->obj_at(0) == NULL) {
264 last->obj_at_put(0, new_dependency->obj_at(0));
265 } else {
561 ClassLoaderData* ClassLoaderDataGraph::_saved_head = NULL;
562
563 bool ClassLoaderDataGraph::_should_purge = false;
564 bool ClassLoaderDataGraph::_metaspace_oom = false;
565
566 // Add a new class loader data node to the list. Assign the newly created
567 // ClassLoaderData into the java/lang/ClassLoader object as a hidden field
568 ClassLoaderData* ClassLoaderDataGraph::add(Handle loader, bool is_anonymous, TRAPS) {
569 // We need to allocate all the oops for the ClassLoaderData before allocating the
570 // actual ClassLoaderData object.
571 ClassLoaderData::Dependencies dependencies(CHECK_NULL);
572
573 No_Safepoint_Verifier no_safepoints; // we mustn't GC until we've installed the
574 // ClassLoaderData in the graph since the CLD
575 // contains unhandled oops
576
577 ClassLoaderData* cld = new ClassLoaderData(loader, is_anonymous, dependencies);
578
579
580 if (!is_anonymous) {
581 ClassLoaderData** cld_addr = java_lang_ClassLoader::loader_data_addr(loader());
582 // First, Atomically set it
583 ClassLoaderData* old = (ClassLoaderData*) Atomic::cmpxchg_ptr(cld, cld_addr, NULL);
584 if (old != NULL) {
585 delete cld;
586 // Returns the data.
587 return old;
588 }
589 }
590
591 // We won the race, and therefore the task of adding the data to the list of
592 // class loader data
593 ClassLoaderData** list_head = &_head;
594 ClassLoaderData* next = _head;
595
596 do {
597 cld->set_next(next);
598 ClassLoaderData* exchanged = (ClassLoaderData*)Atomic::cmpxchg_ptr(cld, list_head, next);
599 if (exchanged == next) {
600 if (TraceClassLoaderData) {
601 ResourceMark rm;
|
225 objArrayHandle last_handle(THREAD, last);
226
227 // Create a new dependency node with fields for (class_loader or mirror, next)
228 objArrayOop deps = oopFactory::new_objectArray(2, CHECK);
229 deps->obj_at_put(0, dependency());
230
231 // Must handle over GC points
232 objArrayHandle new_dependency(THREAD, deps);
233
234 // Add the dependency under lock
235 locked_add(last_handle, new_dependency, THREAD);
236 }
237
238 void ClassLoaderData::Dependencies::locked_add(objArrayHandle last_handle,
239 objArrayHandle new_dependency,
240 Thread* THREAD) {
241
242 // Have to lock and put the new dependency on the end of the dependency
243 // array so the card mark for CMS sees that this dependency is new.
244 // Can probably do this lock free with some effort.
245 ObjectLocker ol(Handle(THREAD, oopDesc::bs()->write_barrier(_list_head)), THREAD);
246
247 oop loader_or_mirror = new_dependency->obj_at(0);
248
249 // Since the dependencies are only added, add to the end.
250 objArrayOop end = last_handle();
251 objArrayOop last = NULL;
252 while (end != NULL) {
253 last = end;
254 // check again if another thread added it to the end.
255 if (end->obj_at(0) == loader_or_mirror) {
256 // Don't need to add it
257 return;
258 }
259 end = (objArrayOop)end->obj_at(1);
260 }
261 assert (last != NULL, "dependencies should be initialized");
262 // fill in the first element with the oop in new_dependency.
263 if (last->obj_at(0) == NULL) {
264 last->obj_at_put(0, new_dependency->obj_at(0));
265 } else {
561 ClassLoaderData* ClassLoaderDataGraph::_saved_head = NULL;
562
563 bool ClassLoaderDataGraph::_should_purge = false;
564 bool ClassLoaderDataGraph::_metaspace_oom = false;
565
566 // Add a new class loader data node to the list. Assign the newly created
567 // ClassLoaderData into the java/lang/ClassLoader object as a hidden field
568 ClassLoaderData* ClassLoaderDataGraph::add(Handle loader, bool is_anonymous, TRAPS) {
569 // We need to allocate all the oops for the ClassLoaderData before allocating the
570 // actual ClassLoaderData object.
571 ClassLoaderData::Dependencies dependencies(CHECK_NULL);
572
573 No_Safepoint_Verifier no_safepoints; // we mustn't GC until we've installed the
574 // ClassLoaderData in the graph since the CLD
575 // contains unhandled oops
576
577 ClassLoaderData* cld = new ClassLoaderData(loader, is_anonymous, dependencies);
578
579
580 if (!is_anonymous) {
581 ClassLoaderData** cld_addr = java_lang_ClassLoader::loader_data_addr(oopDesc::bs()->write_barrier(loader()));
582 // First, Atomically set it
583 ClassLoaderData* old = (ClassLoaderData*) Atomic::cmpxchg_ptr(cld, cld_addr, NULL);
584 if (old != NULL) {
585 delete cld;
586 // Returns the data.
587 return old;
588 }
589 }
590
591 // We won the race, and therefore the task of adding the data to the list of
592 // class loader data
593 ClassLoaderData** list_head = &_head;
594 ClassLoaderData* next = _head;
595
596 do {
597 cld->set_next(next);
598 ClassLoaderData* exchanged = (ClassLoaderData*)Atomic::cmpxchg_ptr(cld, list_head, next);
599 if (exchanged == next) {
600 if (TraceClassLoaderData) {
601 ResourceMark rm;
|