hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp
changeset 13728 882756847a04
parent 12630 ddf6ee008138
child 13878 6e6a462a6cff
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp	Fri Aug 31 16:39:35 2012 -0700
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp	Sat Sep 01 13:25:18 2012 -0400
@@ -32,10 +32,10 @@
 #include "gc_implementation/parallelScavenge/psMarkSweep.hpp"
 #include "gc_implementation/parallelScavenge/psMarkSweepDecorator.hpp"
 #include "gc_implementation/parallelScavenge/psOldGen.hpp"
-#include "gc_implementation/parallelScavenge/psPermGen.hpp"
 #include "gc_implementation/parallelScavenge/psScavenge.hpp"
 #include "gc_implementation/parallelScavenge/psYoungGen.hpp"
 #include "gc_implementation/shared/isGCActiveMark.hpp"
+#include "gc_implementation/shared/markSweep.hpp"
 #include "gc_implementation/shared/spaceDecorator.hpp"
 #include "gc_interface/gcCause.hpp"
 #include "memory/gcLocker.inline.hpp"
@@ -52,7 +52,6 @@
 #include "utilities/stack.inline.hpp"
 
 elapsedTimer        PSMarkSweep::_accumulated_time;
-unsigned int        PSMarkSweep::_total_invocations = 0;
 jlong               PSMarkSweep::_time_of_last_gc   = 0;
 CollectorCounters*  PSMarkSweep::_counters = NULL;
 
@@ -119,7 +118,6 @@
 
   PSYoungGen* young_gen = heap->young_gen();
   PSOldGen* old_gen = heap->old_gen();
-  PSPermGen* perm_gen = heap->perm_gen();
 
   // Increment the invocation count
   heap->increment_total_collections(true /* full */);
@@ -148,7 +146,6 @@
   if (VerifyObjectStartArray &&
       VerifyBeforeGC) {
     old_gen->verify_object_start_array();
-    perm_gen->verify_object_start_array();
   }
 
   heap->pre_full_gc_dump();
@@ -172,8 +169,6 @@
     // Let the size policy know we're starting
     size_policy->major_collection_begin();
 
-    // When collecting the permanent generation methodOops may be moving,
-    // so we either have to flush all bcp data or convert it into bci.
     CodeCache::gc_prologue();
     Threads::gc_prologue();
     BiasedLocking::preserve_marks();
@@ -181,8 +176,8 @@
     // Capture heap size before collection for printing.
     size_t prev_used = heap->used();
 
-    // Capture perm gen size before collection for sizing.
-    size_t perm_gen_prev_used = perm_gen->used_in_bytes();
+    // Capture metadata size before collection for sizing.
+    size_t metadata_prev_used = MetaspaceAux::used_in_bytes();
 
     // For PrintGCDetails
     size_t old_gen_prev_used = old_gen->used_in_bytes();
@@ -234,16 +229,16 @@
     if (bs->is_a(BarrierSet::ModRef)) {
       ModRefBarrierSet* modBS = (ModRefBarrierSet*)bs;
       MemRegion old_mr = heap->old_gen()->reserved();
-      MemRegion perm_mr = heap->perm_gen()->reserved();
-      assert(perm_mr.end() <= old_mr.start(), "Generations out of order");
-
       if (young_gen_empty) {
-        modBS->clear(MemRegion(perm_mr.start(), old_mr.end()));
+        modBS->clear(MemRegion(old_mr.start(), old_mr.end()));
       } else {
-        modBS->invalidate(MemRegion(perm_mr.start(), old_mr.end()));
+        modBS->invalidate(MemRegion(old_mr.start(), old_mr.end()));
       }
     }
 
+    // Delete metaspaces for unloaded class loaders and clean up loader_data graph
+    ClassLoaderDataGraph::purge();
+
     BiasedLocking::restore_marks();
     Threads::gc_epilogue();
     CodeCache::gc_epilogue();
@@ -267,10 +262,8 @@
         gclog_or_tty->print_cr(" collection: %d ",
                        heap->total_collections());
         if (Verbose) {
-          gclog_or_tty->print("old_gen_capacity: %d young_gen_capacity: %d"
-            " perm_gen_capacity: %d ",
-            old_gen->capacity_in_bytes(), young_gen->capacity_in_bytes(),
-            perm_gen->capacity_in_bytes());
+          gclog_or_tty->print("old_gen_capacity: %d young_gen_capacity: %d",
+            old_gen->capacity_in_bytes(), young_gen->capacity_in_bytes());
         }
       }
 
@@ -290,7 +283,6 @@
         size_policy->compute_generation_free_space(young_gen->used_in_bytes(),
                                  young_gen->eden_space()->used_in_bytes(),
                                  old_gen->used_in_bytes(),
-                                 perm_gen->used_in_bytes(),
                                  young_gen->eden_space()->capacity_in_bytes(),
                                  old_gen->max_gen_size(),
                                  max_eden_size,
@@ -323,8 +315,8 @@
 
     heap->resize_all_tlabs();
 
-    // We collected the perm gen, so we'll resize it here.
-    perm_gen->compute_new_size(perm_gen_prev_used);
+    // We collected the heap, recalculate the metaspace capacity
+    MetaspaceGC::compute_new_size();
 
     if (TraceGen1Time) accumulated_time()->stop();
 
@@ -336,11 +328,8 @@
         old_gen->print_used_change(old_gen_prev_used);
       }
       heap->print_heap_change(prev_used);
