Skip to content

Commit cd20c01

Browse files
author
Thomas Schatzl
committed
8268458: Add verification type for evacuation failures
Reviewed-by: kbarrett, iwalulya
1 parent a58c477 commit cd20c01

File tree

6 files changed

+53
-12
lines changed

6 files changed

+53
-12
lines changed

src/hotspot/share/gc/g1/g1Arguments.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ void G1Arguments::parse_verification_type(const char* type) {
9393
G1HeapVerifier::enable_verification_type(G1HeapVerifier::G1VerifyConcurrentStart);
9494
} else if (strcmp(type, "mixed") == 0) {
9595
G1HeapVerifier::enable_verification_type(G1HeapVerifier::G1VerifyMixed);
96+
} else if (strcmp(type, "young-evac-fail") == 0) {
97+
G1HeapVerifier::enable_verification_type(G1HeapVerifier::G1VerifyYoungEvacFail);
9698
} else if (strcmp(type, "remark") == 0) {
9799
G1HeapVerifier::enable_verification_type(G1HeapVerifier::G1VerifyRemark);
98100
} else if (strcmp(type, "cleanup") == 0) {
@@ -101,7 +103,7 @@ void G1Arguments::parse_verification_type(const char* type) {
101103
G1HeapVerifier::enable_verification_type(G1HeapVerifier::G1VerifyFull);
102104
} else {
103105
log_warning(gc, verify)("VerifyGCType: '%s' is unknown. Available types are: "
104-
"young-normal, concurrent-start, mixed, remark, cleanup and full", type);
106+
"young-normal, young-evac-fail, concurrent-start, mixed, remark, cleanup and full", type);
105107
}
106108
}
107109

src/hotspot/share/gc/g1/g1CollectedHeap.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2851,6 +2851,9 @@ void G1CollectedHeap::verify_before_young_collection(G1HeapVerifier::G1VerifyTyp
28512851
}
28522852

