8161604: TestNewSizeFlags fails with RuntimeException: max new size != MaxNewSize value

Reviewed-by: sangheki, tschatzl
This commit is contained in:
Michail Chernov 2016-08-02 15:22:41 +03:00
parent 4b428d9b3a
commit 18a908de4a
2 changed files with 98 additions and 54 deletions

View file

@ -350,6 +350,11 @@ WB_ENTRY(jlong, WB_GetHeapSpaceAlignment(JNIEnv* env, jobject o))
return (jlong)alignment; return (jlong)alignment;
WB_END WB_END
WB_ENTRY(jlong, WB_GetHeapAlignment(JNIEnv* env, jobject o))
size_t alignment = Universe::heap()->collector_policy()->heap_alignment();
return (jlong)alignment;
WB_END
#if INCLUDE_ALL_GCS #if INCLUDE_ALL_GCS
WB_ENTRY(jboolean, WB_G1IsHumongous(JNIEnv* env, jobject o, jobject obj)) WB_ENTRY(jboolean, WB_G1IsHumongous(JNIEnv* env, jobject o, jobject obj))
G1CollectedHeap* g1 = G1CollectedHeap::heap(); G1CollectedHeap* g1 = G1CollectedHeap::heap();
@ -401,14 +406,21 @@ WB_ENTRY(jint, WB_G1RegionSize(JNIEnv* env, jobject o))
WB_END WB_END
WB_ENTRY(jlong, WB_PSVirtualSpaceAlignment(JNIEnv* env, jobject o)) WB_ENTRY(jlong, WB_PSVirtualSpaceAlignment(JNIEnv* env, jobject o))
ParallelScavengeHeap* ps = ParallelScavengeHeap::heap(); #if INCLUDE_ALL_GCS
size_t alignment = ps->gens()->virtual_spaces()->alignment(); if (UseParallelGC) {
return (jlong)alignment; return ParallelScavengeHeap::heap()->gens()->virtual_spaces()->alignment();
}
#endif // INCLUDE_ALL_GCS
THROW_MSG_0(vmSymbols::java_lang_RuntimeException(), "WB_PSVirtualSpaceAlignment: Parallel GC is not enabled");
WB_END WB_END
WB_ENTRY(jlong, WB_PSHeapGenerationAlignment(JNIEnv* env, jobject o)) WB_ENTRY(jlong, WB_PSHeapGenerationAlignment(JNIEnv* env, jobject o))
size_t alignment = ParallelScavengeHeap::heap()->generation_alignment(); #if INCLUDE_ALL_GCS
return (jlong)alignment; if (UseParallelGC) {
return ParallelScavengeHeap::heap()->generation_alignment();
}
#endif // INCLUDE_ALL_GCS
THROW_MSG_0(vmSymbols::java_lang_RuntimeException(), "WB_PSHeapGenerationAlignment: Parallel GC is not enabled");
WB_END WB_END
WB_ENTRY(jobject, WB_G1AuxiliaryMemoryUsage(JNIEnv* env)) WB_ENTRY(jobject, WB_G1AuxiliaryMemoryUsage(JNIEnv* env))
@ -1693,6 +1705,7 @@ static JNINativeMethod methods[] = {
{CC"getVMAllocationGranularity", CC"()J", (void*)&WB_GetVMAllocationGranularity }, {CC"getVMAllocationGranularity", CC"()J", (void*)&WB_GetVMAllocationGranularity },
{CC"getVMLargePageSize", CC"()J", (void*)&WB_GetVMLargePageSize}, {CC"getVMLargePageSize", CC"()J", (void*)&WB_GetVMLargePageSize},
{CC"getHeapSpaceAlignment", CC"()J", (void*)&WB_GetHeapSpaceAlignment}, {CC"getHeapSpaceAlignment", CC"()J", (void*)&WB_GetHeapSpaceAlignment},
{CC"getHeapAlignment", CC"()J", (void*)&WB_GetHeapAlignment},
{CC"isClassAlive0", CC"(Ljava/lang/String;)Z", (void*)&WB_IsClassAlive }, {CC"isClassAlive0", CC"(Ljava/lang/String;)Z", (void*)&WB_IsClassAlive },
{CC"parseCommandLine0", {CC"parseCommandLine0",
CC"(Ljava/lang/String;C[Lsun/hotspot/parser/DiagnosticCommand;)[Ljava/lang/Object;", CC"(Ljava/lang/String;C[Lsun/hotspot/parser/DiagnosticCommand;)[Ljava/lang/Object;",

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -60,13 +60,13 @@ public class TestNewSizeFlags {
// Test NewSize and MaxNewSize // Test NewSize and MaxNewSize
testNewSizeFlags(20 * M, 10 * M, 30 * M, 40 * M, options, false); testNewSizeFlags(20 * M, 10 * M, 30 * M, 40 * M, options, false);
testNewSizeFlags(10 * M, 20 * M, 30 * M, 40 * M, options, false); testNewSizeFlags(10 * M, 20 * M, 30 * M, 80 * M, options, false);
testNewSizeFlags(-1, 20 * M, 30 * M, 40 * M, options, false); testNewSizeFlags(-1, 20 * M, 30 * M, 40 * M, options, false);
testNewSizeFlags(10 * M, -1, 30 * M, 40 * M, options, false); testNewSizeFlags(10 * M, -1, 30 * M, 40 * M, options, false);
testNewSizeFlags(20 * M, 20 * M, 30 * M, 40 * M, options, false); testNewSizeFlags(20 * M, 20 * M, 30 * M, 40 * M, options, false);
testNewSizeFlags(20 * M, 30 * M, 40 * M, 50 * M, options, false); testNewSizeFlags(20 * M, 30 * M, 40 * M, 50 * M, options, false);
testNewSizeFlags(30 * M, 100 * M, 150 * M, 200 * M, options, false); testNewSizeFlags(30 * M, 100 * M, 150 * M, 200 * M, options, false);
testNewSizeFlags(0, -1, 30 * M, 40 * M, options, false); testNewSizeFlags(20 * M, 30 * M, 128 * M, 128 * M, options, false);
// Test -Xmn // Test -Xmn
testXmnFlags(0, 30 * M, 40 * M, options, true); testXmnFlags(0, 30 * M, 40 * M, options, true);
@ -88,9 +88,11 @@ public class TestNewSizeFlags {
long heapSize, long maxHeapSize, long heapSize, long maxHeapSize,
LinkedList<String> options, LinkedList<String> options,
boolean failureExpected) throws Exception { boolean failureExpected) throws Exception {
long expectedNewSize = newSize;
long expectedMaxNewSize = (maxNewSize >= 0 ? Math.max(maxNewSize, newSize) : maxNewSize);
testVMOptions(newSize, maxNewSize, testVMOptions(newSize, maxNewSize,
heapSize, maxHeapSize, heapSize, maxHeapSize,
newSize, (maxNewSize >= 0 ? Math.max(maxNewSize, newSize) : maxNewSize), expectedNewSize, expectedMaxNewSize,
options, failureExpected); options, failureExpected);
} }
@ -159,7 +161,9 @@ public class TestNewSizeFlags {
"-XX:-UseLargePages", "-XX:-UseLargePages",
NewSizeVerifier.class.getName(), NewSizeVerifier.class.getName(),
Long.toString(expectedNewSize), Long.toString(expectedNewSize),
Long.toString(expectedMaxNewSize) Long.toString(expectedMaxNewSize),
Long.toString(heapSize),
Long.toString(maxHeapSize)
); );
vmOptions.removeIf(String::isEmpty); vmOptions.removeIf(String::isEmpty);
ProcessBuilder procBuilder = ProcessTools.createJavaProcessBuilder(vmOptions.toArray(new String[vmOptions.size()])); ProcessBuilder procBuilder = ProcessTools.createJavaProcessBuilder(vmOptions.toArray(new String[vmOptions.size()]));
@ -177,7 +181,12 @@ public class TestNewSizeFlags {
*/ */
public static class NewSizeVerifier { public static class NewSizeVerifier {
static WhiteBox wb = WhiteBox.getWhiteBox(); private static final WhiteBox WB = WhiteBox.getWhiteBox();
private static final GCTypes.YoungGCType YOUNG_GC_TYPE = GCTypes.YoungGCType.getYoungGCType();
private static final long HEAP_SPACE_ALIGNMENT = WB.getHeapSpaceAlignment();
private static final long HEAP_ALIGNMENT = WB.getHeapAlignment();
private static final long PS_VIRTUAL_SPACE_ALIGNMENT =
(YOUNG_GC_TYPE == GCTypes.YoungGCType.PSNew) ? WB.psVirtualSpaceAlignment() : 0;
public static final int ARRAY_LENGTH = 100; public static final int ARRAY_LENGTH = 100;
public static final int CHUNK_SIZE = 1024; public static final int CHUNK_SIZE = 1024;
@ -185,63 +194,79 @@ public class TestNewSizeFlags {
public static byte garbage[][] = new byte[ARRAY_LENGTH][]; public static byte garbage[][] = new byte[ARRAY_LENGTH][];
public static void main(String args[]) throws Exception { public static void main(String args[]) throws Exception {
if (args.length != 2) { if (args.length != 4) {
throw new IllegalArgumentException("Expected 2 args: <expectedNewSize> <expectedMaxNewSize>"); throw new IllegalArgumentException("Expected 4 args: <expectedNewSize> <expectedMaxNewSize> <initialHeapSize> <maxHeapSize>");
} }
final long newSize = Long.valueOf(args[0]); final long newSize = Long.valueOf(args[0]);
final long maxNewSize = Long.valueOf(args[1]); final long maxNewSize = Long.valueOf(args[1]);
final long initialHeapSize = Long.valueOf(args[2]);
final long maxHeapSize = Long.valueOf(args[3]);
// verify initial size // verify initial size
verifyNewSize(newSize, maxNewSize); verifyNewSize(newSize, maxNewSize, initialHeapSize, maxHeapSize);
// force GC and verify that size is still correct // force GC and verify that size is still correct
AllocationHelper allocator = new AllocationHelper(MAX_ITERATIONS, ARRAY_LENGTH, CHUNK_SIZE, () -> (verifyNewSize(newSize, maxNewSize))); AllocationHelper allocator = new AllocationHelper(MAX_ITERATIONS, ARRAY_LENGTH, CHUNK_SIZE, () -> (verifyNewSize(newSize, maxNewSize, initialHeapSize, maxHeapSize)));
allocator.allocateMemoryAndVerifyNoOOME(); allocator.allocateMemoryAndVerifyNoOOME();
} }
/** /**
* Verify that actual young gen size conforms NewSize and MaxNewSize values. * Verify that actual young gen size conforms NewSize and MaxNewSize values.
*/ */
public static Void verifyNewSize(long newSize, long maxNewSize) { public static Void verifyNewSize(long newSize, long maxNewSize,
long alignedNewSize = alignNewSize(newSize); long initialHeapSize, long maxHeapSize) {
long alignedMaxNewSize = alignNewSize(maxNewSize); long alignedNewSize = alignGenSize(newSize);
long alignedMaxNewSize = alignGenSize(maxNewSize);
long alignedXms = alignHeapSize(initialHeapSize);
long alignedXmx = alignHeapSize(maxHeapSize);
MemoryUsage youngGenUsage = getYoungGenUsage(); MemoryUsage youngGenUsage = getYoungGenUsage();
long initSize = youngGenUsage.getInit();
long commitedSize = youngGenUsage.getCommitted();
long maxSize = youngGenUsage.getMax();
if (newSize != -1) { if (newSize != -1) {
if (youngGenUsage.getInit() < alignedNewSize) { if (initSize < alignedNewSize) {
throw new RuntimeException("initial new size < NewSize value: " throw new RuntimeException("initial new size < NewSize value: "
+ youngGenUsage.getInit() + " < " + alignedNewSize); + initSize + " < " + alignedNewSize);
} }
if (youngGenUsage.getCommitted() < alignedNewSize) { if (commitedSize < alignedNewSize) {
throw new RuntimeException("actual new size < NewSize value: " throw new RuntimeException("actual new size < NewSize value: "
+ youngGenUsage.getCommitted() + " < " + alignedNewSize); + commitedSize + " < " + alignedNewSize);
} }
// for G1 max new size == committed new size // for G1 max new size == committed new size
if (GCTypes.YoungGCType.getYoungGCType() != GCTypes.YoungGCType.G1 if (YOUNG_GC_TYPE != GCTypes.YoungGCType.G1
&& youngGenUsage.getMax() < alignedNewSize) { && maxSize < alignedNewSize) {
throw new RuntimeException("max new size < NewSize value: " throw new RuntimeException("max new size < NewSize value: "
+ youngGenUsage.getMax() + " < " + alignedNewSize); + maxSize + " < " + alignedNewSize);
} }
} }
if (maxNewSize != -1) { if (maxNewSize != -1) {
if (youngGenUsage.getInit() > alignedMaxNewSize) { if (initSize > alignedMaxNewSize) {
throw new RuntimeException("initial new size > MaxNewSize value: " throw new RuntimeException("initial new size > MaxNewSize value: "
+ youngGenUsage.getInit() + " > " + alignedMaxNewSize); + initSize + " > " + alignedMaxNewSize);
} }
if (youngGenUsage.getCommitted() > alignedMaxNewSize) { if (commitedSize > alignedMaxNewSize) {
throw new RuntimeException("actual new size > MaxNewSize value: " throw new RuntimeException("actual new size > MaxNewSize value: "
+ youngGenUsage.getCommitted() + " > " + alignedMaxNewSize); + commitedSize + " > " + alignedMaxNewSize);
} }
if (GCTypes.YoungGCType.getYoungGCType() != GCTypes.YoungGCType.G1 if (alignedXms != alignedXmx) {
&& youngGenUsage.getMax() != alignedMaxNewSize) { if (YOUNG_GC_TYPE != GCTypes.YoungGCType.G1
throw new RuntimeException("max new size != MaxNewSize value: " && maxSize != alignedMaxNewSize) {
+ youngGenUsage.getMax() + " != " + alignedMaxNewSize); throw new RuntimeException("max new size != MaxNewSize value: "
+ maxSize + " != " + alignedMaxNewSize);
}
} else {
if (YOUNG_GC_TYPE != GCTypes.YoungGCType.G1
&& maxSize != alignedNewSize) {
throw new RuntimeException("max new size != NewSize for case InitialHeapSize == MaxHeapSize value: "
+ maxSize + " != " + alignedNewSize + " HeapSize == " + alignedXms);
}
} }
} }
return null; return null;
@ -256,41 +281,47 @@ public class TestNewSizeFlags {
* For all GCs used value is 0. * For all GCs used value is 0.
*/ */
private static MemoryUsage getYoungGenUsage() { private static MemoryUsage getYoungGenUsage() {
if (GCTypes.YoungGCType.getYoungGCType() == GCTypes.YoungGCType.G1) { MemoryUsage edenUsage = HeapRegionUsageTool.getEdenUsage();
return new MemoryUsage(HeapRegionUsageTool.getEdenUsage().getInit() MemoryUsage survivorUsage = HeapRegionUsageTool.getSurvivorUsage();
+ HeapRegionUsageTool.getSurvivorUsage().getInit(), long edenUsageInit = edenUsage.getInit();
0, long edenUsageCommited = edenUsage.getCommitted();
HeapRegionUsageTool.getEdenUsage().getCommitted() long survivorUsageInit = survivorUsage.getInit();
+ HeapRegionUsageTool.getSurvivorUsage().getCommitted(), long survivorUsageCommited = survivorUsage.getCommitted();
Long.MAX_VALUE);
if (YOUNG_GC_TYPE == GCTypes.YoungGCType.G1) {
return new MemoryUsage(edenUsageInit + survivorUsageInit, 0,
edenUsageCommited + survivorUsageCommited, Long.MAX_VALUE);
} else { } else {
return new MemoryUsage(HeapRegionUsageTool.getEdenUsage().getInit() return new MemoryUsage(edenUsageInit + survivorUsageInit * 2, 0,
+ HeapRegionUsageTool.getSurvivorUsage().getInit() * 2, edenUsageCommited + survivorUsageCommited * 2,
0, edenUsage.getMax() + survivorUsage.getMax() * 2);
HeapRegionUsageTool.getEdenUsage().getCommitted()
+ HeapRegionUsageTool.getSurvivorUsage().getCommitted() * 2,
HeapRegionUsageTool.getEdenUsage().getMax()
+ HeapRegionUsageTool.getSurvivorUsage().getMax() * 2);
} }
} }
/** /**
* Align value regardful to used young GC. * Align generation size regardful to used young GC.
*/ */
public static long alignNewSize(long value) { public static long alignGenSize(long value) {
switch (GCTypes.YoungGCType.getYoungGCType()) { switch (YOUNG_GC_TYPE) {
case DefNew: case DefNew:
case ParNew: case ParNew:
return HeapRegionUsageTool.alignDown(value, wb.getHeapSpaceAlignment()); return HeapRegionUsageTool.alignDown(value, HEAP_SPACE_ALIGNMENT);
case PSNew: case PSNew:
return HeapRegionUsageTool.alignUp(HeapRegionUsageTool.alignDown(value, return HeapRegionUsageTool.alignUp(HeapRegionUsageTool.alignDown(value,
wb.getHeapSpaceAlignment()), HEAP_SPACE_ALIGNMENT),
wb.psVirtualSpaceAlignment()); PS_VIRTUAL_SPACE_ALIGNMENT);
case G1: case G1:
return HeapRegionUsageTool.alignUp(value, wb.g1RegionSize()); return HeapRegionUsageTool.alignUp(value, WB.g1RegionSize());
default: default:
throw new RuntimeException("Unexpected young GC type"); throw new RuntimeException("Unexpected young GC type");
} }
} }
/**
* Align heap size.
*/
public static long alignHeapSize(long value){
return HeapRegionUsageTool.alignUp(value,HEAP_ALIGNMENT);
}
} }
} }