Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/hotspot/jtreg/compiler/compilercontrol/share/scenario/Scenario.java
41161 views
1
/*
2
* Copyright (c) 2015, 2020, 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.share.scenario;
25
26
import compiler.compilercontrol.share.method.MethodDescriptor;
27
import compiler.compilercontrol.share.pool.PoolHelper;
28
import compiler.compilercontrol.share.processors.CommandProcessor;
29
import compiler.compilercontrol.share.processors.LogProcessor;
30
import compiler.compilercontrol.share.processors.PrintDirectivesProcessor;
31
import compiler.compilercontrol.share.processors.PrintProcessor;
32
import jdk.test.lib.Asserts;
33
import jdk.test.lib.process.OutputAnalyzer;
34
import jdk.test.lib.util.Pair;
35
36
import java.lang.reflect.Executable;
37
import java.util.ArrayList;
38
import java.util.Collections;
39
import java.util.HashMap;
40
import java.util.LinkedHashSet;
41
import java.util.List;
42
import java.util.Map;
43
import java.util.Set;
44
import java.util.concurrent.Callable;
45
import java.util.function.Consumer;
46
47
/**
48
* Test scenario
49
*/
50
public final class Scenario {
51
private final boolean isValid;
52
private final boolean isJcmdValid;
53
private final Map<Executable, State> states;
54
private final List<Consumer<OutputAnalyzer>> processors;
55
private final Executor executor;
56
private final Consumer<List<OutputAnalyzer>> jcmdProcessor;
57
58
private Scenario(boolean isValid,
59
boolean isJcmdValid,
60
List<String> vmopts,
61
Map<Executable, State> states,
62
List<CompileCommand> compileCommands,
63
List<JcmdCommand> jcmdCommands,
64
List<CompileCommand> directives) {
65
this.isValid = isValid;
66
this.isJcmdValid = isJcmdValid;
67
this.states = states;
68
processors = new ArrayList<>();
69
processors.add(new LogProcessor(states));
70
processors.add(new PrintProcessor(states));
71
List<CompileCommand> nonQuieted = new ArrayList<>();
72
List<CompileCommand> quieted = new ArrayList<>();
73
boolean metQuiet = false;
74
for (CompileCommand cc : compileCommands) {
75
metQuiet |= cc.command == Command.QUIET;
76
if (metQuiet) {
77
quieted.add(cc);
78
} else {
79
nonQuieted.add(cc);
80
}
81
}
82
processors.add(new CommandProcessor(nonQuieted, quieted));
83
List<String> jcmdExecCommands = new ArrayList<>();
84
boolean addCommandMet = false;
85
boolean printCommandMet = false;
86
for (JcmdCommand cmd : jcmdCommands) {
87
switch (cmd.jcmdType) {
88
case ADD:
89
if (!addCommandMet) {
90
jcmdExecCommands.add(JcmdType.ADD.command);
91
}
92
addCommandMet = true;
93
break;
94
case PRINT:
95
printCommandMet = true;
96
break;
97
default:
98
jcmdExecCommands.add(cmd.jcmdType.command);
99
break;
100
}
101
}
102
// Add print command only in the end to get directives printed
103
if (printCommandMet) {
104
jcmdExecCommands.add(JcmdType.PRINT.command);
105
}
106
jcmdProcessor = new PrintDirectivesProcessor(directives);
107
executor = new Executor(isValid, vmopts, states, jcmdExecCommands);
108
}
109
110
/**
111
* Executes scenario
112
*/
113
public void execute() {
114
List<OutputAnalyzer> outputList = executor.execute();
115
// The first one contains output from the test VM
116
OutputAnalyzer mainOutput = outputList.get(0);
117
if (isValid) {
118
mainOutput.shouldHaveExitValue(0);
119
processors.forEach(processor -> processor.accept(mainOutput));
120
// only the last output contains directives got from print command
121
List<OutputAnalyzer> last = new ArrayList<>();
122
last.add(outputList.get(outputList.size() - 1));
123
jcmdProcessor.accept(last);
124
} else {
125
// two cases for invalid inputs.
126
if (mainOutput.getExitValue() == 0) {
127
if (!isJcmdValid) {
128
boolean parse_error_found = false;
129
for(OutputAnalyzer out : outputList) {
130
if (out.getOutput().contains("Parsing of compiler directives failed")) {
131
parse_error_found = true;
132
break;
133
}
134
}
135
Asserts.assertTrue(parse_error_found, "'Parsing of compiler directives failed' missing from output");
136
} else {
137
mainOutput.shouldContain("CompileCommand: An error occurred during parsing");
138
}
139
} else {
140
Asserts.assertNE(mainOutput.getExitValue(), 0, "VM should exit with "
141
+ "error for incorrect directives");
142
mainOutput.shouldContain("Parsing of compiler directives failed");
143
}
144
}
145
}
146
147
/**
148
* Gets states of methods for this scenario
149
*
150
* @return pairs of executable and its state
151
*/
152
public Map<Executable, State> getStates() {
153
return states;
154
}
155
156
public static enum Compiler {
157
C1("c1"),
158
C2("c2");
159
160
public final String name;
161
162
Compiler(String name) {
163
this.name = name;
164
}
165
}
166
167
/**
168
* Type of diagnostic (jcmd) command
169
*/
170
public static enum JcmdType {
171
ADD("Compiler.directives_add " + Type.JCMD.fileName),
172
PRINT("Compiler.directives_print"),
173
CLEAR("Compiler.directives_clear"),
174
REMOVE("Compiler.directives_remove");
175
176
public final String command;
177
private JcmdType(String command) {
178
this.command = command;
179
}
180
}
181
182
/**
183
* Type of the compile command
184
*/
185
public static enum Type {
186
OPTION(""), // CompilerOracle: -XX:CompileCommand=
187
FILE("command_file"), // CompilerOracle: -XX:CompileCommandFile=
188
DIRECTIVE("directives.json"),
189
JCMD("jcmd_directives.json") {
190
@Override
191
public CompileCommand createCompileCommand(Command command,
192
MethodDescriptor md, Compiler compiler) {
193
return new JcmdCommand(command, md, compiler, this,
194
JcmdType.ADD);
195
}
196
197
@Override
198
public CompileCommand createCompileCommand(Command command,
199
MethodDescriptor md, Compiler compiler, String argument) {
200
return new JcmdCommand(command, md, compiler, this,
201
JcmdType.ADD, argument);
202
}
203
};
204
205
public final String fileName;
206
207
public CompileCommand createCompileCommand(Command command,
208
MethodDescriptor md, Compiler compiler) {
209
return new CompileCommand(command, md, compiler, this);
210
}
211
212
public CompileCommand createCompileCommand(Command command,
213
MethodDescriptor md, Compiler compiler, String argument) {
214
return new CompileCommand(command, md, compiler, this, argument);
215
}
216
217
private Type(String fileName) {
218
this.fileName = fileName;
219
}
220
}
221
222
public static Builder getBuilder() {
223
return new Builder();
224
}
225
226
public static class Builder {
227
private final Set<String> vmopts = new LinkedHashSet<>();
228
private final Map<Type, StateBuilder<CompileCommand>> builders
229
= new HashMap<>();
230
private final JcmdStateBuilder jcmdStateBuilder;
231
private final List<JcmdCommand> jcmdCommands = new ArrayList<>();
232
private boolean logCommandMet = false;
233
234
public Builder() {
235
addFlag("-Xmixed");
236
builders.put(Type.FILE, new CommandFileBuilder(Type.FILE.fileName));
237
builders.put(Type.OPTION, new CommandOptionsBuilder());
238
builders.put(Type.DIRECTIVE, new DirectiveBuilder(
239
Type.DIRECTIVE.fileName));
240
jcmdStateBuilder = new JcmdStateBuilder(Type.JCMD.fileName);
241
}
242
243
public void addFlag(String flag) {
244
vmopts.add(flag);
245
}
246
247
public void add(CompileCommand compileCommand) {
248
System.out.println(compileCommand);
249
String[] vmOptions = compileCommand.command.vmOpts;
250
Collections.addAll(vmopts, vmOptions);
251
if (compileCommand.command == Command.LOG) {
252
logCommandMet = true;
253
}
254
if (compileCommand.type == Type.JCMD) {
255
jcmdStateBuilder.add((JcmdCommand) compileCommand);
256
jcmdCommands.add((JcmdCommand) compileCommand);
257
} else {
258
StateBuilder<CompileCommand> builder = builders.get(
259
compileCommand.type);
260
if (builder == null) {
261
throw new Error("TESTBUG: Missing builder for the type: "
262
+ compileCommand.type);
263
}
264
builder.add(compileCommand);
265
}
266
}
267
268
public Scenario build() {
269
boolean isValid = true;
270
boolean isJcmdValid = true;
271
272
// Get states from each of the state builders
273
Map<Executable, State> commandFileStates
274
= builders.get(Type.FILE).getStates();
275
Map<Executable, State> commandOptionStates
276
= builders.get(Type.OPTION).getStates();
277
Map<Executable, State> directiveFileStates
278
= builders.get(Type.DIRECTIVE).getStates();
279
280
// check if directives stack was cleared by jcmd
281
boolean isClearedState = false;
282
if (jcmdContainsCommand(JcmdType.CLEAR)) {
283
isClearedState = true;
284
}
285
286
// Merge states
287
List<Pair<Executable, Callable<?>>> methods = new PoolHelper()
288
.getAllMethods();
289
Map<Executable, State> finalStates = new HashMap<>();
290
Map<Executable, State> jcmdStates = jcmdStateBuilder.getStates();
291
for (Pair<Executable, Callable<?>> pair : methods) {
292
Executable x = pair.first;
293
State commandOptionState = commandOptionStates.get(x);
294
State commandFileState = commandFileStates.get(x);
295
State st = State.merge(commandOptionState, commandFileState);
296
if (!isClearedState) {
297
State directiveState = directiveFileStates.get(x);
298
State jcmdState = jcmdStates.get(x);
299
if (jcmdState != null) {
300
st = State.merge(st, jcmdState);
301
} else if (directiveState != null) {
302
st = State.merge(st, directiveState);
303
}
304
}
305
finalStates.put(x, st);
306
}
307
308
/*
309
* Create a list of commands from options and file
310
* to handle quiet command
311
*/
312
List<CompileCommand> ccList = new ArrayList<>();
313
ccList.addAll(builders.get(Type.OPTION).getCompileCommands());
314
ccList.addAll(builders.get(Type.FILE).getCompileCommands());
315
316
// Create a list of directives to check which one was printed
317
List<CompileCommand> directives = new ArrayList<>();
318
if (jcmdContainsCommand(JcmdType.PRINT)) {
319
if (!isClearedState) {
320
directives.addAll(builders.get(Type.DIRECTIVE)
321
.getCompileCommands());
322
}
323
directives.addAll(jcmdStateBuilder.getCompileCommands());
324
}
325
326
// Get all VM options after we build all states and files
327
List<String> options = new ArrayList<>();
328
options.addAll(vmopts);
329
for (StateBuilder<?> builder : builders.values()) {
330
options.addAll(builder.getOptions());
331
isValid &= builder.isValid();
332
}
333
isJcmdValid = jcmdStateBuilder.isFileValid;
334
options.addAll(jcmdStateBuilder.getOptions());
335
336
/*
337
* Update final states if LogCompilation is enabled and
338
* there is no any log command, then all methods should be logged
339
*/
340
boolean isLogComp = vmopts.stream()
341
.anyMatch(opt -> opt.contains("-XX:+LogCompilation"));
342
if (isLogComp && !logCommandMet) {
343
finalStates.entrySet()
344
.forEach(entry -> entry.getValue().setLog(true));
345
}
346
347
return new Scenario(isValid, isJcmdValid, options, finalStates, ccList,
348
jcmdCommands, directives);
349
}
350
351
// shows if jcmd have passed a specified jcmd command type
352
private boolean jcmdContainsCommand(JcmdType type) {
353
for (JcmdCommand jcmdCommand : jcmdCommands) {
354
if (jcmdCommand.jcmdType == type) {
355
return true;
356
}
357
}
358
return false;
359
}
360
}
361
}
362
363