1 /* 2 * Copyright (c) 2015, 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.jcmd; 25 26 import compiler.compilercontrol.parser.HugeDirectiveUtil; 27 import compiler.compilercontrol.share.AbstractTestBase; 28 import compiler.compilercontrol.share.method.MethodDescriptor; 29 import compiler.compilercontrol.share.scenario.Executor; 30 import jdk.test.lib.OutputAnalyzer; 31 import jdk.test.lib.TimeLimitedRunner; 32 import jdk.test.lib.Utils; 33 import pool.PoolHelper; 34 35 import java.util.ArrayList; 36 import java.util.List; 37 import java.util.Random; 38 import java.util.concurrent.TimeUnit; 39 import java.util.stream.Collectors; 40 41 public abstract class StressAddJcmdBase { 42 private static final int DIRECTIVES_AMOUNT = Integer.getInteger( 43 "compiler.compilercontrol.jcmd.StressAddJcmdBase.directivesAmount", 44 200); 45 private static final int TIMEOUT = Integer.getInteger( 46 "compiler.compilercontrol.jcmd.StressAddJcmdBase.timeout", 47 30); 48 private static final List<MethodDescriptor> DESCRIPTORS = new PoolHelper() 49 .getAllMethods().stream() 50 .map(pair -> AbstractTestBase 51 .getValidMethodDescriptor(pair.first)) 52 .collect(Collectors.toList()); 53 private static final String DIRECTIVE_FILE = "directives.json"; 54 private static final List<String> VM_OPTIONS = new ArrayList<>(); 55 private static final Random RANDOM = Utils.getRandomInstance(); 56 57 static { 58 VM_OPTIONS.add("-Xmixed"); 59 VM_OPTIONS.add("-XX:+UnlockDiagnosticVMOptions"); 60 VM_OPTIONS.add("-XX:+LogCompilation"); 61 VM_OPTIONS.add("-XX:CompilerDirectivesLimit=1001"); 62 } 63 64 /** 65 * Performs test 66 */ 67 public void test() { 68 HugeDirectiveUtil.createHugeFile(DESCRIPTORS, DIRECTIVE_FILE, 69 DIRECTIVES_AMOUNT); 70 Executor executor = new TimeLimitedExecutor(); 71 List<OutputAnalyzer> outputAnalyzers = executor.execute(); 72 outputAnalyzers.get(0).shouldHaveExitValue(0); 73 } 74 75 /** 76 * Makes connection to the test VM and performs a diagnostic command 77 * 78 * @param pid a pid of the VM under test 79 * @return true if the test should continue invocation of this method 80 */ 81 protected abstract boolean makeConnection(int pid); 82 83 /** 84 * Finish test executions 85 */ 86 protected void finish() { } 87 88 protected String nextCommand() { 89 int i = RANDOM.nextInt(JcmdCommand.values().length); 90 JcmdCommand jcmdCommand = JcmdCommand.values()[i]; 91 switch (jcmdCommand) { 92 case ADD: 93 return jcmdCommand.command + " " + DIRECTIVE_FILE; 94 case PRINT: 95 case CLEAR: 96 case REMOVE: 97 return jcmdCommand.command; 98 default: 99 throw new Error("TESTBUG: incorrect command: " + jcmdCommand); 100 } 101 } 102 103 private enum JcmdCommand { 104 ADD("Compiler.directives_add"), 105 PRINT("Compiler.directives_print"), 106 CLEAR("Compiler.directives_clear"), 107 REMOVE("Compiler.directives_remove"); 108 109 public final String command; 110 111 JcmdCommand(String command) { 112 this.command = command; 113 } 114 } 115 116 private class TimeLimitedExecutor extends Executor { 117 public TimeLimitedExecutor() { 118 /* There are no need to check the state */ 119 super(true, VM_OPTIONS, null, null); 120 } 121 122 @Override 123 protected OutputAnalyzer[] executeJCMD(int pid) { 124 TimeLimitedRunner runner = new TimeLimitedRunner( 125 TimeUnit.SECONDS.toMillis(TIMEOUT), 126 Utils.TIMEOUT_FACTOR, 127 () -> makeConnection(pid)); 128 try { 129 runner.call(); 130 } catch (Exception e) { 131 throw new Error("Exception during the execution: " + e, e); 132 } 133 finish(); 134 return new OutputAnalyzer[0]; 135 } 136 } 137 }