7029458: G1: Add newly-reclaimed regions to the beginning of the region free list, not the end
Summary: What the synopsis says.
Reviewed-by: jwilhelm, iveresov, johnc
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Mon Mar 28 10:58:54 2011 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Tue Mar 29 22:36:16 2011 -0400
@@ -3879,7 +3879,7 @@
if (r->is_empty()) {
// We didn't actually allocate anything in it; let's just put
// 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) {
// retain it so that we can use it at the beginning of the next GC
_retained_gc_alloc_regions[ap] = r;
@@ -5013,7 +5013,7 @@
*pre_used += hr->used();
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,
@@ -5065,7 +5065,7 @@
}
if (free_list != NULL && !free_list->is_empty()) {
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()) {
MutexLockerEx x(OldSets_lock, Mutex::_no_safepoint_check_flag);
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Mon Mar 28 10:58:54 2011 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Tue Mar 29 22:36:16 2011 -0400
@@ -1061,7 +1061,7 @@
}
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() {
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.cpp Mon Mar 28 10:58:54 2011 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.cpp Tue Mar 29 22:36:16 2011 -0400
@@ -261,6 +261,45 @@
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) {
hrs_assert_mt_safety_ok(this);
hrs_assert_mt_safety_ok(from_list);
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.hpp Mon Mar 28 10:58:54 2011 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.hpp Tue Mar 29 22:36:16 2011 -0400
@@ -277,6 +277,10 @@
}
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
// a member of another set.
inline void add_as_tail(HeapRegion* hr);
@@ -290,6 +294,11 @@
// 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
+ // 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.
void add_as_tail(HeapRegionLinkedList* from_list);
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.inline.hpp Mon Mar 28 10:58:54 2011 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.inline.hpp Tue Mar 29 22:36:16 2011 -0400
@@ -110,6 +110,23 @@
//////////////////// 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) {
hrs_assert_mt_safety_ok(this);
assert((length() == 0 && _head == NULL && _tail == NULL) ||