VMProps.java revision 2762:caf2fd524fd5
1/* 2 * Copyright (c) 2016, 2017, 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 */ 23package requires; 24 25import java.io.IOException; 26import java.nio.file.Files; 27import java.nio.file.Path; 28import java.nio.file.Paths; 29import java.nio.file.StandardOpenOption; 30import java.util.ArrayList; 31import java.util.HashMap; 32import java.util.List; 33import java.util.Map; 34import java.util.concurrent.Callable; 35import java.util.regex.Matcher; 36import java.util.regex.Pattern; 37 38import sun.hotspot.cpuinfo.CPUInfo; 39import sun.hotspot.gc.GC; 40import sun.hotspot.WhiteBox; 41import jdk.test.lib.Platform; 42 43/** 44 * The Class to be invoked by jtreg prior Test Suite execution to 45 * collect information about VM. 46 * Do not use any API's that may not be available in all target VMs. 47 * Properties set by this Class will be available in the @requires expressions. 48 */ 49public class VMProps implements Callable<Map<String, String>> { 50 51 private static final WhiteBox WB = WhiteBox.getWhiteBox(); 52 53 /** 54 * Collects information about VM properties. 55 * This method will be invoked by jtreg. 56 * 57 * @return Map of property-value pairs. 58 */ 59 @Override 60 public Map<String, String> call() { 61 Map<String, String> map = new HashMap<>(); 62 map.put("vm.flavor", vmFlavor()); 63 map.put("vm.compMode", vmCompMode()); 64 map.put("vm.bits", vmBits()); 65 map.put("vm.flightRecorder", vmFlightRecorder()); 66 map.put("vm.simpleArch", vmArch()); 67 map.put("vm.debug", vmDebug()); 68 map.put("vm.jvmci", vmJvmci()); 69 map.put("vm.emulatedClient", vmEmulatedClient()); 70 map.put("vm.cpu.features", cpuFeatures()); 71 map.put("vm.rtm.cpu", vmRTMCPU()); 72 map.put("vm.rtm.os", vmRTMOS()); 73 map.put("vm.aot", vmAOT()); 74 // vm.cds is true if the VM is compiled with cds support. 75 map.put("vm.cds", vmCDS()); 76 vmGC(map); // vm.gc.X = true/false 77 78 VMProps.dump(map); 79 return map; 80 } 81 82 /** 83 * Prints a stack trace before returning null. 84 * Used by the various helper functions which parse information from 85 * VM properties in the case where they don't find an expected property 86 * or a propoerty doesn't conform to an expected format. 87 * 88 * @return null 89 */ 90 private String nullWithException(String message) { 91 new Exception(message).printStackTrace(); 92 return null; 93 } 94 95 /** 96 * @return vm.simpleArch value of "os.simpleArch" property of tested JDK. 97 */ 98 protected String vmArch() { 99 String arch = System.getProperty("os.arch"); 100 if (arch.equals("x86_64") || arch.equals("amd64")) { 101 return "x64"; 102 } 103 else if (arch.contains("86")) { 104 return "x86"; 105 } else { 106 return arch; 107 } 108 } 109 110 111 112 /** 113 * @return VM type value extracted from the "java.vm.name" property. 114 */ 115 protected String vmFlavor() { 116 // E.g. "Java HotSpot(TM) 64-Bit Server VM" 117 String vmName = System.getProperty("java.vm.name"); 118 if (vmName == null) { 119 return nullWithException("Can't get 'java.vm.name' property"); 120 } 121 122 Pattern startP = Pattern.compile(".* (\\S+) VM"); 123 Matcher m = startP.matcher(vmName); 124 if (m.matches()) { 125 return m.group(1).toLowerCase(); 126 } 127 return nullWithException("Can't get VM flavor from 'java.vm.name'"); 128 } 129 130 /** 131 * @return VM compilation mode extracted from the "java.vm.info" property. 132 */ 133 protected String vmCompMode() { 134 // E.g. "mixed mode" 135 String vmInfo = System.getProperty("java.vm.info"); 136 if (vmInfo == null) { 137 return nullWithException("Can't get 'java.vm.info' property"); 138 } 139 if (vmInfo.toLowerCase().indexOf("mixed mode") != -1) { 140 return "Xmixed"; 141 } else if (vmInfo.toLowerCase().indexOf("compiled mode") != -1) { 142 return "Xcomp"; 143 } else if (vmInfo.toLowerCase().indexOf("interpreted mode") != -1) { 144 return "Xint"; 145 } else { 146 return nullWithException("Can't get compilation mode from 'java.vm.info'"); 147 } 148 } 149 150 /** 151 * @return VM bitness, the value of the "sun.arch.data.model" property. 152 */ 153 protected String vmBits() { 154 String dataModel = System.getProperty("sun.arch.data.model"); 155 if (dataModel != null) { 156 return dataModel; 157 } else { 158 return nullWithException("Can't get 'sun.arch.data.model' property"); 159 } 160 } 161 162 /** 163 * @return "true" if Flight Recorder is enabled, "false" if is disabled. 164 */ 165 protected String vmFlightRecorder() { 166 Boolean isUnlockedCommercialFatures = WB.getBooleanVMFlag("UnlockCommercialFeatures"); 167 Boolean isFlightRecorder = WB.getBooleanVMFlag("FlightRecorder"); 168 String startFROptions = WB.getStringVMFlag("StartFlightRecording"); 169 if (isUnlockedCommercialFatures != null && isUnlockedCommercialFatures) { 170 if (isFlightRecorder != null && isFlightRecorder) { 171 return "true"; 172 } 173 if (startFROptions != null && !startFROptions.isEmpty()) { 174 return "true"; 175 } 176 } 177 return "false"; 178 } 179 180 /** 181 * @return debug level value extracted from the "jdk.debug" property. 182 */ 183 protected String vmDebug() { 184 String debug = System.getProperty("jdk.debug"); 185 if (debug != null) { 186 return "" + debug.contains("debug"); 187 } else { 188 return nullWithException("Can't get 'jdk.debug' property"); 189 } 190 } 191 192 /** 193 * @return true if VM supports JVMCI and false otherwise 194 */ 195 protected String vmJvmci() { 196 // builds with jvmci have this flag 197 return "" + (WB.getBooleanVMFlag("EnableJVMCI") != null); 198 } 199 200 /** 201 * @return true if VM runs in emulated-client mode and false otherwise. 202 */ 203 protected String vmEmulatedClient() { 204 String vmInfo = System.getProperty("java.vm.info"); 205 if (vmInfo == null) { 206 return "false"; 207 } 208 return "" + vmInfo.contains(" emulated-client"); 209 } 210 211 /** 212 * @return supported CPU features 213 */ 214 protected String cpuFeatures() { 215 return CPUInfo.getFeatures().toString(); 216 } 217 218 /** 219 * For all existing GC sets vm.gc.X property. 220 * Example vm.gc.G1=true means: 221 * VM supports G1 222 * User either set G1 explicitely (-XX:+UseG1GC) or did not set any GC 223 * @param map - property-value pairs 224 */ 225 protected void vmGC(Map<String, String> map){ 226 GC currentGC = GC.current(); 227 boolean isByErgo = GC.currentSetByErgo(); 228 List<GC> supportedGC = GC.allSupported(); 229 for (GC gc: GC.values()) { 230 boolean isSupported = supportedGC.contains(gc); 231 boolean isAcceptable = isSupported && (gc == currentGC || isByErgo); 232 map.put("vm.gc." + gc.name(), "" + isAcceptable); 233 } 234 } 235 236 /** 237 * @return true if VM runs RTM supported OS and false otherwise. 238 */ 239 protected String vmRTMOS() { 240 boolean isRTMOS = true; 241 242 if (Platform.isAix()) { 243 // Actually, this works since AIX 7.1.3.30, but os.version property 244 // is set to 7.1. 245 isRTMOS = (Platform.getOsVersionMajor() > 7) || 246 (Platform.getOsVersionMajor() == 7 && Platform.getOsVersionMinor() > 1); 247 248 } else if (Platform.isLinux()) { 249 if (Platform.isPPC()) { 250 isRTMOS = (Platform.getOsVersionMajor() > 4) || 251 (Platform.getOsVersionMajor() == 4 && Platform.getOsVersionMinor() > 1); 252 } 253 } 254 return "" + isRTMOS; 255 } 256 257 /** 258 * @return true if VM runs RTM supported CPU and false otherwise. 259 */ 260 protected String vmRTMCPU() { 261 boolean vmRTMCPU = (Platform.isPPC() ? CPUInfo.hasFeature("tcheck") : CPUInfo.hasFeature("rtm")); 262 263 return "" + vmRTMCPU; 264 } 265 266 /** 267 * @return true if VM supports AOT and false otherwise 268 */ 269 protected String vmAOT() { 270 // builds with aot have jaotc in <JDK>/bin 271 Path bin = Paths.get(System.getProperty("java.home")) 272 .resolve("bin"); 273 Path jaotc; 274 if (Platform.isWindows()) { 275 jaotc = bin.resolve("jaotc.exe"); 276 } else { 277 jaotc = bin.resolve("jaotc"); 278 } 279 return "" + Files.exists(jaotc); 280 } 281 282 /** 283 * Check for CDS support. 284 * 285 * @return true if CDS is supported by the VM to be tested. 286 */ 287 protected String vmCDS() { 288 if (WB.isCDSIncludedInVmBuild()) { 289 return "true"; 290 } else { 291 return "false"; 292 } 293 } 294 295 /** 296 * Dumps the map to the file if the file name is given as the property. 297 * This functionality could be helpful to know context in the real 298 * execution. 299 * 300 * @param map 301 */ 302 protected static void dump(Map<String, String> map) { 303 String dumpFileName = System.getProperty("vmprops.dump"); 304 if (dumpFileName == null) { 305 return; 306 } 307 List<String> lines = new ArrayList<>(); 308 map.forEach((k, v) -> lines.add(k + ":" + v)); 309 try { 310 Files.write(Paths.get(dumpFileName), lines, StandardOpenOption.APPEND); 311 } catch (IOException e) { 312 throw new RuntimeException("Failed to dump properties into '" 313 + dumpFileName + "'", e); 314 } 315 } 316 317 /** 318 * This method is for the testing purpose only. 319 * @param args 320 */ 321 public static void main(String args[]) { 322 Map<String, String> map = new VMProps().call(); 323 map.forEach((k, v) -> System.out.println(k + ": '" + v + "'")); 324 } 325} 326