--- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp Fri Oct 09 20:45:45 2015 +0000
+++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp Tue Oct 13 08:37:44 2015 +0200
@@ -125,213 +125,6 @@
size_t num_processed() const { return _num_processed; }
};
-YoungList::YoungList(G1CollectedHeap* g1h) :
- _g1h(g1h), _head(NULL), _length(0), _last_sampled_rs_lengths(0),
- _survivor_head(NULL), _survivor_tail(NULL), _survivor_length(0) {
- guarantee(check_list_empty(false), "just making sure...");
-}
-
-void YoungList::push_region(HeapRegion *hr) {
- assert(!hr->is_young(), "should not already be young");
- assert(hr->get_next_young_region() == NULL, "cause it should!");
-
- hr->set_next_young_region(_head);
- _head = hr;
-
- _g1h->g1_policy()->set_region_eden(hr, (int) _length);
- ++_length;
-}
-
-void YoungList::add_survivor_region(HeapRegion* hr) {
- assert(hr->is_survivor(), "should be flagged as survivor region");
- assert(hr->get_next_young_region() == NULL, "cause it should!");
-
- hr->set_next_young_region(_survivor_head);
- if (_survivor_head == NULL) {
- _survivor_tail = hr;
- }
- _survivor_head = hr;
- ++_survivor_length;
-}
-
-void YoungList::empty_list(HeapRegion* list) {
- while (list != NULL) {
- HeapRegion* next = list->get_next_young_region();
- list->set_next_young_region(NULL);
- list->uninstall_surv_rate_group();
- // This is called before a Full GC and all the non-empty /
- // non-humongous regions at the end of the Full GC will end up as
- // old anyway.
- list->set_old();
- list = next;
- }
-}
-
-void YoungList::empty_list() {
- assert(check_list_well_formed(), "young list should be well formed");
-
- empty_list(_head);
- _head = NULL;
- _length = 0;
-
- empty_list(_survivor_head);
- _survivor_head = NULL;
- _survivor_tail = NULL;
- _survivor_length = 0;
-
- _last_sampled_rs_lengths = 0;
-
- assert(check_list_empty(false), "just making sure...");
-}
-
-bool YoungList::check_list_well_formed() {
- bool ret = true;
-
- uint length = 0;
- HeapRegion* curr = _head;
- HeapRegion* last = NULL;
- while (curr != NULL) {
- if (!curr->is_young()) {
- gclog_or_tty->print_cr("### YOUNG REGION " PTR_FORMAT "-" PTR_FORMAT " "
- "incorrectly tagged (y: %d, surv: %d)",
- p2i(curr->bottom()), p2i(curr->end()),
- curr->is_young(), curr->is_survivor());
- ret = false;
- }
- ++length;
- last = curr;
- curr = curr->get_next_young_region();
- }
- ret = ret && (length == _length);
-
- if (!ret) {
- gclog_or_tty->print_cr("### YOUNG LIST seems not well formed!");
- gclog_or_tty->print_cr("### list has %u entries, _length is %u",
- length, _length);
- }
-
- return ret;
-}
-
-bool YoungList::check_list_empty(bool check_sample) {
- bool ret = true;
-
- if (_length != 0) {
- gclog_or_tty->print_cr("### YOUNG LIST should have 0 length, not %u",
- _length);
- ret = false;
- }
- if (check_sample && _last_sampled_rs_lengths != 0) {
- gclog_or_tty->print_cr("### YOUNG LIST has non-zero last sampled RS lengths");
- ret = false;
- }
- if (_head != NULL) {
- gclog_or_tty->print_cr("### YOUNG LIST does not have a NULL head");
- ret = false;
- }
- if (!ret) {
- gclog_or_tty->print_cr("### YOUNG LIST does not seem empty");
- }
-
- return ret;
-}
-
-void
-YoungList::rs_length_sampling_init() {
- _sampled_rs_lengths = 0;
- _curr = _head;
-}
-
-bool
-YoungList::rs_length_sampling_more() {
- return _curr != NULL;
-}
-
-void
-YoungList::rs_length_sampling_next() {
- assert( _curr != NULL, "invariant" );
- size_t rs_length = _curr->rem_set()->occupied();
-
- _sampled_rs_lengths += rs_length;
-
- // The current region may not yet have been added to the
- // incremental collection set (it gets added when it is
- // retired as the current allocation region).
- if (_curr->in_collection_set()) {
- // Update the collection set policy information for this region
- _g1h->g1_policy()->update_incremental_cset_info(_curr, rs_length);
- }
-
- _curr = _curr->get_next_young_region();
- if (_curr == NULL) {
- _last_sampled_rs_lengths = _sampled_rs_lengths;
- // gclog_or_tty->print_cr("last sampled RS lengths = %d", _last_sampled_rs_lengths);
- }
-}
-
-void
-YoungList::reset_auxilary_lists() {
- guarantee( is_empty(), "young list should be empty" );
- assert(check_list_well_formed(), "young list should be well formed");
-
- // Add survivor regions to SurvRateGroup.
- _g1h->g1_policy()->note_start_adding_survivor_regions();
- _g1h->g1_policy()->finished_recalculating_age_indexes(true /* is_survivors */);
-
- int young_index_in_cset = 0;
- for (HeapRegion* curr = _survivor_head;
- curr != NULL;
- curr = curr->get_next_young_region()) {
- _g1h->g1_policy()->set_region_survivor(curr, young_index_in_cset);
-
- // The region is a non-empty survivor so let's add it to
- // the incremental collection set for the next evacuation
- // pause.
- _g1h->g1_policy()->add_region_to_incremental_cset_rhs(curr);
- young_index_in_cset += 1;
- }
- assert((uint) young_index_in_cset == _survivor_length, "post-condition");
- _g1h->g1_policy()->note_stop_adding_survivor_regions();
-
- _head = _survivor_head;
- _length = _survivor_length;
- if (_survivor_head != NULL) {
- assert(_survivor_tail != NULL, "cause it shouldn't be");
- assert(_survivor_length > 0, "invariant");
- _survivor_tail->set_next_young_region(NULL);
- }
-
- // Don't clear the survivor list handles until the start of
- // the next evacuation pause - we need it in order to re-tag
- // the survivor regions from this evacuation pause as 'young'
- // at the start of the next.
-
- _g1h->g1_policy()->finished_recalculating_age_indexes(false /* is_survivors */);
-
- assert(check_list_well_formed(), "young list should be well formed");
-}
-
-void YoungList::print() {
- HeapRegion* lists[] = {_head, _survivor_head};
- const char* names[] = {"YOUNG", "SURVIVOR"};
-
- for (uint list = 0; list < ARRAY_SIZE(lists); ++list) {
- gclog_or_tty->print_cr("%s LIST CONTENTS", names[list]);
- HeapRegion *curr = lists[list];
- if (curr == NULL)
- gclog_or_tty->print_cr(" empty");
- while (curr != NULL) {
- gclog_or_tty->print_cr(" " HR_FORMAT ", P: " PTR_FORMAT ", N: " PTR_FORMAT ", age: %4d",
- HR_FORMAT_PARAMS(curr),
- p2i(curr->prev_top_at_mark_start()),
- p2i(curr->next_top_at_mark_start()),
- curr->age_in_surv_rate_group_cond());
- curr = curr->get_next_young_region();
- }
- }
-
- gclog_or_tty->cr();
-}
void G1RegionMappingChangedListener::reset_from_card_cache(uint start_idx, size_t num_regions) {
HeapRegionRemSet::invalidate_from_card_cache(start_idx, num_regions);
--- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.hpp Fri Oct 09 20:45:45 2015 +0000
+++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.hpp Tue Oct 13 08:37:44 2015 +0200
@@ -39,6 +39,7 @@
#include "gc/g1/hSpaceCounters.hpp"
#include "gc/g1/heapRegionManager.hpp"
#include "gc/g1/heapRegionSet.hpp"
+#include "gc/g1/youngList.hpp"
#include "gc/shared/barrierSet.hpp"
#include "gc/shared/collectedHeap.hpp"
#include "gc/shared/plab.hpp"
@@ -88,79 +89,6 @@
typedef int RegionIdx_t; // needs to hold [ 0..max_regions() )
typedef int CardIdx_t; // needs to hold [ 0..CardsPerRegion )
-class YoungList : public CHeapObj<mtGC> {
-private:
- G1CollectedHeap* _g1h;
-
- HeapRegion* _head;
-
- HeapRegion* _survivor_head;
- HeapRegion* _survivor_tail;
-
- HeapRegion* _curr;
-
- uint _length;
- uint _survivor_length;
-
- size_t _last_sampled_rs_lengths;
- size_t _sampled_rs_lengths;
-
- void empty_list(HeapRegion* list);
-
-public:
- YoungList(G1CollectedHeap* g1h);
-
- void push_region(HeapRegion* hr);
- void add_survivor_region(HeapRegion* hr);
-
- void empty_list();
- bool is_empty() { return _length == 0; }
- uint length() { return _length; }
- uint eden_length() { return length() - survivor_length(); }
- uint survivor_length() { return _survivor_length; }
-
- // Currently we do not keep track of the used byte sum for the
- // young list and the survivors and it'd be quite a lot of work to
- // do so. When we'll eventually replace the young list with
- // instances of HeapRegionLinkedList we'll get that for free. So,
- // we'll report the more accurate information then.
- size_t eden_used_bytes() {
- assert(length() >= survivor_length(), "invariant");
- return (size_t) eden_length() * HeapRegion::GrainBytes;
- }
- size_t survivor_used_bytes() {
- return (size_t) survivor_length() * HeapRegion::GrainBytes;
- }
-
- void rs_length_sampling_init();
- bool rs_length_sampling_more();
- void rs_length_sampling_next();
-
- void reset_sampled_info() {
- _last_sampled_rs_lengths = 0;
- }
- size_t sampled_rs_lengths() { return _last_sampled_rs_lengths; }
-
- // for development purposes
- void reset_auxilary_lists();
- void clear() { _head = NULL; _length = 0; }
-
- void clear_survivors() {
- _survivor_head = NULL;
- _survivor_tail = NULL;
- _survivor_length = 0;
- }
-
- HeapRegion* first_region() { return _head; }
- HeapRegion* first_survivor_region() { return _survivor_head; }
- HeapRegion* last_survivor_region() { return _survivor_tail; }
-
- // debugging
- bool check_list_well_formed();
- bool check_list_empty(bool check_sample = true);
- void print();
-};
-
// The G1 STW is alive closure.
// An instance is embedded into the G1CH and used as the
// (optional) _is_alive_non_header closure in the STW
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/gc/g1/youngList.cpp Tue Oct 13 08:37:44 2015 +0200
@@ -0,0 +1,241 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc/g1/g1CollectedHeap.hpp"
+#include "gc/g1/g1CollectorPolicy.hpp"
+#include "gc/g1/heapRegion.hpp"
+#include "gc/g1/heapRegion.inline.hpp"
+#include "gc/g1/heapRegionRemSet.hpp"
+#include "gc/g1/youngList.hpp"
+#include "utilities/ostream.hpp"
+
+YoungList::YoungList(G1CollectedHeap* g1h) :
+ _g1h(g1h), _head(NULL), _length(0), _last_sampled_rs_lengths(0),
+ _survivor_head(NULL), _survivor_tail(NULL), _survivor_length(0) {
+ guarantee(check_list_empty(false), "just making sure...");
+}
+
+void YoungList::push_region(HeapRegion *hr) {
+ assert(!hr->is_young(), "should not already be young");
+ assert(hr->get_next_young_region() == NULL, "cause it should!");
+
+ hr->set_next_young_region(_head);
+ _head = hr;
+
+ _g1h->g1_policy()->set_region_eden(hr, (int) _length);
+ ++_length;
+}
+
+void YoungList::add_survivor_region(HeapRegion* hr) {
+ assert(hr->is_survivor(), "should be flagged as survivor region");
+ assert(hr->get_next_young_region() == NULL, "cause it should!");
+
+ hr->set_next_young_region(_survivor_head);
+ if (_survivor_head == NULL) {
+ _survivor_tail = hr;
+ }
+ _survivor_head = hr;
+ ++_survivor_length;
+}
+
+void YoungList::empty_list(HeapRegion* list) {
+ while (list != NULL) {
+ HeapRegion* next = list->get_next_young_region();
+ list->set_next_young_region(NULL);
+ list->uninstall_surv_rate_group();
+ // This is called before a Full GC and all the non-empty /
+ // non-humongous regions at the end of the Full GC will end up as
+ // old anyway.
+ list->set_old();
+ list = next;
+ }
+}
+
+void YoungList::empty_list() {
+ assert(check_list_well_formed(), "young list should be well formed");
+
+ empty_list(_head);
+ _head = NULL;
+ _length = 0;
+
+ empty_list(_survivor_head);
+ _survivor_head = NULL;
+ _survivor_tail = NULL;
+ _survivor_length = 0;
+
+ _last_sampled_rs_lengths = 0;
+
+ assert(check_list_empty(false), "just making sure...");
+}
+
+bool YoungList::check_list_well_formed() {
+ bool ret = true;
+
+ uint length = 0;
+ HeapRegion* curr = _head;
+ HeapRegion* last = NULL;
+ while (curr != NULL) {
+ if (!curr->is_young()) {
+ gclog_or_tty->print_cr("### YOUNG REGION " PTR_FORMAT "-" PTR_FORMAT " "
+ "incorrectly tagged (y: %d, surv: %d)",
+ p2i(curr->bottom()), p2i(curr->end()),
+ curr->is_young(), curr->is_survivor());
+ ret = false;
+ }
+ ++length;
+ last = curr;
+ curr = curr->get_next_young_region();
+ }
+ ret = ret && (length == _length);
+
+ if (!ret) {
+ gclog_or_tty->print_cr("### YOUNG LIST seems not well formed!");
+ gclog_or_tty->print_cr("### list has %u entries, _length is %u",
+ length, _length);
+ }
+
+ return ret;
+}
+
+bool YoungList::check_list_empty(bool check_sample) {
+ bool ret = true;
+
+ if (_length != 0) {
+ gclog_or_tty->print_cr("### YOUNG LIST should have 0 length, not %u",
+ _length);
+ ret = false;
+ }
+ if (check_sample && _last_sampled_rs_lengths != 0) {
+ gclog_or_tty->print_cr("### YOUNG LIST has non-zero last sampled RS lengths");
+ ret = false;
+ }
+ if (_head != NULL) {
+ gclog_or_tty->print_cr("### YOUNG LIST does not have a NULL head");
+ ret = false;
+ }
+ if (!ret) {
+ gclog_or_tty->print_cr("### YOUNG LIST does not seem empty");
+ }
+
+ return ret;
+}
+
+void
+YoungList::rs_length_sampling_init() {
+ _sampled_rs_lengths = 0;
+ _curr = _head;
+}
+
+bool
+YoungList::rs_length_sampling_more() {
+ return _curr != NULL;
+}
+
+void
+YoungList::rs_length_sampling_next() {
+ assert( _curr != NULL, "invariant" );
+ size_t rs_length = _curr->rem_set()->occupied();
+
+ _sampled_rs_lengths += rs_length;
+
+ // The current region may not yet have been added to the
+ // incremental collection set (it gets added when it is
+ // retired as the current allocation region).
+ if (_curr->in_collection_set()) {
+ // Update the collection set policy information for this region
+ _g1h->g1_policy()->update_incremental_cset_info(_curr, rs_length);
+ }
+
+ _curr = _curr->get_next_young_region();
+ if (_curr == NULL) {
+ _last_sampled_rs_lengths = _sampled_rs_lengths;
+ // gclog_or_tty->print_cr("last sampled RS lengths = %d", _last_sampled_rs_lengths);
+ }
+}
+
+void
+YoungList::reset_auxilary_lists() {
+ guarantee( is_empty(), "young list should be empty" );
+ assert(check_list_well_formed(), "young list should be well formed");
+
+ // Add survivor regions to SurvRateGroup.
+ _g1h->g1_policy()->note_start_adding_survivor_regions();
+ _g1h->g1_policy()->finished_recalculating_age_indexes(true /* is_survivors */);
+
+ int young_index_in_cset = 0;
+ for (HeapRegion* curr = _survivor_head;
+ curr != NULL;
+ curr = curr->get_next_young_region()) {
+ _g1h->g1_policy()->set_region_survivor(curr, young_index_in_cset);
+
+ // The region is a non-empty survivor so let's add it to
+ // the incremental collection set for the next evacuation
+ // pause.
+ _g1h->g1_policy()->add_region_to_incremental_cset_rhs(curr);
+ young_index_in_cset += 1;
+ }
+ assert((uint) young_index_in_cset == _survivor_length, "post-condition");
+ _g1h->g1_policy()->note_stop_adding_survivor_regions();
+
+ _head = _survivor_head;
+ _length = _survivor_length;
+ if (_survivor_head != NULL) {
+ assert(_survivor_tail != NULL, "cause it shouldn't be");
+ assert(_survivor_length > 0, "invariant");
+ _survivor_tail->set_next_young_region(NULL);
+ }
+
+ // Don't clear the survivor list handles until the start of
+ // the next evacuation pause - we need it in order to re-tag
+ // the survivor regions from this evacuation pause as 'young'
+ // at the start of the next.
+
+ _g1h->g1_policy()->finished_recalculating_age_indexes(false /* is_survivors */);
+
+ assert(check_list_well_formed(), "young list should be well formed");
+}
+
+void YoungList::print() {
+ HeapRegion* lists[] = {_head, _survivor_head};
+ const char* names[] = {"YOUNG", "SURVIVOR"};
+
+ for (uint list = 0; list < ARRAY_SIZE(lists); ++list) {
+ gclog_or_tty->print_cr("%s LIST CONTENTS", names[list]);
+ HeapRegion *curr = lists[list];
+ if (curr == NULL) {
+ gclog_or_tty->print_cr(" empty");
+ }
+ while (curr != NULL) {
+ gclog_or_tty->print_cr(" " HR_FORMAT ", P: " PTR_FORMAT ", N: " PTR_FORMAT ", age: %4d",
+ HR_FORMAT_PARAMS(curr),
+ p2i(curr->prev_top_at_mark_start()),
+ p2i(curr->next_top_at_mark_start()),
+ curr->age_in_surv_rate_group_cond());
+ curr = curr->get_next_young_region();
+ }
+ }
+
+ gclog_or_tty->cr();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/gc/g1/youngList.hpp Tue Oct 13 08:37:44 2015 +0200
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_GC_G1_YOUNGLIST_HPP
+#define SHARE_VM_GC_G1_YOUNGLIST_HPP
+
+#include "memory/allocation.hpp"
+#include "runtime/globals.hpp"
+
+class YoungList : public CHeapObj<mtGC> {
+private:
+ G1CollectedHeap* _g1h;
+
+ HeapRegion* _head;
+
+ HeapRegion* _survivor_head;
+ HeapRegion* _survivor_tail;
+
+ HeapRegion* _curr;
+
+ uint _length;
+ uint _survivor_length;
+
+ size_t _last_sampled_rs_lengths;
+ size_t _sampled_rs_lengths;
+
+ void empty_list(HeapRegion* list);
+
+public:
+ YoungList(G1CollectedHeap* g1h);
+
+ void push_region(HeapRegion* hr);
+ void add_survivor_region(HeapRegion* hr);
+
+ void empty_list();
+ bool is_empty() { return _length == 0; }
+ uint length() { return _length; }
+ uint eden_length() { return length() - survivor_length(); }
+ uint survivor_length() { return _survivor_length; }
+
+ // Currently we do not keep track of the used byte sum for the
+ // young list and the survivors and it'd be quite a lot of work to
+ // do so. When we'll eventually replace the young list with
+ // instances of HeapRegionLinkedList we'll get that for free. So,
+ // we'll report the more accurate information then.
+ size_t eden_used_bytes() {
+ assert(length() >= survivor_length(), "invariant");
+ return (size_t) eden_length() * HeapRegion::GrainBytes;
+ }
+ size_t survivor_used_bytes() {
+ return (size_t) survivor_length() * HeapRegion::GrainBytes;
+ }
+
+ void rs_length_sampling_init();
+ bool rs_length_sampling_more();
+ void rs_length_sampling_next();
+
+ void reset_sampled_info() {
+ _last_sampled_rs_lengths = 0;
+ }
+ size_t sampled_rs_lengths() { return _last_sampled_rs_lengths; }
+
+ // for development purposes
+ void reset_auxilary_lists();
+ void clear() { _head = NULL; _length = 0; }
+
+ void clear_survivors() {
+ _survivor_head = NULL;
+ _survivor_tail = NULL;
+ _survivor_length = 0;
+ }
+
+ HeapRegion* first_region() { return _head; }
+ HeapRegion* first_survivor_region() { return _survivor_head; }
+ HeapRegion* last_survivor_region() { return _survivor_tail; }
+
+ // debugging
+ bool check_list_well_formed();
+ bool check_list_empty(bool check_sample = true);
+ void print();
+};
+
+#endif // SHARE_VM_GC_G1_YOUNGLIST_HPP