HugeDirectiveUtil.java revision 11833:1cbffa2beba6
1189747Ssam/*
2189747Ssam * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
3189747Ssam * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4189747Ssam *
5189747Ssam * This code is free software; you can redistribute it and/or modify it
6189747Ssam * under the terms of the GNU General Public License version 2 only, as
7189747Ssam * published by the Free Software Foundation.
8189747Ssam *
9189747Ssam * This code is distributed in the hope that it will be useful, but WITHOUT
10189747Ssam * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11189747Ssam * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12189747Ssam * version 2 for more details (a copy is included in the LICENSE file that
13189747Ssam * accompanied this code).
14189747Ssam *
15189747Ssam * You should have received a copy of the GNU General Public License version
16189747Ssam * 2 along with this work; if not, write to the Free Software Foundation,
17189747Ssam * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18189747Ssam *
19189747Ssam * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20189747Ssam * or visit www.oracle.com if you need additional information or have any
21189747Ssam * questions.
22189747Ssam */
23189747Ssam
24189747Ssampackage compiler.compilercontrol.parser;
25189747Ssam
26189747Ssamimport compiler.compilercontrol.share.JSONFile;
27189747Ssamimport compiler.compilercontrol.share.method.MethodDescriptor;
28189747Ssamimport compiler.compilercontrol.share.scenario.DirectiveWriter;
29189747Ssamimport compiler.compilercontrol.share.scenario.Scenario;
30189747Ssamimport jdk.test.lib.process.OutputAnalyzer;
31189747Ssamimport jdk.test.lib.process.ProcessTools;
32189747Ssamimport jdk.test.lib.Utils;
33189747Ssam
34189747Ssamimport java.util.EnumSet;
35189747Ssamimport java.util.List;
36189747Ssamimport java.util.Random;
37189747Ssamimport java.util.stream.Collectors;
38189747Ssam
39189747Ssam/**
40189747Ssam * Creates a huge directive file
41189747Ssam */
42189747Ssampublic final class HugeDirectiveUtil {
43189747Ssam    private static final Random RANDOM = Utils.getRandomInstance();
44189747Ssam    protected static final String EXPECTED_ERROR_STRING = "Parsing of compiler "
45189747Ssam            + "directives failed";
46189747Ssam
47189747Ssam    private HugeDirectiveUtil() { }
48189747Ssam
49189747Ssam    /**
50189747Ssam     * Creates huge file with specified amount of directives
51189747Ssam     *
52189747Ssam     * @param descriptors a list of descriptors to be randomly used
53189747Ssam     *                    in match and inline blocks
54189747Ssam     * @param fileName    a directives file name to be created
55189747Ssam     * @param amount      an amount of match objects
56189747Ssam     */
57189747Ssam    public static void createHugeFile(List<MethodDescriptor> descriptors,
58189747Ssam            String fileName, int amount) {
59189747Ssam        try (DirectiveWriter file = new DirectiveWriter(fileName)) {
60189747Ssam            file.write(JSONFile.Element.ARRAY);
61189747Ssam            for (int i = 0; i < amount; i++) {
62189747Ssam                createMatchObject(descriptors, file, 1);
63189747Ssam            }
64189747Ssam            file.end();
65189747Ssam        }
66189747Ssam    }
67189747Ssam
68189747Ssam    /**
69189747Ssam     * Creates match object in the given file with specified size
70189747Ssam     *
71189747Ssam     * @param descriptors a list of method descriptors to be used
72189747Ssam     * @param file        a directive file to write at
73189747Ssam     * @param objectSize  a size of the match object
74189747Ssam     */
75189747Ssam    public static void createMatchObject(List<MethodDescriptor> descriptors,
76189747Ssam            DirectiveWriter file, int objectSize) {
77189747Ssam        // get random amount of methods for the match
78189747Ssam        List<String> methods = getRandomDescriptors(descriptors);
79189747Ssam        file.match(methods.toArray(new String[methods.size()]));
80189747Ssam        for (int i = 0; i < objectSize; i++) {
81189747Ssam            // emit compiler block
82189747Ssam            file.emitCompiler(Utils.getRandomElement(
83189747Ssam                    Scenario.Compiler.values()));
84189747Ssam            // add option inside the compiler block
85189747Ssam            file.option(Utils.getRandomElement(DirectiveWriter.Option.values()),
86189747Ssam                    RANDOM.nextBoolean());
87189747Ssam            file.end(); // ends compiler block
88189747Ssam
89189747Ssam            // add standalone option, enable can't be used standalone
90189747Ssam            EnumSet<DirectiveWriter.Option> options = EnumSet.complementOf(
91189747Ssam                    EnumSet.of(DirectiveWriter.Option.ENABLE));
92189747Ssam            file.option(Utils.getRandomElement(options), RANDOM.nextBoolean());
93189747Ssam        }
94189747Ssam        // add inline block with random inlinees
95189747Ssam        methods = getRandomDescriptors(descriptors).stream()
96189747Ssam                .map(s -> (RANDOM.nextBoolean() ? "+" : "-") + s)
97189747Ssam                .collect(Collectors.toList());
98189747Ssam        file.inline(methods);
99189747Ssam
100189747Ssam        // end match block
101189747Ssam        file.end();
102189747Ssam    }
103189747Ssam
104189747Ssam    private static List<String> getRandomDescriptors(
105189747Ssam            List<MethodDescriptor> descriptors) {
106189747Ssam        int amount = 1 + RANDOM.nextInt(descriptors.size() - 1);
107189747Ssam        int skipAmount = RANDOM.nextInt(descriptors.size() - amount);
108189747Ssam        return descriptors.stream()
109189747Ssam                .skip(skipAmount)
110189747Ssam                .limit(amount)
111189747Ssam                .map(MethodDescriptor::getString)
112189747Ssam                .collect(Collectors.toList());
113189747Ssam    }
114189747Ssam
115189747Ssam    protected static OutputAnalyzer execute(String fileName) {
116189747Ssam        OutputAnalyzer output;
117189747Ssam        try {
118189747Ssam            output = ProcessTools.executeTestJvm(
119189747Ssam                    "-XX:+UnlockDiagnosticVMOptions",
120189747Ssam                    "-XX:CompilerDirectivesLimit=1000",
121189747Ssam                    "-XX:CompilerDirectivesFile=" + fileName,
122189747Ssam                    "-version");
123189747Ssam        } catch (Throwable thr) {
124189747Ssam            throw new Error("Execution failed with: " + thr, thr);
125189747Ssam        }
126189747Ssam        return output;
127189747Ssam    }
128189747Ssam}
129189747Ssam