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:


  49 #include "precompiled.hpp"
  50 #include "classfile/classLoaderData.hpp"
  51 #include "classfile/classLoaderData.inline.hpp"
  52 #include "classfile/javaClasses.hpp"
  53 #include "classfile/metadataOnStackMark.hpp"
  54 #include "classfile/systemDictionary.hpp"
  55 #include "code/codeCache.hpp"
  56 #include "memory/gcLocker.hpp"
  57 #include "memory/metadataFactory.hpp"
  58 #include "memory/metaspaceShared.hpp"
  59 #include "memory/oopFactory.hpp"
  60 #include "runtime/jniHandles.hpp"
  61 #include "runtime/mutex.hpp"
  62 #include "runtime/safepoint.hpp"
  63 #include "runtime/synchronizer.hpp"
  64 #include "utilities/growableArray.hpp"
  65 #include "utilities/ostream.hpp"
  66 
  67 ClassLoaderData * ClassLoaderData::_the_null_class_loader_data = NULL;
  68 
  69 ClassLoaderData::ClassLoaderData(Handle h_class_loader, bool is_anonymous) :
  70   _class_loader(h_class_loader()),
  71   _is_anonymous(is_anonymous), _keep_alive(is_anonymous), // initially
  72   _metaspace(NULL), _unloading(false), _klasses(NULL),
  73   _claimed(0), _jmethod_ids(NULL), _handles(NULL), _deallocate_list(NULL),
  74   _next(NULL), _dependencies(),
  75   _metaspace_lock(new Mutex(Monitor::leaf+1, "Metaspace allocation lock", true)) {
  76     // empty
  77 }
  78 
  79 void ClassLoaderData::init_dependencies(TRAPS) {


  80   _dependencies.init(CHECK);
  81 }
  82 
  83 void ClassLoaderData::Dependencies::init(TRAPS) {
  84   // Create empty dependencies array to add to. CMS requires this to be
  85   // an oop so that it can track additions via card marks.  We think.
  86   _list_head = oopFactory::new_objectArray(2, CHECK);
  87 }
  88 
  89 bool ClassLoaderData::claim() {
  90   if (_claimed == 1) {
  91     return false;
  92   }
  93 
  94   return (int) Atomic::cmpxchg(1, &_claimed, 0) == 0;
  95 }
  96 
  97 void ClassLoaderData::oops_do(OopClosure* f, KlassClosure* klass_closure, bool must_claim) {
  98   if (must_claim && !claim()) {
  99     return;


 482   if (metaspace_or_null() != NULL) {
 483     metaspace_or_null()->verify();
 484   }
 485 
 486   for (Klass* k = _klasses; k != NULL; k = k->next_link()) {
 487     guarantee(k->class_loader_data() == this, "Must be the same");
 488     k->verify();
 489     assert(k != k->next_link(), "no loops!");
 490   }
 491 }
 492 
 493 
 494 // GC root of class loader data created.
 495 ClassLoaderData* ClassLoaderDataGraph::_head = NULL;
 496 ClassLoaderData* ClassLoaderDataGraph::_unloading = NULL;
 497 ClassLoaderData* ClassLoaderDataGraph::_saved_head = NULL;
 498 
 499 // Add a new class loader data node to the list.  Assign the newly created
 500 // ClassLoaderData into the java/lang/ClassLoader object as a hidden field
 501 ClassLoaderData* ClassLoaderDataGraph::add(Handle loader, bool is_anonymous, TRAPS) {
 502   // Not assigned a class loader data yet.
 503   // Create one.
 504   ClassLoaderData* cld = new ClassLoaderData(loader, is_anonymous);
 505   cld->init_dependencies(THREAD);
 506   if (HAS_PENDING_EXCEPTION) {
 507     delete cld;
 508     return NULL;
 509   }

 510 
 511   No_Safepoint_Verifier no_safepoints; // nothing is keeping the dependencies array in cld alive
 512                                        // make sure we don't encounter a GC until we've inserted
 513                                        // cld into the CLDG
 514 
 515   if (!is_anonymous) {
 516     ClassLoaderData** cld_addr = java_lang_ClassLoader::loader_data_addr(loader());
 517     if (cld_addr != NULL) {
 518       // First, Atomically set it
 519       ClassLoaderData* old = (ClassLoaderData*) Atomic::cmpxchg_ptr(cld, cld_addr, NULL);
 520       if (old != NULL) {
 521         delete cld;
 522         // Returns the data.
 523         return old;
 524       }
 525     }
 526   }
 527 
 528   // We won the race, and therefore the task of adding the data to the list of
 529   // class loader data
 530   ClassLoaderData** list_head = &_head;
 531   ClassLoaderData* next = _head;
 532 
 533   do {
 534     cld->set_next(next);
 535     ClassLoaderData* exchanged = (ClassLoaderData*)Atomic::cmpxchg_ptr(cld, list_head, next);
 536     if (exchanged == next) {
 537       if (TraceClassLoaderData) {
 538         ResourceMark rm;
 539         tty->print("[ClassLoaderData: ");
 540         tty->print("create class loader data "PTR_FORMAT, cld);
 541         tty->print(" for instance "PTR_FORMAT" of %s", cld->class_loader(),
 542                    cld->loader_name());
 543         tty->print_cr("]");
 544       }




  49 #include "precompiled.hpp"
  50 #include "classfile/classLoaderData.hpp"
  51 #include "classfile/classLoaderData.inline.hpp"
  52 #include "classfile/javaClasses.hpp"
  53 #include "classfile/metadataOnStackMark.hpp"
  54 #include "classfile/systemDictionary.hpp"
  55 #include "code/codeCache.hpp"
  56 #include "memory/gcLocker.hpp"
  57 #include "memory/metadataFactory.hpp"
  58 #include "memory/metaspaceShared.hpp"
  59 #include "memory/oopFactory.hpp"
  60 #include "runtime/jniHandles.hpp"
  61 #include "runtime/mutex.hpp"
  62 #include "runtime/safepoint.hpp"
  63 #include "runtime/synchronizer.hpp"
  64 #include "utilities/growableArray.hpp"
  65 #include "utilities/ostream.hpp"
  66 
  67 ClassLoaderData * ClassLoaderData::_the_null_class_loader_data = NULL;
  68 
  69 ClassLoaderData::ClassLoaderData(Handle h_class_loader, bool is_anonymous, Dependencies dependencies) :
  70   _class_loader(h_class_loader()),
  71   _is_anonymous(is_anonymous), _keep_alive(is_anonymous), // initially
  72   _metaspace(NULL), _unloading(false), _klasses(NULL),
  73   _claimed(0), _jmethod_ids(NULL), _handles(NULL), _deallocate_list(NULL),
  74   _next(NULL), _dependencies(dependencies),
  75   _metaspace_lock(new Mutex(Monitor::leaf+1, "Metaspace allocation lock", true)) {
  76     // empty
  77 }
  78 
  79 void ClassLoaderData::init_dependencies(TRAPS) {
  80   assert(!Universe::is_fully_initialized(), "should only be called when initializing");
  81   assert(is_the_null_class_loader_data(), "should only call this for the null class loader");
  82   _dependencies.init(CHECK);
  83 }
  84 
  85 void ClassLoaderData::Dependencies::init(TRAPS) {
  86   // Create empty dependencies array to add to. CMS requires this to be
  87   // an oop so that it can track additions via card marks.  We think.
  88   _list_head = oopFactory::new_objectArray(2, CHECK);
  89 }
  90 
  91 bool ClassLoaderData::claim() {
  92   if (_claimed == 1) {
  93     return false;
  94   }
  95 
  96   return (int) Atomic::cmpxchg(1, &_claimed, 0) == 0;
  97 }
  98 
  99 void ClassLoaderData::oops_do(OopClosure* f, KlassClosure* klass_closure, bool must_claim) {
 100   if (must_claim && !claim()) {
 101     return;


 484   if (metaspace_or_null() != NULL) {
 485     metaspace_or_null()->verify();
 486   }
 487 
 488   for (Klass* k = _klasses; k != NULL; k = k->next_link()) {
 489     guarantee(k->class_loader_data() == this, "Must be the same");
 490     k->verify();
 491     assert(k != k->next_link(), "no loops!");
 492   }
 493 }
 494 
 495 
 496 // GC root of class loader data created.
 497 ClassLoaderData* ClassLoaderDataGraph::_head = NULL;
 498 ClassLoaderData* ClassLoaderDataGraph::_unloading = NULL;
 499 ClassLoaderData* ClassLoaderDataGraph::_saved_head = NULL;
 500 
 501 // Add a new class loader data node to the list.  Assign the newly created
 502 // ClassLoaderData into the java/lang/ClassLoader object as a hidden field
 503 ClassLoaderData* ClassLoaderDataGraph::add(Handle loader, bool is_anonymous, TRAPS) {
 504   // We need to allocate all the oops for the ClassLoaderData before allocating the
 505   // actual ClassLoaderData object.
 506   ClassLoaderData::Dependencies dependencies(CHECK_NULL);
 507 
 508   No_Safepoint_Verifier no_safepoints; // we mustn't GC until we've installed the
 509                                        // ClassLoaderData in the graph since the CLD
 510                                        // contains unhandled oops
 511 
 512   ClassLoaderData* cld = new ClassLoaderData(loader, is_anonymous, dependencies);
 513 



 514 
 515   if (!is_anonymous) {
 516     ClassLoaderData** cld_addr = java_lang_ClassLoader::loader_data_addr(loader());

 517     // First, Atomically set it
 518     ClassLoaderData* old = (ClassLoaderData*) Atomic::cmpxchg_ptr(cld, cld_addr, NULL);
 519     if (old != NULL) {
 520       delete cld;
 521       // Returns the data.
 522       return old;

 523     }
 524   }
 525 
 526   // We won the race, and therefore the task of adding the data to the list of
 527   // class loader data
 528   ClassLoaderData** list_head = &_head;
 529   ClassLoaderData* next = _head;
 530 
 531   do {
 532     cld->set_next(next);
 533     ClassLoaderData* exchanged = (ClassLoaderData*)Atomic::cmpxchg_ptr(cld, list_head, next);
 534     if (exchanged == next) {
 535       if (TraceClassLoaderData) {
 536         ResourceMark rm;
 537         tty->print("[ClassLoaderData: ");
 538         tty->print("create class loader data "PTR_FORMAT, cld);
 539         tty->print(" for instance "PTR_FORMAT" of %s", cld->class_loader(),
 540                    cld->loader_name());
 541         tty->print_cr("]");
 542       }