void do_oop_work(T* p) {
   _work->do_oop(p);
   T oop_or_narrowoop = oopDesc::load_heap_oop(p);
   if (!oopDesc::is_null(oop_or_narrowoop)) {
     oop o = oopDesc::decode_heap_oop_not_null(oop_or_narrowoop);
     HeapRegion* hr = _g1h->heap_region_containing_raw(o);
     assert(!_g1h->obj_in_cs(o) || hr->rem_set()->strong_code_roots_list_contains(_nm), "if o still in CS then evacuation failed and nm must already be in the remset");
     hr->add_strong_code_root(_nm);
   }
 }
Exemple #2
0
 ScanRSClosure(OopsInHeapRegionClosure* oc, int worker_i) :
   _oc(oc),
   _cards(0),
   _cards_done(0),
   _worker_i(worker_i),
   _try_claimed(false)
 {
   _g1h = G1CollectedHeap::heap();
   _bot_shared = _g1h->bot_shared();
   _ct_bs = (CardTableModRefBS*) (_g1h->barrier_set());
   _block_size = MAX2<int>(G1RSetScanBlockSize, 1);
 }
  bool doHeapRegion(HeapRegion* r) {
    assert(r->in_collection_set(), "should only be called on elements of CS.");
    HeapRegionRemSet* hrrs = r->rem_set();
    if (hrrs->iter_is_complete()) return false; // All done.
    if (!_try_claimed && !hrrs->claim_iter()) return false;
    // If we ever free the collection set concurrently, we should also
    // clear the card table concurrently therefore we won't need to
    // add regions of the collection set to the dirty cards region.
    _g1h->push_dirty_cards_region(r);
    // If we didn't return above, then
    //   _try_claimed || r->claim_iter()
    // is true: either we're supposed to work on claimed-but-not-complete
    // regions, or we successfully claimed the region.

    HeapRegionRemSetIterator iter(hrrs);
    size_t card_index;

    // We claim cards in block so as to reduce the contention. The block size is determined by
    // the G1RSetScanBlockSize parameter.
    size_t jump_to_card = hrrs->iter_claimed_next(_block_size);
    for (size_t current_card = 0; iter.has_next(card_index); current_card++) {
      if (current_card >= jump_to_card + _block_size) {
        jump_to_card = hrrs->iter_claimed_next(_block_size);
      }
      if (current_card < jump_to_card) continue;
      HeapWord* card_start = _g1h->bot_shared()->address_for_index(card_index);
#if 0
      gclog_or_tty->print("Rem set iteration yielded card [" PTR_FORMAT ", " PTR_FORMAT ").\n",
                          card_start, card_start + CardTableModRefBS::card_size_in_words);
#endif

      HeapRegion* card_region = _g1h->heap_region_containing(card_start);
      _cards++;

      if (!card_region->is_on_dirty_cards_region_list()) {
        _g1h->push_dirty_cards_region(card_region);
      }

      // If the card is dirty, then we will scan it during updateRS.
      if (!card_region->in_collection_set() &&
          !_ct_bs->is_card_dirty(card_index)) {
        scanCard(card_index, card_region);
      }
    }
    if (!_try_claimed) {
      // Scan the strong code root list attached to the current region
      scan_strong_code_roots(r);

      hrrs->set_iter_complete();
    }
    return false;
  }
