src/hotspot/share/classfile/classLoaderData.cpp
changeset 48884 7e17b00dc245
parent 48874 f09fdaad7321
child 49041 44122f767467
--- a/src/hotspot/share/classfile/classLoaderData.cpp	Thu Feb 08 08:38:42 2018 -0800
+++ b/src/hotspot/share/classfile/classLoaderData.cpp	Thu Feb 08 13:21:22 2018 -0500
@@ -80,6 +80,9 @@
 #include "trace/tracing.hpp"
 #endif
 
+volatile size_t ClassLoaderDataGraph::_num_array_classes = 0;
+volatile size_t ClassLoaderDataGraph::_num_instance_classes = 0;
+
 ClassLoaderData * ClassLoaderData::_the_null_class_loader_data = NULL;
 
 ClassLoaderData::ClassLoaderData(Handle h_class_loader, bool is_anonymous, Dependencies dependencies) :
@@ -443,6 +446,11 @@
     // Link the new item into the list, making sure the linked class is stable
     // since the list can be walked without a lock
     OrderAccess::release_store(&_klasses, k);
+    if (k->is_array_klass()) {
+      ClassLoaderDataGraph::inc_array_classes(1);
+    } else {
+      ClassLoaderDataGraph::inc_instance_classes(1);
+    }
   }
 
   if (publicize && k->class_loader_data() != NULL) {
@@ -468,9 +476,9 @@
 
   InstanceKlass* try_get_next_class() {
     assert(SafepointSynchronize::is_at_safepoint(), "only called at safepoint");
-    int max_classes = InstanceKlass::number_of_instance_classes();
+    size_t max_classes = ClassLoaderDataGraph::num_instance_classes();
     assert(max_classes > 0, "should not be called with no instance classes");
-    for (int i = 0; i < max_classes; ) {
+    for (size_t i = 0; i < max_classes; ) {
 
       if (_current_class_entry != NULL) {
         Klass* k = _current_class_entry;
@@ -545,6 +553,13 @@
         Klass* next = k->next_link();
         prev->set_next_link(next);
       }
+
+      if (k->is_array_klass()) {
+        ClassLoaderDataGraph::dec_array_classes(1);
+      } else {
+        ClassLoaderDataGraph::dec_instance_classes(1);
+      }
+
       return;
     }
     prev = k;
@@ -639,9 +654,34 @@
   return alive;
 }
 
+class ReleaseKlassClosure: public KlassClosure {
+private:
+  size_t  _instance_class_released;
+  size_t  _array_class_released;
+public:
+  ReleaseKlassClosure() : _instance_class_released(0), _array_class_released(0) { }
+
+  size_t instance_class_released() const { return _instance_class_released; }
+  size_t array_class_released()    const { return _array_class_released;    }
+
+  void do_klass(Klass* k) {
+    if (k->is_array_klass()) {
+      _array_class_released ++;
+    } else {
+      assert(k->is_instance_klass(), "Must be");
+      _instance_class_released ++;
+      InstanceKlass::release_C_heap_structures(InstanceKlass::cast(k));
+    }
+  }
+};
+
 ClassLoaderData::~ClassLoaderData() {
   // Release C heap structures for all the classes.
-  classes_do(InstanceKlass::release_C_heap_structures);
+  ReleaseKlassClosure cl;
+  classes_do(&cl);
+
+  ClassLoaderDataGraph::dec_array_classes(cl.array_class_released());
+  ClassLoaderDataGraph::dec_instance_classes(cl.instance_class_released());
 
   // Release C heap allocated hashtable for all the packages.
   if (_packages != NULL) {