< prev index next >
src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
Print this page
rev 7471 : 8060025: Object copy time regressions after JDK-8031323 and JDK-8057536
Summary: Evaluate and improve object copy time by micro-optimizations and splitting out slow and fast paths aggressively.
Reviewed-by:
Contributed-by: Tony Printezis <tprintezis@twitter.com>, Thomas Schatzl <thomas.schatzl@oracle.com>
rev 7472 : [mq]: 8060025-mikael-review1
rev 7473 : imported patch mikael-refactor-cset-state
*** 4215,4226 ****
oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
assert(_worker_id == _par_scan_state->queue_num(), "sanity");
! const in_cset_state_t state = _g1->in_cset_state(obj);
! if (InCSetState::is_in_cset(state)) {
oop forwardee;
markOop m = obj->mark();
if (m->is_marked()) {
forwardee = (oop) m->decode_pointer();
} else {
--- 4215,4226 ----
oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
assert(_worker_id == _par_scan_state->queue_num(), "sanity");
! const InCSetState state = _g1->in_cset_state(obj);
! if (state.is_in_cset()) {
oop forwardee;
markOop m = obj->mark();
if (m->is_marked()) {
forwardee = (oop) m->decode_pointer();
} else {
*** 4236,4246 ****
if (barrier == G1BarrierKlass) {
do_klass_barrier(p, forwardee);
}
} else {
! if (InCSetState::is_humongous(state)) {
_g1->set_humongous_is_live(obj);
}
// The object is not in collection set. If we're a root scanning
// closure during an initial mark pause then attempt to mark the object.
if (do_mark_object == G1MarkFromRoot) {
--- 4236,4246 ----
if (barrier == G1BarrierKlass) {
do_klass_barrier(p, forwardee);
}
} else {
! if (state.is_humongous()) {
_g1->set_humongous_is_live(obj);
}
// The object is not in collection set. If we're a root scanning
// closure during an initial mark pause then attempt to mark the object.
if (do_mark_object == G1MarkFromRoot) {
*** 5092,5112 ****
void do_oop(narrowOop* p) { guarantee(false, "Not needed"); }
void do_oop(oop* p) {
oop obj = *p;
assert(obj != NULL, "the caller should have filtered out NULL values");
! const in_cset_state_t cset_state = _g1->in_cset_state(obj);
! if (InCSetState::is_not_in_cset(cset_state)) {
return;
}
! if (InCSetState::is_in_cset(cset_state)) {
assert( obj->is_forwarded(), "invariant" );
*p = obj->forwardee();
} else {
assert(!obj->is_forwarded(), "invariant" );
! assert(InCSetState::is_humongous(cset_state),
! err_msg("Only allowed InCSet state is IsHumongous, but is %d", cset_state));
_g1->set_humongous_is_live(obj);
}
}
};
--- 5092,5112 ----
void do_oop(narrowOop* p) { guarantee(false, "Not needed"); }
void do_oop(oop* p) {
oop obj = *p;
assert(obj != NULL, "the caller should have filtered out NULL values");
! const InCSetState cset_state = _g1->in_cset_state(obj);
! if (cset_state.is_not_in_cset()) {
return;
}
! if (cset_state.is_in_cset()) {
assert( obj->is_forwarded(), "invariant" );
*p = obj->forwardee();
} else {
assert(!obj->is_forwarded(), "invariant" );
! assert(cset_state.is_humongous(),
! err_msg("Only allowed InCSet state is IsHumongous, but is %d", cset_state.value()));
_g1->set_humongous_is_live(obj);
}
}
};
*** 5903,5951 ****
bool G1CollectedHeap::check_cset_fast_test() {
bool failures = false;
for (uint i = 0; i < _hrm.length(); i += 1) {
HeapRegion* hr = _hrm.at(i);
! in_cset_state_t cset_state = (in_cset_state_t) _in_cset_fast_test.get_by_index((uint) i);
if (hr->is_humongous()) {
if (hr->in_collection_set()) {
gclog_or_tty->print_cr("\n## humongous region %u in CSet", i);
failures = true;
break;
}
! if (InCSetState::is_in_cset(cset_state)) {
! gclog_or_tty->print_cr("\n## inconsistent cset state %d for humongous region %u", cset_state, i);
failures = true;
break;
}
! if (hr->is_continues_humongous() && InCSetState::is_humongous(cset_state)) {
! gclog_or_tty->print_cr("\n## inconsistent cset state %d for continues humongous region %u", cset_state, i);
failures = true;
break;
}
} else {
! if (InCSetState::is_humongous(cset_state)) {
! gclog_or_tty->print_cr("\n## inconsistent cset state %d for non-humongous region %u", cset_state, i);
failures = true;
break;
}
! if (hr->in_collection_set() != InCSetState::is_in_cset(cset_state)) {
gclog_or_tty->print_cr("\n## in CSet %d / cset state %d inconsistency for region %u",
! hr->in_collection_set(), cset_state, i);
failures = true;
break;
}
! if (InCSetState::is_in_cset(cset_state)) {
! if (hr->is_young() != (cset_state == InCSetState::Young)) {
gclog_or_tty->print_cr("\n## is_young %d / cset state %d inconsistency for region %u",
! hr->is_young(), cset_state, i);
failures = true;
break;
}
! if (hr->is_old() != (cset_state == InCSetState::Old)) {
gclog_or_tty->print_cr("\n## is_old %d / cset state %d inconsistency for region %u",
! hr->is_old(), cset_state, i);
failures = true;
break;
}
}
}
--- 5903,5951 ----
bool G1CollectedHeap::check_cset_fast_test() {
bool failures = false;
for (uint i = 0; i < _hrm.length(); i += 1) {
HeapRegion* hr = _hrm.at(i);
! InCSetState cset_state = (InCSetState) _in_cset_fast_test.get_by_index((uint) i);
if (hr->is_humongous()) {
if (hr->in_collection_set()) {
gclog_or_tty->print_cr("\n## humongous region %u in CSet", i);
failures = true;
break;
}
! if (cset_state.is_in_cset()) {
! gclog_or_tty->print_cr("\n## inconsistent cset state %d for humongous region %u", cset_state.value(), i);
failures = true;
break;
}
! if (hr->is_continues_humongous() && cset_state.is_humongous()) {
! gclog_or_tty->print_cr("\n## inconsistent cset state %d for continues humongous region %u", cset_state.value(), i);
failures = true;
break;
}
} else {
! if (cset_state.is_humongous()) {
! gclog_or_tty->print_cr("\n## inconsistent cset state %d for non-humongous region %u", cset_state.value(), i);
failures = true;
break;
}
! if (hr->in_collection_set() != cset_state.is_in_cset()) {
gclog_or_tty->print_cr("\n## in CSet %d / cset state %d inconsistency for region %u",
! hr->in_collection_set(), cset_state.value(), i);
failures = true;
break;
}
! if (cset_state.is_in_cset()) {
! if (hr->is_young() != (cset_state.is_young())) {
gclog_or_tty->print_cr("\n## is_young %d / cset state %d inconsistency for region %u",
! hr->is_young(), cset_state.value(), i);
failures = true;
break;
}
! if (hr->is_old() != (cset_state.is_old())) {
gclog_or_tty->print_cr("\n## is_old %d / cset state %d inconsistency for region %u",
! hr->is_old(), cset_state.value(), i);
failures = true;
break;
}
}
}
*** 6518,6532 ****
// Methods for the GC alloc regions
HeapRegion* G1CollectedHeap::new_gc_alloc_region(size_t word_size,
uint count,
! in_cset_state_t dest) {
assert(FreeList_lock->owned_by_self(), "pre-condition");
if (count < g1_policy()->max_regions(dest)) {
! const bool is_survivor = (dest == InCSetState::Young);
HeapRegion* new_alloc_region = new_region(word_size,
!is_survivor,
true /* do_expand */);
if (new_alloc_region != NULL) {
// We really only need to do this for old regions given that we
--- 6518,6532 ----
// Methods for the GC alloc regions
HeapRegion* G1CollectedHeap::new_gc_alloc_region(size_t word_size,
uint count,
! InCSetState dest) {
assert(FreeList_lock->owned_by_self(), "pre-condition");
if (count < g1_policy()->max_regions(dest)) {
! const bool is_survivor = (dest.is_young());
HeapRegion* new_alloc_region = new_region(word_size,
!is_survivor,
true /* do_expand */);
if (new_alloc_region != NULL) {
// We really only need to do this for old regions given that we
*** 6550,6564 ****
return NULL;
}
void G1CollectedHeap::retire_gc_alloc_region(HeapRegion* alloc_region,
size_t allocated_bytes,
! in_cset_state_t dest) {
bool during_im = g1_policy()->during_initial_mark_pause();
alloc_region->note_end_of_copying(during_im);
g1_policy()->record_bytes_copied_during_gc(allocated_bytes);
! if (dest == InCSetState::Young) {
young_list()->add_survivor_region(alloc_region);
} else {
_old_set.add(alloc_region);
}
_hr_printer.retire(alloc_region);
--- 6550,6564 ----
return NULL;
}
void G1CollectedHeap::retire_gc_alloc_region(HeapRegion* alloc_region,
size_t allocated_bytes,
! InCSetState dest) {
bool during_im = g1_policy()->during_initial_mark_pause();
alloc_region->note_end_of_copying(during_im);
g1_policy()->record_bytes_copied_during_gc(allocated_bytes);
! if (dest.is_young()) {
young_list()->add_survivor_region(alloc_region);
} else {
_old_set.add(alloc_region);
}
_hr_printer.retire(alloc_region);
< prev index next >