Exemple #4
0
  bool doHeapRegion(HeapRegion* r) {
    assert(r->in_collection_set(), "should only be called on elements of CS.");
    HeapRegionRemSet* hrrs = r->rem_set();
    if (hrrs->iter_is_complete()) return false; // All done.
    if (!_try_claimed && !hrrs->claim_iter()) return false;
    _g1h->push_dirty_cards_region(r);
    // If we didn't return above, then
    //   _try_claimed || r->claim_iter()
    // is true: either we're supposed to work on claimed-but-not-complete
    // regions, or we successfully claimed the region.
    HeapRegionRemSetIterator* iter = _g1h->rem_set_iterator(_worker_i);
    hrrs->init_iterator(iter);
    size_t card_index;

    // We claim cards in block so as to recude the contention. The block size is determined by
    // the G1RSetScanBlockSize parameter.
    size_t jump_to_card = hrrs->iter_claimed_next(_block_size);
    for (size_t current_card = 0; iter->has_next(card_index); current_card++) {
      if (current_card >= jump_to_card + _block_size) {
        jump_to_card = hrrs->iter_claimed_next(_block_size);
      }
      if (current_card < jump_to_card) continue;
      HeapWord* card_start = _g1h->bot_shared()->address_for_index(card_index);
#if 0
      gclog_or_tty->print("Rem set iteration yielded card [" PTR_FORMAT ", " PTR_FORMAT ").\n",
                          card_start, card_start + CardTableModRefBS::card_size_in_words);
#endif

      HeapRegion* card_region = _g1h->heap_region_containing(card_start);
      assert(card_region != NULL, "Yielding cards not in the heap?");
      _cards++;

      if (!card_region->is_on_dirty_cards_region_list()) {
        _g1h->push_dirty_cards_region(card_region);
      }

       // If the card is dirty, then we will scan it during updateRS.
      if (!card_region->in_collection_set() && !_ct_bs->is_card_dirty(card_index)) {
        // We make the card as "claimed" lazily (so races are possible but they're benign),
        // which reduces the number of duplicate scans (the rsets of the regions in the cset
        // can intersect).
        if (!_ct_bs->is_card_claimed(card_index)) {
          _ct_bs->set_card_claimed(card_index);
          scanCard(card_index, card_region);
        }
      }
    }
    if (!_try_claimed) {
      hrrs->set_iter_complete();
    }
    return false;
  }
 ScanRSClosure(G1ParPushHeapRSClosure* oc,
               CodeBlobClosure* code_root_cl,
               uint worker_i) :
   _oc(oc),
   _code_root_cl(code_root_cl),
   _strong_code_root_scan_time_sec(0.0),
   _cards(0),
   _cards_done(0),
   _worker_i(worker_i),
   _try_claimed(false)
 {
   _g1h = G1CollectedHeap::heap();
   _bot_shared = _g1h->bot_shared();
   _ct_bs = _g1h->g1_barrier_set();
   _block_size = MAX2<int>(G1RSetScanBlockSize, 1);
 }
Exemple #6
0
 // use_prev_marking == true  -> use "prev" marking information,
 // use_prev_marking == false -> use "next" marking information
 VerifyLiveClosure(G1CollectedHeap* g1h, bool use_prev_marking) :
   _g1h(g1h), _bs(NULL), _containing_obj(NULL),
   _failures(false), _n_failures(0), _use_prev_marking(use_prev_marking)
 {
   BarrierSet* bs = _g1h->barrier_set();
   if (bs->is_a(BarrierSet::CardTableModRef))
     _bs = (CardTableModRefBS*)bs;
 }
 // _vo == UsePrevMarking -> use "prev" marking information,
 // _vo == UseNextMarking -> use "next" marking information,
 // _vo == UseMarkWord    -> use mark word from object header.
 VerifyLiveClosure(G1CollectedHeap* g1h, VerifyOption vo) :
   _g1h(g1h), _bs(NULL), _containing_obj(NULL),
   _failures(false), _n_failures(0), _vo(vo)
 {
   BarrierSet* bs = _g1h->barrier_set();
   if (bs->is_a(BarrierSet::CardTableModRef))
     _bs = (CardTableModRefBS*)bs;
 }
Exemple #8
0
 ScrubRSClosure(BitMap* region_bm, BitMap* card_bm) :
   _g1h(G1CollectedHeap::heap()),
   _region_bm(region_bm), _card_bm(card_bm),
   _ctbs(NULL)
 {
   ModRefBarrierSet* bs = _g1h->mr_bs();
   guarantee(bs->is_a(BarrierSet::CardTableModRef), "Precondition");
   _ctbs = (CardTableModRefBS*)bs;
 }
