src/share/vm/gc_implementation/g1/heapRegion.cpp

Print this page
rev 4801 : imported patch code-movement
rev 4802 : imported patch optimize-nmethod-scanning
rev 4803 : imported patch thomas-comments-2

@@ -21,20 +21,20 @@
  * questions.
  *
  */
 
 #include "precompiled.hpp"
+#include "code/nmethod.hpp"
 #include "gc_implementation/g1/g1BlockOffsetTable.inline.hpp"
 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
 #include "gc_implementation/g1/g1OopClosures.inline.hpp"
 #include "gc_implementation/g1/heapRegion.inline.hpp"
 #include "gc_implementation/g1/heapRegionRemSet.hpp"
 #include "gc_implementation/g1/heapRegionSeq.inline.hpp"
 #include "memory/genOopClosures.inline.hpp"
 #include "memory/iterator.hpp"
 #include "oops/oop.inline.hpp"
-#include "utilities/growableArray.hpp"
 
 int    HeapRegion::LogOfHRGrainBytes = 0;
 int    HeapRegion::LogOfHRGrainWords = 0;
 size_t HeapRegion::GrainBytes        = 0;
 size_t HeapRegion::GrainWords        = 0;

@@ -224,24 +224,17 @@
   reset_pre_dummy_top();
 
   if (!par) {
     // If this is parallel, this will be done later.
     HeapRegionRemSet* hrrs = rem_set();
-    if (hrrs != NULL) hrrs->clear();
+    hrrs->clear();
     _claimed = InitialClaimValue;
   }
   zero_marked_bytes();
 
   _offsets.resize(HeapRegion::GrainWords);
   init_top_at_mark_start();
