--- /dev/null 2014-09-08 10:40:15.076620215 +0400 +++ new/test/compiler/codecache/cli/TestSegmentedCodeCacheOption.java 2014-12-05 20:56:33.949932255 +0400 @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2014, 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. + */ +import com.oracle.java.testlibrary.ExitCode; +import com.oracle.java.testlibrary.Platform; +import com.oracle.java.testlibrary.cli.CommandLineOptionTest; +import common.CodeCacheOptions; +import sun.hotspot.code.BlobType; + +/** + * @test + * @summary Verify SegmentedCodeCache option's processing + * @library /testlibrary /testlibrary/whitebox + * @build TestSegmentedCodeCacheOption com.oracle.java.testlibrary.* + * @run main TestSegmentedCodeCacheOption + */ +public class TestSegmentedCodeCacheOption { + private static final String INT_MODE = "-Xint"; + private static final String TIERED_COMPILATION = "TieredCompilation"; + private static final String SEGMENTED_CODE_CACHE = "SegmentedCodeCache"; + private static final String USE_SEGMENTED_CODE_CACHE + = CommandLineOptionTest.prepareBooleanFlag(SEGMENTED_CODE_CACHE, + true); + private static final long THRESHOLD_CC_SIZE_VALUE + = CodeCacheOptions.mB(240); + private static final long BELOW_THRESHOLD_CC_SIZE + = THRESHOLD_CC_SIZE_VALUE - CodeCacheOptions.mB(1); + private static final String[] UNEXPECTED_MESSAGES = new String[] { + ".*" + SEGMENTED_CODE_CACHE + ".*" + }; + + + private static enum TestCase { + JVM_STARTUP { + @Override + public void run() throws Throwable { + // There should be no errors when we're trying to enable SCC ... + String testCaseWarningMessage = "JVM output should not contain " + + "any warnings related to " + SEGMENTED_CODE_CACHE; + String testCaseExitCodeMessage = "JVM should start without any " + + "issues with " + USE_SEGMENTED_CODE_CACHE; + + CommandLineOptionTest.verifySameJVMStartup( + /* expectedMessages */ null, UNEXPECTED_MESSAGES, + testCaseExitCodeMessage, testCaseWarningMessage, + ExitCode.OK, USE_SEGMENTED_CODE_CACHE); + // ... and when we're trying to enable it w/o TieredCompilation + testCaseExitCodeMessage = "Disabled tiered compilation should " + + "not cause startup failure w/ " + + USE_SEGMENTED_CODE_CACHE; + + CommandLineOptionTest.verifySameJVMStartup( + /* expectedMessages */ null, UNEXPECTED_MESSAGES, + testCaseExitCodeMessage, testCaseWarningMessage, + ExitCode.OK, USE_SEGMENTED_CODE_CACHE, + CommandLineOptionTest.prepareBooleanFlag( + TIERED_COMPILATION, false)); + // ... and even w/ Xint. + testCaseExitCodeMessage = "It should be possible to use " + + USE_SEGMENTED_CODE_CACHE + " in interpreted mode " + + "without any errors."; + + CommandLineOptionTest.verifyJVMStartup( + /* expected messages */ null, UNEXPECTED_MESSAGES, + ExitCode.OK, testCaseExitCodeMessage, + testCaseWarningMessage, false, INT_MODE, + USE_SEGMENTED_CODE_CACHE); + } + }, + OPTION_VALUES_GENERIC { + @Override + public void run() throws Throwable { + // SCC is disabled w/o TieredCompilation by default + String errorMessage = SEGMENTED_CODE_CACHE + + " should be disabled by default when tiered " + + "compilation is disabled"; + + CommandLineOptionTest.verifyOptionValueForSameVM( + SEGMENTED_CODE_CACHE, "false", errorMessage, + CommandLineOptionTest.prepareBooleanFlag( + TIERED_COMPILATION, false)); + // SCC is disabled by default when ReservedCodeCacheSize is too + // small + errorMessage = String.format("%s should be disabled bu default " + + "when %s value is too small.", SEGMENTED_CODE_CACHE, + BlobType.All.sizeOptionName); + + CommandLineOptionTest.verifyOptionValueForSameVM( + SEGMENTED_CODE_CACHE, "false", errorMessage, + CommandLineOptionTest.prepareNumericFlag( + BlobType.All.sizeOptionName, + BELOW_THRESHOLD_CC_SIZE)); + // SCC could be explicitly enabled w/ Xint + errorMessage = String.format("It should be possible to " + + "explicitly enable %s in interpreted mode.", + SEGMENTED_CODE_CACHE); + + CommandLineOptionTest.verifyOptionValue(SEGMENTED_CODE_CACHE, + "true", errorMessage, false, INT_MODE, + USE_SEGMENTED_CODE_CACHE); + // SCC could be explicitly enabled w/o TieredCompilation and w/ + // small ReservedCodeCacheSize value + errorMessage = String.format("It should be possible to " + + "explicitly enable %s with small %s and " + + "disabled tiered comp.", SEGMENTED_CODE_CACHE, + BlobType.All.sizeOptionName); + + CommandLineOptionTest.verifyOptionValueForSameVM( + SEGMENTED_CODE_CACHE, "true", errorMessage, + CommandLineOptionTest.prepareBooleanFlag( + TIERED_COMPILATION, false), + CommandLineOptionTest.prepareNumericFlag( + BlobType.All.sizeOptionName, + BELOW_THRESHOLD_CC_SIZE), + USE_SEGMENTED_CODE_CACHE); + } + }, + OPTION_VALUES_SERVER_SPECIFIC { + @Override + public boolean isApplicable() { + return Platform.isServer(); + } + + @Override + public void run() throws Throwable { + // SCC is enabled by default when TieredCompilation is on and + // ReservedCodeCacheSize is large enough + String errorMessage = String.format("Large enough %s and " + + "enabled tiered compilation should enable %s " + + "by default.", BlobType.All.sizeOptionName, + SEGMENTED_CODE_CACHE); + + CommandLineOptionTest.verifyOptionValueForSameVM( + SEGMENTED_CODE_CACHE, "true", errorMessage, + CommandLineOptionTest.prepareNumericFlag( + BlobType.All.sizeOptionName, + THRESHOLD_CC_SIZE_VALUE), + CommandLineOptionTest.prepareBooleanFlag( + TIERED_COMPILATION, true)); + } + }; + + TestCase() { + } + + public boolean isApplicable() { + return true; + } + + public abstract void run() throws Throwable; + } + + public static void main(String args[]) throws Throwable { + for (TestCase testCase : TestCase.values()) { + if (testCase.isApplicable()) { + System.out.println("Running test case: " + testCase.name()); + testCase.run(); + } else { + System.out.println("Test case skipped: " + testCase.name()); + } + } + } +} --- /dev/null 2014-09-08 10:40:15.076620215 +0400 +++ new/test/compiler/codecache/cli/codeheapsize/CodeCacheFreeSpaceRunner.java 2014-12-05 20:56:34.261932265 +0400 @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2014, 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. + */ +package codeheapsize; + +import com.oracle.java.testlibrary.ExitCode; +import com.oracle.java.testlibrary.Platform; +import com.oracle.java.testlibrary.cli.CommandLineOptionTest; +import common.CodeCacheCLITestCase; +import common.CodeCacheOptions; +import sun.hotspot.code.BlobType; + +/** + * Test case runner aimed to verify that NonNMethodCodeHeapSize smaller than + * CodeCacheMinimumUseSpace cause JVM startup failure. + */ +public class CodeCacheFreeSpaceRunner implements CodeCacheCLITestCase.Runner { + private static final String CC_MIN_USE_SPACE = "CodeCacheMinimumUseSpace"; + private static final String TOO_SMALL_NMETHOD_CH_ERROR + = "Invalid NonNMethodCodeHeapSize.*"; + private static final long MULTIPLIER = Platform.isDebugBuild() ? 3L : 1L; + @Override + public void run(CodeCacheCLITestCase.Description testCaseDescription, + CodeCacheOptions options) throws Throwable { + long ccMinUseSpace = ((options.nonNmethods - 1) / MULTIPLIER + 1); + + String exitCodeErrorMessage = String.format("JVM startup should fail " + + "if %s's value lower then %s.", + BlobType.NonNMethod.sizeOptionName, CC_MIN_USE_SPACE); + String vmOutputErrorMessage = String.format("JVM's output should " + + "contain appropriate error message when %s lower " + + "then %s.", BlobType.NonNMethod.sizeOptionName, + CC_MIN_USE_SPACE); + + CommandLineOptionTest.verifySameJVMStartup( + new String[]{ TOO_SMALL_NMETHOD_CH_ERROR }, + /* unexpected messages */ null, + exitCodeErrorMessage, vmOutputErrorMessage, ExitCode.FAIL, + testCaseDescription.getTestOptions(options, + CommandLineOptionTest.prepareNumericFlag( + CC_MIN_USE_SPACE, ccMinUseSpace + 1))); + } +} --- /dev/null 2014-09-08 10:40:15.076620215 +0400 +++ new/test/compiler/codecache/cli/codeheapsize/GenericCodeHeapSizeRunner.java 2014-12-05 20:56:34.569932274 +0400 @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2014, 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. + */ +package codeheapsize; + +import com.oracle.java.testlibrary.cli.CommandLineOptionTest; +import common.CodeCacheCLITestCase; +import common.CodeCacheOptions; +import sun.hotspot.code.BlobType; + +/** + * Test case runner aimed to verify that all four options related to code cache + * sizing have correct values. + */ +public class GenericCodeHeapSizeRunner implements CodeCacheCLITestCase.Runner { + @Override + public void run(CodeCacheCLITestCase.Description testCaseDescription, + CodeCacheOptions options) throws Throwable { + CodeCacheOptions expectedValues + = options.mapOptions(testCaseDescription.involvedCodeHeaps); + + CommandLineOptionTest.verifyOptionValueForSameVM( + BlobType.All.sizeOptionName, + Long.toString(expectedValues.reserved), + String.format("%s should have value %d.", + BlobType.All.sizeOptionName, expectedValues.reserved), + testCaseDescription.getTestOptions(options)); + + CommandLineOptionTest.verifyOptionValueForSameVM( + BlobType.NonNMethod.sizeOptionName, + Long.toString(expectedValues.nonNmethods), + String.format("%s should have value %d.", + BlobType.NonNMethod.sizeOptionName, + expectedValues.nonNmethods), + testCaseDescription.getTestOptions(options)); + + CommandLineOptionTest.verifyOptionValueForSameVM( + BlobType.MethodNonProfiled.sizeOptionName, + Long.toString(expectedValues.nonProfiled), + String.format("%s should have value %d.", + BlobType.MethodNonProfiled.sizeOptionName, + expectedValues.nonProfiled), + testCaseDescription.getTestOptions(options)); + + CommandLineOptionTest.verifyOptionValueForSameVM( + BlobType.MethodProfiled.sizeOptionName, + Long.toString(expectedValues.profiled), + String.format("%s should have value %d.", + BlobType.MethodProfiled.sizeOptionName, + expectedValues.profiled), + testCaseDescription.getTestOptions(options)); + } +} --- /dev/null 2014-09-08 10:40:15.076620215 +0400 +++ new/test/compiler/codecache/cli/codeheapsize/JVMStartupRunner.java 2014-12-05 20:56:34.877932285 +0400 @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2014, 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. + */ +package codeheapsize; + +import common.CodeCacheCLITestCase; +import common.CodeCacheOptions; +import com.oracle.java.testlibrary.ExitCode; +import com.oracle.java.testlibrary.Utils; +import com.oracle.java.testlibrary.cli.CommandLineOptionTest; +import sun.hotspot.code.BlobType; +import java.util.Random; + +/** + * Test case runner aimed to verify option's consistency. + */ +public class JVMStartupRunner implements CodeCacheCLITestCase.Runner { + private static final String INCONSISTENT_CH_SIZES_ERROR + = "Invalid code heap sizes.*"; + + @Override + public void run(CodeCacheCLITestCase.Description testCaseDescription, + CodeCacheOptions options) throws Throwable { + // Everything should be fine when + // sum(all code heap sizes) == reserved CC size + CommandLineOptionTest.verifySameJVMStartup(/* expected messages */ null, + new String[]{ INCONSISTENT_CH_SIZES_ERROR }, + "JVM startup should not fail with consistent code heap sizes", + "JVM output should not contain warning about inconsistent code " + + "heap sizes", ExitCode.OK, options.prepareOptions()); + + verifySingleInconsistentValue(options); + verifyAllInconsistentValues(options); + } + + /** + * Verifies that if at least one of three options will have value, such + * that sum of all three values will be inconsistent, then JVM startup will + * fail. + */ + private static void verifySingleInconsistentValue(CodeCacheOptions options) + throws Throwable { + verifyHeapSizesSum(options.reserved, + scaleCodeHeapSize(options.profiled), options.nonProfiled, + options.nonNmethods); + verifyHeapSizesSum(options.reserved, options.profiled, + scaleCodeHeapSize(options.nonProfiled), options.nonNmethods); + verifyHeapSizesSum(options.reserved, options.profiled, + options.nonProfiled, scaleCodeHeapSize(options.nonNmethods)); + } + + /** + * Verifies that if all three options will have values such that their sum + * is inconsistent with ReservedCodeCacheSize value, then JVM startup will + * fail. + */ + private static void verifyAllInconsistentValues(CodeCacheOptions options) + throws Throwable { + long profiled = options.profiled; + long nonProfiled = options.nonProfiled; + long nonNMethods = options.nonNmethods; + + while (options.reserved == profiled + nonProfiled + nonNMethods) { + profiled = scaleCodeHeapSize(profiled); + nonProfiled = scaleCodeHeapSize(nonProfiled); + nonNMethods = scaleCodeHeapSize(nonNMethods); + } + + verifyHeapSizesSum(options.reserved, profiled, nonProfiled, + nonNMethods); + } + + private static void verifyHeapSizesSum(long reserved, long profiled, + long nonProfiled, long nonNmethods) throws Throwable { + // JVM startup expected to fail when + // sum(all code heap sizes) != reserved CC size + CommandLineOptionTest.verifySameJVMStartup( + new String[]{ INCONSISTENT_CH_SIZES_ERROR }, + /* unexpected messages */ null, + "JVM startup should fail with inconsistent code heap size.", + "JVM output should contain appropriate error message of code " + + "heap sizes are inconsistent", + ExitCode.FAIL, + CommandLineOptionTest.prepareBooleanFlag( + CodeCacheOptions.SEGMENTED_CODE_CACHE, true), + CommandLineOptionTest.prepareNumericFlag( + BlobType.All.sizeOptionName, reserved), + CommandLineOptionTest.prepareNumericFlag( + BlobType.MethodProfiled.sizeOptionName, profiled), + CommandLineOptionTest.prepareNumericFlag( + BlobType.MethodNonProfiled.sizeOptionName, nonProfiled), + CommandLineOptionTest.prepareNumericFlag( + BlobType.NonNMethod.sizeOptionName, nonNmethods)); + } + + /** + * Returns {@code unscaledSize} value scaled by a random factor from + * range (1, 2). If {@code unscaledSize} is not 0, then this + * method will return value that won't be equal to {@code unscaledSize}. + * + * @param unscaledSize The value to be scaled. + * @return {@code unscaledSize} value scaled by a factor from range (1, 2). + */ + private static long scaleCodeHeapSize(long unscaledSize) { + Random random = Utils.getRandomInstance(); + + long scaledSize = unscaledSize; + while (scaledSize == unscaledSize && unscaledSize != 0) { + float scale = 1.0f + random.nextFloat(); + scaledSize = (long) Math.ceil(scale * unscaledSize); + } + return scaledSize; + } +} --- /dev/null 2014-09-08 10:40:15.076620215 +0400 +++ new/test/compiler/codecache/cli/codeheapsize/TestCodeHeapSizeOptions.java 2014-12-05 20:56:35.181932295 +0400 @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2014, 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. + */ +package codeheapsize; + +import common.CodeCacheCLITestBase; +import common.CodeCacheCLITestCase; +import sun.hotspot.code.BlobType; +import java.util.EnumSet; +/** + * @test + * @summary Verify processing of options related to code heaps sizing. + * @library /testlibrary /testlibrary/whitebox .. + * @build TestCodeHeapSizeOptions com.oracle.java.testlibrary.* codeheapsize.* + * common.* + * @run main/timeout=240 codeheapsize.TestCodeHeapSizeOptions + */ +public class TestCodeHeapSizeOptions extends CodeCacheCLITestBase { + private static final CodeCacheCLITestCase JVM_STARTUP + = new CodeCacheCLITestCase(new CodeCacheCLITestCase.Description( + options -> options.segmented, + EnumSet.noneOf(BlobType.class)), + new JVMStartupRunner()); + + private static final CodeCacheCLITestCase CODE_CACHE_FREE_SPACE + = new CodeCacheCLITestCase(new CodeCacheCLITestCase.Description( + options -> options.segmented, + EnumSet.noneOf(BlobType.class)), + new CodeCacheFreeSpaceRunner()); + + private static final GenericCodeHeapSizeRunner GENERIC_RUNNER + = new GenericCodeHeapSizeRunner(); + + private TestCodeHeapSizeOptions() { + super(CodeCacheCLITestBase.OPTIONS_SET, + new CodeCacheCLITestCase(CodeCacheCLITestCase + .CommonDescriptions.INT_MODE.description, + GENERIC_RUNNER), + new CodeCacheCLITestCase(CodeCacheCLITestCase + .CommonDescriptions.NON_TIERED.description, + GENERIC_RUNNER), + new CodeCacheCLITestCase(CodeCacheCLITestCase + .CommonDescriptions.TIERED_LEVEL_0.description, + GENERIC_RUNNER), + new CodeCacheCLITestCase(CodeCacheCLITestCase + .CommonDescriptions.TIERED_LEVEL_1.description, + GENERIC_RUNNER), + new CodeCacheCLITestCase(CodeCacheCLITestCase + .CommonDescriptions.TIERED_LEVEL_4.description, + GENERIC_RUNNER), + JVM_STARTUP, + CODE_CACHE_FREE_SPACE); + } + + public static void main(String args[]) throws Throwable { + new TestCodeHeapSizeOptions().runTestCases(); + } +} --- /dev/null 2014-09-08 10:40:15.076620215 +0400 +++ new/test/compiler/codecache/cli/common/CodeCacheCLITestBase.java 2014-12-05 20:56:35.485932305 +0400 @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2014, 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. + */ +package common; + +/** + * Base for code cache related command line options tests. + */ +public class CodeCacheCLITestBase { + public static final CodeCacheOptions[] OPTIONS_SET + = new CodeCacheOptions[] { + new CodeCacheOptions(CodeCacheOptions.mB(60), + CodeCacheOptions.mB(20), CodeCacheOptions.mB(20), + CodeCacheOptions.mB(20)), + new CodeCacheOptions(CodeCacheOptions.mB(200), + CodeCacheOptions.mB(75), CodeCacheOptions.mB(75), + CodeCacheOptions.mB(50)), + new CodeCacheOptions(CodeCacheOptions.mB(300), + CodeCacheOptions.mB(100), CodeCacheOptions.mB(100), + CodeCacheOptions.mB(100)), + new CodeCacheOptions(CodeCacheOptions.mB(60)), + new CodeCacheOptions(CodeCacheOptions.mB(200)), + new CodeCacheOptions(CodeCacheOptions.mB(300)) + }; + + private final CodeCacheCLITestCase[] testCases; + private final CodeCacheOptions[] options; + + public CodeCacheCLITestBase(CodeCacheOptions[] options, + CodeCacheCLITestCase... testCases) { + this.testCases = testCases; + this.options = options; + } + + protected void runTestCases() throws Throwable { + for (CodeCacheCLITestCase testCase : testCases) { + for (CodeCacheOptions opts : options) { + testCase.run(opts); + } + } + } +} --- /dev/null 2014-09-08 10:40:15.076620215 +0400 +++ new/test/compiler/codecache/cli/common/CodeCacheCLITestCase.java 2014-12-05 20:56:35.789932313 +0400 @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2014, 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. + */ +package common; + +import com.oracle.java.testlibrary.Platform; +import com.oracle.java.testlibrary.cli.CommandLineOptionTest; +import sun.hotspot.code.BlobType; + +import java.util.Collections; +import java.util.EnumSet; +import java.util.LinkedList; +import java.util.List; +import java.util.function.Function; + +/** + * Code cache related command line option test case consisting of description + * of code heaps used during test case run and additional options that should + * be passed to JVM and runner aimed to perform actual testing based on the + * description. + */ +public class CodeCacheCLITestCase { + private static final Function ONLY_SEGMENTED + = options -> options.segmented; + private static final Function SEGMENTED_SERVER + = ONLY_SEGMENTED.andThen(isSegmented -> isSegmented + && Platform.isServer()); + private static final String USE_INT_MODE = "-Xint"; + private static final String SEGMENTED_CODE_CACHE = "SegmentedCodeCache"; + private static final String TIERED_COMPILATION = "TieredCompilation"; + private static final String TIERED_STOP_AT = "TieredStopAtLevel"; + + private final Description description; + private final Runner runner; + + public CodeCacheCLITestCase(Description description, Runner runner) { + this.description = description; + this.runner = runner; + } + + public final void run(CodeCacheOptions options) throws Throwable { + if (description.isApplicable(options)) { + runner.run(description, options); + } + } + + public enum CommonDescriptions { + /** + * Verifies that in interpreted mode PrintCodeCache output contains + * only NonNMethod code heap. + */ + INT_MODE(ONLY_SEGMENTED, EnumSet.of(BlobType.NonNMethod), USE_INT_MODE), + /** + * Verifies that with disabled SegmentedCodeCache PrintCodeCache output + * contains only CodeCache's entry. + */ + NON_SEGMENTED(options -> !options.segmented, EnumSet.of(BlobType.All), + CommandLineOptionTest.prepareBooleanFlag(SEGMENTED_CODE_CACHE, + false)), + /** + * Verifies that with disabled tiered compilation and enabled segmented + * code cache PrintCodeCache output does not contain information about + * profiled-nmethods heap and non-segmented CodeCache. + */ + NON_TIERED(ONLY_SEGMENTED, + EnumSet.of(BlobType.NonNMethod, BlobType.MethodNonProfiled), + CommandLineOptionTest.prepareBooleanFlag(TIERED_COMPILATION, + false)), + /** + * Verifies that with TieredStopAtLevel=0 PrintCodeCache output will + * contain information about non-nmethods and non-profiled nmethods + * heaps only. + */ + TIERED_LEVEL_0(SEGMENTED_SERVER, + EnumSet.of(BlobType.NonNMethod, BlobType.MethodNonProfiled), + CommandLineOptionTest.prepareBooleanFlag(TIERED_COMPILATION, + true), + CommandLineOptionTest.prepareNumericFlag(TIERED_STOP_AT, 0)), + /** + * Verifies that with TieredStopAtLevel=1 PrintCodeCache output will + * contain information about non-nmethods and non-profiled nmethods + * heaps only. + */ + TIERED_LEVEL_1(SEGMENTED_SERVER, + EnumSet.of(BlobType.NonNMethod, BlobType.MethodNonProfiled), + CommandLineOptionTest.prepareBooleanFlag(TIERED_COMPILATION, + true), + CommandLineOptionTest.prepareNumericFlag(TIERED_STOP_AT, 1)), + /** + * Verifies that with TieredStopAtLevel=4 PrintCodeCache output will + * contain information about all three code heaps. + */ + TIERED_LEVEL_4(SEGMENTED_SERVER, + EnumSet.complementOf(EnumSet.of(BlobType.All)), + CommandLineOptionTest.prepareBooleanFlag(TIERED_COMPILATION, + true), + CommandLineOptionTest.prepareNumericFlag(TIERED_STOP_AT, 4)); + + CommonDescriptions(Function predicate, + EnumSet involvedCodeHeaps, + String... additionalOptions) { + this.description = new Description(predicate, + involvedCodeHeaps, additionalOptions); + } + + + public final Description description; + } + + public static class Description { + public final EnumSet involvedCodeHeaps; + private final String[] testCaseSpecificOptions; + private final Function predicate; + + public Description(Function predicate, + EnumSet involvedCodeHeaps, + String... testCaseSpecificOptions) { + this.involvedCodeHeaps = involvedCodeHeaps; + this.testCaseSpecificOptions = testCaseSpecificOptions; + this.predicate = predicate; + } + + public boolean isApplicable(CodeCacheOptions options) { + return predicate.apply(options); + } + + public CodeCacheOptions expectedValues(CodeCacheOptions options) { + return options.mapOptions(involvedCodeHeaps); + } + + public String[] getTestOptions(CodeCacheOptions codeCacheOptions, + String... additionalOptions) { + List options = new LinkedList<>(); + Collections.addAll(options, testCaseSpecificOptions); + Collections.addAll(options, additionalOptions); + return codeCacheOptions.prepareOptions( + options.toArray(new String[options.size()])); + } + } + + public static interface Runner { + public void run(Description testCaseDescription, + CodeCacheOptions options) throws Throwable; + } +} + --- /dev/null 2014-09-08 10:40:15.076620215 +0400 +++ new/test/compiler/codecache/cli/common/CodeCacheInfoFormatter.java 2014-12-05 20:56:36.097932324 +0400 @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2014, 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. + */ +package common; + +import sun.hotspot.code.BlobType; +import java.util.Arrays; + +public class CodeCacheInfoFormatter { + private static final String DEFAULT_SIZE_FORMAT = "[0-9]+Kb"; + private BlobType heap = null; + private String size = DEFAULT_SIZE_FORMAT; + private String used = DEFAULT_SIZE_FORMAT; + private String maxUsed = DEFAULT_SIZE_FORMAT; + private String free = DEFAULT_SIZE_FORMAT; + + public static CodeCacheInfoFormatter forHeap(BlobType heap) { + return new CodeCacheInfoFormatter(heap); + } + + public static String[] forHeaps(BlobType... heaps) { + return Arrays.stream(heaps) + .map(CodeCacheInfoFormatter::forHeap) + .map(CodeCacheInfoFormatter::getInfoString) + .toArray(String[]::new); + } + + private static String formatSize(long suffix) { + return String.format("%dKb", suffix / 1024); + } + + private CodeCacheInfoFormatter(BlobType heap) { + this.heap = heap; + } + + public CodeCacheInfoFormatter withSize(long size) { + this.size = CodeCacheInfoFormatter.formatSize(size); + return this; + } + + public CodeCacheInfoFormatter withUsed(long used) { + this.used = CodeCacheInfoFormatter.formatSize(used); + return this; + } + + public CodeCacheInfoFormatter withMaxUsed(long maxUsed) { + this.maxUsed = CodeCacheInfoFormatter.formatSize(maxUsed); + return this; + } + + public CodeCacheInfoFormatter withFree(long free) { + this.free = CodeCacheInfoFormatter.formatSize(free); + return this; + } + + public String getInfoString() { + return String.format("%s: size=%s used=%s max_used=%s free=%s", + heap.beanName, size, used, maxUsed, free); + } +} --- /dev/null 2014-09-08 10:40:15.076620215 +0400 +++ new/test/compiler/codecache/cli/common/CodeCacheOptions.java 2014-12-05 20:56:36.401932334 +0400 @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2014, 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. + */ +package common; + +import com.oracle.java.testlibrary.cli.CommandLineOptionTest; +import sun.hotspot.code.BlobType; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.EnumSet; +import java.util.List; + +public class CodeCacheOptions { + public static final String SEGMENTED_CODE_CACHE = "SegmentedCodeCache"; + + private static final EnumSet NON_SEGMENTED_HEAPS + = EnumSet.of(BlobType.All); + private static final EnumSet ALL_SEGMENTED_HEAPS + = EnumSet.complementOf(NON_SEGMENTED_HEAPS); + private static final EnumSet SEGMENTED_HEAPS_WO_PROFILED + = EnumSet.of(BlobType.NonNMethod, BlobType.MethodNonProfiled); + private static final EnumSet ONLY_NON_METHODS_HEAP + = EnumSet.of(BlobType.NonNMethod); + + public final long reserved; + public final long nonNmethods; + public final long nonProfiled; + public final long profiled; + public final boolean segmented; + + public static long mB(long val) { + return CodeCacheOptions.kB(val) * 1024L; + } + + public static long kB(long val) { + return val * 1024L; + } + + public CodeCacheOptions(long reserved) { + this.reserved = reserved; + this.nonNmethods = 0; + this.nonProfiled = 0; + this.profiled = 0; + this.segmented = false; + } + + public CodeCacheOptions(long reserved, long nonNmethods, long nonProfiled, + long profiled) { + this.reserved = reserved; + this.nonNmethods = nonNmethods; + this.nonProfiled = nonProfiled; + this.profiled = profiled; + this.segmented = true; + } + + public long sizeForHeap(BlobType heap) { + switch (heap) { + case All: + return this.reserved; + case NonNMethod: + return this.nonNmethods; + case MethodNonProfiled: + return this.nonProfiled; + case MethodProfiled: + return this.profiled; + default: + throw new Error("Unknown heap: " + heap.name()); + } + } + + public String[] prepareOptions(String... additionalOptions) { + List options = new ArrayList<>(); + Collections.addAll(options, additionalOptions); + Collections.addAll(options, + CommandLineOptionTest.prepareBooleanFlag( + SEGMENTED_CODE_CACHE, segmented), + CommandLineOptionTest.prepareNumericFlag( + BlobType.All.sizeOptionName, reserved)); + + if (segmented) { + Collections.addAll(options, + CommandLineOptionTest.prepareNumericFlag( + BlobType.NonNMethod.sizeOptionName, nonNmethods), + CommandLineOptionTest.prepareNumericFlag( + BlobType.MethodNonProfiled.sizeOptionName, + nonProfiled), + CommandLineOptionTest.prepareNumericFlag( + BlobType.MethodProfiled.sizeOptionName, profiled)); + } + return options.toArray(new String[options.size()]); + } + + public CodeCacheOptions mapOptions(EnumSet involvedCodeHeaps) { + if (involvedCodeHeaps.isEmpty() + || involvedCodeHeaps.equals(NON_SEGMENTED_HEAPS) + || involvedCodeHeaps.equals(ALL_SEGMENTED_HEAPS)) { + return this; + } else if (involvedCodeHeaps.equals(SEGMENTED_HEAPS_WO_PROFILED)) { + return new CodeCacheOptions(reserved, nonNmethods, + profiled + nonProfiled, 0L); + } else if (involvedCodeHeaps.equals(ONLY_NON_METHODS_HEAP)) { + return new CodeCacheOptions(reserved, nonNmethods + profiled + + nonProfiled, 0L, 0L); + } else { + throw new Error("Test bug: unexpected set of code heaps involved " + + "into test."); + } + } +} --- /dev/null 2014-09-08 10:40:15.076620215 +0400 +++ new/test/compiler/codecache/cli/printcodecache/PrintCodeCacheRunner.java 2014-12-05 20:56:36.705932344 +0400 @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2014, 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. + */ +package printcodecache; + +import com.oracle.java.testlibrary.ExitCode; +import com.oracle.java.testlibrary.cli.CommandLineOptionTest; +import common.CodeCacheCLITestCase; +import common.CodeCacheInfoFormatter; +import common.CodeCacheOptions; +import sun.hotspot.code.BlobType; + +import java.util.EnumSet; +import java.util.stream.Collectors; + +/** + * Runner implementation aimed to verify PrintCodeCache output. + */ +public class PrintCodeCacheRunner implements CodeCacheCLITestCase.Runner { + private final boolean printCodeCache; + + public PrintCodeCacheRunner(boolean printCodeCache) { + this.printCodeCache = printCodeCache; + } + + public PrintCodeCacheRunner() { + this(true); + } + + @Override + public void run(CodeCacheCLITestCase.Description testCaseDescription, + CodeCacheOptions options) throws Throwable { + CodeCacheOptions expectedValues + = testCaseDescription.expectedValues(options); + + String[] expectedMessages + = testCaseDescription.involvedCodeHeaps.stream() + .map(heap -> CodeCacheInfoFormatter.forHeap(heap) + .withSize(expectedValues.sizeForHeap(heap))) + .map(CodeCacheInfoFormatter::getInfoString) + .toArray(String[]::new); + + EnumSet unexpectedHeapsSet + = EnumSet.complementOf(testCaseDescription.involvedCodeHeaps); + + String[] unexpectedMessages = CodeCacheInfoFormatter.forHeaps( + unexpectedHeapsSet.toArray( + new BlobType[unexpectedHeapsSet.size()])); + + String description = String.format("JVM output should contain entries " + + "for following code heaps: [%s] and should not contain " + + "entries for following code heaps: [%s].", + testCaseDescription.involvedCodeHeaps.stream() + .map(BlobType::name) + .collect(Collectors.joining(", ")), + unexpectedHeapsSet.stream() + .map(BlobType::name) + .collect(Collectors.joining(", "))); + + CommandLineOptionTest.verifySameJVMStartup(expectedMessages, + unexpectedMessages, "JVM startup failure is not expected, " + + "since all options have allowed values", description, + ExitCode.OK, + testCaseDescription.getTestOptions(options, + CommandLineOptionTest.prepareBooleanFlag( + "PrintCodeCache", printCodeCache))); + } +} --- /dev/null 2014-09-08 10:40:15.076620215 +0400 +++ new/test/compiler/codecache/cli/printcodecache/TestPrintCodeCacheOption.java 2014-12-05 20:56:37.013932354 +0400 @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2014, 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. + */ +package printcodecache; + +import common.CodeCacheCLITestBase; +import common.CodeCacheCLITestCase; +import sun.hotspot.code.BlobType; +import java.util.EnumSet; +/** + * @test + * @summary Verify that PrintCodeCache option print correct information. + * @library /testlibrary /testlibrary/whitebox .. + * @build TestPrintCodeCacheOption com.oracle.java.testlibrary.* + * printcodecache.* common.* + * @run main/timeout=240 printcodecache.TestPrintCodeCacheOption + */ +public class TestPrintCodeCacheOption extends CodeCacheCLITestBase { + private static final CodeCacheCLITestCase DISABLED_PRINT_CODE_CACHE + = new CodeCacheCLITestCase(new CodeCacheCLITestCase.Description( + options -> true, EnumSet.noneOf(BlobType.class)), + new PrintCodeCacheRunner(false)); + + private static final CodeCacheCLITestCase.Runner DEFAULT_RUNNER + = new PrintCodeCacheRunner(); + + private TestPrintCodeCacheOption() { + super(CodeCacheCLITestBase.OPTIONS_SET, + new CodeCacheCLITestCase(CodeCacheCLITestCase + .CommonDescriptions.INT_MODE.description, + DEFAULT_RUNNER), + new CodeCacheCLITestCase(CodeCacheCLITestCase + .CommonDescriptions.NON_SEGMENTED.description, + DEFAULT_RUNNER), + new CodeCacheCLITestCase(CodeCacheCLITestCase + .CommonDescriptions.NON_TIERED.description, + DEFAULT_RUNNER), + new CodeCacheCLITestCase(CodeCacheCLITestCase + .CommonDescriptions.TIERED_LEVEL_0.description, + DEFAULT_RUNNER), + new CodeCacheCLITestCase(CodeCacheCLITestCase + .CommonDescriptions.TIERED_LEVEL_1.description, + DEFAULT_RUNNER), + new CodeCacheCLITestCase(CodeCacheCLITestCase + .CommonDescriptions.TIERED_LEVEL_4.description, + DEFAULT_RUNNER), + DISABLED_PRINT_CODE_CACHE); + } + + public static void main(String args[]) throws Throwable { + new TestPrintCodeCacheOption().runTestCases(); + } +}