7029458: G1: Add newly-reclaimed regions to the beginning of the region free list, not the end

What the synopsis says.

Reviewed-by: jwilhelm, iveresov, johnc
This commit is contained in:
Antonios Printezis 2011-03-29 22:36:16 -04:00
parent c2275649b7
commit 349d820dd1
5 changed files with 69 additions and 4 deletions

View file

@ -3879,7 +3879,7 @@ void G1CollectedHeap::release_gc_alloc_regions(bool totally) {
if (r->is_empty()) { if (r->is_empty()) {
// We didn't actually allocate anything in it; let's just put // We didn't actually allocate anything in it; let's just put
// it back on the free list. // it back on the free list.
_free_list.add_as_tail(r); _free_list.add_as_head(r);
} else if (_retain_gc_alloc_region[ap] && !totally) { } else if (_retain_gc_alloc_region[ap] && !totally) {
// retain it so that we can use it at the beginning of the next GC // retain it so that we can use it at the beginning of the next GC
_retained_gc_alloc_regions[ap] = r; _retained_gc_alloc_regions[ap] = r;
@ -5013,7 +5013,7 @@ void G1CollectedHeap::free_region(HeapRegion* hr,
*pre_used += hr->used(); *pre_used += hr->used();
hr->hr_clear(par, true /* clear_space */); hr->hr_clear(par, true /* clear_space */);
free_list->add_as_tail(hr); free_list->add_as_head(hr);
} }
void G1CollectedHeap::free_humongous_region(HeapRegion* hr, void G1CollectedHeap::free_humongous_region(HeapRegion* hr,
@ -5065,7 +5065,7 @@ void G1CollectedHeap::update_sets_after_freeing_regions(size_t pre_used,
} }
if (free_list != NULL && !free_list->is_empty()) { if (free_list != NULL && !free_list->is_empty()) {
MutexLockerEx x(FreeList_lock, Mutex::_no_safepoint_check_flag); MutexLockerEx x(FreeList_lock, Mutex::_no_safepoint_check_flag);
_free_list.add_as_tail(free_list); _free_list.add_as_head(free_list);
} }
if (humongous_proxy_set != NULL && !humongous_proxy_set->is_empty()) { if (humongous_proxy_set != NULL && !humongous_proxy_set->is_empty()) {
MutexLockerEx x(OldSets_lock, Mutex::_no_safepoint_check_flag); MutexLockerEx x(OldSets_lock, Mutex::_no_safepoint_check_flag);

View file

@ -1061,7 +1061,7 @@ public:
} }
void append_secondary_free_list() { void append_secondary_free_list() {
_free_list.add_as_tail(&_secondary_free_list); _free_list.add_as_head(&_secondary_free_list);
} }
void append_secondary_free_list_if_not_empty_with_lock() { void append_secondary_free_list_if_not_empty_with_lock() {

View file

@ -261,6 +261,45 @@ void HeapRegionLinkedList::fill_in_ext_msg_extra(hrs_ext_msg* msg) {
msg->append(" hd: "PTR_FORMAT" tl: "PTR_FORMAT, head(), tail()); msg->append(" hd: "PTR_FORMAT" tl: "PTR_FORMAT, head(), tail());
} }
void HeapRegionLinkedList::add_as_head(HeapRegionLinkedList* from_list) {
hrs_assert_mt_safety_ok(this);
hrs_assert_mt_safety_ok(from_list);
verify_optional();
from_list->verify_optional();
if (from_list->is_empty()) return;
#ifdef ASSERT
HeapRegionLinkedListIterator iter(from_list);
while (iter.more_available()) {
HeapRegion* hr = iter.get_next();
// In set_containing_set() we check that we either set the value
// from NULL to non-NULL or vice versa to catch bugs. So, we have
// to NULL it first before setting it to the value.
hr->set_containing_set(NULL);
hr->set_containing_set(this);
}
#endif // ASSERT
if (_head != NULL) {
assert(length() > 0 && _tail != NULL, hrs_ext_msg(this, "invariant"));
from_list->_tail->set_next(_head);
} else {
assert(length() == 0 && _head == NULL, hrs_ext_msg(this, "invariant"));
_tail = from_list->_tail;
}
_head = from_list->_head;
_length += from_list->length();
_region_num += from_list->region_num();
_total_used_bytes += from_list->total_used_bytes();
from_list->clear();
verify_optional();
from_list->verify_optional();
}
void HeapRegionLinkedList::add_as_tail(HeapRegionLinkedList* from_list) { void HeapRegionLinkedList::add_as_tail(HeapRegionLinkedList* from_list) {
hrs_assert_mt_safety_ok(this); hrs_assert_mt_safety_ok(this);
hrs_assert_mt_safety_ok(from_list); hrs_assert_mt_safety_ok(from_list);

View file

@ -277,6 +277,10 @@ protected:
} }
public: public:
// It adds hr to the list as the new head. The region should not be
// a member of another set.
inline void add_as_head(HeapRegion* hr);
// It adds hr to the list as the new tail. The region should not be // It adds hr to the list as the new tail. The region should not be
// a member of another set. // a member of another set.
inline void add_as_tail(HeapRegion* hr); inline void add_as_tail(HeapRegion* hr);
@ -288,6 +292,11 @@ public:
// Convenience method. // Convenience method.
inline HeapRegion* remove_head_or_null(); inline HeapRegion* remove_head_or_null();
// It moves the regions from from_list to this list and empties
// from_list. The new regions will appear in the same order as they
// were in from_list and be linked in the beginning of this list.
void add_as_head(HeapRegionLinkedList* from_list);
// It moves the regions from from_list to this list and empties // It moves the regions from from_list to this list and empties
// from_list. The new regions will appear in the same order as they // from_list. The new regions will appear in the same order as they
// were in from_list and be linked in the end of this list. // were in from_list and be linked in the end of this list.

View file

@ -110,6 +110,23 @@ inline void HeapRegionSet::remove_with_proxy(HeapRegion* hr,
//////////////////// HeapRegionLinkedList //////////////////// //////////////////// HeapRegionLinkedList ////////////////////
inline void HeapRegionLinkedList::add_as_head(HeapRegion* hr) {
hrs_assert_mt_safety_ok(this);
assert((length() == 0 && _head == NULL && _tail == NULL) ||
(length() > 0 && _head != NULL && _tail != NULL),
hrs_ext_msg(this, "invariant"));
// add_internal() will verify the region.
add_internal(hr);
// Now link the region.
if (_head != NULL) {
hr->set_next(_head);
} else {
_tail = hr;
}
_head = hr;
}
inline void HeapRegionLinkedList::add_as_tail(HeapRegion* hr) { inline void HeapRegionLinkedList::add_as_tail(HeapRegion* hr) {
hrs_assert_mt_safety_ok(this); hrs_assert_mt_safety_ok(this);
assert((length() == 0 && _head == NULL && _tail == NULL) || assert((length() == 0 && _head == NULL && _tail == NULL) ||