提交 74bdbba5 编写于 作者: S sfriberg

8064473: Improved handling of age during object copy in G1

Reviewed-by: brutisso, tschatzl
上级 a4f92823
...@@ -4479,10 +4479,11 @@ void G1ParCopyClosure<barrier, do_mark_object>::do_oop_work(T* p) { ...@@ -4479,10 +4479,11 @@ void G1ParCopyClosure<barrier, do_mark_object>::do_oop_work(T* p) {
if (state == G1CollectedHeap::InCSet) { if (state == G1CollectedHeap::InCSet) {
oop forwardee; oop forwardee;
if (obj->is_forwarded()) { markOop m = obj->mark();
forwardee = obj->forwardee(); if (m->is_marked()) {
forwardee = (oop) m->decode_pointer();
} else { } else {
forwardee = _par_scan_state->copy_to_survivor_space(obj); forwardee = _par_scan_state->copy_to_survivor_space(obj, m);
} }
assert(forwardee != NULL, "forwardee should not be NULL"); assert(forwardee != NULL, "forwardee should not be NULL");
oopDesc::encode_store_heap_oop(p, forwardee); oopDesc::encode_store_heap_oop(p, forwardee);
......
...@@ -150,7 +150,8 @@ void G1ParScanThreadState::trim_queue() { ...@@ -150,7 +150,8 @@ void G1ParScanThreadState::trim_queue() {
} while (!_refs->is_empty()); } while (!_refs->is_empty());
} }
oop G1ParScanThreadState::copy_to_survivor_space(oop const old) { oop G1ParScanThreadState::copy_to_survivor_space(oop const old,
markOop const old_mark) {
size_t word_sz = old->size(); size_t word_sz = old->size();
HeapRegion* from_region = _g1h->heap_region_containing_raw(old); HeapRegion* from_region = _g1h->heap_region_containing_raw(old);
// +1 to make the -1 indexes valid... // +1 to make the -1 indexes valid...
...@@ -158,9 +159,8 @@ oop G1ParScanThreadState::copy_to_survivor_space(oop const old) { ...@@ -158,9 +159,8 @@ oop G1ParScanThreadState::copy_to_survivor_space(oop const old) {
assert( (from_region->is_young() && young_index > 0) || assert( (from_region->is_young() && young_index > 0) ||
(!from_region->is_young() && young_index == 0), "invariant" ); (!from_region->is_young() && young_index == 0), "invariant" );
G1CollectorPolicy* g1p = _g1h->g1_policy(); G1CollectorPolicy* g1p = _g1h->g1_policy();
markOop m = old->mark(); uint age = old_mark->has_displaced_mark_helper() ? old_mark->displaced_mark_helper()->age()
int age = m->has_displaced_mark_helper() ? m->displaced_mark_helper()->age() : old_mark->age();
: m->age();
GCAllocPurpose alloc_purpose = g1p->evacuation_destination(from_region, age, GCAllocPurpose alloc_purpose = g1p->evacuation_destination(from_region, age,
word_sz); word_sz);
AllocationContext_t context = from_region->allocation_context(); AllocationContext_t context = from_region->allocation_context();
...@@ -196,30 +196,22 @@ oop G1ParScanThreadState::copy_to_survivor_space(oop const old) { ...@@ -196,30 +196,22 @@ oop G1ParScanThreadState::copy_to_survivor_space(oop const old) {
alloc_purpose = to_region->is_young() ? GCAllocForSurvived : GCAllocForTenured; alloc_purpose = to_region->is_young() ? GCAllocForSurvived : GCAllocForTenured;
if (g1p->track_object_age(alloc_purpose)) { if (g1p->track_object_age(alloc_purpose)) {
// We could simply do obj->incr_age(). However, this causes a if (age < markOopDesc::max_age) {
// performance issue. obj->incr_age() will first check whether age++;
// the object has a displaced mark by checking its mark word; }
// getting the mark word from the new location of the object if (old_mark->has_displaced_mark_helper()) {
// stalls. So, given that we already have the mark word and we // In this case, we have to install the mark word first,
// are about to install it anyway, it's better to increase the
// age on the mark word, when the object does not have a
// displaced mark word. We're not expecting many objects to have
// a displaced marked word, so that case is not optimized
// further (it could be...) and we simply call obj->incr_age().
if (m->has_displaced_mark_helper()) {
// in this case, we have to install the mark word first,
// otherwise obj looks to be forwarded (the old mark word, // otherwise obj looks to be forwarded (the old mark word,
// which contains the forward pointer, was copied) // which contains the forward pointer, was copied)
obj->set_mark(m); obj->set_mark(old_mark);
obj->incr_age(); markOop new_mark = old_mark->displaced_mark_helper()->set_age(age);
old_mark->set_displaced_mark_helper(new_mark);
} else { } else {
m = m->incr_age(); obj->set_mark(old_mark->set_age(age));
obj->set_mark(m);
} }
age_table()->add(obj, word_sz); age_table()->add(age, word_sz);
} else { } else {
obj->set_mark(m); obj->set_mark(old_mark);
} }
if (G1StringDedup::is_enabled()) { if (G1StringDedup::is_enabled()) {
......
...@@ -195,7 +195,7 @@ class G1ParScanThreadState : public StackObj { ...@@ -195,7 +195,7 @@ class G1ParScanThreadState : public StackObj {
inline void dispatch_reference(StarTask ref); inline void dispatch_reference(StarTask ref);
public: public:
oop copy_to_survivor_space(oop const obj); oop copy_to_survivor_space(oop const obj, markOop const old_mark);
void trim_queue(); void trim_queue();
......
...@@ -41,10 +41,11 @@ template <class T> void G1ParScanThreadState::do_oop_evac(T* p, HeapRegion* from ...@@ -41,10 +41,11 @@ template <class T> void G1ParScanThreadState::do_oop_evac(T* p, HeapRegion* from
G1CollectedHeap::in_cset_state_t in_cset_state = _g1h->in_cset_state(obj); G1CollectedHeap::in_cset_state_t in_cset_state = _g1h->in_cset_state(obj);
if (in_cset_state == G1CollectedHeap::InCSet) { if (in_cset_state == G1CollectedHeap::InCSet) {
oop forwardee; oop forwardee;
if (obj->is_forwarded()) { markOop m = obj->mark();
forwardee = obj->forwardee(); if (m->is_marked()) {
forwardee = (oop) m->decode_pointer();
} else { } else {
forwardee = copy_to_survivor_space(obj); forwardee = copy_to_survivor_space(obj, m);
} }
oopDesc::encode_store_heap_oop(p, forwardee); oopDesc::encode_store_heap_oop(p, forwardee);
} else if (in_cset_state == G1CollectedHeap::IsHumongous) { } else if (in_cset_state == G1CollectedHeap::IsHumongous) {
......
...@@ -55,7 +55,10 @@ class ageTable VALUE_OBJ_CLASS_SPEC { ...@@ -55,7 +55,10 @@ class ageTable VALUE_OBJ_CLASS_SPEC {
// add entry // add entry
void add(oop p, size_t oop_size) { void add(oop p, size_t oop_size) {
uint age = p->age(); add(p->age(), oop_size);
}
void add(uint age, size_t oop_size) {
assert(age > 0 && age < table_size, "invalid age of object"); assert(age > 0 && age < table_size, "invalid age of object");
sizes[age] += oop_size; sizes[age] += oop_size;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册