--- old/test/gc/g1/plab/TestPLABNoResize.java 2016-01-19 19:38:43.006240964 +0300 +++ /dev/null 2016-01-18 10:06:43.462756840 +0300 @@ -1,306 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - - /* - * @test TestPLABNoResize - * @bug 8141278 - * @summary Test for PLAB allocation in Survivor and Old - * @requires vm.gc=="G1" | vm.gc=="null" - * @library /testlibrary /../../test/lib / - * @modules java.management - * @build ClassFileInstaller - * sun.hotspot.WhiteBox - * gc.g1.plab.lib.Storage - * gc.g1.plab.lib.LogParser - * gc.g1.plab.lib.AppPLABFixedSize - * @run main ClassFileInstaller sun.hotspot.WhiteBox - * sun.hotspot.WhiteBox$WhiteBoxPermission - * @run main gc.g1.plab.TestPLABNoResize - */ -package gc.g1.plab; - -import java.util.List; -import java.util.Map; -import java.util.Arrays; -import java.io.PrintStream; - -import gc.g1.plab.lib.AppPLABFixedSize; -import gc.g1.plab.lib.LogParser; -import gc.g1.plab.lib.PLABUtils; - -import jdk.test.lib.OutputAnalyzer; -import jdk.test.lib.ProcessTools; -import jdk.test.lib.Platform; - -/** - * Test for fixed size PLAB. - */ -public class TestPLABNoResize { - - // GC ID with survivor PLAB statistics - private final static long GC_ID_SURVIVOR_STATS = 1l; - // GC ID with old PLAB statistics - private final static long GC_ID_OLD_STATS = 2l; - - // Some threshold. We do not expect actual size of promoted with PLAB, - // just check that 'dead objects were not promoted','small objects were promoted' and - // 'large object were not promoted'. - private final static long MEM_CONSUMPTION_THRESHOLD = 256l * 1024l; - - private static final int PLAB_SIZE_SMALL = 1024; - private static final int PLAB_SIZE_MEDIUM = 4096; - private static final int PLAB_SIZE_HIGH = 65536; - private static final int OBJECT_SIZE_SMALL = 10; - private static final int OBJECT_SIZE_MEDIUM = 100; - private static final int OBJECT_SIZE_HIGH = 1000; - private static final int GC_NUM_SMALL = 1; - private static final int GC_NUM_MEDIUM = 3; - private static final int GC_NUM_HIGH = 7; - private static final int WASTE_PCT_SMALL = 10; - private static final int WASTE_PCT_MEDIUM = 20; - private static final int WASTE_PCT_HIGH = 30; - private static final int YOUNG_SIZE_LOW = 16; - private static final int YOUNG_SIZE_HIGH = 64; - - private final static TestCase[] TEST_CASES = { - // Test cases for unreachable object - new TestCase(WASTE_PCT_SMALL, PLAB_SIZE_SMALL, OBJECT_SIZE_MEDIUM, GC_NUM_SMALL, YOUNG_SIZE_LOW, false, false), - new TestCase(WASTE_PCT_HIGH, PLAB_SIZE_MEDIUM, OBJECT_SIZE_SMALL, GC_NUM_HIGH, YOUNG_SIZE_HIGH, false, false), - // Test cases for reachable objects - new TestCase(WASTE_PCT_SMALL, PLAB_SIZE_SMALL, OBJECT_SIZE_SMALL, GC_NUM_HIGH, YOUNG_SIZE_HIGH, true, true), - new TestCase(WASTE_PCT_SMALL, PLAB_SIZE_MEDIUM, OBJECT_SIZE_MEDIUM, GC_NUM_SMALL, YOUNG_SIZE_LOW, true, true), - new TestCase(WASTE_PCT_SMALL, PLAB_SIZE_SMALL, OBJECT_SIZE_HIGH, GC_NUM_MEDIUM, YOUNG_SIZE_LOW, true, false), - new TestCase(WASTE_PCT_MEDIUM, PLAB_SIZE_HIGH, OBJECT_SIZE_SMALL, GC_NUM_HIGH, YOUNG_SIZE_HIGH, true, true), - new TestCase(WASTE_PCT_MEDIUM, PLAB_SIZE_SMALL, OBJECT_SIZE_MEDIUM, GC_NUM_SMALL, YOUNG_SIZE_LOW, true, true), - new TestCase(WASTE_PCT_MEDIUM, PLAB_SIZE_MEDIUM, OBJECT_SIZE_HIGH, GC_NUM_MEDIUM, YOUNG_SIZE_LOW, true, true), - new TestCase(WASTE_PCT_HIGH, PLAB_SIZE_SMALL, OBJECT_SIZE_SMALL, GC_NUM_HIGH, YOUNG_SIZE_HIGH, true, true), - new TestCase(WASTE_PCT_HIGH, PLAB_SIZE_HIGH, OBJECT_SIZE_MEDIUM, GC_NUM_SMALL, YOUNG_SIZE_LOW, true, true), - new TestCase(WASTE_PCT_HIGH, PLAB_SIZE_SMALL, OBJECT_SIZE_HIGH, GC_NUM_MEDIUM, YOUNG_SIZE_HIGH, true, false) - }; - - private static final String[] PLAB_OPTIONS = { - "-XX:-ResizePLAB" - }; - - public static void main(String[] args) throws Throwable { - - for (TestCase testCase : TEST_CASES) { - // What we going to check. - testCase.print(System.out); - List options = PLABUtils.prepareOptions(PLAB_OPTIONS); - options.addAll(testCase.toOptions()); - options.add(AppPLABFixedSize.class.getName()); - OutputAnalyzer out = ProcessTools.executeTestJvm(options.toArray(new String[options.size()])); - if (out.getExitValue() != 0) { - System.out.println(out.getOutput()); - throw new RuntimeException("Expect exit code 0."); - } - checkResults(out.getOutput(), testCase); - } - } - - private static void checkResults(String output, TestCase testCase) { - long plabAllocatedSurvivor; - long directAllocatedSurvivor; - long plabAllocatedOld; - long directAllocatedOld; - long memAllocated = testCase.getMemToFill(); - long wordSize = Platform.is32bit() ? 4l : 8l; - LogParser logParser = new LogParser(output); - - Map survivorStats = getPlabStats(logParser, LogParser.ReportType.SURVIVOR_STATS, GC_ID_SURVIVOR_STATS); - Map oldStats = getPlabStats(logParser, LogParser.ReportType.OLD_STATS, GC_ID_OLD_STATS); - - plabAllocatedSurvivor = wordSize * survivorStats.get("used"); - directAllocatedSurvivor = wordSize * survivorStats.get("direct_allocated"); - plabAllocatedOld = wordSize * oldStats.get("used"); - directAllocatedOld = wordSize * oldStats.get("direct_allocated"); - - System.out.printf("Survivor PLAB allocated:%17d Direct allocated: %17d Mem consumed:%17d%n", plabAllocatedSurvivor, directAllocatedSurvivor, memAllocated); - System.out.printf("Old PLAB allocated:%17d Direct allocated: %17d Mem consumed:%17d%n", plabAllocatedSurvivor, directAllocatedSurvivor, memAllocated); - - // Unreachable object case - if (testCase.isDeadObjectCase()) { - // All dead object should not be promoted - if (plabAllocatedSurvivor > MEM_CONSUMPTION_THRESHOLD || directAllocatedSurvivor > MEM_CONSUMPTION_THRESHOLD) { - System.out.println(output); - throw new RuntimeException("Unreachable objects should not be allocated using PLAB or direct allocated to Survivor"); - } - if (plabAllocatedOld > MEM_CONSUMPTION_THRESHOLD || directAllocatedOld > MEM_CONSUMPTION_THRESHOLD) { - System.out.println(output); - throw new RuntimeException("Unreachable objects should not be allocated using PLAB or direct allocated to Old"); - } - } else { - // All live small objects should be promoted using PLAB - if (testCase.isPromotedByPLAB() && Math.abs(plabAllocatedSurvivor - memAllocated) > MEM_CONSUMPTION_THRESHOLD) { - System.out.println(output); - throw new RuntimeException("Expect that Survivor PLAB allocation are similar to all mem consumed"); - } - if (testCase.isPromotedByPLAB() && Math.abs(plabAllocatedOld - memAllocated) > MEM_CONSUMPTION_THRESHOLD) { - System.out.println(output); - throw new RuntimeException("Expect that Old PLAB allocation are similar to all mem consumed"); - } - - // All big objects should be directly allocated - if (!testCase.isPromotedByPLAB() && Math.abs(directAllocatedSurvivor - memAllocated) > MEM_CONSUMPTION_THRESHOLD) { - System.out.println(output); - throw new RuntimeException("Test fails. Expect that Survivor direct allocation are similar to all mem consumed"); - } - if (!testCase.isPromotedByPLAB() && Math.abs(directAllocatedOld - memAllocated) > MEM_CONSUMPTION_THRESHOLD) { - System.out.println(output); - throw new RuntimeException("Test fails. Expect that Old direct allocation are similar to all mem consumed"); - } - } - System.out.println("Test passed!"); - } - - private static Map getPlabStats(LogParser logParser, LogParser.ReportType type, long gc_id) { - Map survivorStats = logParser.getEntries() - .stream() - .filter(p -> p.first == type) - .map(p -> p.second) - .filter(l -> l.get(LogParser.GC_ID) == gc_id) - .findFirst() - .orElseThrow(() -> { - System.out.println(logParser.getLog()); - return new RuntimeException("Cannot find requested GC_ID - " + gc_id); - }); - return survivorStats; - } - - /** - * Description of one test case. - */ - private static class TestCase { - - private final int wastePct; - private final int plabSize; - private final int chunkSize; - private final int parGCThreads; - private final int edenSize; - private final boolean objectsAreReachable; - private final boolean promotedByPLAB; - - /** - * @param wastePct - * ParallelGCBufferWastePct - * @param plabSize - * -XX:OldPLABSize and -XX:YoungPLABSize - * @param chunkSize - * requested object size for memory consumption - * @param parGCThreads - * -XX:ParallelGCThreads - * @param objectsAreReachable - * true - allocate live objects - * false - allocate unreachable objects - * @param promotedByPLAB - * true - we expect to see PLAB allocation during promotion - * false - objects will be directly allocated during promotion - */ - public TestCase(int wastePct, - int plabSize, - int chunkSize, - int parGCThreads, - int edenSize, - boolean objectsAreReachable, - boolean promotedByPLAB - ) { - if (wastePct == 0 || plabSize == 0 || chunkSize == 0 || parGCThreads == 0 || edenSize == 0) { - throw new IllegalArgumentException("Parameters should not be 0"); - } - this.wastePct = wastePct; - this.plabSize = plabSize; - this.chunkSize = chunkSize; - this.parGCThreads = parGCThreads; - this.edenSize = edenSize; - this.objectsAreReachable = objectsAreReachable; - this.promotedByPLAB = promotedByPLAB; - } - - /** - * Convert current TestCase to List of options. - * Assume test will fill half of existed eden. - * - * @return - * List of options - */ - public List toOptions() { - return Arrays.asList("-XX:ParallelGCThreads=" + parGCThreads, - "-XX:ParallelGCBufferWastePct=" + wastePct, - "-XX:OldPLABSize=" + plabSize, - "-XX:YoungPLABSize=" + plabSize, - "-Dchunk.size=" + chunkSize, - "-Dreachable=" + objectsAreReachable, - "-XX:NewSize=" + edenSize + "m", - "-XX:MaxNewSize=" + edenSize + "m", - "-Dmem.to.fill=" + getMemToFill() - ); - } - - /** - * Print details about test case. - */ - public void print(PrintStream out) { - boolean expectPLABAllocation = promotedByPLAB && objectsAreReachable; - boolean expectDirectAllocation = (!promotedByPLAB) && objectsAreReachable; - - out.println("Test case details:"); - out.println(" Young gen size : " + edenSize + "M"); - out.println(" Predefined PLAB size : " + plabSize); - out.println(" Parallel GC buffer waste pct : " + wastePct); - out.println(" Chunk size : " + chunkSize); - out.println(" Parallel GC threads : " + parGCThreads); - out.println(" Objects are created : " + (objectsAreReachable ? "reachable" : "unreachable")); - out.println("Test expectations:"); - out.println(" PLAB allocation : " + (expectPLABAllocation ? "expected" : "unexpected")); - out.println(" Direct allocation : " + (expectDirectAllocation ? "expected" : "unexpected")); - } - - /** - * @return - * true if we expect PLAB allocation - * false if no - */ - public boolean isPromotedByPLAB() { - return promotedByPLAB; - } - - /** - * @return - * true if it is test case for unreachable objects - * false - for live objects - */ - public boolean isDeadObjectCase() { - return !objectsAreReachable; - } - - /** - * Returns amount of memory to fill - * - * @return amount of memory - */ - public long getMemToFill() { - return (long) (edenSize) * 1024l * 1024l / 2; - } - } -}