-      // Do perm gen after heap becase prev_used does
-      // not include the perm gen (done this way in the other
-      // collectors).
       if (PrintGCDetails) {
-        perm_gen->print_used_change(perm_gen_prev_used);
+        MetaspaceAux::print_metaspace_change(metadata_prev_used);
       }
     }
 
@@ -359,12 +348,10 @@
   if (VerifyObjectStartArray &&
       VerifyAfterGC) {
     old_gen->verify_object_start_array();
-    perm_gen->verify_object_start_array();
   }
 
   if (ZapUnusedHeapArea) {
     old_gen->object_space()->check_mangled_unused_area_complete();
-    perm_gen->object_space()->check_mangled_unused_area_complete();
   }
 
   NOT_PRODUCT(ref_processor()->verify_no_references_recorded());
@@ -490,8 +477,6 @@
   _preserved_oop_stack.clear(true);
   _marking_stack.clear();
   _objarray_stack.clear(true);
-  _revisit_klass_stack.clear(true);
-  _revisit_mdo_stack.clear(true);
 }
 
 void PSMarkSweep::mark_sweep_phase1(bool clear_all_softrefs) {
@@ -502,6 +487,9 @@
   ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
   assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
 
+  // Need to clear claim bits before the tracing starts.
+  ClassLoaderDataGraph::clear_claimed_marks();
+
   // General strong roots.
   {
     ParallelScavengeHeap::ParStrongRootsScope psrs;
@@ -514,6 +502,7 @@
     Management::oops_do(mark_and_push_closure());
     JvmtiExport::oops_do(mark_and_push_closure());
     SystemDictionary::always_strong_oops_do(mark_and_push_closure());
+    ClassLoaderDataGraph::always_strong_oops_do(mark_and_push_closure(), follow_klass_closure(), true);
     // Do not treat nmethods as strong roots for mark/sweep, since we can unload them.
     //CodeCache::scavenge_root_nmethods_do(CodeBlobToOopClosure(mark_and_push_closure()));
   }
@@ -537,11 +526,7 @@
   follow_stack(); // Flush marking stack
 
   // Update subklass/sibling/implementor links of live klasses
-  follow_weak_klass_links();
-  assert(_marking_stack.is_empty(), "just drained");
-
-  // Visit memoized mdo's and clear unmarked weak refs
-  follow_mdo_weak_refs();
+  Klass::clean_weak_klass_links(&is_alive);
   assert(_marking_stack.is_empty(), "just drained");
 
   // Visit interned string tables and delete unmarked oops
@@ -559,13 +544,6 @@
 
   // Now all live objects are marked, compute the new object addresses.
 
-  // It is imperative that we traverse perm_gen LAST. If dead space is
-  // allowed a range of dead object may get overwritten by a dead int
-  // array. If perm_gen is not traversed last a klassOop may get
-  // overwritten. This is fine since it is dead, but if the class has dead
-  // instances we have to skip them, and in order to find their size we
-  // need the klassOop!
-  //
   // It is not required that we traverse spaces in the same order in
   // phase2, phase3 and phase4, but the ValidateMarkSweep live oops
   // tracking expects us to do so. See comment under phase4.
@@ -574,18 +552,12 @@
   assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
 
   PSOldGen* old_gen = heap->old_gen();
-  PSPermGen* perm_gen = heap->perm_gen();
 
   // Begin compacting into the old gen
   PSMarkSweepDecorator::set_destination_decorator_tenured();
 
   // This will also compact the young gen spaces.
   old_gen->precompact();
-
-  // Compact the perm gen into the perm gen
-  PSMarkSweepDecorator::set_destination_decorator_perm_gen();
-
-  perm_gen->precompact();
 }
 
 // This should be moved to the shared markSweep code!
@@ -606,7 +578,9 @@
 
   PSYoungGen* young_gen = heap->young_gen();
   PSOldGen* old_gen = heap->old_gen();
-  PSPermGen* perm_gen = heap->perm_gen();
+
+  // Need to clear claim bits before the tracing starts.
+  ClassLoaderDataGraph::clear_claimed_marks();
 
   // General strong roots.
   Universe::oops_do(adjust_root_pointer_closure());
@@ -618,6 +592,7 @@
   JvmtiExport::oops_do(adjust_root_pointer_closure());
   // SO_AllClasses
   SystemDictionary::oops_do(adjust_root_pointer_closure());
+  ClassLoaderDataGraph::oops_do(adjust_root_pointer_closure(), adjust_klass_closure(), true);
   //CodeCache::scavenge_root_nmethods_oops_do(adjust_root_pointer_closure());
 
   // Now adjust pointers in remaining weak roots.  (All of which should
@@ -634,7 +609,6 @@
 
   young_gen->adjust_pointers();
   old_gen->adjust_pointers();
-  perm_gen->adjust_pointers();
 }
 
 void PSMarkSweep::mark_sweep_phase4() {
@@ -644,18 +618,12 @@
 
   // All pointers are now adjusted, move objects accordingly
 
-  // It is imperative that we traverse perm_gen first in phase4. All
-  // classes must be allocated earlier than their instances, and traversing
-  // perm_gen first makes sure that all klassOops have moved to their new
-  // location before any instance does a dispatch through it's klass!
   ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
   assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
 
   PSYoungGen* young_gen = heap->young_gen();
   PSOldGen* old_gen = heap->old_gen();
-  PSPermGen* perm_gen = heap->perm_gen();
 
-  perm_gen->compact();
   old_gen->compact();
   young_gen->compact();
 }