diff src/share/vm/classfile/classLoaderData.cpp @ 14909:4ca6dc0799b6

Backout jdk9 merge
author Gilles Duboscq <duboscq@ssw.jku.at>
date Tue, 01 Apr 2014 13:57:07 +0200
parents f460c6926af7
children 52b4284cb496
line wrap: on
line diff
--- a/src/share/vm/classfile/classLoaderData.cpp	Tue Apr 01 14:09:03 2014 +0200
+++ b/src/share/vm/classfile/classLoaderData.cpp	Tue Apr 01 13:57:07 2014 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -73,11 +73,7 @@
 
 ClassLoaderData::ClassLoaderData(Handle h_class_loader, bool is_anonymous, Dependencies dependencies) :
   _class_loader(h_class_loader()),
-  _is_anonymous(is_anonymous),
-  // An anonymous class loader data doesn't have anything to keep
-  // it from being unloaded during parsing of the anonymous class.
-  // The null-class-loader should always be kept alive.
-  _keep_alive(is_anonymous || h_class_loader.is_null()),
+  _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),
@@ -321,15 +317,11 @@
   }
 }
 
-oop ClassLoaderData::keep_alive_object() const {
-  assert(!keep_alive(), "Don't use with CLDs that are artificially kept alive");
-  return is_anonymous() ? _klasses->java_mirror() : class_loader();
-}
-
 bool ClassLoaderData::is_alive(BoolObjectClosure* is_alive_closure) const {
-  bool alive = keep_alive() // null class loader and incomplete anonymous klasses.
-      || is_alive_closure->do_object_b(keep_alive_object());
-
+  bool alive =
+    is_anonymous() ?
+       is_alive_closure->do_object_b(_klasses->java_mirror()) :
+       class_loader() == NULL || is_alive_closure->do_object_b(class_loader());
   assert(!alive || claimed(), "must be claimed");
   return alive;
 }
@@ -528,13 +520,6 @@
   }
 }
 
-bool ClassLoaderData::contains_klass(Klass* klass) {
-  for (Klass* k = _klasses; k != NULL; k = k->next_link()) {
-    if (k == klass) return true;
-  }
-  return false;
-}
-
 
 // GC root of class loader data created.
 ClassLoaderData* ClassLoaderDataGraph::_head = NULL;
@@ -606,6 +591,8 @@
 
 void ClassLoaderDataGraph::always_strong_oops_do(OopClosure* f, KlassClosure* klass_closure, bool must_claim) {
   if (ClassUnloading) {
+    ClassLoaderData::the_null_class_loader_data()->oops_do(f, klass_closure, must_claim);
+    // keep any special CLDs alive.
     ClassLoaderDataGraph::keep_alive_oops_do(f, klass_closure, must_claim);
   } else {
     ClassLoaderDataGraph::oops_do(f, klass_closure, must_claim);
@@ -661,12 +648,12 @@
   return array;
 }
 
-// For profiling and hsfind() only.  Otherwise, this is unsafe (and slow).  This
-// is done lock free to avoid lock inversion problems.  It is safe because
-// new ClassLoaderData are added to the end of the CLDG, and only removed at
-// safepoint.  The _unloading list can be deallocated concurrently with CMS so
-// this doesn't look in metaspace for classes that have been unloaded.
-bool ClassLoaderDataGraph::contains(const void* x) {
+#ifndef PRODUCT
+// for debugging and hsfind(x)
+bool ClassLoaderDataGraph::contains(address x) {
+  // I think we need the _metaspace_lock taken here because the class loader
+  // data graph could be changing while we are walking it (new entries added,
+  // new entries being unloaded, etc).
   if (DumpSharedSpaces) {
     // There are only two metaspaces to worry about.
     ClassLoaderData* ncld = ClassLoaderData::the_null_class_loader_data();
@@ -683,11 +670,16 @@
     }
   }
 
-  // Do not check unloading list because deallocation can be concurrent.
+  // Could also be on an unloading list which is okay, ie. still allocated
+  // for a little while.
+  for (ClassLoaderData* ucld = _unloading; ucld != NULL; ucld = ucld->next()) {
+    if (ucld->metaspace_or_null() != NULL && ucld->metaspace_or_null()->contains(x)) {
+      return true;
+    }
+  }
   return false;
 }
 
-#ifndef PRODUCT
 bool ClassLoaderDataGraph::contains_loader_data(ClassLoaderData* loader_data) {
   for (ClassLoaderData* data = _head; data != NULL; data = data->next()) {
     if (loader_data == data) {
@@ -711,7 +703,7 @@
   bool has_redefined_a_class = JvmtiExport::has_redefined_a_class();
   MetadataOnStackMark md_on_stack;
   while (data != NULL) {
-    if (data->is_alive(is_alive_closure)) {
+    if (data->keep_alive() || data->is_alive(is_alive_closure)) {
       if (has_redefined_a_class) {
         data->classes_do(InstanceKlass::purge_previous_versions);
       }