src/share/vm/classfile/classLoaderData.cpp

changeset 5013
1cb4795305b9
parent 5007
c23dbf0e8ab7
child 5015
868d87ed63c8
     1.1 --- a/src/share/vm/classfile/classLoaderData.cpp	Mon Apr 22 22:00:03 2013 -0700
     1.2 +++ b/src/share/vm/classfile/classLoaderData.cpp	Tue Apr 23 08:39:55 2013 +0200
     1.3 @@ -53,6 +53,7 @@
     1.4  #include "classfile/metadataOnStackMark.hpp"
     1.5  #include "classfile/systemDictionary.hpp"
     1.6  #include "code/codeCache.hpp"
     1.7 +#include "memory/gcLocker.hpp"
     1.8  #include "memory/metadataFactory.hpp"
     1.9  #include "memory/metaspaceShared.hpp"
    1.10  #include "memory/oopFactory.hpp"
    1.11 @@ -423,7 +424,7 @@
    1.12  // These anonymous class loaders are to contain classes used for JSR292
    1.13  ClassLoaderData* ClassLoaderData::anonymous_class_loader_data(oop loader, TRAPS) {
    1.14    // Add a new class loader data to the graph.
    1.15 -  return ClassLoaderDataGraph::add(NULL, loader, CHECK_NULL);
    1.16 +  return ClassLoaderDataGraph::add(loader, true, CHECK_NULL);
    1.17  }
    1.18  
    1.19  const char* ClassLoaderData::loader_name() {
    1.20 @@ -495,30 +496,40 @@
    1.21  ClassLoaderData* ClassLoaderDataGraph::_unloading = NULL;
    1.22  ClassLoaderData* ClassLoaderDataGraph::_saved_head = NULL;
    1.23  
    1.24 -
    1.25  // Add a new class loader data node to the list.  Assign the newly created
    1.26  // ClassLoaderData into the java/lang/ClassLoader object as a hidden field
    1.27 -ClassLoaderData* ClassLoaderDataGraph::add(ClassLoaderData** cld_addr, Handle loader, TRAPS) {
    1.28 +ClassLoaderData* ClassLoaderDataGraph::add(Handle loader, bool is_anonymous, TRAPS) {
    1.29    // Not assigned a class loader data yet.
    1.30    // Create one.
    1.31 -  ClassLoaderData* *list_head = &_head;
    1.32 -  ClassLoaderData* next = _head;
    1.33 +  ClassLoaderData* cld = new ClassLoaderData(loader, is_anonymous);
    1.34 +  cld->init_dependencies(THREAD);
    1.35 +  if (HAS_PENDING_EXCEPTION) {
    1.36 +    delete cld;
    1.37 +    return NULL;
    1.38 +  }
    1.39  
    1.40 -  bool is_anonymous = (cld_addr == NULL);
    1.41 -  ClassLoaderData* cld = new ClassLoaderData(loader, is_anonymous);
    1.42 +  No_Safepoint_Verifier no_safepoints; // nothing is keeping the dependencies array in cld alive
    1.43 +                                       // make sure we don't encounter a GC until we've inserted
    1.44 +                                       // cld into the CLDG
    1.45  
    1.46 -  if (cld_addr != NULL) {
    1.47 -    // First, Atomically set it
    1.48 -    ClassLoaderData* old = (ClassLoaderData*) Atomic::cmpxchg_ptr(cld, cld_addr, NULL);
    1.49 -    if (old != NULL) {
    1.50 -      delete cld;
    1.51 -      // Returns the data.
    1.52 -      return old;
    1.53 +  if (!is_anonymous) {
    1.54 +    ClassLoaderData** cld_addr = java_lang_ClassLoader::loader_data_addr(loader());
    1.55 +    if (cld_addr != NULL) {
    1.56 +      // First, Atomically set it
    1.57 +      ClassLoaderData* old = (ClassLoaderData*) Atomic::cmpxchg_ptr(cld, cld_addr, NULL);
    1.58 +      if (old != NULL) {
    1.59 +        delete cld;
    1.60 +        // Returns the data.
    1.61 +        return old;
    1.62 +      }
    1.63      }
    1.64    }
    1.65  
    1.66    // We won the race, and therefore the task of adding the data to the list of
    1.67    // class loader data
    1.68 +  ClassLoaderData** list_head = &_head;
    1.69 +  ClassLoaderData* next = _head;
    1.70 +
    1.71    do {
    1.72      cld->set_next(next);
    1.73      ClassLoaderData* exchanged = (ClassLoaderData*)Atomic::cmpxchg_ptr(cld, list_head, next);
    1.74 @@ -531,10 +542,6 @@
    1.75                     cld->loader_name());
    1.76          tty->print_cr("]");
    1.77        }
    1.78 -      // Create dependencies after the CLD is added to the list.  Otherwise,
    1.79 -      // the GC GC will not find the CLD and the _class_loader field will
    1.80 -      // not be updated.
    1.81 -      cld->init_dependencies(CHECK_NULL);
    1.82        return cld;
    1.83      }
    1.84      next = exchanged;

mercurial