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.calls.common; 25 26 import compiler.testlibrary.CompilerUtils; 27 import jdk.test.lib.Asserts; 28 import sun.hotspot.WhiteBox; 29 30 import java.lang.reflect.Method; 31 import java.util.Arrays; 32 33 /** 34 * A common class for Invoke* classes 35 */ 36 public abstract class CallsBase { 37 public static final String CALL_ERR_MSG = "Call insuccessfull"; 38 protected final Method calleeMethod; 39 protected final Method callerMethod; 40 protected final WhiteBox wb = WhiteBox.getWhiteBox(); 41 protected int compileCallee = -1; 42 protected int compileCaller = -1; 43 protected boolean nativeCallee = false; 44 protected boolean nativeCaller = false; 45 protected boolean calleeVisited = false; 46 protected boolean checkCallerCompilationLevel; 47 protected boolean checkCalleeCompilationLevel; 48 protected int expectedCallerCompilationLevel; 49 protected int expectedCalleeCompilationLevel; 50 51 protected CallsBase() { 52 try { 53 callerMethod = getClass().getDeclaredMethod("caller"); 54 calleeMethod = getClass().getDeclaredMethod("callee", 55 getCalleeParametersTypes()); 56 wb.testSetDontInlineMethod(callerMethod, /* dontinline= */ true); 57 wb.testSetDontInlineMethod(calleeMethod, /* dontinline= */ true); 58 } catch (NoSuchMethodException e) { 59 throw new Error("TEST BUG: can't find test method", e); 60 } 61 } 62 63 /** 64 * Provides callee parameters types to search method 65 * @return array of types 66 */ 67 protected Class[] getCalleeParametersTypes() { 68 return new Class[] {int.class, long.class, float.class, 69 double.class, String.class}; 70 } 71 72 /** 73 * Loads native library(libCallsNative.so) 74 */ 75 protected static void loadNativeLibrary() { 76 System.loadLibrary("CallsNative"); 77 } 78 79 /** 80 * Checks if requested compilation levels are inside of current vm capabilities 81 * @return true if vm is capable of requested compilation levels 82 */ 83 protected final boolean compilationLevelsSupported() { 84 int[] compLevels = CompilerUtils.getAvailableCompilationLevels(); 85 boolean callerCompLevelSupported = compileCaller > 0 86 && Arrays.stream(compLevels) 87 .filter(elem -> elem == compileCaller) 88 .findAny() 89 .isPresent(); 90 boolean calleeCompLevelSupported = compileCallee > 0 91 && Arrays.stream(compLevels) 92 .filter(elem -> elem == compileCallee) 93 .findAny() 94 .isPresent(); 95 return callerCompLevelSupported && calleeCompLevelSupported; 96 } 97 98 /** 99 * Parse test arguments 100 * @param args test arguments 101 */ 102 protected final void parseArgs(String args[]) { 103 for (int i = 0; i < args.length; i++) { 104 switch (args[i]) { 105 case "-nativeCallee": 106 nativeCallee = true; 107 break; 108 case "-nativeCaller": 109 nativeCaller = true; 110 break; 111 case "-compileCallee": 112 compileCallee = Integer.parseInt(args[++i]); 113 break; 114 case "-compileCaller": 115 compileCaller = Integer.parseInt(args[++i]); 116 break; 117 case "-checkCallerCompileLevel": 118 checkCallerCompilationLevel = true; 119 expectedCallerCompilationLevel = Integer.parseInt(args[++i]); 120 break; 121 case "-checkCalleeCompileLevel": 122 checkCalleeCompilationLevel = true; 123 expectedCalleeCompilationLevel = Integer.parseInt(args[++i]); 124 break; 125 default: 126 throw new Error("Can't parse test parameter:" + args[i]); 127 } 128 } 129 } 130 131 /** 132 * Run basic logic of a test by doing compile 133 * action(if needed). An arguments can be -compileCallee 134 * $calleeCompilationLevel and/or -compileCaller $callerCompilationLevel 135 * and/or -nativeCaller and/or -nativeCallee to indicate that native methods 136 * for caller/callee should be used 137 * @param args test args 138 */ 139 protected final void runTest(String args[]) { 140 parseArgs(args); 141 if (compilationLevelsSupported()) { 142 if (nativeCaller || nativeCallee) { 143 CallsBase.loadNativeLibrary(); 144 } 145 Object lock = getLockObject(); 146 Asserts.assertNotNull(lock, "Lock object is null"); 147 /* a following lock is needed in case several instances of this 148 test are launched in same vm */ 149 synchronized (lock) { 150 if (compileCaller > 0 || compileCallee > 0) { 151 caller(); // call once to have everything loaded 152 calleeVisited = false; // reset state 153 } 154 // compile with requested level if needed 155 if (compileCallee > 0) { 156 compileMethod(calleeMethod, compileCallee); 157 } 158 if (checkCalleeCompilationLevel) { 159 Asserts.assertEQ(expectedCalleeCompilationLevel, 160 wb.getMethodCompilationLevel(calleeMethod), 161 "Unexpected callee compilation level"); 162 } 163 if (compileCaller > 0) { 164 compileMethod(callerMethod, compileCaller); 165 } 166 if (checkCallerCompilationLevel) { 167 Asserts.assertEQ(expectedCallerCompilationLevel, 168 wb.getMethodCompilationLevel(callerMethod), 169 "Unexpected caller compilation level"); 170 } 171 // do calling work 172 if (nativeCaller) { 173 callerNative(); 174 } else { 175 caller(); 176 } 177 } 178 } else { 179 System.out.println("WARNING: Requested compilation levels are " 180 + "out of current vm capabilities. Skipping."); 181 } 182 } 183 184 /** 185 * A method to compile another method, searching it by name in current class 186 * @param method a method to compile 187 * @param compLevel a compilation level 188 */ 189 protected final void compileMethod(Method method, int compLevel) { 190 wb.deoptimizeMethod(method); 191 Asserts.assertTrue(wb.isMethodCompilable(method, compLevel)); 192 wb.enqueueMethodForCompilation(method, compLevel); 193 } 194 195 /* 196 * @return Object to lock on during execution 197 */ 198 199 protected abstract Object getLockObject(); 200 201 protected abstract void caller(); 202 203 protected abstract void callerNative(); 204 205 /** 206 * A method checking values. Should be used to verify if all parameters are 207 * passed as expected. Parameter N should have a value indicating number "N" 208 * in respective type representation. 209 */ 210 public static void checkValues(int param1, long param2, float param3, 211 double param4, String param5) { 212 Asserts.assertEQ(param1, 1); 213 Asserts.assertEQ(param2, 2L); 214 Asserts.assertEQ(param3, 3.0f); 215 Asserts.assertEQ(param4, 4.0d); 216 Asserts.assertEQ(param5, "5"); 217 } 218 }