Exemple #9
0
 template <class T> void do_oop_work(T* p) {
   oop obj = oopDesc::load_decode_heap_oop(p);
   if (_g1->obj_in_cs(obj)) {
     size_t card_index = _ct_bs->index_for(p);
     if (_ct_bs->mark_card_deferred(card_index)) {
       _dcq->enqueue((jbyte*)_ct_bs->byte_for_index(card_index));
     }
   }
 }
Exemple #10
0
 void update_sets() {
     // We'll recalculate total used bytes and recreate the free list
     // at the end of the GC, so no point in updating those values here.
     _g1h->update_sets_after_freeing_regions(0, /* pre_used */
                                             NULL, /* free_list */
                                             NULL, /* old_proxy_set */
                                             &_humongous_proxy_set,
                                             false /* par */);
 }
  bool doHeapRegion(HeapRegion *hr) {
    bool during_initial_mark = _g1h->g1_policy()->during_initial_mark_pause();
    bool during_conc_mark = _g1h->mark_in_progress();

    assert(!hr->isHumongous(), "sanity");
    assert(hr->in_collection_set(), "bad CS");

    if (hr->claimHeapRegion(HeapRegion::ParEvacFailureClaimValue)) {
      if (hr->evacuation_failed()) {
        RemoveSelfForwardPtrObjClosure rspc(_g1h, _cm, hr, &_update_rset_cl,
                                            during_initial_mark,
                                            during_conc_mark,
                                            _worker_id);

        hr->note_self_forwarding_removal_start(during_initial_mark,
                                               during_conc_mark);
        _g1h->check_bitmaps("Self-Forwarding Ptr Removal", hr);

        // In the common case (i.e. when there is no evacuation
        // failure) we make sure that the following is done when
        // the region is freed so that it is "ready-to-go" when it's
        // re-allocated. However, when evacuation failure happens, a
        // region will remain in the heap and might ultimately be added
        // to a CSet in the future. So we have to be careful here and
        // make sure the region's RSet is ready for parallel iteration
        // whenever this might be required in the future.
        hr->rem_set()->reset_for_par_iteration();
        hr->reset_bot();
        _update_rset_cl.set_region(hr);
        hr->object_iterate(&rspc);

        hr->rem_set()->clean_strong_code_roots(hr);

        hr->note_self_forwarding_removal_end(during_initial_mark,
                                             during_conc_mark,
                                             rspc.marked_bytes());
      }
    }
    return false;
  }
Exemple #12
0
  bool do_card_ptr(jbyte* card_ptr, int worker_i) {
    // Construct the region representing the card.
    HeapWord* start = _ct_bs->addr_for(card_ptr);
    // And find the region containing it.
    HeapRegion* r = _g1->heap_region_containing(start);
    assert(r != NULL, "unexpected null");

    // Scan oops in the card looking for references into the collection set
    HeapWord* end   = _ct_bs->addr_for(card_ptr + 1);
    MemRegion scanRegion(start, end);

    UpdateRSetImmediate update_rs_cl(_g1->g1_rem_set());
    FilterIntoCSClosure update_rs_cset_oop_cl(NULL, _g1, &update_rs_cl);
    FilterOutOfRegionClosure filter_then_update_rs_cset_oop_cl(r, &update_rs_cset_oop_cl);

    // We can pass false as the "filter_young" parameter here as:
    // * we should be in a STW pause,
    // * the DCQS to which this closure is applied is used to hold
    //   references that point into the collection set from the prior
    //   RSet updating,
    // * the post-write barrier shouldn't be logging updates to young
    //   regions (but there is a situation where this can happen - see
    //   the comment in G1RemSet::concurrentRefineOneCard below -
    //   that should not be applicable here), and
    // * during actual RSet updating, the filtering of cards in young
    //   regions in HeapRegion::oops_on_card_seq_iterate_careful is
    //   employed.
    // As a result, when this closure is applied to "refs into cset"
    // DCQS, we shouldn't see any cards in young regions.
    update_rs_cl.set_region(r);
    HeapWord* stop_point =
      r->oops_on_card_seq_iterate_careful(scanRegion,
                                        &filter_then_update_rs_cset_oop_cl,
                                        false /* filter_young */);

    // Since this is performed in the event of an evacuation failure, we
    // we shouldn't see a non-null stop point
    assert(stop_point == NULL, "saw an unallocated region");
    return true;
  }
