src/share/vm/classfile/dictionary.cpp

Print this page
rev 5310 : imported patch ioi_original_patch
rev 5311 : imported patch cleanup

@@ -36,20 +36,20 @@
 
 Dictionary::Dictionary(int table_size)
   : TwoOopHashtable<Klass*, mtClass>(table_size, sizeof(DictionaryEntry)) {
   _current_class_index = 0;
   _current_class_entry = NULL;
-  _pd_cache_table = new ProtectionDomainCacheTable(137);
+  _pd_cache_table = new ProtectionDomainCacheTable(ProtectionDomainCacheSize);
 };
 
 
 Dictionary::Dictionary(int table_size, HashtableBucket<mtClass>* t,
                        int number_of_entries)
   : TwoOopHashtable<Klass*, mtClass>(table_size, sizeof(DictionaryEntry), t, number_of_entries) {
   _current_class_index = 0;
   _current_class_entry = NULL;
-  _pd_cache_table = new ProtectionDomainCacheTable(137);
+  _pd_cache_table = new ProtectionDomainCacheTable(ProtectionDomainCacheSize);
 };
 
 ProtectionDomainCacheEntry* Dictionary::cache_get(oop protection_domain) {
   return _pd_cache_table->get(protection_domain);
 }

@@ -200,34 +200,28 @@
   return class_was_unloaded;
 }
 
 
 void Dictionary::always_strong_oops_do(OopClosure* blk) {
-  // This code is not multi-thread safe, but it should be called only
-  // by GC thread.
-  static int scan_generation = 0;
-  scan_generation++;
-  if (scan_generation == 0) {
-    // Wrapped around 32-bit. Never use 0 -- it's the initial value of
-    // ProtectionDomainCacheEntry::_scan_generation.
-    scan_generation = 1;
-  }
-
-  // Follow all system classes and temporary placeholders in dictionary
+  // Follow all system classes and temporary placeholders in dictionary; only
+  // protection domain oops contain references into the heap. In a first
+  // pass over the system dictionary determine which need to be treated as
+  // strongly reachable and mark them as such.
   for (int index = 0; index < table_size(); index++) {
     for (DictionaryEntry *probe = bucket(index);
                           probe != NULL;
                           probe = probe->next()) {
       Klass* e = probe->klass();
       ClassLoaderData* loader_data = probe->loader_data();
       if (is_strongly_reachable(loader_data, e)) {
-        probe->set_strongly_reachable(scan_generation);
+        probe->set_strongly_reachable();
       }
     }
   }
-
-  _pd_cache_table->always_strong_oops_do(blk, scan_generation);
+  // then iterate over the protection domain cache to apply the closure on the
+  // previously marked ones.
+  _pd_cache_table->always_strong_oops_do(blk);
 }
 
 
 void Dictionary::always_strong_classes_do(KlassClosure* closure) {
   // Follow all system classes and temporary placeholders in dictionary

@@ -286,10 +280,12 @@
     }
   }
 }
 
 void Dictionary::oops_do(OopClosure* f) {
+  // only the protection domain oops contain references into the heap. Iterate
+  // over all of them.
   _pd_cache_table->oops_do(f);
 }
 
 void Dictionary::methods_do(void f(Method*)) {
   for (int index = 0; index < table_size(); index++) {

@@ -470,17 +466,62 @@
       probe->oops_do(f);
     }
   }
 }
 
+uint ProtectionDomainCacheTable::bucket_size() {
+  return sizeof(ProtectionDomainCacheEntry);
+}
 
-void ProtectionDomainCacheTable::always_strong_oops_do(OopClosure* f, int gen) {
+#ifndef PRODUCT
+void ProtectionDomainCacheTable::print() {
+  tty->print_cr("Protection domain cache table (table_size=%d, classes=%d)",
+                table_size(), number_of_entries());
   for (int index = 0; index < table_size(); index++) {
     for (ProtectionDomainCacheEntry* probe = bucket(index);
                                      probe != NULL;
                                      probe = probe->next()) {
-      if (probe->is_strongly_reachable(gen)) {
+      probe->print();
+    }
+  }
+}
+
+void ProtectionDomainCacheEntry::print() {
+  tty->print_cr("entry "PTR_FORMAT" value "PTR_FORMAT" refcount %d strongly_reachable %d next "PTR_FORMAT,
+                this, literal(), refcount(), _strongly_reachable, next());
+}
+#endif
+
+void ProtectionDomainCacheTable::verify() {
+  int element_count = 0;
+  for (int index = 0; index < table_size(); index++) {
+    for (ProtectionDomainCacheEntry* probe = bucket(index);
+                                     probe != NULL;
+                                     probe = probe->next()) {
+      probe->verify();
+      element_count++;
+    }
+  }
+  guarantee(number_of_entries() == element_count,
+            "Verify of protection domain cache table failed");
+  debug_only(verify_lookup_length((double)number_of_entries() / table_size()));
+}
+
+void ProtectionDomainCacheEntry::verify() {
+  guarantee(literal()->is_oop(), "must be an oop");
+  guarantee(_refcount >= 0, "must be");
+}
+
+void ProtectionDomainCacheTable::always_strong_oops_do(OopClosure* f) {
+  // the caller marked the protection domain cache entries that we need to apply
+  // the closure on. Only process them.
+  for (int index = 0; index < table_size(); index++) {
+    for (ProtectionDomainCacheEntry* probe = bucket(index);
+                                     probe != NULL;
+                                     probe = probe->next()) {
+      if (probe->is_strongly_reachable()) {
+        probe->reset_strongly_reachable();
         probe->oops_do(f);
       }
     }
   }
 }

@@ -620,15 +661,16 @@
         tty->print(", loader ");
       loader_data->print_value();
       tty->cr();
     }
   }
+  tty->cr();
+  _pd_cache_table->print();
 }
 
 #endif
 
-
 void Dictionary::verify() {
   guarantee(number_of_entries() >= 0, "Verify of system dictionary failed");
 
   int element_count = 0;
   for (int index = 0; index < table_size(); index++) {

@@ -651,7 +693,9 @@
     }
   }
   guarantee(number_of_entries() == element_count,
             "Verify of system dictionary failed");
   debug_only(verify_lookup_length((double)number_of_entries() / table_size()));
+
+  _pd_cache_table->verify();
 }