annotate src/share/vm/gc_implementation/g1/collectionSetChooser.cpp @ 4912:a9647476d1a4

7132029: G1: mixed GC phase lasts for longer than it should Summary: Revamp of the mechanism that chooses old regions for inclusion in the CSet. It simplifies the code and introduces min and max bounds on the number of old regions added to the CSet at each mixed GC to avoid pathological cases. It also ensures that when we do a mixed GC we'll always find old regions to add to the CSet (i.e., it eliminates the case where a mixed GC will collect no old regions which can happen today). Reviewed-by: johnc, brutisso
author tonyp
date Wed, 15 Feb 2012 13:06:53 -0500
parents 441e946dc1af
children 21595f05bc93
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
1 /*
4912
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
2 * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
4 *
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
7 * published by the Free Software Foundation.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
8 *
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
13 * accompanied this code).
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
14 *
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
18 *
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1103
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1103
diff changeset
20 * or visit www.oracle.com if you need additional information or have any
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1103
diff changeset
21 * questions.
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
22 *
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
23 */
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
24
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1688
diff changeset
25 #include "precompiled.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1688
diff changeset
26 #include "gc_implementation/g1/collectionSetChooser.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1688
diff changeset
27 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1688
diff changeset
28 #include "gc_implementation/g1/g1CollectorPolicy.hpp"
3914
20213c8a3c40 7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents: 2435
diff changeset
29 #include "gc_implementation/g1/g1ErgoVerbose.hpp"
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1688
diff changeset
30 #include "memory/space.inline.hpp"
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
31
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
32 CSetChooserCache::CSetChooserCache() {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
33 for (int i = 0; i < CacheLength; ++i)
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
34 _cache[i] = NULL;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
35 clear();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
36 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
37
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
38 void CSetChooserCache::clear() {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
39 _occupancy = 0;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
40 _first = 0;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
41 for (int i = 0; i < CacheLength; ++i) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
42 HeapRegion *hr = _cache[i];
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
43 if (hr != NULL)
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
44 hr->set_sort_index(-1);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
45 _cache[i] = NULL;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
46 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
47 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
48
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
49 #ifndef PRODUCT
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
50 bool CSetChooserCache::verify() {
4912
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
51 guarantee(false, "CSetChooserCache::verify(): don't call this any more");
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
52
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
53 int index = _first;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
54 HeapRegion *prev = NULL;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
55 for (int i = 0; i < _occupancy; ++i) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
56 guarantee(_cache[index] != NULL, "cache entry should not be empty");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
57 HeapRegion *hr = _cache[index];
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
58 guarantee(!hr->is_young(), "should not be young!");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
59 if (prev != NULL) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
60 guarantee(prev->gc_efficiency() >= hr->gc_efficiency(),
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
61 "cache should be correctly ordered");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
62 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
63 guarantee(hr->sort_index() == get_sort_index(index),
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
64 "sort index should be correct");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
65 index = trim_index(index + 1);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
66 prev = hr;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
67 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
68
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
69 for (int i = 0; i < (CacheLength - _occupancy); ++i) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
70 guarantee(_cache[index] == NULL, "cache entry should be empty");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
71 index = trim_index(index + 1);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
72 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
73
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
74 guarantee(index == _first, "we should have reached where we started from");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
75 return true;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
76 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
77 #endif // PRODUCT
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
78
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
79 void CSetChooserCache::insert(HeapRegion *hr) {
4912
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
80 guarantee(false, "CSetChooserCache::insert(): don't call this any more");
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
81
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
82 assert(!is_full(), "cache should not be empty");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
83 hr->calc_gc_efficiency();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
84
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
85 int empty_index;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
86 if (_occupancy == 0) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
87 empty_index = _first;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
88 } else {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
89 empty_index = trim_index(_first + _occupancy);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
90 assert(_cache[empty_index] == NULL, "last slot should be empty");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
91 int last_index = trim_index(empty_index - 1);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
92 HeapRegion *last = _cache[last_index];
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
93 assert(last != NULL,"as the cache is not empty, last should not be empty");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
94 while (empty_index != _first &&
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
95 last->gc_efficiency() < hr->gc_efficiency()) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
96 _cache[empty_index] = last;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
97 last->set_sort_index(get_sort_index(empty_index));
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
98 empty_index = last_index;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
99 last_index = trim_index(last_index - 1);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
100 last = _cache[last_index];
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
101 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
102 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
103 _cache[empty_index] = hr;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
104 hr->set_sort_index(get_sort_index(empty_index));
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
105
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
106 ++_occupancy;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
107 assert(verify(), "cache should be consistent");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
108 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
109
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
110 HeapRegion *CSetChooserCache::remove_first() {
4912
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
111 guarantee(false, "CSetChooserCache::remove_first(): "
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
112 "don't call this any more");
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
113
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
114 if (_occupancy > 0) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
115 assert(_cache[_first] != NULL, "cache should have at least one region");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
116 HeapRegion *ret = _cache[_first];
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
117 _cache[_first] = NULL;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
118 ret->set_sort_index(-1);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
119 --_occupancy;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
120 _first = trim_index(_first + 1);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
121 assert(verify(), "cache should be consistent");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
122 return ret;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
123 } else {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
124 return NULL;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
125 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
126 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
127
4912
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
128 // Even though we don't use the GC efficiency in our heuristics as
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
129 // much as we used to, we still order according to GC efficiency. This
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
130 // will cause regions with a lot of live objects and large RSets to
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
131 // end up at the end of the array. Given that we might skip collecting
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
132 // the last few old regions, if after a few mixed GCs the remaining
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
133 // have reclaimable bytes under a certain threshold, the hope is that
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
134 // the ones we'll skip are ones with both large RSets and a lot of
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
135 // live objects, not the ones with just a lot of live objects if we
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
136 // ordered according to the amount of reclaimable bytes per region.
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
137 static int orderRegions(HeapRegion* hr1, HeapRegion* hr2) {
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
138 if (hr1 == NULL) {
4912
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
139 if (hr2 == NULL) {
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
140 return 0;
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
141 } else {
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
142 return 1;
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
143 }
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
144 } else if (hr2 == NULL) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
145 return -1;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
146 }
4912
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
147
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
148 double gc_eff1 = hr1->gc_efficiency();
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
149 double gc_eff2 = hr2->gc_efficiency();
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
150 if (gc_eff1 > gc_eff2) {
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
151 return -1;
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
152 } if (gc_eff1 < gc_eff2) {
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
153 return 1;
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
154 } else {
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
155 return 0;
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
156 }
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
157 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
158
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
159 static int orderRegions(HeapRegion** hr1p, HeapRegion** hr2p) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
160 return orderRegions(*hr1p, *hr2p);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
161 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
162
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
163 CollectionSetChooser::CollectionSetChooser() :
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
164 // The line below is the worst bit of C++ hackery I've ever written
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
165 // (Detlefs, 11/23). You should think of it as equivalent to
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
166 // "_regions(100, true)": initialize the growable array and inform it
1688
2dfd013a7465 6975078: assert(allocated_on_res_area() || allocated_on_C_heap() || allocated_on_arena()
kvn
parents: 1552
diff changeset
167 // that it should allocate its elem array(s) on the C heap.
2dfd013a7465 6975078: assert(allocated_on_res_area() || allocated_on_C_heap() || allocated_on_arena()
kvn
parents: 1552
diff changeset
168 //
2dfd013a7465 6975078: assert(allocated_on_res_area() || allocated_on_C_heap() || allocated_on_arena()
kvn
parents: 1552
diff changeset
169 // The first argument, however, is actually a comma expression
2dfd013a7465 6975078: assert(allocated_on_res_area() || allocated_on_C_heap() || allocated_on_arena()
kvn
parents: 1552
diff changeset
170 // (set_allocation_type(this, C_HEAP), 100). The purpose of the
2dfd013a7465 6975078: assert(allocated_on_res_area() || allocated_on_C_heap() || allocated_on_arena()
kvn
parents: 1552
diff changeset
171 // set_allocation_type() call is to replace the default allocation
2dfd013a7465 6975078: assert(allocated_on_res_area() || allocated_on_C_heap() || allocated_on_arena()
kvn
parents: 1552
diff changeset
172 // type for embedded objects STACK_OR_EMBEDDED with C_HEAP. It will
2dfd013a7465 6975078: assert(allocated_on_res_area() || allocated_on_C_heap() || allocated_on_arena()
kvn
parents: 1552
diff changeset
173 // allow to pass the assert in GenericGrowableArray() which checks
2dfd013a7465 6975078: assert(allocated_on_res_area() || allocated_on_C_heap() || allocated_on_arena()
kvn
parents: 1552
diff changeset
174 // that a growable array object must be on C heap if elements are.
2dfd013a7465 6975078: assert(allocated_on_res_area() || allocated_on_C_heap() || allocated_on_arena()
kvn
parents: 1552
diff changeset
175 //
2dfd013a7465 6975078: assert(allocated_on_res_area() || allocated_on_C_heap() || allocated_on_arena()
kvn
parents: 1552
diff changeset
176 // Note: containing object is allocated on C heap since it is CHeapObj.
2dfd013a7465 6975078: assert(allocated_on_res_area() || allocated_on_C_heap() || allocated_on_arena()
kvn
parents: 1552
diff changeset
177 //
2dfd013a7465 6975078: assert(allocated_on_res_area() || allocated_on_C_heap() || allocated_on_arena()
kvn
parents: 1552
diff changeset
178 _markedRegions((ResourceObj::set_allocation_type((address)&_markedRegions,
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
179 ResourceObj::C_HEAP),
4912
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
180 100), true /* C_Heap */),
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
181 _curr_index(0), _length(0),
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
182 _regionLiveThresholdBytes(0), _remainingReclaimableBytes(0),
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
183 _first_par_unreserved_idx(0) {
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
184 _regionLiveThresholdBytes =
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
185 HeapRegion::GrainBytes * (size_t) G1OldCSetRegionLiveThresholdPercent / 100;
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
186 }
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
187
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
188 #ifndef PRODUCT
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
189 bool CollectionSetChooser::verify() {
4912
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
190 guarantee(_length >= 0, err_msg("_length: %d", _length));
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
191 guarantee(0 <= _curr_index && _curr_index <= _length,
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
192 err_msg("_curr_index: %d _length: %d", _curr_index, _length));
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
193 int index = 0;
4912
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
194 size_t sum_of_reclaimable_bytes = 0;
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
195 while (index < _curr_index) {
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
196 guarantee(_markedRegions.at(index) == NULL,
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
197 "all entries before _curr_index should be NULL");
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
198 index += 1;
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
199 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
200 HeapRegion *prev = NULL;
4912
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
201 while (index < _length) {
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
202 HeapRegion *curr = _markedRegions.at(index++);
3989
b9390528617c 7095236: G1: _markedRegions never contains NULL regions
ysr
parents: 3914
diff changeset
203 guarantee(curr != NULL, "Regions in _markedRegions array cannot be NULL");
b9390528617c 7095236: G1: _markedRegions never contains NULL regions
ysr
parents: 3914
diff changeset
204 int si = curr->sort_index();
b9390528617c 7095236: G1: _markedRegions never contains NULL regions
ysr
parents: 3914
diff changeset
205 guarantee(!curr->is_young(), "should not be young!");
4912
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
206 guarantee(!curr->isHumongous(), "should not be humongous!");
3989
b9390528617c 7095236: G1: _markedRegions never contains NULL regions
ysr
parents: 3914
diff changeset
207 guarantee(si > -1 && si == (index-1), "sort index invariant");
b9390528617c 7095236: G1: _markedRegions never contains NULL regions
ysr
parents: 3914
diff changeset
208 if (prev != NULL) {
4912
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
209 guarantee(orderRegions(prev, curr) != 1,
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
210 err_msg("GC eff prev: %1.4f GC eff curr: %1.4f",
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
211 prev->gc_efficiency(), curr->gc_efficiency()));
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
212 }
4912
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
213 sum_of_reclaimable_bytes += curr->reclaimable_bytes();
3989
b9390528617c 7095236: G1: _markedRegions never contains NULL regions
ysr
parents: 3914
diff changeset
214 prev = curr;
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
215 }
4912
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
216 guarantee(sum_of_reclaimable_bytes == _remainingReclaimableBytes,
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
217 err_msg("reclaimable bytes inconsistent, "
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
218 "remaining: "SIZE_FORMAT" sum: "SIZE_FORMAT,
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
219 _remainingReclaimableBytes, sum_of_reclaimable_bytes));
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
220 return true;
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
221 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
222 #endif
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
223
4912
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
224 void CollectionSetChooser::fillCache() {
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
225 guarantee(false, "fillCache: don't call this any more");
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
226
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
227 while (!_cache.is_full() && (_curr_index < _length)) {
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
228 HeapRegion* hr = _markedRegions.at(_curr_index);
3989
b9390528617c 7095236: G1: _markedRegions never contains NULL regions
ysr
parents: 3914
diff changeset
229 assert(hr != NULL,
b9390528617c 7095236: G1: _markedRegions never contains NULL regions
ysr
parents: 3914
diff changeset
230 err_msg("Unexpected NULL hr in _markedRegions at index %d",
4912
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
231 _curr_index));
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
232 _curr_index += 1;
3989
b9390528617c 7095236: G1: _markedRegions never contains NULL regions
ysr
parents: 3914
diff changeset
233 assert(!hr->is_young(), "should not be young!");
4912
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
234 assert(hr->sort_index() == _curr_index-1, "sort_index invariant");
3989
b9390528617c 7095236: G1: _markedRegions never contains NULL regions
ysr
parents: 3914
diff changeset
235 _markedRegions.at_put(hr->sort_index(), NULL);
b9390528617c 7095236: G1: _markedRegions never contains NULL regions
ysr
parents: 3914
diff changeset
236 _cache.insert(hr);
b9390528617c 7095236: G1: _markedRegions never contains NULL regions
ysr
parents: 3914
diff changeset
237 assert(!_cache.is_empty(), "cache should not be empty");
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
238 }
3989
b9390528617c 7095236: G1: _markedRegions never contains NULL regions
ysr
parents: 3914
diff changeset
239 assert(verify(), "cache should be consistent");
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
240 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
241
4912
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
242 void CollectionSetChooser::sortMarkedHeapRegions() {
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
243 // First trim any unused portion of the top in the parallel case.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
244 if (_first_par_unreserved_idx > 0) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
245 if (G1PrintParCleanupStats) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
246 gclog_or_tty->print(" Truncating _markedRegions from %d to %d.\n",
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
247 _markedRegions.length(), _first_par_unreserved_idx);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
248 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
249 assert(_first_par_unreserved_idx <= _markedRegions.length(),
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
250 "Or we didn't reserved enough length");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
251 _markedRegions.trunc_to(_first_par_unreserved_idx);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
252 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
253 _markedRegions.sort(orderRegions);
4912
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
254 assert(_length <= _markedRegions.length(), "Requirement");
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
255 assert(_length == 0 || _markedRegions.at(_length - 1) != NULL,
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
256 "Testing _length");
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
257 assert(_length == _markedRegions.length() ||
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
258 _markedRegions.at(_length) == NULL, "Testing _length");
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
259 if (G1PrintParCleanupStats) {
4912
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
260 gclog_or_tty->print_cr(" Sorted %d marked regions.", _length);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
261 }
4912
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
262 for (int i = 0; i < _length; i++) {
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
263 assert(_markedRegions.at(i) != NULL, "Should be true by sorting!");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
264 _markedRegions.at(i)->set_sort_index(i);
2435
371bbc844bf1 7027766: G1: introduce flag to dump the liveness information per region at the end of marking
tonyp
parents: 1972
diff changeset
265 }
371bbc844bf1 7027766: G1: introduce flag to dump the liveness information per region at the end of marking
tonyp
parents: 1972
diff changeset
266 if (G1PrintRegionLivenessInfo) {
371bbc844bf1 7027766: G1: introduce flag to dump the liveness information per region at the end of marking
tonyp
parents: 1972
diff changeset
267 G1PrintRegionLivenessInfoClosure cl(gclog_or_tty, "Post-Sorting");
4912
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
268 for (int i = 0; i < _length; ++i) {
2435
371bbc844bf1 7027766: G1: introduce flag to dump the liveness information per region at the end of marking
tonyp
parents: 1972
diff changeset
269 HeapRegion* r = _markedRegions.at(i);
371bbc844bf1 7027766: G1: introduce flag to dump the liveness information per region at the end of marking
tonyp
parents: 1972
diff changeset
270 cl.doHeapRegion(r);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
271 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
272 }
4912
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
273 assert(verify(), "CSet chooser verification");
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
274 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
275
4912
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
276 size_t CollectionSetChooser::calcMinOldCSetLength() {
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
277 // The min old CSet region bound is based on the maximum desired
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
278 // number of mixed GCs after a cycle. I.e., even if some old regions
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
279 // look expensive, we should add them to the CSet anyway to make
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
280 // sure we go through the available old regions in no more than the
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
281 // maximum desired number of mixed GCs.
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
282 //
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
283 // The calculation is based on the number of marked regions we added
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
284 // to the CSet chooser in the first place, not how many remain, so
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
285 // that the result is the same during all mixed GCs that follow a cycle.
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
286
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
287 const size_t region_num = (size_t) _length;
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
288 const size_t gc_num = (size_t) G1MaxMixedGCNum;
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
289 size_t result = region_num / gc_num;
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
290 // emulate ceiling
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
291 if (result * gc_num < region_num) {
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
292 result += 1;
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
293 }
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
294 return result;
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
295 }
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
296
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
297 size_t CollectionSetChooser::calcMaxOldCSetLength() {
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
298 // The max old CSet region bound is based on the threshold expressed
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
299 // as a percentage of the heap size. I.e., it should bound the
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
300 // number of old regions added to the CSet irrespective of how many
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
301 // of them are available.
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
302
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
303 G1CollectedHeap* g1h = G1CollectedHeap::heap();
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
304 const size_t region_num = g1h->n_regions();
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
305 const size_t perc = (size_t) G1OldCSetRegionThresholdPercent;
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
306 size_t result = region_num * perc / 100;
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
307 // emulate ceiling
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
308 if (100 * result < region_num * perc) {
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
309 result += 1;
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
310 }
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
311 return result;
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
312 }
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
313
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
314 void CollectionSetChooser::addMarkedHeapRegion(HeapRegion* hr) {
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
315 assert(!hr->isHumongous(),
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
316 "Humongous regions shouldn't be added to the collection set");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
317 assert(!hr->is_young(), "should not be young!");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
318 _markedRegions.append(hr);
4912
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
319 _length++;
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
320 _remainingReclaimableBytes += hr->reclaimable_bytes();
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
321 hr->calc_gc_efficiency();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
322 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
323
4912
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
324 void CollectionSetChooser::prepareForAddMarkedHeapRegionsPar(size_t n_regions,
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
325 size_t chunkSize) {
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
326 _first_par_unreserved_idx = 0;
4095
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 3989
diff changeset
327 int n_threads = ParallelGCThreads;
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 3989
diff changeset
328 if (UseDynamicNumberOfGCThreads) {
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 3989
diff changeset
329 assert(G1CollectedHeap::heap()->workers()->active_workers() > 0,
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 3989
diff changeset
330 "Should have been set earlier");
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 3989
diff changeset
331 // This is defensive code. As the assertion above says, the number
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 3989
diff changeset
332 // of active threads should be > 0, but in case there is some path
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 3989
diff changeset
333 // or some improperly initialized variable with leads to no
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 3989
diff changeset
334 // active threads, protect against that in a product build.
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 3989
diff changeset
335 n_threads = MAX2(G1CollectedHeap::heap()->workers()->active_workers(),
4728
441e946dc1af 7121618: Change type of number of GC workers to unsigned int.
jmasa
parents: 4095
diff changeset
336 1U);
4095
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 3989
diff changeset
337 }
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 3989
diff changeset
338 size_t max_waste = n_threads * chunkSize;
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
339 // it should be aligned with respect to chunkSize
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
340 size_t aligned_n_regions =
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
341 (n_regions + (chunkSize - 1)) / chunkSize * chunkSize;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
342 assert( aligned_n_regions % chunkSize == 0, "should be aligned" );
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
343 _markedRegions.at_put_grow((int)(aligned_n_regions + max_waste - 1), NULL);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
344 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
345
4912
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
346 jint CollectionSetChooser::getParMarkedHeapRegionChunk(jint n_regions) {
4095
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 3989
diff changeset
347 // Don't do this assert because this can be called at a point
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 3989
diff changeset
348 // where the loop up stream will not execute again but might
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 3989
diff changeset
349 // try to claim more chunks (loop test has not been done yet).
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 3989
diff changeset
350 // assert(_markedRegions.length() > _first_par_unreserved_idx,
bca17e38de00 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 3989
diff changeset
351 // "Striding beyond the marked regions");
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
352 jint res = Atomic::add(n_regions, &_first_par_unreserved_idx);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
353 assert(_markedRegions.length() > res + n_regions - 1,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
354 "Should already have been expanded");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
355 return res - n_regions;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
356 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
357
4912
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
358 void CollectionSetChooser::setMarkedHeapRegion(jint index, HeapRegion* hr) {
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
359 assert(_markedRegions.at(index) == NULL, "precondition");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
360 assert(!hr->is_young(), "should not be young!");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
361 _markedRegions.at_put(index, hr);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
362 hr->calc_gc_efficiency();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
363 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
364
4912
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
365 void CollectionSetChooser::updateTotals(jint region_num,
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
366 size_t reclaimable_bytes) {
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
367 // Only take the lock if we actually need to update the totals.
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
368 if (region_num > 0) {
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
369 assert(reclaimable_bytes > 0, "invariant");
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
370 // We could have just used atomics instead of taking the
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
371 // lock. However, we currently don't have an atomic add for size_t.
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
372 MutexLockerEx x(ParGCRareEvent_lock, Mutex::_no_safepoint_check_flag);
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
373 _length += (int) region_num;
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
374 _remainingReclaimableBytes += reclaimable_bytes;
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
375 } else {
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
376 assert(reclaimable_bytes == 0, "invariant");
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
377 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
378 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
379
4912
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
380 void CollectionSetChooser::clearMarkedHeapRegions() {
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
381 for (int i = 0; i < _markedRegions.length(); i++) {
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
382 HeapRegion* r = _markedRegions.at(i);
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
383 if (r != NULL) {
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
384 r->set_sort_index(-1);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
385 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
386 }
4912
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
387 _markedRegions.clear();
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
388 _curr_index = 0;
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
389 _length = 0;
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
390 _remainingReclaimableBytes = 0;
a9647476d1a4 7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents: 4728
diff changeset
391 };