Exemple #13
0
    void free_humongous_region(HeapRegion* hr) {
        HeapWord* end = hr->end();
        size_t dummy_pre_used;
        FreeRegionList dummy_free_list("Dummy Free List for G1MarkSweep");

        assert(hr->startsHumongous(),
               "Only the start of a humongous region should be freed.");
        _g1h->free_humongous_region(hr, &dummy_pre_used, &dummy_free_list,
                                    &_humongous_proxy_set, false /* par */);
        hr->prepare_for_compaction(&_cp);
        // Also clear the part of the card table that will be unused after
        // compaction.
        _mrbs->clear(MemRegion(hr->compaction_top(), end));
        dummy_free_list.remove_all();
    }
 ScrubRSClosure(BitMap* region_bm, BitMap* card_bm) :
   _g1h(G1CollectedHeap::heap()),
   _region_bm(region_bm), _card_bm(card_bm),
   _ctbs(_g1h->g1_barrier_set()) {}
 UpdateRSetDeferred(G1CollectedHeap* g1, DirtyCardQueue* dcq) :
   _g1(g1), _ct_bs(_g1->g1_barrier_set()), _dcq(dcq) {}
  void work(uint worker_id) {
    RemoveSelfForwardPtrHRClosure rsfp_cl(_g1h, worker_id);

    HeapRegion* hr = _g1h->start_cset_region_for_worker(worker_id);
    _g1h->collection_set_iterate_from(hr, &rsfp_cl);
  }
 RemoveSelfForwardPtrHRClosure(G1CollectedHeap* g1h,
                               uint worker_id) :
   _g1h(g1h), _dcq(&g1h->dirty_card_queue_set()), _update_rset_cl(g1h, &_dcq),
   _worker_id(worker_id), _cm(_g1h->concurrent_mark()) {
   }
 G1PrepareCompactClosure() :
   _g1h(G1CollectedHeap::heap()),
   _mrbs(_g1h->g1_barrier_set()),
   _humongous_regions_removed() { }
Exemple #19
0
 template <class T> void do_oop_work(T* p) {
   HeapRegion* to = _g1->heap_region_containing(oopDesc::load_decode_heap_oop(p));
   if (to->in_collection_set()) {
     to->rem_set()->add_reference(p, 0);
   }
 }
 G1PrepareCompactClosure(CompactibleSpace* cs)
 : _g1h(G1CollectedHeap::heap()),
   _mrbs(_g1h->g1_barrier_set()),
   _cp(NULL, cs, cs->initialize_threshold()),
   _humongous_proxy_set("G1MarkSweep Humongous Proxy Set") { }
Exemple #21
0
 template <class T> void do_oop_work(T* p) {
   oop obj = oopDesc::load_decode_heap_oop(p);
   HeapRegion* to = _g1->heap_region_containing(obj);
   guarantee(to == NULL || !to->in_collection_set(),
             "Missed a rem set member.");
 }
Exemple #22
0
 UpdateRSetOopsIntoCSDeferred(G1CollectedHeap* g1, DirtyCardQueue* dcq) :
   _g1(g1), _ct_bs((CardTableModRefBS*)_g1->barrier_set()), _dcq(dcq) { }
 bool is_young_list_full() {
   uint young_list_length = _g1->young_list()->length();
   uint young_list_target_length = _young_list_target_length;
   return young_list_length >= young_list_target_length;
 }
 bool can_expand_young_list() {
   uint young_list_length = _g1->young_list()->length();
   uint young_list_max_length = _young_list_max_length;
   return young_list_length < young_list_max_length;
 }
Exemple #25
0
 // Set all cards back to clean.
 void cleanup() {_g1h->cleanUpCardTable();}
