1 /* 2 * Copyright (c) 2016, 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 package requires; 24 25 import java.io.IOException; 26 import java.nio.file.Files; 27 import java.nio.file.Paths; 28 import java.nio.file.StandardOpenOption; 29 import java.util.ArrayList; 30 import java.util.HashMap; 31 import java.util.List; 32 import java.util.Map; 33 import java.util.concurrent.Callable; 34 import java.util.regex.Matcher; 35 import java.util.regex.Pattern; 36 37 import sun.hotspot.cpuinfo.CPUInfo; 38 import sun.hotspot.gc.GC; 39 import 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 */ 47 public 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 * @return vm.simpleArch value of "os.simpleArch" property of tested JDK. 77 */ 78 protected String vmArch() { 79 String arch = System.getProperty("os.arch"); 80 if (arch.equals("x86_64") || arch.equals("amd64")) { 81 return "x64"; 82 } 83 else if (arch.contains("86")) { 84 return "x86"; 85 } else { 86 return arch; 87 } 88 } 89 90 91 92 /** 93 * @return VM type value extracted from the "java.vm.name" property. 94 */ 95 protected String vmFlavor() { 96 // E.g. "Java HotSpot(TM) 64-Bit Server VM" 97 String vmName = System.getProperty("java.vm.name"); 98 if (vmName == null) { 99 return null; 100 } 101 102 Pattern startP = Pattern.compile(".* (\\S+) VM"); 103 Matcher m = startP.matcher(vmName); 104 if (m.matches()) { 105 return m.group(1).toLowerCase(); 106 } 107 return null; 108 } 109 110 /** 111 * @return VM compilation mode extracted from the "java.vm.info" property. 112 */ 113 protected String vmCompMode() { 114 // E.g. "mixed mode" 115 String vmInfo = System.getProperty("java.vm.info"); 116 if (vmInfo == null) { 117 return null; 118 } 119 int k = vmInfo.toLowerCase().indexOf(" mode"); 120 if (k < 0) { 121 return null; 122 } 123 vmInfo = vmInfo.substring(0, k); 124 switch (vmInfo) { 125 case "mixed" : return "Xmixed"; 126 case "compiled" : return "Xcomp"; 127 case "interpreted" : return "Xint"; 128 default: return null; 129 } 130 } 131 132 /** 133 * @return VM bitness, the value of the "sun.arch.data.model" property. 134 */ 135 protected String vmBits() { 136 return System.getProperty("sun.arch.data.model"); 137 } 138 139 /** 140 * @return "true" if Flight Recorder is enabled, "false" if is disabled. 141 */ 142 protected String vmFlightRecorder() { 143 Boolean isUnlockedCommercialFatures = WB.getBooleanVMFlag("UnlockCommercialFeatures"); 144 Boolean isFlightRecorder = WB.getBooleanVMFlag("FlightRecorder"); 145 String startFROptions = WB.getStringVMFlag("StartFlightRecording"); 146 if (isUnlockedCommercialFatures != null && isUnlockedCommercialFatures) { 147 if (isFlightRecorder != null && isFlightRecorder) { 148 return "true"; 149 } 150 if (startFROptions != null && !startFROptions.isEmpty()) { 151 return "true"; 152 } 153 } 154 return "false"; 155 } 156 157 /** 158 * @return debug level value extracted from the "jdk.debug" property. 159 */ 160 protected String vmDebug() { 161 return "" + System.getProperty("jdk.debug").contains("debug"); 162 } 163 164 /** 165 * @return true if VM supports JVMCI and false otherwise 166 */ 167 protected String vmJvmci() { 168 // builds with jvmci have this flag 169 return "" + (WB.getBooleanVMFlag("EnableJVMCI") != null); 170 } 171 172 /** 173 * @return true if VM runs in emulated-client mode and false otherwise. 174 */ 175 protected String vmEmulatedClient() { 176 String vmInfo = System.getProperty("java.vm.info"); 177 if (vmInfo == null) { 178 return "false"; 179 } 180 return "" + vmInfo.contains(" emulated-client"); 181 } 182 183 /** 184 * @return supported CPU features 185 */ 186 protected String cpuFeatures() { 187 return CPUInfo.getFeatures().toString(); 188 } 189 190 /** 191 * For all existing GC sets vm.gc.X property. 192 * Example vm.gc.G1=true means: 193 * VM supports G1 194 * User either set G1 explicitely (-XX:+UseG1GC) or did not set any GC 195 * @param map - property-value pairs 196 */ 197 protected void vmGC(Map<String, String> map){ 198 GC currentGC = GC.current(); 199 boolean isByErgo = GC.currentSetByErgo(); 200 List<GC> supportedGC = GC.allSupported(); 201 for (GC gc: GC.values()) { 202 boolean isSupported = supportedGC.contains(gc); 203 boolean isAcceptable = isSupported && (gc == currentGC || isByErgo); 204 map.put("vm.gc." + gc.name(), "" + isAcceptable); 205 } 206 } 207 208 /** 209 * Dumps the map to the file if the file name is given as the property. 210 * This functionality could be helpful to know context in the real 211 * execution. 212 * 213 * @param map 214 */ 215 protected static void dump(Map<String, String> map) { 216 String dumpFileName = System.getProperty("vmprops.dump"); 217 if (dumpFileName == null) { 218 return; 219 } 220 List<String> lines = new ArrayList<>(); 221 map.forEach((k, v) -> lines.add(k + ":" + v)); 222 try { 223 Files.write(Paths.get(dumpFileName), lines, StandardOpenOption.APPEND); 224 } catch (IOException e) { 225 throw new RuntimeException("Failed to dump properties into '" 226 + dumpFileName + "'", e); 227 } 228 } 229 230 /** 231 * This method is for the testing purpose only. 232 * @param args 233 */ 234 public static void main(String args[]) { 235 Map<String, String> map = new VMProps().call(); 236 map.forEach((k, v) -> System.out.println(k + ": '" + v + "'")); 237 } 238 }