7041440: G1: assert(obj->is_oop_or_null(true )) failed: Error #

Tue, 17 May 2011 00:56:01 -0700

author
johnc
date
Tue, 17 May 2011 00:56:01 -0700
changeset 2910
69293e516993
parent 2909
2aa9ddbb9e60
child 2911
ea4859d7fee7

7041440: G1: assert(obj->is_oop_or_null(true )) failed: Error #
Summary: During an evacuation pause clear the region fields of any concurrent marking task whose local finger points into the collection set as the values in the region fields will become stale. Clearing these fields causes the concurrent mark task to claim a new region when marking restarts after the pause.
Reviewed-by: tonyp, iveresov

src/share/vm/gc_implementation/g1/concurrentMark.cpp file | annotate | diff | comparison | revisions
src/share/vm/gc_implementation/g1/concurrentMark.hpp file | annotate | diff | comparison | revisions
src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/vm/gc_implementation/g1/concurrentMark.cpp	Tue May 03 10:30:34 2011 -0700
     1.2 +++ b/src/share/vm/gc_implementation/g1/concurrentMark.cpp	Tue May 17 00:56:01 2011 -0700
     1.3 @@ -3054,6 +3054,28 @@
     1.4      _should_gray_objects = true;
     1.5  }
     1.6  
     1.7 +// Resets the region fields of active CMTasks whose values point
     1.8 +// into the collection set.
     1.9 +void ConcurrentMark::reset_active_task_region_fields_in_cset() {
    1.10 +  assert(SafepointSynchronize::is_at_safepoint(), "should be in STW");
    1.11 +  assert(parallel_marking_threads() <= _max_task_num, "sanity");
    1.12 +
    1.13 +  for (int i = 0; i < (int)parallel_marking_threads(); i += 1) {
    1.14 +    CMTask* task = _tasks[i];
    1.15 +    HeapWord* task_finger = task->finger();
    1.16 +    if (task_finger != NULL) {
    1.17 +      assert(_g1h->is_in_g1_reserved(task_finger), "not in heap");
    1.18 +      HeapRegion* finger_region = _g1h->heap_region_containing(task_finger);
    1.19 +      if (finger_region->in_collection_set()) {
    1.20 +        // The task's current region is in the collection set.
    1.21 +        // This region will be evacuated in the current GC and
    1.22 +        // the region fields in the task will be stale.
    1.23 +        task->giveup_current_region();
    1.24 +      }
    1.25 +    }
    1.26 +  }
    1.27 +}
    1.28 +
    1.29  // abandon current marking iteration due to a Full GC
    1.30  void ConcurrentMark::abort() {
    1.31    // Clear all marks to force marking thread to do nothing
     2.1 --- a/src/share/vm/gc_implementation/g1/concurrentMark.hpp	Tue May 03 10:30:34 2011 -0700
     2.2 +++ b/src/share/vm/gc_implementation/g1/concurrentMark.hpp	Tue May 17 00:56:01 2011 -0700
     2.3 @@ -809,10 +809,19 @@
     2.4  
     2.5    // It indicates that a new collection set is being chosen.
     2.6    void newCSet();
     2.7 +
     2.8    // It registers a collection set heap region with CM. This is used
     2.9    // to determine whether any heap regions are located above the finger.
    2.10    void registerCSetRegion(HeapRegion* hr);
    2.11  
    2.12 +  // Resets the region fields of any active CMTask whose region fields
    2.13 +  // are in the collection set (i.e. the region currently claimed by
    2.14 +  // the CMTask will be evacuated and may be used, subsequently, as
    2.15 +  // an alloc region). When this happens the region fields in the CMTask
    2.16 +  // are stale and, hence, should be cleared causing the worker thread
    2.17 +  // to claim a new region.
    2.18 +  void reset_active_task_region_fields_in_cset();
    2.19 +
    2.20    // Registers the maximum region-end associated with a set of
    2.21    // regions with CM. Again this is used to determine whether any
    2.22    // heap regions are located above the finger.
    2.23 @@ -1039,9 +1048,6 @@
    2.24    void setup_for_region(HeapRegion* hr);
    2.25    // it brings up-to-date the limit of the region
    2.26    void update_region_limit();
    2.27 -  // it resets the local fields after a task has finished scanning a
    2.28 -  // region
    2.29 -  void giveup_current_region();
    2.30  
    2.31    // called when either the words scanned or the refs visited limit
    2.32    // has been reached
    2.33 @@ -1094,6 +1100,11 @@
    2.34    // exit the termination protocol after it's entered it.
    2.35    virtual bool should_exit_termination();
    2.36  
    2.37 +  // Resets the local region fields after a task has finished scanning a
    2.38 +  // region; or when they have become stale as a result of the region
    2.39 +  // being evacuated.
    2.40 +  void giveup_current_region();
    2.41 +
    2.42    HeapWord* finger()            { return _finger; }
    2.43  
    2.44    bool has_aborted()            { return _has_aborted; }
     3.1 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Tue May 03 10:30:34 2011 -0700
     3.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Tue May 17 00:56:01 2011 -0700
     3.3 @@ -3323,8 +3323,9 @@
     3.4        // progress, this will be zero.
     3.5        _cm->set_oops_do_bound();
     3.6  
     3.7 -      if (mark_in_progress())
     3.8 +      if (mark_in_progress()) {
     3.9          concurrent_mark()->newCSet();
    3.10 +      }
    3.11  
    3.12  #if YOUNG_LIST_VERBOSE
    3.13        gclog_or_tty->print_cr("\nBefore choosing collection set.\nYoung_list:");
    3.14 @@ -3334,6 +3335,16 @@
    3.15  
    3.16        g1_policy()->choose_collection_set(target_pause_time_ms);
    3.17  
    3.18 +      // We have chosen the complete collection set. If marking is
    3.19 +      // active then, we clear the region fields of any of the
    3.20 +      // concurrent marking tasks whose region fields point into
    3.21 +      // the collection set as these values will become stale. This
    3.22 +      // will cause the owning marking threads to claim a new region
    3.23 +      // when marking restarts.
    3.24 +      if (mark_in_progress()) {
    3.25 +        concurrent_mark()->reset_active_task_region_fields_in_cset();
    3.26 +      }
    3.27 +
    3.28        // Nothing to do if we were unable to choose a collection set.
    3.29  #if G1_REM_SET_LOGGING
    3.30        gclog_or_tty->print_cr("\nAfter pause, heap:");

mercurial