Sat, 06 Oct 2012 01:17:44 -0700
7127708: G1: change task num types from int to uint in concurrent mark
Summary: Change the type of various task num fields, parameters etc to unsigned and rename them to be more consistent with the other collectors. Code changes were also reviewed by Vitaly Davidovich.
Reviewed-by: johnc
Contributed-by: Kaushik Srenevasan <kaushik@twitter.com>
1 /*
2 * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
25 #include "precompiled.hpp"
26 #include "gc_implementation/g1/g1MonitoringSupport.hpp"
27 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
28 #include "gc_implementation/g1/g1CollectorPolicy.hpp"
30 G1GenerationCounters::G1GenerationCounters(G1MonitoringSupport* g1mm,
31 const char* name,
32 int ordinal, int spaces,
33 size_t min_capacity,
34 size_t max_capacity,
35 size_t curr_capacity)
36 : GenerationCounters(name, ordinal, spaces, min_capacity,
37 max_capacity, curr_capacity), _g1mm(g1mm) { }
39 // We pad the capacity three times given that the young generation
40 // contains three spaces (eden and two survivors).
41 G1YoungGenerationCounters::G1YoungGenerationCounters(G1MonitoringSupport* g1mm,
42 const char* name)
43 : G1GenerationCounters(g1mm, name, 0 /* ordinal */, 3 /* spaces */,
44 G1MonitoringSupport::pad_capacity(0, 3) /* min_capacity */,
45 G1MonitoringSupport::pad_capacity(g1mm->young_gen_max(), 3),
46 G1MonitoringSupport::pad_capacity(0, 3) /* curr_capacity */) {
47 if (UsePerfData) {
48 update_all();
49 }
50 }
52 G1OldGenerationCounters::G1OldGenerationCounters(G1MonitoringSupport* g1mm,
53 const char* name)
54 : G1GenerationCounters(g1mm, name, 1 /* ordinal */, 1 /* spaces */,
55 G1MonitoringSupport::pad_capacity(0) /* min_capacity */,
56 G1MonitoringSupport::pad_capacity(g1mm->old_gen_max()),
57 G1MonitoringSupport::pad_capacity(0) /* curr_capacity */) {
58 if (UsePerfData) {
59 update_all();
60 }
61 }
63 void G1YoungGenerationCounters::update_all() {
64 size_t committed =
65 G1MonitoringSupport::pad_capacity(_g1mm->young_gen_committed(), 3);
66 _current_size->set_value(committed);
67 }
69 void G1OldGenerationCounters::update_all() {
70 size_t committed =
71 G1MonitoringSupport::pad_capacity(_g1mm->old_gen_committed());
72 _current_size->set_value(committed);
73 }
75 G1MonitoringSupport::G1MonitoringSupport(G1CollectedHeap* g1h) :
76 _g1h(g1h),
77 _incremental_collection_counters(NULL),
78 _full_collection_counters(NULL),
79 _old_collection_counters(NULL),
80 _old_space_counters(NULL),
81 _young_collection_counters(NULL),
82 _eden_counters(NULL),
83 _from_counters(NULL),
84 _to_counters(NULL),
86 _overall_reserved(0),
87 _overall_committed(0), _overall_used(0),
88 _young_region_num(0),
89 _young_gen_committed(0),
90 _eden_committed(0), _eden_used(0),
91 _survivor_committed(0), _survivor_used(0),
92 _old_committed(0), _old_used(0) {
94 _overall_reserved = g1h->max_capacity();
95 recalculate_sizes();
97 // Counters for GC collections
98 //
99 // name "collector.0". In a generational collector this would be the
100 // young generation collection.
101 _incremental_collection_counters =
102 new CollectorCounters("G1 incremental collections", 0);
103 // name "collector.1". In a generational collector this would be the
104 // old generation collection.
105 _full_collection_counters =
106 new CollectorCounters("G1 stop-the-world full collections", 1);
108 // timer sampling for all counters supporting sampling only update the
109 // used value. See the take_sample() method. G1 requires both used and
110 // capacity updated so sampling is not currently used. It might
111 // be sufficient to update all counters in take_sample() even though
112 // take_sample() only returns "used". When sampling was used, there
113 // were some anomolous values emitted which may have been the consequence
114 // of not updating all values simultaneously (i.e., see the calculation done
115 // in eden_space_used(), is it possbile that the values used to
116 // calculate either eden_used or survivor_used are being updated by
117 // the collector when the sample is being done?).
118 const bool sampled = false;
120 // "Generation" and "Space" counters.
121 //
122 // name "generation.1" This is logically the old generation in
123 // generational GC terms. The "1, 1" parameters are for
124 // the n-th generation (=1) with 1 space.
125 // Counters are created from minCapacity, maxCapacity, and capacity
126 _old_collection_counters = new G1OldGenerationCounters(this, "old");
128 // name "generation.1.space.0"
129 // Counters are created from maxCapacity, capacity, initCapacity,
130 // and used.
131 _old_space_counters = new HSpaceCounters("space", 0 /* ordinal */,
132 pad_capacity(overall_reserved()) /* max_capacity */,
133 pad_capacity(old_space_committed()) /* init_capacity */,
134 _old_collection_counters);
136 // Young collection set
137 // name "generation.0". This is logically the young generation.
138 // The "0, 3" are paremeters for the n-th genertaion (=0) with 3 spaces.
139 // See _old_collection_counters for additional counters
140 _young_collection_counters = new G1YoungGenerationCounters(this, "young");
142 // name "generation.0.space.0"
143 // See _old_space_counters for additional counters
144 _eden_counters = new HSpaceCounters("eden", 0 /* ordinal */,
145 pad_capacity(overall_reserved()) /* max_capacity */,
146 pad_capacity(eden_space_committed()) /* init_capacity */,
147 _young_collection_counters);
149 // name "generation.0.space.1"
150 // See _old_space_counters for additional counters
151 // Set the arguments to indicate that this survivor space is not used.
152 _from_counters = new HSpaceCounters("s0", 1 /* ordinal */,
153 pad_capacity(0) /* max_capacity */,
154 pad_capacity(0) /* init_capacity */,
155 _young_collection_counters);
157 // name "generation.0.space.2"
158 // See _old_space_counters for additional counters
159 _to_counters = new HSpaceCounters("s1", 2 /* ordinal */,
160 pad_capacity(overall_reserved()) /* max_capacity */,
161 pad_capacity(survivor_space_committed()) /* init_capacity */,
162 _young_collection_counters);
164 if (UsePerfData) {
165 // Given that this survivor space is not used, we update it here
166 // once to reflect that its used space is 0 so that we don't have to
167 // worry about updating it again later.
168 _from_counters->update_used(0);
169 }
170 }
172 void G1MonitoringSupport::recalculate_sizes() {
173 G1CollectedHeap* g1 = g1h();
175 // Recalculate all the sizes from scratch. We assume that this is
176 // called at a point where no concurrent updates to the various
177 // values we read here are possible (i.e., at a STW phase at the end
178 // of a GC).
180 uint young_list_length = g1->young_list()->length();
181 uint survivor_list_length = g1->g1_policy()->recorded_survivor_regions();
182 assert(young_list_length >= survivor_list_length, "invariant");
183 uint eden_list_length = young_list_length - survivor_list_length;
184 // Max length includes any potential extensions to the young gen
185 // we'll do when the GC locker is active.
186 uint young_list_max_length = g1->g1_policy()->young_list_max_length();
187 assert(young_list_max_length >= survivor_list_length, "invariant");
188 uint eden_list_max_length = young_list_max_length - survivor_list_length;
190 _overall_used = g1->used_unlocked();
191 _eden_used = (size_t) eden_list_length * HeapRegion::GrainBytes;
192 _survivor_used = (size_t) survivor_list_length * HeapRegion::GrainBytes;
193 _young_region_num = young_list_length;
194 _old_used = subtract_up_to_zero(_overall_used, _eden_used + _survivor_used);
196 // First calculate the committed sizes that can be calculated independently.
197 _survivor_committed = _survivor_used;
198 _old_committed = HeapRegion::align_up_to_region_byte_size(_old_used);
200 // Next, start with the overall committed size.
201 _overall_committed = g1->capacity();
202 size_t committed = _overall_committed;
204 // Remove the committed size we have calculated so far (for the
205 // survivor and old space).
206 assert(committed >= (_survivor_committed + _old_committed), "sanity");
207 committed -= _survivor_committed + _old_committed;
209 // Next, calculate and remove the committed size for the eden.
210 _eden_committed = (size_t) eden_list_max_length * HeapRegion::GrainBytes;
211 // Somewhat defensive: be robust in case there are inaccuracies in
212 // the calculations
213 _eden_committed = MIN2(_eden_committed, committed);
214 committed -= _eden_committed;
216 // Finally, give the rest to the old space...
217 _old_committed += committed;
218 // ..and calculate the young gen committed.
219 _young_gen_committed = _eden_committed + _survivor_committed;
221 assert(_overall_committed ==
222 (_eden_committed + _survivor_committed + _old_committed),
223 "the committed sizes should add up");
224 // Somewhat defensive: cap the eden used size to make sure it
225 // never exceeds the committed size.
226 _eden_used = MIN2(_eden_used, _eden_committed);
227 // _survivor_committed and _old_committed are calculated in terms of
228 // the corresponding _*_used value, so the next two conditions
229 // should hold.
230 assert(_survivor_used <= _survivor_committed, "post-condition");
231 assert(_old_used <= _old_committed, "post-condition");
232 }
234 void G1MonitoringSupport::recalculate_eden_size() {
235 G1CollectedHeap* g1 = g1h();
237 // When a new eden region is allocated, only the eden_used size is
238 // affected (since we have recalculated everything else at the last GC).
240 uint young_region_num = g1h()->young_list()->length();
241 if (young_region_num > _young_region_num) {
242 uint diff = young_region_num - _young_region_num;
243 _eden_used += (size_t) diff * HeapRegion::GrainBytes;
244 // Somewhat defensive: cap the eden used size to make sure it
245 // never exceeds the committed size.
246 _eden_used = MIN2(_eden_used, _eden_committed);
247 _young_region_num = young_region_num;
248 }
249 }
251 void G1MonitoringSupport::update_sizes() {
252 recalculate_sizes();
253 if (UsePerfData) {
254 eden_counters()->update_capacity(pad_capacity(eden_space_committed()));
255 eden_counters()->update_used(eden_space_used());
256 // only the to survivor space (s1) is active, so we don't need to
257 // update the counteres for the from survivor space (s0)
258 to_counters()->update_capacity(pad_capacity(survivor_space_committed()));
259 to_counters()->update_used(survivor_space_used());
260 old_space_counters()->update_capacity(pad_capacity(old_space_committed()));
261 old_space_counters()->update_used(old_space_used());
262 old_collection_counters()->update_all();
263 young_collection_counters()->update_all();
264 MetaspaceCounters::update_performance_counters();
265 }
266 }
268 void G1MonitoringSupport::update_eden_size() {
269 recalculate_eden_size();
270 if (UsePerfData) {
271 eden_counters()->update_used(eden_space_used());
272 }
273 }