Skip to content
Permalink
Browse files
Automatic merge of jdk:master into master
  • Loading branch information
duke committed Jun 21, 2021
2 parents ce1d1de + cd20c01 commit 1af5cc65fed52295aefee38ba46753e7d5d9469b
Showing 6 changed files with 53 additions and 12 deletions.
@@ -93,6 +93,8 @@ void G1Arguments::parse_verification_type(const char* type) {
G1HeapVerifier::enable_verification_type(G1HeapVerifier::G1VerifyConcurrentStart);
} else if (strcmp(type, "mixed") == 0) {
G1HeapVerifier::enable_verification_type(G1HeapVerifier::G1VerifyMixed);
} else if (strcmp(type, "young-evac-fail") == 0) {
G1HeapVerifier::enable_verification_type(G1HeapVerifier::G1VerifyYoungEvacFail);
} else if (strcmp(type, "remark") == 0) {
G1HeapVerifier::enable_verification_type(G1HeapVerifier::G1VerifyRemark);
} else if (strcmp(type, "cleanup") == 0) {
@@ -101,7 +103,7 @@ void G1Arguments::parse_verification_type(const char* type) {
G1HeapVerifier::enable_verification_type(G1HeapVerifier::G1VerifyFull);
} else {
log_warning(gc, verify)("VerifyGCType: '%s' is unknown. Available types are: "
"young-normal, concurrent-start, mixed, remark, cleanup and full", type);
"young-normal, young-evac-fail, concurrent-start, mixed, remark, cleanup and full", type);
}
}

@@ -2851,6 +2851,9 @@ void G1CollectedHeap::verify_before_young_collection(G1HeapVerifier::G1VerifyTyp
}

