8059623: JEP-JDK-8043304: Test task: command line options tests
authorfzhinkin
Fri, 26 Dec 2014 14:33:23 +0300
changeset 28390 263a69157012
parent 28389 bbd61e9179a5
child 28391 899a849e55f8
8059623: JEP-JDK-8043304: Test task: command line options tests Reviewed-by: twisti, thartmann, goetz, iignatyev
hotspot/test/compiler/codecache/cli/TestSegmentedCodeCacheOption.java
hotspot/test/compiler/codecache/cli/codeheapsize/CodeCacheFreeSpaceRunner.java
hotspot/test/compiler/codecache/cli/codeheapsize/GenericCodeHeapSizeRunner.java
hotspot/test/compiler/codecache/cli/codeheapsize/JVMStartupRunner.java
hotspot/test/compiler/codecache/cli/codeheapsize/TestCodeHeapSizeOptions.java
hotspot/test/compiler/codecache/cli/common/CodeCacheCLITestBase.java
hotspot/test/compiler/codecache/cli/common/CodeCacheCLITestCase.java
hotspot/test/compiler/codecache/cli/common/CodeCacheInfoFormatter.java
hotspot/test/compiler/codecache/cli/common/CodeCacheOptions.java
hotspot/test/compiler/codecache/cli/printcodecache/PrintCodeCacheRunner.java
hotspot/test/compiler/codecache/cli/printcodecache/TestPrintCodeCacheOption.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/codecache/cli/TestSegmentedCodeCacheOption.java	Fri Dec 26 14:33:23 2014 +0300
@@ -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
+ * @bug 8015774
+ * @summary Verify SegmentedCodeCache option's processing
+ * @library /testlibrary /../../test/lib
+ * @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,
+                        testCaseExitCodeMessage, testCaseWarningMessage,
+                        ExitCode.OK, 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() && Platform.isTieredSupported();
+            }
+
+            @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	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/codecache/cli/codeheapsize/CodeCacheFreeSpaceRunner.java	Fri Dec 26 14:33:23 2014 +0300
@@ -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	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/codecache/cli/codeheapsize/GenericCodeHeapSizeRunner.java	Fri Dec 26 14:33:23 2014 +0300
@@ -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	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/codecache/cli/codeheapsize/JVMStartupRunner.java	Fri Dec 26 14:33:23 2014 +0300
@@ -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	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/codecache/cli/codeheapsize/TestCodeHeapSizeOptions.java	Fri Dec 26 14:33:23 2014 +0300
@@ -0,0 +1,80 @@
+/*
+ * 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.Platform;
+import common.CodeCacheCLITestBase;
+import common.CodeCacheCLITestCase;
+import sun.hotspot.code.BlobType;
+import java.util.EnumSet;
+/**
+ * @test
+ * @bug 8015774
+ * @summary Verify processing of options related to code heaps sizing.
+ * @library /testlibrary .. /../../test/lib
+ * @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
+                                    && Platform.isDebugBuild(),
+                            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	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/codecache/cli/common/CodeCacheCLITestBase.java	Fri Dec 26 14:33:23 2014 +0300
@@ -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	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/codecache/cli/common/CodeCacheCLITestCase.java	Fri Dec 26 14:33:23 2014 +0300
@@ -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<CodeCacheOptions, Boolean> ONLY_SEGMENTED
+            = options -> options.segmented;
+    private static final Function<CodeCacheOptions, Boolean> SEGMENTED_SERVER
+            = ONLY_SEGMENTED.andThen(isSegmented -> isSegmented
+                    && Platform.isServer() && Platform.isTieredSupported());
+    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<CodeCacheOptions, Boolean> predicate,
+                EnumSet<BlobType> involvedCodeHeaps,
+                String... additionalOptions) {
+            this.description = new Description(predicate,
+                    involvedCodeHeaps, additionalOptions);
+        }
+
+
+        public final Description description;
+    }
+
+    public static class Description {
+        public final EnumSet<BlobType> involvedCodeHeaps;
+        private final String[] testCaseSpecificOptions;
+        private final Function<CodeCacheOptions, Boolean> predicate;
+
+        public Description(Function<CodeCacheOptions, Boolean> predicate,
+                EnumSet<BlobType> 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<String> 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	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/codecache/cli/common/CodeCacheInfoFormatter.java	Fri Dec 26 14:33:23 2014 +0300
@@ -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	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/codecache/cli/common/CodeCacheOptions.java	Fri Dec 26 14:33:23 2014 +0300
@@ -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<BlobType> NON_SEGMENTED_HEAPS
+            = EnumSet.of(BlobType.All);
+    private static final EnumSet<BlobType> ALL_SEGMENTED_HEAPS
+            = EnumSet.complementOf(NON_SEGMENTED_HEAPS);
+    private static final EnumSet<BlobType> SEGMENTED_HEAPS_WO_PROFILED
+            = EnumSet.of(BlobType.NonNMethod, BlobType.MethodNonProfiled);
+    private static final EnumSet<BlobType> 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<String> 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<BlobType> 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	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/codecache/cli/printcodecache/PrintCodeCacheRunner.java	Fri Dec 26 14:33:23 2014 +0300
@@ -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<BlobType> 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	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/codecache/cli/printcodecache/TestPrintCodeCacheOption.java	Fri Dec 26 14:33:23 2014 +0300
@@ -0,0 +1,73 @@
+/*
+ * 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
+ * @bug 8015774
+ * @summary Verify that PrintCodeCache option print correct information.
+ * @library /testlibrary .. /../../test/lib
+ * @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();
+    }
+}