src/share/vm/gc_implementation/g1/concurrentMark.hpp
Print this page
rev 2724 : 6484965: G1: piggy-back liveness accounting phase on marking
Summary: Remove the separate counting phase of concurrent marking by tracking the amount of marked bytes and the cards spanned by marked objects in marking task/worker thread local data structures, which are updated as individual objects are marked.
Reviewed-by:
*** 426,436 ****
// structures (local and global) have been re-initialised. When they
// exit it, they are free to start working again.
WorkGangBarrierSync _first_overflow_barrier_sync;
WorkGangBarrierSync _second_overflow_barrier_sync;
-
// this is set by any task, when an overflow on the global data
// structures is detected.
volatile bool _has_overflown;
// true: marking is concurrent, false: we're in remark
volatile bool _concurrent;
--- 426,435 ----
*** 577,586 ****
--- 576,602 ----
} else {
return force_overflow_stw();
}
}
+ // Live Data Counting data structures...
+ // These data structures are initialized at the start of
+ // marking. They are written to while marking is active.
+ // They are aggregated during remark; the aggregated values
+ // are then used to populate the _region_bm, _card_bm, and
+ // the total live bytes, which are then subsequently updated
+ // during cleanup.
+
+ // An array of bitmaps (one bit map per task). Each bitmap
+ // is used to record the cards spanned by the live objects
+ // marked by that task/worker.
+ BitMap* _count_card_bitmaps;
+
+ // Used to record the number of marked live bytes
+ // (for each region, by worker thread).
+ size_t** _count_marked_bytes;
+
public:
// Manipulation of the global mark stack.
// Notice that the first mark_stack_push is CAS-based, whereas the
// two below are Mutex-based. This is OK since the first one is only
// called during evacuation pauses and doesn't compete with the
*** 714,738 ****
// This notifies CM that a root during initial-mark needs to be
// grayed and it's MT-safe. Currently, we just mark it. But, in the
// future, we can experiment with pushing it on the stack and we can
// do this without changing G1CollectedHeap.
! void grayRoot(oop p);
// It's used during evacuation pauses to gray a region, if
// necessary, and it's MT-safe. It assumes that the caller has
// marked any objects on that region. If _should_gray_objects is
// true and we're still doing concurrent marking, the region is
// pushed on the region stack, if it is located below the global
// finger, otherwise we do nothing.
void grayRegionIfNecessary(MemRegion mr);
// It's used during evacuation pauses to mark and, if necessary,
// gray a single object and it's MT-safe. It assumes the caller did
// not mark the object. If _should_gray_objects is true and we're
// still doing concurrent marking, the objects is pushed on the
// global stack, if it is located below the global finger, otherwise
// we do nothing.
! void markAndGrayObjectIfNecessary(oop p);
// It iterates over the heap and for each object it comes across it
// will dump the contents of its reference fields, as well as
// liveness information for the object and its referents. The dump
// will be written to a file with the following name:
--- 730,756 ----
// This notifies CM that a root during initial-mark needs to be
// grayed and it's MT-safe. Currently, we just mark it. But, in the
// future, we can experiment with pushing it on the stack and we can
// do this without changing G1CollectedHeap.
! void grayRoot(oop p, int worker_i);
!
// It's used during evacuation pauses to gray a region, if
// necessary, and it's MT-safe. It assumes that the caller has
// marked any objects on that region. If _should_gray_objects is
// true and we're still doing concurrent marking, the region is
// pushed on the region stack, if it is located below the global
// finger, otherwise we do nothing.
void grayRegionIfNecessary(MemRegion mr);
+
// It's used during evacuation pauses to mark and, if necessary,
// gray a single object and it's MT-safe. It assumes the caller did
// not mark the object. If _should_gray_objects is true and we're
// still doing concurrent marking, the objects is pushed on the
// global stack, if it is located below the global finger, otherwise
// we do nothing.
! void markAndGrayObjectIfNecessary(oop p, int worker_i);
// It iterates over the heap and for each object it comes across it
// will dump the contents of its reference fields, as well as
// liveness information for the object and its referents. The dump
// will be written to a file with the following name:
*** 772,789 ****
// beginning of an evacuation pause.
void drainAllSATBBuffers();
void checkpointRootsFinal(bool clear_all_soft_refs);
void checkpointRootsFinalWork();
- void calcDesiredRegions();
void cleanup();
void completeCleanup();
// Mark in the previous bitmap. NB: this is usually read-only, so use
// this carefully!
void markPrev(oop p);
void clear(oop p);
// Clears marks for all objects in the given range, for both prev and
// next bitmaps. NB: the previous bitmap is usually read-only, so use
// this carefully!
void clearRangeBothMaps(MemRegion mr);
--- 790,809 ----
// beginning of an evacuation pause.
void drainAllSATBBuffers();
void checkpointRootsFinal(bool clear_all_soft_refs);
void checkpointRootsFinalWork();
void cleanup();
void completeCleanup();
// Mark in the previous bitmap. NB: this is usually read-only, so use
// this carefully!
void markPrev(oop p);
+
+ // Clears the mark in the next bitmap for the given object.
void clear(oop p);
+
// Clears marks for all objects in the given range, for both prev and
// next bitmaps. NB: the previous bitmap is usually read-only, so use
// this carefully!
void clearRangeBothMaps(MemRegion mr);
*** 888,897 ****
--- 908,981 ----
return _MARKING_VERBOSE_ && _verbose_level >= medium_verbose;
}
bool verbose_high() {
return _MARKING_VERBOSE_ && _verbose_level >= high_verbose;
}
+
+ // Counting data structure accessors
+
+ // Returns the card bitmap for a given task or worker id.
+ BitMap& count_card_bitmap_for(int worker_i) {
+ assert(0 <= worker_i && worker_i < _max_task_num, "oob");
+ assert(_count_card_bitmaps != NULL, "uninitialized");
+ BitMap& task_card_bm = _count_card_bitmaps[worker_i];
+ assert(task_card_bm.size() == _card_bm.size(), "size mismatch");
+ return task_card_bm;
+ }
+
+ // Returns the array containing the marked bytes for each region,
+ // for the given worker or task id.
+ size_t* count_marked_bytes_for(int worker_i) {
+ assert(0 <= worker_i && worker_i < _max_task_num, "oob");
+ assert(_count_marked_bytes != NULL, "uninitialized");
+ size_t* marked_bytes_array = _count_marked_bytes[worker_i];
+ assert(marked_bytes_array != NULL, "uninitialized");
+ return marked_bytes_array;
+ }
+
+ // Add the given region's size to the # marked bytes for
+ // the given worker and region. Set the bits in the
+ // worker's/task's card bitmap that are associated
+ // with the range of cards spanned by the region.
+ // Note the memory region could be just one object.
+ void add_to_count_data_for(MemRegion mr, int worker_i);
+
+ // As above, but for a single object
+ void add_to_count_data_for(oop obj, int worker_i);
+
+ // As above but when we have already been given the heap
+ // region.
+ void add_to_count_data_for(MemRegion mr, HeapRegion* hr, int worker_i);
+
+ // As above, but for a single object
+ void add_to_count_data_for(oop obj, HeapRegion* hr, int worker_i);
+
+ // Updates the counting data with liveness info recorded for a
+ // region (typically a GCLab).
+ void add_to_count_data_for_region(MemRegion lab_mr,
+ BitMap* lab_card_bm,
+ intptr_t lab_bottom_card_num,
+ size_t lab_marked_bytes,
+ int worker_i);
+
+ // Clears the count data for the given region from _all_ of
+ // the per-task counting data structures.
+ void clear_count_data_for_heap_region(HeapRegion* hr);
+
+ protected:
+ // Clear all the per-task bitmaps and arrays used to store the
+ // counting data.
+ void clear_all_count_data();
+
+ // Aggregates the counting data for each worker/task
+ // that was constructed while marking. Also sets
+ // the amount of marked bytes for each region and
+ // the top at concurrent mark count.
+ void aggregate_all_count_data();
+
+ // Verification routine
+ void verify_count_data();
};
// A class representing a marking task.
class CMTask : public TerminatorTerminator {
private: