Skip to content

Commit

Permalink
8256265: G1: Improve parallelism in regions that failed evacuation
Browse files Browse the repository at this point in the history
Co-authored-by: Hamlin Li <mli@openjdk.org>
Co-authored-by: Albert Mingkun Yang <ayang@openjdk.org>
Reviewed-by: sjohanss, ayang
  • Loading branch information
3 people committed Sep 15, 2022
1 parent b31a03c commit 15cb1fb
Show file tree
Hide file tree
Showing 22 changed files with 366 additions and 240 deletions.
20 changes: 16 additions & 4 deletions src/hotspot/share/gc/g1/g1CollectedHeap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,16 @@ void G1CollectedHeap::run_batch_task(G1BatchedTask* cl) {
workers()->run_task(cl, num_workers);
}

uint G1CollectedHeap::get_chunks_per_region() {
uint log_region_size = HeapRegion::LogOfHRGrainBytes;
// Limit the expected input values to current known possible values of the
// (log) region size. Adjust as necessary after testing if changing the permissible
// values for region size.
assert(log_region_size >= 20 && log_region_size <= 29,
"expected value in [20,29], but got %u", log_region_size);
return 1u << (log_region_size / 2 - 4);
}

HeapRegion* G1CollectedHeap::new_heap_region(uint hrs_index,
MemRegion mr) {
return new HeapRegion(hrs_index, bot(), mr, &_card_set_config);
Expand Down Expand Up @@ -3290,11 +3300,13 @@ HeapRegion* G1CollectedHeap::alloc_highest_free_region() {
return NULL;
}

void G1CollectedHeap::mark_evac_failure_object(const oop obj) const {
// All objects failing evacuation are live. What we'll do is
// that we'll update the marking info so that they are
// all below TAMS and explicitly marked.
void G1CollectedHeap::mark_evac_failure_object(uint worker_id, const oop obj, size_t obj_size) const {
assert(!_cm->is_marked_in_bitmap(obj), "must be");

_cm->raw_mark_in_bitmap(obj);
if (collector_state()->in_concurrent_start_gc()) {
_cm->add_to_liveness(worker_id, obj, obj_size);
}
}

// Optimized nmethod scanning
Expand Down
13 changes: 11 additions & 2 deletions src/hotspot/share/gc/g1/g1CollectedHeap.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -523,6 +523,14 @@ class G1CollectedHeap : public CollectedHeap {
// Run the given batch task using the workers.
void run_batch_task(G1BatchedTask* cl);

// Return "optimal" number of chunks per region we want to use for claiming areas
// within a region to claim.
// The returned value is a trade-off between granularity of work distribution and
// memory usage and maintenance costs of that table.
// Testing showed that 64 for 1M/2M region, 128 for 4M/8M regions, 256 for 16/32M regions,
// and so on seems to be such a good trade-off.
static uint get_chunks_per_region();

G1Allocator* allocator() {
return _allocator;
}
Expand Down Expand Up @@ -1216,6 +1224,7 @@ class G1CollectedHeap : public CollectedHeap {

bool is_marked(oop obj) const;

inline static bool is_obj_filler(const oop obj);
// Determine if an object is dead, given the object and also
// the region to which the object belongs.
inline bool is_obj_dead(const oop obj, const HeapRegion* hr) const;
Expand All @@ -1229,8 +1238,8 @@ class G1CollectedHeap : public CollectedHeap {
inline bool is_obj_dead_full(const oop obj, const HeapRegion* hr) const;
inline bool is_obj_dead_full(const oop obj) const;

// Mark the live object that failed evacuation in the prev bitmap.
void mark_evac_failure_object(oop obj) const;
// Mark the live object that failed evacuation in the bitmap.
void mark_evac_failure_object(uint worker_id, oop obj, size_t obj_size) const;

G1ConcurrentMark* concurrent_mark() const { return _cm; }

Expand Down
5 changes: 5 additions & 0 deletions src/hotspot/share/gc/g1/g1CollectedHeap.inline.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,11 @@ inline bool G1CollectedHeap::requires_barriers(stackChunkOop obj) const {
return !heap_region_containing(obj)->is_young(); // is_in_young does an unnecessary NULL check
}

inline bool G1CollectedHeap::is_obj_filler(const oop obj) {
Klass* k = obj->klass();
return k == Universe::fillerArrayKlassObj() || k == vmClasses::FillerObject_klass();
}

inline bool G1CollectedHeap::is_obj_dead(const oop obj, const HeapRegion* hr) const {
return hr->is_obj_dead(obj, hr->parsable_bottom());
}
Expand Down
6 changes: 3 additions & 3 deletions src/hotspot/share/gc/g1/g1ConcurrentMark.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -603,7 +603,8 @@ class G1ClearBitMapTask : public WorkerTask {
// live_words data are current wrt to the _mark_bitmap. We use this information
// to only clear ranges of the bitmap that require clearing.
if (is_clear_concurrent_undo()) {
// No need to clear bitmaps for empty regions.
// No need to clear bitmaps for empty regions (which includes regions we
// did not mark through).
if (_cm->live_words(r->hrm_index()) == 0) {
assert(_bitmap->get_next_marked_addr(r->bottom(), r->end()) == r->end(), "Should not have marked bits");
return r->bottom();
Expand Down Expand Up @@ -652,7 +653,7 @@ class G1ClearBitMapTask : public WorkerTask {
}
assert(cur >= end, "Must have completed iteration over the bitmap for region %u.", r->hrm_index());

r->note_end_of_clearing();
r->reset_top_at_mark_start();

return false;
}
Expand Down Expand Up @@ -1887,7 +1888,6 @@ void G1ConcurrentMark::flush_all_task_caches() {
void G1ConcurrentMark::clear_bitmap_for_region(HeapRegion* hr) {
assert_at_safepoint();
_mark_bitmap.clear_range(MemRegion(hr->bottom(), hr->end()));
hr->note_end_of_clearing();
}

HeapRegion* G1ConcurrentMark::claim_region(uint worker_id) {
Expand Down
4 changes: 2 additions & 2 deletions src/hotspot/share/gc/g1/g1ConcurrentMark.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -579,10 +579,10 @@ class G1ConcurrentMark : public CHeapObj<mtGC> {

// Mark in the marking bitmap. Used during evacuation failure to
// remember what objects need handling. Not for use during marking.
inline void raw_mark_in_bitmap(oop p);
inline void raw_mark_in_bitmap(oop obj);

// Clears marks for all objects in the given region in the marking
// bitmap. This should only be used clean the bitmap during a
// bitmap. This should only be used to clean the bitmap during a
// safepoint.
void clear_bitmap_for_region(HeapRegion* hr);

Expand Down
4 changes: 2 additions & 2 deletions src/hotspot/share/gc/g1/g1ConcurrentMark.inline.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -280,8 +280,8 @@ inline bool G1CMTask::deal_with_reference(T* p) {
return make_reference_grey(obj);
}

inline void G1ConcurrentMark::raw_mark_in_bitmap(oop p) {
_mark_bitmap.par_mark(p);
inline void G1ConcurrentMark::raw_mark_in_bitmap(oop obj) {
_mark_bitmap.par_mark(obj);
}

bool G1ConcurrentMark::is_marked_in_bitmap(oop p) const {
Expand Down

1 comment on commit 15cb1fb

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.