1 /*
2  * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 package compiler.compilercontrol.parser;
25 
26 import compiler.compilercontrol.share.JSONFile;
27 import compiler.compilercontrol.share.method.MethodDescriptor;
28 import compiler.compilercontrol.share.scenario.DirectiveWriter;
29 import compiler.compilercontrol.share.scenario.Scenario;
30 import jdk.test.lib.process.OutputAnalyzer;
31 import jdk.test.lib.process.ProcessTools;
32 import jdk.test.lib.Utils;
33 
34 import java.util.EnumSet;
35 import java.util.List;
36 import java.util.Random;
37 import java.util.stream.Collectors;
38 
39 /**
40  * Creates a huge directive file
41  */
42 public final class HugeDirectiveUtil {
43     private static final Random RANDOM = Utils.getRandomInstance();
44     protected static final String EXPECTED_ERROR_STRING = "Parsing of compiler "
45             + "directives failed";
46 
HugeDirectiveUtil()47     private HugeDirectiveUtil() { }
48 
49     /**
50      * Creates huge file with specified amount of directives
51      *
52      * @param descriptors a list of descriptors to be randomly used
53      *                    in match and inline blocks
54      * @param fileName    a directives file name to be created
55      * @param amount      an amount of match objects
56      */
createHugeFile(List<MethodDescriptor> descriptors, String fileName, int amount)57     public static void createHugeFile(List<MethodDescriptor> descriptors,
58             String fileName, int amount) {
59         try (DirectiveWriter file = new DirectiveWriter(fileName)) {
60             file.write(JSONFile.Element.ARRAY);
61             for (int i = 0; i < amount; i++) {
62                 createMatchObject(descriptors, file, 1);
63             }
64             file.end();
65         }
66     }
67 
68     /**
69      * Creates match object in the given file with specified size
70      *
71      * @param descriptors a list of method descriptors to be used
72      * @param file        a directive file to write at
73      * @param objectSize  a size of the match object
74      */
createMatchObject(List<MethodDescriptor> descriptors, DirectiveWriter file, int objectSize)75     public static void createMatchObject(List<MethodDescriptor> descriptors,
76             DirectiveWriter file, int objectSize) {
77         // get random amount of methods for the match
78         List<String> methods = getRandomDescriptors(descriptors);
79         file.match(methods.toArray(new String[methods.size()]));
80         for (int i = 0; i < objectSize; i++) {
81             // emit compiler block
82             file.emitCompiler(Utils.getRandomElement(
83                     Scenario.Compiler.values()));
84             // add option inside the compiler block
85             file.option(Utils.getRandomElement(DirectiveWriter.Option.values()),
86                     RANDOM.nextBoolean());
87             file.end(); // ends compiler block
88 
89             // add standalone option, enable can't be used standalone
90             EnumSet<DirectiveWriter.Option> options = EnumSet.complementOf(
91                     EnumSet.of(DirectiveWriter.Option.ENABLE));
92             file.option(Utils.getRandomElement(options), RANDOM.nextBoolean());
93         }
94         // add inline block with random inlinees
95         methods = getRandomDescriptors(descriptors).stream()
96                 .map(s -> (RANDOM.nextBoolean() ? "+" : "-") + s)
97                 .collect(Collectors.toList());
98         file.inline(methods);
99 
100         // end match block
101         file.end();
102     }
103 
getRandomDescriptors( List<MethodDescriptor> descriptors)104     private static List<String> getRandomDescriptors(
105             List<MethodDescriptor> descriptors) {
106         int amount = 1 + RANDOM.nextInt(descriptors.size() - 1);
107         int skipAmount = RANDOM.nextInt(descriptors.size() - amount);
108         return descriptors.stream()
109                 .skip(skipAmount)
110                 .limit(amount)
111                 .map(MethodDescriptor::getString)
112                 .collect(Collectors.toList());
113     }
114 
execute(String fileName)115     protected static OutputAnalyzer execute(String fileName) {
116         OutputAnalyzer output;
117         try {
118             output = ProcessTools.executeTestJvm(
119                     "-XX:+UnlockDiagnosticVMOptions",
120                     "-XX:CompilerDirectivesLimit=1000",
121                     "-XX:CompilerDirectivesFile=" + fileName,
122                     "-version");
123         } catch (Throwable thr) {
124             throw new Error("Execution failed with: " + thr, thr);
125         }
126         return output;
127     }
128 }
129