28532853
void G1CollectedHeap::verify_after_young_collection(G1HeapVerifier::G1VerifyType type) {
2854+
if (evacuation_failed()) {
2855+
type = (G1HeapVerifier::G1VerifyType)(type | G1HeapVerifier::G1VerifyYoungEvacFail);
2856+
}
28542857
if (VerifyRememberedSets) {
28552858
log_info(gc, verify)("[Verifying RemSets after GC]");
28562859
VerifyRegionRemSetClosure v_cl;

src/hotspot/share/gc/g1/g1HeapVerifier.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -467,7 +467,7 @@ void G1HeapVerifier::enable_verification_type(G1VerifyType type) {
467467
}
468468

469469
bool G1HeapVerifier::should_verify(G1VerifyType type) {
470-
return (_enabled_verification_types & type) == type;
470+
return (_enabled_verification_types & type) != 0;
471471
}
472472

473473
void G1HeapVerifier::verify(VerifyOption vo) {

src/hotspot/share/gc/g1/g1HeapVerifier.hpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,10 @@ class G1HeapVerifier : public CHeapObj<mtGC> {
4545
G1VerifyYoungNormal = 1, // -XX:VerifyGCType=young-normal
4646
G1VerifyConcurrentStart = 2, // -XX:VerifyGCType=concurrent-start
4747
G1VerifyMixed = 4, // -XX:VerifyGCType=mixed
48-
G1VerifyRemark = 8, // -XX:VerifyGCType=remark
49-
G1VerifyCleanup = 16, // -XX:VerifyGCType=cleanup
50-
G1VerifyFull = 32, // -XX:VerifyGCType=full
48+
G1VerifyYoungEvacFail = 8, // -XX:VerifyGCType=young-evac-fail
49+
G1VerifyRemark = 16, // -XX:VerifyGCType=remark
50+
G1VerifyCleanup = 32, // -XX:VerifyGCType=cleanup
51+
G1VerifyFull = 64, // -XX:VerifyGCType=full
5152
G1VerifyAll = -1
5253
};
5354

test/hotspot/gtest/gc/g1/test_g1HeapVerifier.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,20 +41,20 @@ TEST_VM_F(G1HeapVerifierTest, parse) {
4141
LogConfiguration::configure_stdout(LogLevel::Off, true, LOG_TAGS(gc, verify));
4242

4343
// Default is to verify everything.
44-
ASSERT_TRUE(G1HeapVerifier::should_verify(G1HeapVerifier::G1VerifyAll));
4544
ASSERT_TRUE(G1HeapVerifier::should_verify(G1HeapVerifier::G1VerifyYoungNormal));
4645
ASSERT_TRUE(G1HeapVerifier::should_verify(G1HeapVerifier::G1VerifyConcurrentStart));
4746
ASSERT_TRUE(G1HeapVerifier::should_verify(G1HeapVerifier::G1VerifyMixed));
47+
ASSERT_TRUE(G1HeapVerifier::should_verify(G1HeapVerifier::G1VerifyYoungEvacFail));
4848
ASSERT_TRUE(G1HeapVerifier::should_verify(G1HeapVerifier::G1VerifyRemark));
4949
ASSERT_TRUE(G1HeapVerifier::should_verify(G1HeapVerifier::G1VerifyCleanup));
5050
ASSERT_TRUE(G1HeapVerifier::should_verify(G1HeapVerifier::G1VerifyFull));
5151

5252
// Setting one will disable all other.
5353
G1HeapVerifierTest::parse_verification_type("full");
54-
ASSERT_FALSE(G1HeapVerifier::should_verify(G1HeapVerifier::G1VerifyAll));
5554
ASSERT_FALSE(G1HeapVerifier::should_verify(G1HeapVerifier::G1VerifyYoungNormal));
5655
ASSERT_FALSE(G1HeapVerifier::should_verify(G1HeapVerifier::G1VerifyConcurrentStart));
5756
ASSERT_FALSE(G1HeapVerifier::should_verify(G1HeapVerifier::G1VerifyMixed));
57+
ASSERT_FALSE(G1HeapVerifier::should_verify(G1HeapVerifier::G1VerifyYoungEvacFail));
5858
ASSERT_FALSE(G1HeapVerifier::should_verify(G1HeapVerifier::G1VerifyRemark));
5959
ASSERT_FALSE(G1HeapVerifier::should_verify(G1HeapVerifier::G1VerifyCleanup));
6060
ASSERT_TRUE(G1HeapVerifier::should_verify(G1HeapVerifier::G1VerifyFull));
@@ -79,7 +79,4 @@ TEST_VM_F(G1HeapVerifierTest, parse) {
7979
G1HeapVerifierTest::parse_verification_type("cleanup");
8080
ASSERT_TRUE(G1HeapVerifier::should_verify(G1HeapVerifier::G1VerifyRemark));
8181
ASSERT_TRUE(G1HeapVerifier::should_verify(G1HeapVerifier::G1VerifyCleanup));
82-
83-
// Enabling all is not the same as G1VerifyAll
84-
ASSERT_FALSE(G1HeapVerifier::should_verify(G1HeapVerifier::G1VerifyAll));
8582
}

test/hotspot/jtreg/gc/g1/TestVerifyGCType.java

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import java.util.Collections;
3838

3939
import jdk.test.lib.Asserts;
40+
import jdk.test.lib.Platform;
4041
import jdk.test.lib.process.OutputAnalyzer;
4142
import jdk.test.lib.process.ProcessTools;
4243
import sun.hotspot.WhiteBox;
@@ -52,6 +53,9 @@ public static void main(String args[]) throws Exception {
5253
testAllExplicitlyEnabled();
5354
testFullAndRemark();
5455
testConcurrentMark();
56+
if (Platform.isDebugBuild()) {
57+
testYoungEvacFail();
58+
}
5559
testBadVerificationType();
5660
}
5761

@@ -115,13 +119,33 @@ private static void testConcurrentMark() throws Exception {
115119
verifyCollection("Pause Full", false, false, false, output.getStdout());
116120
}
117121

122+
private static void testYoungEvacFail() throws Exception {
123+
OutputAnalyzer output;
124+
output = testWithVerificationType(new String[] {"young-evac-fail"},
125+
new String[] {"-XX:+G1EvacuationFailureALot",
126+
"-XX:G1EvacuationFailureALotCount=100",
127+
"-XX:G1EvacuationFailureALotInterval=1",
128+
"-XX:+UnlockDiagnosticVMOptions",
129+
"-XX:-G1AllowPreventiveGC"});
130+
output.shouldHaveExitValue(0);
131+
132+
verifyCollection("Pause Young (Normal)", false, false, true, output.getStdout());
133+
verifyCollection("Pause Young (Concurrent Start)", false, false, true, output.getStdout());
134+
verifyCollection("Pause Young (Mixed)", false, false, true, output.getStdout());
135+
verifyCollection("Pause Young (Prepare Mixed)", false, false, true, output.getStdout());
136+
verifyCollection("Pause Remark", false, false, false, output.getStdout());
137+
verifyCollection("Pause Cleanup", false, false, false, output.getStdout());
138+
verifyCollection("Pause Full", false, false, false, output.getStdout());
139+
}
140+
141+
118142
private static void testBadVerificationType() throws Exception {
119143
OutputAnalyzer output;
120144
// Test bad type
121145
output = testWithVerificationType(new String[] {"old"});
122146
output.shouldHaveExitValue(0);
123147

124-
output.shouldMatch("VerifyGCType: '.*' is unknown. Available types are: young-normal, concurrent-start, mixed, remark, cleanup and full");
148+
output.shouldMatch("VerifyGCType: '.*' is unknown. Available types are: young-normal, young-evac-fail, concurrent-start, mixed, remark, cleanup and full");
125149
verifyCollection("Pause Young (Normal)", true, false, true, output.getStdout());
126150
verifyCollection("Pause Young (Concurrent Start)", true, false, true, output.getStdout());
127151
verifyCollection("Pause Young (Mixed)", true, false, true, output.getStdout());
@@ -131,7 +155,7 @@ private static void testBadVerificationType() throws Exception {
131155
verifyCollection("Pause Full", true, true, true, output.getStdout());
132156
}
133157

134-
private static OutputAnalyzer testWithVerificationType(String[] types) throws Exception {
158+
private static OutputAnalyzer testWithVerificationType(String[] types, String... extraOpts) throws Exception {
135159
ArrayList<String> basicOpts = new ArrayList<>();
136160
Collections.addAll(basicOpts, new String[] {
137161
"-Xbootclasspath/a:.",
@@ -151,10 +175,13 @@ private static OutputAnalyzer testWithVerificationType(String[] types) throws Ex
151175
basicOpts.add("-XX:VerifyGCType="+verifyType);
152176
}
153177

178+
Collections.addAll(basicOpts, extraOpts);
179+
154180
basicOpts.add(TriggerGCs.class.getName());
155181

156182
ProcessBuilder procBuilder = ProcessTools.createJavaProcessBuilder(basicOpts);
157183
OutputAnalyzer analyzer = new OutputAnalyzer(procBuilder.start());
184+
158185
return analyzer;
159186
}
160187

@@ -228,6 +255,9 @@ static CollectionInfo parseFirst(String name, String data) {
228255
}
229256

230257
public static class TriggerGCs {
258+
259+
// This class triggers GCs; we need to make sure that in all of the young gcs
260+
// at least some objects survive so that evacuation failure can happen.
231261
public static void main(String args[]) throws Exception {
232262
WhiteBox wb = WhiteBox.getWhiteBox();
233263
// Allocate some memory that can be turned into garbage.
@@ -241,16 +271,24 @@ public static void main(String args[]) throws Exception {
241271
// Memory have been promoted to old by full GC. Free
242272
// some memory to be reclaimed by concurrent cycle.
243273
partialFree(used);
274+
275+
used = alloc1M();
244276
wb.g1StartConcMarkCycle(); // concurrent-start, remark and cleanup
277+
partialFree(used);
245278

246279
// Sleep to make sure concurrent cycle is done
247280
while (wb.g1InConcurrentMark()) {
248281
Thread.sleep(1000);
249282
}
250283

251284
// Trigger two young GCs, first will be young-prepare-mixed, second will be mixed.
285+
used = alloc1M();
252286
wb.youngGC(); // young-prepare-mixed
287+
partialFree(used);
288+
289+
used = alloc1M();
253290
wb.youngGC(); // mixed
291+
partialFree(used);
254292
}
255293

256294
private static Object[] alloc1M() {

0 commit comments

Comments
 (0)