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

Print this page
rev 6626 : imported patch 8035400-move-g1parscanthreadstate-into-own-files
rev 6627 : imported patch 8035400-2-bengt-fixes
rev 6628 : imported patch 8035401-fix-visibility-of-g1parscanthreadstate
rev 6629 : imported patch 8035401-3-fix-constructor
rev 6630 : imported patch 8035401-2-another-inline-try

@@ -67,10 +67,15 @@
   _alloc_buffers[GCAllocForTenured]  = &_tenured_alloc_buffer;
 
   _start = os::elapsedTime();
 }
 
+G1ParScanThreadState::~G1ParScanThreadState() {
+  retire_alloc_buffers();
+  FREE_C_HEAP_ARRAY(size_t, _surviving_young_words_base, mtGC);
+}
+
 void
 G1ParScanThreadState::print_termination_stats_hdr(outputStream* const st)
 {
   st->print_raw_cr("GC Termination Stats");
   st->print_raw_cr("     elapsed  --strong roots-- -------termination-------"

@@ -138,32 +143,19 @@
 
   StarTask ref;
   do {
     // Drain the overflow stack first, so other threads can steal.
     while (_refs->pop_overflow(ref)) {
-      deal_with_reference(ref);
+      dispatch_reference(ref);
     }
 
     while (_refs->pop_local(ref)) {
-      deal_with_reference(ref);
+      dispatch_reference(ref);
     }
   } while (!_refs->is_empty());
 }
 
-void G1ParScanThreadState::steal_and_trim_queue(RefToScanQueueSet *task_queues) {
-  StarTask stolen_task;
-  while (task_queues->steal(queue_num(), hash_seed(), stolen_task)) {
-    assert(verify_task(stolen_task), "sanity");
-    deal_with_reference(stolen_task);
-
-    // We've just processed a reference and we might have made
-    // available new entries on the queues. So we have to make sure
-    // we drain the queues as necessary.
-    trim_queue();
-  }
-}
-
 oop G1ParScanThreadState::copy_to_survivor_space(oop const old) {
   size_t word_sz = old->size();
   HeapRegion* from_region = _g1h->heap_region_containing_raw(old);
   // +1 to make the -1 indexes valid...
   int       young_index = from_region->young_index_in_cset()+1;

@@ -313,99 +305,5 @@
     _alloc_buffers[ap]->flush_stats_and_retire(_g1h->stats_for_purpose((GCAllocPurpose)ap),
                                                true /* end_of_gc */,
                                                false /* retain */);
   }
 }
-
-template <class T> void G1ParScanThreadState::do_oop_evac(T* p, HeapRegion* from) {
-  assert(!oopDesc::is_null(oopDesc::load_decode_heap_oop(p)),
-         "Reference should not be NULL here as such are never pushed to the task queue.");
-  oop obj = oopDesc::load_decode_heap_oop_not_null(p);
-
-  // Although we never intentionally push references outside of the collection
-  // set, due to (benign) races in the claim mechanism during RSet scanning more
-  // than one thread might claim the same card. So the same card may be
-  // processed multiple times. So redo this check.
-  if (_g1h->in_cset_fast_test(obj)) {
-    oop forwardee;
-    if (obj->is_forwarded()) {
-      forwardee = obj->forwardee();
-    } else {
-      forwardee = copy_to_survivor_space(obj);
-    }
-    assert(forwardee != NULL, "forwardee should not be NULL");
-    oopDesc::encode_store_heap_oop(p, forwardee);
-  }
-
-  assert(obj != NULL, "Must be");
-  update_rs(from, p, queue_num());
-}
-
-inline void G1ParScanThreadState::do_oop_partial_array(oop* p) {
-  assert(has_partial_array_mask(p), "invariant");
-  oop from_obj = clear_partial_array_mask(p);
-
-  assert(Universe::heap()->is_in_reserved(from_obj), "must be in heap.");
-  assert(from_obj->is_objArray(), "must be obj array");
-  objArrayOop from_obj_array = objArrayOop(from_obj);
-  // The from-space object contains the real length.
-  int length                 = from_obj_array->length();
-
-  assert(from_obj->is_forwarded(), "must be forwarded");
-  oop to_obj                 = from_obj->forwardee();
-  assert(from_obj != to_obj, "should not be chunking self-forwarded objects");
-  objArrayOop to_obj_array   = objArrayOop(to_obj);
-  // We keep track of the next start index in the length field of the
-  // to-space object.
-  int next_index             = to_obj_array->length();
-  assert(0 <= next_index && next_index < length,
-         err_msg("invariant, next index: %d, length: %d", next_index, length));
-
-  int start                  = next_index;
-  int end                    = length;
-  int remainder              = end - start;
-  // We'll try not to push a range that's smaller than ParGCArrayScanChunk.
-  if (remainder > 2 * ParGCArrayScanChunk) {
-    end = start + ParGCArrayScanChunk;
-    to_obj_array->set_length(end);
-    // Push the remainder before we process the range in case another
-    // worker has run out of things to do and can steal it.
-    oop* from_obj_p = set_partial_array_mask(from_obj);
-    push_on_queue(from_obj_p);
-  } else {
-    assert(length == end, "sanity");
-    // We'll process the final range for this object. Restore the length
-    // so that the heap remains parsable in case of evacuation failure.
-    to_obj_array->set_length(end);
-  }
-  _scanner.set_region(_g1h->heap_region_containing_raw(to_obj));
-  // Process indexes [start,end). It will also process the header
-  // along with the first chunk (i.e., the chunk with start == 0).
-  // Note that at this point the length field of to_obj_array is not
-  // correct given that we are using it to keep track of the next
-  // start index. oop_iterate_range() (thankfully!) ignores the length
-  // field and only relies on the start / end parameters.  It does
-  // however return the size of the object which will be incorrect. So
-  // we have to ignore it even if we wanted to use it.
-  to_obj_array->oop_iterate_range(&_scanner, start, end);
-}
-
-template <class T> inline void G1ParScanThreadState::deal_with_reference(T* ref_to_scan) {
-  if (!has_partial_array_mask(ref_to_scan)) {
-    // Note: we can use "raw" versions of "region_containing" because
-    // "obj_to_scan" is definitely in the heap, and is not in a
-    // humongous region.
-    HeapRegion* r = _g1h->heap_region_containing_raw(ref_to_scan);
-    do_oop_evac(ref_to_scan, r);
-  } else {
-    do_oop_partial_array((oop*)ref_to_scan);
-  }
-}
-
-inline void G1ParScanThreadState::deal_with_reference(StarTask ref) {
-  assert(verify_task(ref), "sanity");
-  if (ref.is_narrow()) {
-    deal_with_reference((narrowOop*)ref);
-  } else {
-    deal_with_reference((oop*)ref);
-  }
-}