-
-  if (_strong_code_root_list != NULL) {
-    delete _strong_code_root_list;
-  }
-  _strong_code_root_list = new (ResourceObj::C_HEAP, mtGC)
-                                GrowableArray<nmethod*>(10, 0, NULL, true);
-
   if (clear_space) clear(SpaceDecorator::Mangle);
 }
 
 void HeapRegion::par_clear() {
   assert(used() == 0, "the region should have been already cleared");

@@ -366,21 +359,20 @@
 #ifdef ASSERT
     _containing_set(NULL),
 #endif // ASSERT
      _young_index_in_cset(-1), _surv_rate_group(NULL), _age_index(-1),
     _rem_set(NULL), _recorded_rs_length(0), _predicted_elapsed_time_ms(0),
-    _predicted_bytes_to_copy(0), _strong_code_root_list(NULL)
+    _predicted_bytes_to_copy(0)
 {
+  _rem_set = new HeapRegionRemSet(sharedOffsetArray, this);
   _orig_end = mr.end();
   // Note that initialize() will set the start of the unmarked area of the
   // region.
   hr_clear(false /*par*/, false /*clear_space*/);
   set_top(bottom());
   set_saved_mark();
 
-  _rem_set =  new HeapRegionRemSet(sharedOffsetArray, this);
-
   assert(HeapRegionRemSet::num_par_rem_sets() > 0, "Invariant.");
 }
 
 CompactibleSpace* HeapRegion::next_compaction_space() const {
   // We're not using an iterator given that it will wrap around when

@@ -599,115 +591,30 @@
 }
 
 // Code roots support
 
 void HeapRegion::add_strong_code_root(nmethod* nm) {
-  assert(nm != NULL, "sanity");
-  // Search for the code blob from the RHS to avoid
-  // duplicate entries as much as possible
-  if (_strong_code_root_list->find_from_end(nm) < 0) {
-    // Code blob isn't already in the list
-    _strong_code_root_list->push(nm);
-  }
+  HeapRegionRemSet* hrrs = rem_set();
+  hrrs->add_strong_code_root(nm);
 }
 
 void HeapRegion::remove_strong_code_root(nmethod* nm) {
-  assert(nm != NULL, "sanity");
-  int idx = _strong_code_root_list->find(nm);
-  while (idx >= 0) {
-    _strong_code_root_list->remove_at(idx);
-    idx = _strong_code_root_list->find(nm);
-  }
+  HeapRegionRemSet* hrrs = rem_set();
+  hrrs->remove_strong_code_root(nm);
 }
 
-class NMethodMigrationOopClosure : public OopClosure {
-  G1CollectedHeap* _g1h;
-  HeapRegion* _from;
-  nmethod* _nm;
-
-  uint _num_self_forwarded;
-
-  template <class T> void do_oop_work(T* p) {
-    T heap_oop = oopDesc::load_heap_oop(p);
-    if (!oopDesc::is_null(heap_oop)) {
-      oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
-      if (_from->is_in(obj)) {
-        // Reference still points into the source region.
-        // Since roots are immediately evacuated this means that
-        // we must have self forwarded the object
-        assert(obj->is_forwarded(),
-               err_msg("code roots should be immediately evacuated. "
-                       "Ref: "PTR_FORMAT", "
-                       "Obj: "PTR_FORMAT", "
-                       "Region: "HR_FORMAT,
-                       p, (void*) obj, HR_FORMAT_PARAMS(_from)));
-        assert(obj->forwardee() == obj,
-               err_msg("not self forwarded? obj = "PTR_FORMAT, (void*)obj));
-
-        // The object has been self forwarded.
-        // Note, if we're during an initial mark pause, there is
-        // no need to explicitly mark object. It will be marked
-        // during the regular evacuation failure handling code.
-        _num_self_forwarded++;
-      } else {
-        // The reference points into a promotion or to-space region
-        HeapRegion* to = _g1h->heap_region_containing(obj);
-        to->add_strong_code_root(_nm);
-      }
-    }
-  }
-
-public:
-  NMethodMigrationOopClosure(G1CollectedHeap* g1h, HeapRegion* from, nmethod* nm):
-    _g1h(g1h), _from(from), _nm(nm), _num_self_forwarded(0) {}
-
-  void do_oop(narrowOop* p) { do_oop_work(p); }
-  void do_oop(oop* p)       { do_oop_work(p); }
-
-  uint retain() { return _num_self_forwarded > 0; }
-};
-
 void HeapRegion::migrate_strong_code_roots() {
   assert(in_collection_set(), "only collection set regions");
   assert(!isHumongous(), "not humongous regions");
 
-  ResourceMark rm;
-
-  // List of code blobs to retain for this region
-  GrowableArray<nmethod*> to_be_retained(10);
-  G1CollectedHeap* g1h = G1CollectedHeap::heap();
-
-  while (strong_code_root_list()->is_nonempty()) {
-    nmethod *nm = strong_code_root_list()->pop();
-    if (nm != NULL) {
-      NMethodMigrationOopClosure oop_cl(g1h, this, nm);
-      nm->oops_do(&oop_cl);
-      if (oop_cl.retain()) {
-        to_be_retained.push(nm);
-      }
-    }
-  }
-
-  // Now push any code roots we need to retain
-  // FIXME: assert that region got an evacuation failure if non-empty
-  while (to_be_retained.is_nonempty()) {
-    nmethod* nm = to_be_retained.pop();
-    assert(nm != NULL, "sanity");
-    add_strong_code_root(nm);
-  }
+  HeapRegionRemSet* hrrs = rem_set();
+  hrrs->migrate_strong_code_roots();
 }
 
 void HeapRegion::strong_code_roots_do(CodeBlobClosure* blk) const {
-  for (int i = 0; i < _strong_code_root_list->length(); i += 1) {
-    nmethod* nm = _strong_code_root_list->at(i);
-    blk->do_code_blob(nm);
-  }
-}
-
-size_t HeapRegion::strong_code_root_mem_size() {
-  return sizeof(GrowableArray<nmethod*>) +
-         _strong_code_root_list->max_length() * sizeof(nmethod*);
+  HeapRegionRemSet* hrrs = rem_set();
+  hrrs->strong_code_roots_do(blk);
 }
 
 class VerifyStrongCodeRootOopClosure: public OopClosure {
   const HeapRegion* _hr;
   nmethod* _nm;

@@ -801,28 +708,31 @@
     // time.
     assert(VerifyDuringGC, "only way to get here");
     return;
   }
 
+  HeapRegionRemSet* hrrs = rem_set();
+  int strong_code_roots_length = hrrs->strong_code_roots_list_length();
+
   // if this region is empty then there should be no entries
   // on its strong code root list
   if (is_empty()) {
-    if (!_strong_code_root_list->is_empty()) {
+    if (strong_code_roots_length > 0) {
       gclog_or_tty->print_cr("region ["PTR_FORMAT","PTR_FORMAT"] is empty "
                              "but has "INT32_FORMAT" code root entries",
-                             bottom(), end(), _strong_code_root_list->length());
+                             bottom(), end(), strong_code_roots_length);
       *failures = true;
     }
     return;
   }
 
   // An H-region should have an empty strong code root list
   if (isHumongous()) {
-    if (!_strong_code_root_list->is_empty()) {
+    if (strong_code_roots_length > 0) {
       gclog_or_tty->print_cr("region ["PTR_FORMAT","PTR_FORMAT"] is humongous "
                              "but has "INT32_FORMAT" code root entries",
-                             bottom(), end(), _strong_code_root_list->length());
+                             bottom(), end(), strong_code_roots_length);
       *failures = true;
     }
     return;
   }