Skip to content

Commit fc89fe6

Browse files
author
Ivan Walulya
committedApr 16, 2021
8265119: G1: update_remset_before_rebuild mixes liveness in words with liveness in bytes
Reviewed-by: tschatzl, sjohanss
1 parent 50f3da8 commit fc89fe6

File tree

5 files changed

+143
-8
lines changed

5 files changed

+143
-8
lines changed
 

‎src/hotspot/share/gc/g1/g1ConcurrentMark.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -988,10 +988,10 @@ class G1UpdateRemSetTrackingBeforeRebuildTask : public AbstractGangTask {
988988

989989
bool selected_for_rebuild;
990990
if (hr->is_humongous()) {
991-
bool const is_live = _cm->liveness(hr->humongous_start_region()->hrm_index()) > 0;
991+
bool const is_live = _cm->live_words(hr->humongous_start_region()->hrm_index()) > 0;
992992
selected_for_rebuild = tracking_policy->update_humongous_before_rebuild(hr, is_live);
993993
} else {
994-
size_t const live_bytes = _cm->liveness(hr->hrm_index());
994+
size_t const live_bytes = _cm->live_bytes(hr->hrm_index());
995995
selected_for_rebuild = tracking_policy->update_before_rebuild(hr, live_bytes);
996996
}
997997
if (selected_for_rebuild) {
@@ -1029,7 +1029,7 @@ class G1UpdateRemSetTrackingBeforeRebuildTask : public AbstractGangTask {
10291029

10301030
void update_marked_bytes(HeapRegion* hr) {
10311031
uint const region_idx = hr->hrm_index();
1032-
size_t const marked_words = _cm->liveness(region_idx);
1032+
size_t const marked_words = _cm->live_words(region_idx);
10331033
// The marking attributes the object's size completely to the humongous starts
10341034
// region. We need to distribute this value across the entire set of regions a
10351035
// humongous object spans.
@@ -1042,7 +1042,7 @@ class G1UpdateRemSetTrackingBeforeRebuildTask : public AbstractGangTask {
10421042
}
10431043
} else {
10441044
log_trace(gc, marking)("Adding " SIZE_FORMAT " words to region %u (%s)", marked_words, region_idx, hr->get_type_str());
1045-
add_marked_bytes_and_note_end(hr, marked_words * HeapWordSize);
1045+
add_marked_bytes_and_note_end(hr, _cm->live_bytes(region_idx));
10461046
}
10471047
}
10481048

‎src/hotspot/share/gc/g1/g1ConcurrentMark.hpp

+4-2
Original file line numberDiff line numberDiff line change
@@ -459,9 +459,11 @@ class G1ConcurrentMark : public CHeapObj<mtGC> {
459459
HeapWord* volatile* _top_at_rebuild_starts;
460460
public:
461461
void add_to_liveness(uint worker_id, oop const obj, size_t size);
462-
// Liveness of the given region as determined by concurrent marking, i.e. the amount of
462+
// Live words in the given region as determined by concurrent marking, i.e. the amount of
463463
// live words between bottom and nTAMS.
464-
size_t liveness(uint region) const { return _region_mark_stats[region]._live_words; }
464+
size_t live_words(uint region) const { return _region_mark_stats[region]._live_words; }
465+
// Returns the liveness value in bytes.
466+
size_t live_bytes(uint region) const { return live_words(region) * HeapWordSize; }
465467

466468
// Sets the internal top_at_region_start for the given region to current top of the region.
467469
inline void update_top_at_rebuild_start(HeapRegion* r);

‎src/hotspot/share/gc/g1/g1RemSet.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1821,7 +1821,7 @@ class G1RebuildRemSetTask: public AbstractGangTask {
18211821
"TAMS " PTR_FORMAT " "
18221822
"TARS " PTR_FORMAT,
18231823
region_idx,
1824-
_cm->liveness(region_idx) * HeapWordSize,
1824+
_cm->live_bytes(region_idx),
18251825
time.seconds() * 1000.0,
18261826
marked_bytes,
18271827
p2i(hr->bottom()),

‎src/hotspot/share/gc/g1/g1RemSetTrackingPolicy.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ void G1RemSetTrackingPolicy::update_after_rebuild(HeapRegion* r) {
170170
"size " SIZE_FORMAT ")",
171171
r->hrm_index(),
172172
p2i(r->next_top_at_mark_start()),
173-
cm->liveness(r->hrm_index()) * HeapWordSize,
173+
cm->live_bytes(r->hrm_index()),
174174
r->next_marked_bytes(),
175175
r->rem_set()->occupied(),
176176
r->rem_set()->mem_size());
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
/*
2+
* Copyright (c) 2021, 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+
24+
package gc.g1;
25+
26+
/*
27+
* @test TestMixedGCLiveThreshold
28+
* @summary Test G1MixedGCLiveThresholdPercent. Fill up a region to at least 1/3 region-size,
29+
* the region should not be selected for mixed GC cycle if liveness is above threshold.
30+
* @requires vm.gc.G1
31+
* @library /test/lib
32+
* @build sun.hotspot.WhiteBox
33+
* @run driver jdk.test.lib.helpers.ClassFileInstaller sun.hotspot.WhiteBox
34+
* @run driver gc.g1.TestMixedGCLiveThreshold
35+
*/
36+
37+
import java.util.ArrayList;
38+
import java.util.Collections;
39+
import java.util.regex.Pattern;
40+
import java.util.regex.Matcher;
41+
42+
import jdk.test.lib.process.OutputAnalyzer;
43+
import jdk.test.lib.process.ProcessTools;
44+
import jdk.test.lib.Asserts;
45+
import sun.hotspot.WhiteBox;
46+
47+
public class TestMixedGCLiveThreshold {
48+
private static final String pattern = "Remembered Set Tracking update regions total ([0-9]+), selected ([0-9]+)$";
49+
50+
public static void main(String[] args) throws Exception {
51+
// -XX:G1MixedGCLiveThresholdPercent=0
52+
testMixedGCLiveThresholdPercent(0, false);
53+
54+
// -XX:G1MixedGCLiveThresholdPercent=25
55+
testMixedGCLiveThresholdPercent(25, false);
56+
57+
// -XX:G1MixedGCLiveThresholdPercent=100
58+
testMixedGCLiveThresholdPercent(100, true);
59+
}
60+
61+
private static void testMixedGCLiveThresholdPercent(int liveThresholdPercent, boolean expectedRebuild) throws Exception {
62+
OutputAnalyzer output = testWithMixedGCLiveThresholdPercent(liveThresholdPercent);
63+
64+
boolean regionsSelected = regionsSelectedForRebuild(output.getStdout());
65+
66+
Asserts.assertEquals(regionsSelected, expectedRebuild,
67+
(expectedRebuild ?
68+
"No Regions selected for rebuild. G1MixedGCLiveThresholdPercent=" + liveThresholdPercent +
69+
" at least one region should be selected" :
70+
"Regions selected for rebuild. G1MixedGCLiveThresholdPercent=" + liveThresholdPercent +
71+
" no regions should be selected")
72+
);
73+
output.shouldHaveExitValue(0);
74+
}
75+
76+
private static OutputAnalyzer testWithMixedGCLiveThresholdPercent(int percent) throws Exception {
77+
ArrayList<String> basicOpts = new ArrayList<>();
78+
Collections.addAll(basicOpts, new String[] {
79+
"-Xbootclasspath/a:.",
80+
"-XX:+UseG1GC",
81+
"-XX:+UnlockDiagnosticVMOptions",
82+
"-XX:+UnlockExperimentalVMOptions",
83+
"-XX:+WhiteBoxAPI",
84+
"-Xlog:gc+remset+tracking=trace",
85+
"-Xms10M",
86+
"-Xmx10M"});
87+
88+
basicOpts.add("-XX:G1MixedGCLiveThresholdPercent=" + percent);
89+
90+
basicOpts.add(GCTest.class.getName());
91+
92+
ProcessBuilder procBuilder = ProcessTools.createJavaProcessBuilder(basicOpts);
93+
OutputAnalyzer analyzer = new OutputAnalyzer(procBuilder.start());
94+
return analyzer;
95+
}
96+
97+
private static boolean regionsSelectedForRebuild(String output) throws Exception {
98+
Matcher m = Pattern.compile(pattern, Pattern.MULTILINE).matcher(output);
99+
100+
if (!m.find()) {
101+
throw new Exception("Could not find correct output for Remembered Set Tracking in stdout," +
102+
" should match the pattern \"" + pattern + "\", but stdout is \n" + output);
103+
}
104+
return Integer.parseInt(m.group(2)) > 0;
105+
}
106+
107+
public static class GCTest {
108+
public static void main(String args[]) throws Exception {
109+
WhiteBox wb = WhiteBox.getWhiteBox();
110+
// Allocate some memory less than region size.
111+
Object used = allocate();
112+
113+
// Trigger the full GC using the WhiteBox API.
114+
wb.fullGC(); // full
115+
116+
// Memory objects have been promoted to old by full GC.
117+
// Concurrent cycle may select regions for rebuilding
118+
wb.g1StartConcMarkCycle(); // concurrent-start, remark and cleanup
119+
120+
// Sleep to make sure concurrent cycle is done
121+
while (wb.g1InConcurrentMark()) {
122+
Thread.sleep(1000);
123+
}
124+
System.out.println(used);
125+
}
126+
127+
private static Object allocate() {
128+
final int objectSize = WhiteBox.getWhiteBox().g1RegionSize() / 3;
129+
Object ret = new byte[objectSize];
130+
return ret;
131+
}
132+
}
133+
}

0 commit comments

Comments
 (0)
Please sign in to comment.