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