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