< prev index next >
src/hotspot/share/gc/g1/g1CollectedHeap.cpp
Print this page
rev 55404 : 8226197: Reducing G1?s CPU cost with simplified write post-barrier and disabling concurrent refinement
Summary: A prototype to add a mode for G1 to use a simplified write post-barrier. Guarded by new flag G1FastWriteBarrier.
@@ -750,11 +750,13 @@
}
assert_heap_not_locked();
if (result != NULL) {
assert(*actual_word_size != 0, "Actual size must have been set here");
+ if (!G1FastWriteBarrier) {
dirty_young_block(result, *actual_word_size);
+ }
} else {
*actual_word_size = 0;
}
return result;
@@ -1070,10 +1072,13 @@
// Post collection state updates.
MetaspaceGC::compute_new_size();
}
void G1CollectedHeap::abort_refinement() {
+ if (G1FastWriteBarrier) {
+ return;
+ }
if (_hot_card_cache->use_cache()) {
_hot_card_cache->reset_hot_cache();
}
// Discard all remembered set updates.
@@ -2725,11 +2730,13 @@
CardTable::CardValue* card_ptr = ct->byte_for_index(card_index);
// The remembered set might contain references to already freed
// regions. Filter out such entries to avoid failing card table
// verification.
if (g1h->is_in(ct->addr_for(card_ptr))) {
- if (*card_ptr != G1CardTable::dirty_card_val()) {
+ if (G1FastWriteBarrier) {
+ *card_ptr = G1CardTable::dirty_card_val();
+ } else if (*card_ptr != G1CardTable::dirty_card_val()) {
*card_ptr = G1CardTable::dirty_card_val();
_dcq.enqueue(card_ptr);
}
}
}
@@ -2987,11 +2994,16 @@
print_heap_before_gc();
print_heap_regions();
trace_heap_before_gc(_gc_tracer_stw);
_verifier->verify_region_sets_optional();
+ // With G1FastWriteBarrier, cards for young regions can become dirty,
+ // and the collection set only contains young regions at this point.
+ // So it doesn't make sense to verify the cards for young regions.
+ if (!G1FastWriteBarrier) {
_verifier->verify_dirty_young_regions();
+ }
// We should not be doing initial mark unless the conc mark thread is running
if (!_cm_thread->should_terminate()) {
// This call will decide whether this pause is an initial-mark
// pause. If it is, in_initial_mark_gc() will return true
@@ -3286,12 +3298,16 @@
G1RedirtyLoggedCardsTask redirty_task(&dirty_card_queue_set(), this);
dirty_card_queue_set().reset_for_par_iteration();
workers()->run_task(&redirty_task);
+ if (G1FastWriteBarrier) {
+ dirty_card_queue_set().abandon_completed_buffers();
+ } else {
G1DirtyCardQueueSet& dcq = G1BarrierSet::dirty_card_queue_set();
dcq.merge_bufferlists(&dirty_card_queue_set());
+ }
assert(dirty_card_queue_set().completed_buffers_num() == 0, "All should be consumed");
phase_times()->record_redirty_logged_cards_time_ms((os::elapsedTime() - redirty_logged_cards_start) * 1000.0);
}
@@ -3616,10 +3632,12 @@
// Should G1EvacuationFailureALot be in effect for this GC?
NOT_PRODUCT(set_evacuation_failure_alot_for_current_gc();)
assert(dirty_card_queue_set().completed_buffers_num() == 0, "Should be empty");
+ assert(!G1FastWriteBarrier || G1BarrierSet::dirty_card_queue_set().completed_buffers_num() == 0,
+ "Should be empty");
}
class G1EvacuateRegionsBaseTask : public AbstractGangTask {
protected:
G1CollectedHeap* _g1h;
@@ -3692,14 +3710,19 @@
}
};
class G1EvacuateRegionsTask : public G1EvacuateRegionsBaseTask {
G1RootProcessor* _root_processor;
+ HeapRegionClaimer _card_table_hr_claimer;
void scan_roots(G1ParScanThreadState* pss, uint worker_id) {
_root_processor->evacuate_roots(pss, worker_id);
+ if (G1FastWriteBarrier) {
+ _g1h->rem_set()->process_card_table(pss, worker_id, &_card_table_hr_claimer);
+ } else {
_g1h->rem_set()->update_rem_set(pss, worker_id);
+ }
_g1h->rem_set()->scan_rem_set(pss, worker_id, G1GCPhaseTimes::ScanRS, G1GCPhaseTimes::ObjCopy, G1GCPhaseTimes::CodeRoots);
}
void evacuate_live_objects(G1ParScanThreadState* pss, uint worker_id) {
G1EvacuateRegionsBaseTask::evacuate_live_objects(pss, worker_id, G1GCPhaseTimes::ObjCopy, G1GCPhaseTimes::Termination);
@@ -3718,11 +3741,12 @@
G1ParScanThreadStateSet* per_thread_states,
RefToScanQueueSet* task_queues,
G1RootProcessor* root_processor,
uint num_workers) :
G1EvacuateRegionsBaseTask("G1 Evacuate Regions", per_thread_states, task_queues, num_workers),
- _root_processor(root_processor)
+ _root_processor(root_processor),
+ _card_table_hr_claimer(num_workers)
{ }
};
void G1CollectedHeap::evacuate_initial_collection_set(G1ParScanThreadStateSet* per_thread_states) {
Tickspan task_time;
< prev index next >