void G1CollectedHeap::verify_after_young_collection(G1HeapVerifier::G1VerifyType type) {
if (evacuation_failed()) {
type = (G1HeapVerifier::G1VerifyType)(type | G1HeapVerifier::G1VerifyYoungEvacFail);
}
if (VerifyRememberedSets) {
log_info(gc, verify)("[Verifying RemSets after GC]");
VerifyRegionRemSetClosure v_cl;
@@ -467,7 +467,7 @@ void G1HeapVerifier::enable_verification_type(G1VerifyType type) {
}

bool G1HeapVerifier::should_verify(G1VerifyType type) {
return (_enabled_verification_types & type) == type;
return (_enabled_verification_types & type) != 0;
}

void G1HeapVerifier::verify(VerifyOption vo) {
@@ -45,9 +45,10 @@ class G1HeapVerifier : public CHeapObj<mtGC> {
G1VerifyYoungNormal = 1, // -XX:VerifyGCType=young-normal
G1VerifyConcurrentStart = 2, // -XX:VerifyGCType=concurrent-start
G1VerifyMixed = 4, // -XX:VerifyGCType=mixed
G1VerifyRemark = 8, // -XX:VerifyGCType=remark
G1VerifyCleanup = 16, // -XX:VerifyGCType=cleanup
G1VerifyFull = 32, // -XX:VerifyGCType=full
G1VerifyYoungEvacFail = 8, // -XX:VerifyGCType=young-evac-fail
G1VerifyRemark = 16, // -XX:VerifyGCType=remark
G1VerifyCleanup = 32, // -XX:VerifyGCType=cleanup
G1VerifyFull = 64, // -XX:VerifyGCType=full
G1VerifyAll = -1
};

@@ -41,20 +41,20 @@ TEST_VM_F(G1HeapVerifierTest, parse) {
LogConfiguration::configure_stdout(LogLevel::Off, true, LOG_TAGS(gc, verify));

// Default is to verify everything.
ASSERT_TRUE(G1HeapVerifier::should_verify(G1HeapVerifier::G1VerifyAll));
ASSERT_TRUE(G1HeapVerifier::should_verify(G1HeapVerifier::G1VerifyYoungNormal));
ASSERT_TRUE(G1HeapVerifier::should_verify(G1HeapVerifier::G1VerifyConcurrentStart));
ASSERT_TRUE(G1HeapVerifier::should_verify(G1HeapVerifier::G1VerifyMixed));
ASSERT_TRUE(G1HeapVerifier::should_verify(G1HeapVerifier::G1VerifyYoungEvacFail));
ASSERT_TRUE(G1HeapVerifier::should_verify(G1HeapVerifier::G1VerifyRemark));
ASSERT_TRUE(G1HeapVerifier::should_verify(G1HeapVerifier::G1VerifyCleanup));
ASSERT_TRUE(G1HeapVerifier::should_verify(G1HeapVerifier::G1VerifyFull));

// Setting one will disable all other.
G1HeapVerifierTest::parse_verification_type("full");
ASSERT_FALSE(G1HeapVerifier::should_verify(G1HeapVerifier::G1VerifyAll));
ASSERT_FALSE(G1HeapVerifier::should_verify(G1HeapVerifier::G1VerifyYoungNormal));
ASSERT_FALSE(G1HeapVerifier::should_verify(G1HeapVerifier::G1VerifyConcurrentStart));
ASSERT_FALSE(G1HeapVerifier::should_verify(G1HeapVerifier::G1VerifyMixed));
ASSERT_FALSE(G1HeapVerifier::should_verify(G1HeapVerifier::G1VerifyYoungEvacFail));
ASSERT_FALSE(G1HeapVerifier::should_verify(G1HeapVerifier::G1VerifyRemark));
ASSERT_FALSE(G1HeapVerifier::should_verify(G1HeapVerifier::G1VerifyCleanup));
ASSERT_TRUE(G1HeapVerifier::should_verify(G1HeapVerifier::G1VerifyFull));
@@ -79,7 +79,4 @@ TEST_VM_F(G1HeapVerifierTest, parse) {
G1HeapVerifierTest::parse_verification_type("cleanup");
ASSERT_TRUE(G1HeapVerifier::should_verify(G1HeapVerifier::G1VerifyRemark));
ASSERT_TRUE(G1HeapVerifier::should_verify(G1HeapVerifier::G1VerifyCleanup));

// Enabling all is not the same as G1VerifyAll
ASSERT_FALSE(G1HeapVerifier::should_verify(G1HeapVerifier::G1VerifyAll));
}
@@ -37,6 +37,7 @@
import java.util.Collections;

import jdk.test.lib.Asserts;
import jdk.test.lib.Platform;
import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.process.ProcessTools;
import sun.hotspot.WhiteBox;
@@ -52,6 +53,9 @@ public static void main(String args[]) throws Exception {
testAllExplicitlyEnabled();
testFullAndRemark();
testConcurrentMark();
if (Platform.isDebugBuild()) {
testYoungEvacFail();
}
testBadVerificationType();
}

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

private static void testYoungEvacFail() throws Exception {
OutputAnalyzer output;
output = testWithVerificationType(new String[] {"young-evac-fail"},
new String[] {"-XX:+G1EvacuationFailureALot",
"-XX:G1EvacuationFailureALotCount=100",
"-XX:G1EvacuationFailureALotInterval=1",
"-XX:+UnlockDiagnosticVMOptions",
"-XX:-G1AllowPreventiveGC"});
output.shouldHaveExitValue(0);

verifyCollection("Pause Young (Normal)", false, false, true, output.getStdout());
verifyCollection("Pause Young (Concurrent Start)", false, false, true, output.getStdout());
verifyCollection("Pause Young (Mixed)", false, false, true, output.getStdout());
verifyCollection("Pause Young (Prepare Mixed)", false, false, true, output.getStdout());
verifyCollection("Pause Remark", false, false, false, output.getStdout());
verifyCollection("Pause Cleanup", false, false, false, output.getStdout());
verifyCollection("Pause Full", false, false, false, output.getStdout());
}


private static void testBadVerificationType() throws Exception {
OutputAnalyzer output;
// Test bad type
output = testWithVerificationType(new String[] {"old"});
output.shouldHaveExitValue(0);

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

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

Collections.addAll(basicOpts, extraOpts);

basicOpts.add(TriggerGCs.class.getName());

ProcessBuilder procBuilder = ProcessTools.createJavaProcessBuilder(basicOpts);
OutputAnalyzer analyzer = new OutputAnalyzer(procBuilder.start());

return analyzer;
}

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

public static class TriggerGCs {

// This class triggers GCs; we need to make sure that in all of the young gcs
// at least some objects survive so that evacuation failure can happen.
public static void main(String args[]) throws Exception {
WhiteBox wb = WhiteBox.getWhiteBox();
// Allocate some memory that can be turned into garbage.
@@ -241,16 +271,24 @@ public static void main(String args[]) throws Exception {
// Memory have been promoted to old by full GC. Free
// some memory to be reclaimed by concurrent cycle.
partialFree(used);

used = alloc1M();
wb.g1StartConcMarkCycle(); // concurrent-start, remark and cleanup
partialFree(used);

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

// Trigger two young GCs, first will be young-prepare-mixed, second will be mixed.
used = alloc1M();
wb.youngGC(); // young-prepare-mixed
partialFree(used);

used = alloc1M();
wb.youngGC(); // mixed
partialFree(used);
}

private static Object[] alloc1M() {

0 comments on commit 1af5cc6

Please sign in to comment.