Exemple #26
0
  template <class T> void do_oop_work(T* p) {
    assert(_containing_obj != NULL, "Precondition");
    assert(!_g1h->is_obj_dead_cond(_containing_obj, _use_prev_marking),
           "Precondition");
    T heap_oop = oopDesc::load_heap_oop(p);
    if (!oopDesc::is_null(heap_oop)) {
      oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
      bool failed = false;
      if (!_g1h->is_in_closed_subset(obj) ||
          _g1h->is_obj_dead_cond(obj, _use_prev_marking)) {
        if (!_failures) {
          gclog_or_tty->print_cr("");
          gclog_or_tty->print_cr("----------");
        }
        if (!_g1h->is_in_closed_subset(obj)) {
          HeapRegion* from = _g1h->heap_region_containing((HeapWord*)p);
          gclog_or_tty->print_cr("Field "PTR_FORMAT
                                 " of live obj "PTR_FORMAT" in region "
                                 "["PTR_FORMAT", "PTR_FORMAT")",
                                 p, (void*) _containing_obj,
                                 from->bottom(), from->end());
          print_object(gclog_or_tty, _containing_obj);
          gclog_or_tty->print_cr("points to obj "PTR_FORMAT" not in the heap",
                                 (void*) obj);
        } else {
          HeapRegion* from = _g1h->heap_region_containing((HeapWord*)p);
          HeapRegion* to   = _g1h->heap_region_containing((HeapWord*)obj);
          gclog_or_tty->print_cr("Field "PTR_FORMAT
                                 " of live obj "PTR_FORMAT" in region "
                                 "["PTR_FORMAT", "PTR_FORMAT")",
                                 p, (void*) _containing_obj,
                                 from->bottom(), from->end());
          print_object(gclog_or_tty, _containing_obj);
          gclog_or_tty->print_cr("points to dead obj "PTR_FORMAT" in region "
                                 "["PTR_FORMAT", "PTR_FORMAT")",
                                 (void*) obj, to->bottom(), to->end());
          print_object(gclog_or_tty, obj);
        }
        gclog_or_tty->print_cr("----------");
        _failures = true;
        failed = true;
        _n_failures++;
      }

      if (!_g1h->full_collection()) {
        HeapRegion* from = _g1h->heap_region_containing((HeapWord*)p);
        HeapRegion* to   = _g1h->heap_region_containing(obj);
        if (from != NULL && to != NULL &&
            from != to &&
            !to->isHumongous()) {
          jbyte cv_obj = *_bs->byte_for_const(_containing_obj);
          jbyte cv_field = *_bs->byte_for_const(p);
          const jbyte dirty = CardTableModRefBS::dirty_card_val();

          bool is_bad = !(from->is_young()
                          || to->rem_set()->contains_reference(p)
                          || !G1HRRSFlushLogBuffersOnVerify && // buffers were not flushed
                              (_containing_obj->is_objArray() ?
                                  cv_field == dirty
                               : cv_obj == dirty || cv_field == dirty));
          if (is_bad) {
            if (!_failures) {
              gclog_or_tty->print_cr("");
              gclog_or_tty->print_cr("----------");
            }
            gclog_or_tty->print_cr("Missing rem set entry:");
            gclog_or_tty->print_cr("Field "PTR_FORMAT
                          " of obj "PTR_FORMAT
                          ", in region %d ["PTR_FORMAT
                          ", "PTR_FORMAT"),",
                          p, (void*) _containing_obj,
                          from->hrs_index(),
                          from->bottom(),
                          from->end());
            _containing_obj->print_on(gclog_or_tty);
            gclog_or_tty->print_cr("points to obj "PTR_FORMAT
                          " in region %d ["PTR_FORMAT
                          ", "PTR_FORMAT").",
                          (void*) obj, to->hrs_index(),
                          to->bottom(), to->end());
            obj->print_on(gclog_or_tty);
            gclog_or_tty->print_cr("Obj head CTE = %d, field CTE = %d.",
                          cv_obj, cv_field);
            gclog_or_tty->print_cr("----------");
            _failures = true;
            if (!failed) _n_failures++;
          }
        }
      }
    }
  }
Exemple #27
0
 template <class T> void do_oop_work(T* p) {
   oop obj = oopDesc::load_decode_heap_oop(p);
   if (_g1->obj_in_cs(obj)) _blk->do_oop(p);
 }