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 jdk.vm.ci.hotspot; 24 25 import jdk.vm.ci.common.JVMCIError; 26 27 /** 28 * Access to VM configuration data. 29 */ 30 public class HotSpotVMConfigAccess { 31 32 /** 33 * Gets the available configuration data. 34 */ 35 public HotSpotVMConfigStore getStore() { 36 return store; 37 } 38 39 /** 40 * Gets the address of a C++ symbol. 41 * 42 * @param name name of C++ symbol 43 * @param notPresent if non-null and the symbol is not present then this value is returned 44 * @return the address of the symbol 45 * @throws JVMCIError if the symbol is not present and {@code notPresent == null} 46 */ 47 public long getAddress(String name, Long notPresent) { 48 Long entry = store.vmAddresses.get(name); 49 if (entry == null) { 50 if (notPresent != null) { 51 return notPresent; 52 } 53 store.printConfig(); 54 throw new JVMCIError("expected VM symbol not found in " + store + ": " + name); 55 } 56 return entry; 57 } 58 59 /** 60 * Gets the address of a C++ symbol. 61 * 62 * @param name name of C++ symbol 63 * @return the address of the symbol 64 * @throws JVMCIError if the symbol is not present 65 */ 66 public long getAddress(String name) { 67 return getAddress(name, null); 68 } 69 70 /** 71 * Gets the value of a C++ constant. 72 * 73 * @param name name of the constant (e.g., {@code "frame::arg_reg_save_area_bytes"}) 74 * @param type the boxed type to which the constant value will be converted 75 * @param notPresent if non-null and the constant is not present then this value is returned 76 * @return the constant value converted to {@code type} 77 * @throws JVMCIError if the constant is not present and {@code notPresent == null} 78 */ 79 public <T> T getConstant(String name, Class<T> type, T notPresent) { 80 Long c = store.vmConstants.get(name); 81 if (c == null) { 82 if (notPresent != null) { 83 return notPresent; 84 } 85 store.printConfig(); 86 throw new JVMCIError("expected VM constant not found in " + store + ": " + name); 87 } 88 return type.cast(convertValue(name, type, c, null)); 89 } 90 91 /** 92 * Gets the value of a C++ constant. 93 * 94 * @param name name of the constant (e.g., {@code "frame::arg_reg_save_area_bytes"}) 95 * @param type the boxed type to which the constant value will be converted 96 * @return the constant value converted to {@code type} 97 * @throws JVMCIError if the constant is not present 98 */ 99 public <T> T getConstant(String name, Class<T> type) { 100 return getConstant(name, type, null); 101 } 102 103 /** 104 * Gets the offset of a non-static C++ field. 105 * 106 * @param name fully qualified name of the field 107 * @param type the boxed type to which the offset value will be converted (must be 108 * {@link Integer} or {@link Long}) 109 * @param cppType if non-null, the expected C++ type of the field (e.g., {@code "HeapWord*"}) 110 * @param notPresent if non-null and the field is not present then this value is returned 111 * @return the offset in bytes of the requested field 112 * @throws JVMCIError if the field is static or not present and {@code notPresent} is null 113 */ 114 public <T> T getFieldOffset(String name, Class<T> type, String cppType, T notPresent) { 115 assert type == Integer.class || type == Long.class; 116 VMField entry = getField(name, cppType, notPresent == null); 117 if (entry == null) { 118 return notPresent; 119 } 120 if (entry.address != 0) { 121 throw new JVMCIError("cannot get offset of static field " + name); 122 } 123 return type.cast(convertValue(name, type, entry.offset, cppType)); 124 } 125 126 /** 127 * Gets the offset of a non-static C++ field. 128 * 129 * @param name fully qualified name of the field 130 * @param type the boxed type to which the offset value will be converted (must be 131 * {@link Integer} or {@link Long}) 132 * @param cppType if non-null, the expected C++ type of the field (e.g., {@code "HeapWord*"}) 133 * @return the offset in bytes of the requested field 134 * @throws JVMCIError if the field is static or not present 135 */ 136 public <T> T getFieldOffset(String name, Class<T> type, String cppType) { 137 return getFieldOffset(name, type, cppType, null); 138 } 139 140 /** 141 * Gets the offset of a non-static C++ field. 142 * 143 * @param name fully qualified name of the field 144 * @param type the boxed type to which the offset value will be converted (must be 145 * {@link Integer} or {@link Long}) 146 * @return the offset in bytes of the requested field 147 * @throws JVMCIError if the field is static or not present 148 */ 149 public <T> T getFieldOffset(String name, Class<T> type) { 150 return getFieldOffset(name, type, null, null); 151 } 152 153 /** 154 * Gets the address of a static C++ field. 155 * 156 * @param name fully qualified name of the field 157 * @param cppType if non-null, the expected C++ type of the field (e.g., {@code "HeapWord*"}) 158 * @param notPresent if non-null and the field is not present then this value is returned 159 * @return the address of the requested field 160 * @throws JVMCIError if the field is not static or not present and {@code notPresent} is null 161 */ 162 public long getFieldAddress(String name, String cppType, Long notPresent) { 163 VMField entry = getField(name, cppType, notPresent == null); 164 if (entry == null) { 165 return notPresent; 166 } 167 if (entry.address == 0) { 168 throw new JVMCIError(name + " is not a static field"); 169 } 170 return entry.address; 171 } 172 173 /** 174 * Gets the address of a static C++ field. 175 * 176 * @param name fully qualified name of the field 177 * @param cppType if non-null, the expected C++ type of the field (e.g., {@code "HeapWord*"}) 178 * @return the address of the requested field 179 * @throws JVMCIError if the field is not static or not present 180 */ 181 public long getFieldAddress(String name, String cppType) { 182 return getFieldAddress(name, cppType, null); 183 } 184 185 /** 186 * Gets the value of a static C++ field. 187 * 188 * @param name fully qualified name of the field 189 * @param type the boxed type to which the constant value will be converted 190 * @param cppType if non-null, the expected C++ type of the field (e.g., {@code "HeapWord*"}) 191 * @param notPresent if non-null and the field is not present then this value is returned 192 * @return the value of the requested field 193 * @throws JVMCIError if the field is not static or not present and {@code notPresent} is null 194 */ 195 public <T> T getFieldValue(String name, Class<T> type, String cppType, T notPresent) { 196 VMField entry = getField(name, cppType, notPresent == null); 197 if (entry == null) { 198 return notPresent; 199 } 200 if (entry.value == null) { 201 throw new JVMCIError(name + " is not a static field"); 202 } 203 return type.cast(convertValue(name, type, entry.value, cppType)); 204 } 205 206 /** 207 * Gets the value of a static C++ field. 208 * 209 * @param name fully qualified name of the field 210 * @param type the boxed type to which the constant value will be converted 211 * @param cppType if non-null, the expected C++ type of the field (e.g., {@code "HeapWord*"}) 212 * @return the value of the requested field 213 * @throws JVMCIError if the field is not static or not present 214 */ 215 public <T> T getFieldValue(String name, Class<T> type, String cppType) { 216 return getFieldValue(name, type, cppType, null); 217 } 218 219 /** 220 * Gets the value of a static C++ field. 221 * 222 * @param name fully qualified name of the field 223 * @param type the boxed type to which the constant value will be converted 224 * @return the value of the requested field 225 * @throws JVMCIError if the field is not static or not present 226 */ 227 public <T> T getFieldValue(String name, Class<T> type) { 228 return getFieldValue(name, type, null, null); 229 } 230 231 /** 232 * Gets a C++ field. 233 * 234 * @param name fully qualified name of the field 235 * @param cppType if non-null, the expected C++ type of the field (e.g., {@code "HeapWord*"}) 236 * @param required specifies if the field must be present 237 * @return the field 238 * @throws JVMCIError if the field is not present and {@code required == true} 239 */ 240 private VMField getField(String name, String cppType, boolean required) { 241 VMField entry = store.vmFields.get(name); 242 if (entry == null) { 243 if (!required) { 244 return null; 245 } 246 store.printConfig(); 247 throw new JVMCIError("expected VM field not found in " + store + ": " + name); 248 } 249 250 // Make sure the native type is still the type we expect. 251 if (cppType != null && !cppType.equals(entry.type)) { 252 throw new JVMCIError("expected type " + cppType + " but VM field " + name + " is of type " + entry.type); 253 } 254 return entry; 255 } 256 257 /** 258 * Gets a VM flag value. 259 * 260 * @param name name of the flag (e.g., {@code "CompileTheWorldStartAt"}) 261 * @param type the boxed type to which the flag's value will be converted 262 * @return the flag's value converted to {@code type} or {@code notPresent} if the flag is not 263 * present 264 * @throws JVMCIError if the flag is not present 265 */ 266 public <T> T getFlag(String name, Class<T> type) { 267 return getFlag(name, type, null); 271 * Gets a VM flag value. 272 * 273 * @param name name of the flag (e.g., {@code "CompileTheWorldStartAt"}) 274 * @param type the boxed type to which the flag's value will be converted 275 * @param notPresent if non-null and the flag is not present then this value is returned 276 * @return the flag's value converted to {@code type} or {@code notPresent} if the flag is not 277 * present 278 * @throws JVMCIError if the flag is not present and {@code notPresent == null} 279 */ 280 public <T> T getFlag(String name, Class<T> type, T notPresent) { 281 VMFlag entry = store.vmFlags.get(name); 282 Object value; 283 String cppType; 284 if (entry == null) { 285 // Fall back to VM call 286 value = store.compilerToVm.getFlagValue(name); 287 if (value == store.compilerToVm) { 288 if (notPresent != null) { 289 return notPresent; 290 } 291 store.printConfig(); 292 throw new JVMCIError("expected VM flag not found in " + store + ": " + name); 293 } else { 294 cppType = null; 295 } 296 } else { 297 value = entry.value; 298 cppType = entry.type; 299 } 300 return type.cast(convertValue(name, type, value, cppType)); 301 } 302 303 private static <T> Object convertValue(String name, Class<T> toType, Object value, String cppType) throws JVMCIError { 304 if (toType == Boolean.class) { 305 if (value instanceof String) { 306 return Boolean.valueOf((String) value); 307 } else if (value instanceof Boolean) { 308 return value; 309 } else if (value instanceof Long) { 310 return ((long) value) != 0; 311 } 312 } else if (toType == Byte.class) { 313 if (value instanceof Long) { 314 return (byte) (long) value; 315 } 316 } else if (toType == Integer.class) { 317 if (value instanceof Integer) { 318 return value; 319 } else if (value instanceof Long) { 320 return (int) (long) value; 321 } 322 } else if (toType == String.class) { | 1 /* 2 * Copyright (c) 2016, 2019, 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 jdk.vm.ci.hotspot; 24 25 import java.util.Set; 26 import java.util.stream.Collectors; 27 28 import jdk.vm.ci.common.JVMCIError; 29 30 /** 31 * Access to VM configuration data. 32 */ 33 public class HotSpotVMConfigAccess { 34 35 /** 36 * Gets the available configuration data. 37 */ 38 public HotSpotVMConfigStore getStore() { 39 return store; 40 } 41 42 /** 43 * Gets the address of a C++ symbol. 44 * 45 * @param name name of C++ symbol 46 * @param notPresent if non-null and the symbol is not present then this value is returned 47 * @return the address of the symbol 48 * @throws JVMCIError if the symbol is not present and {@code notPresent == null} 49 */ 50 public long getAddress(String name, Long notPresent) { 51 Long entry = store.vmAddresses.get(name); 52 if (entry == null) { 53 if (notPresent != null) { 54 return notPresent; 55 } 56 throw missingEntry("address", name, store.vmFlags.keySet()); 57 58 } 59 return entry; 60 } 61 62 /** 63 * Gets the address of a C++ symbol. 64 * 65 * @param name name of C++ symbol 66 * @return the address of the symbol 67 * @throws JVMCIError if the symbol is not present 68 */ 69 public long getAddress(String name) { 70 return getAddress(name, null); 71 } 72 73 /** 74 * Gets the value of a C++ constant. 75 * 76 * @param name name of the constant (e.g., {@code "frame::arg_reg_save_area_bytes"}) 77 * @param type the boxed type to which the constant value will be converted 78 * @param notPresent if non-null and the constant is not present then this value is returned 79 * @return the constant value converted to {@code type} 80 * @throws JVMCIError if the constant is not present and {@code notPresent == null} 81 */ 82 public <T> T getConstant(String name, Class<T> type, T notPresent) { 83 Long c = store.vmConstants.get(name); 84 if (c == null) { 85 if (notPresent != null) { 86 return notPresent; 87 } 88 throw missingEntry("constant", name, store.vmConstants.keySet()); 89 } 90 return type.cast(convertValue(name, type, c, null)); 91 } 92 93 /** 94 * Gets the value of a C++ constant. 95 * 96 * @param name name of the constant (e.g., {@code "frame::arg_reg_save_area_bytes"}) 97 * @param type the boxed type to which the constant value will be converted 98 * @return the constant value converted to {@code type} 99 * @throws JVMCIError if the constant is not present 100 */ 101 public <T> T getConstant(String name, Class<T> type) { 102 return getConstant(name, type, null); 103 } 104 105 /** 106 * Gets the offset of a non-static C++ field. 107 * 108 * @param name fully qualified name of the field 109 * @param type the boxed type to which the offset value will be converted (must be 110 * {@link Integer} or {@link Long}) 111 * @param cppType if non-null, the expected C++ type of the field (e.g., {@code "HeapWord*"}) 112 * @param notPresent if non-null and the field is not present then this value is returned 113 * @return the offset in bytes of the requested field 114 * @throws JVMCIError if the field is static or not present and {@code notPresent} is null 115 */ 116 public <T> T getFieldOffset(String name, Class<T> type, String cppType, T notPresent) { 117 return getFieldOffset0(name, type, notPresent, cppType, null); 118 } 119 120 /** 121 * Gets the offset of a non-static C++ field. 122 * 123 * @param name fully qualified name of the field 124 * @param type the boxed type to which the offset value will be converted (must be 125 * {@link Integer} or {@link Long}) 126 * @param notPresent if non-null and the field is not present then this value is returned 127 * @param outCppType if non-null, the C++ type of the field (e.g., {@code "HeapWord*"}) is 128 * returned in element 0 of this array 129 * @return the offset in bytes of the requested field 130 * @throws JVMCIError if the field is static or not present and {@code notPresent} is null 131 */ 132 public <T> T getFieldOffset(String name, Class<T> type, T notPresent, String[] outCppType) { 133 return getFieldOffset0(name, type, notPresent, null, outCppType); 134 } 135 136 /** 137 * Gets the offset of a non-static C++ field. 138 * 139 * @param name fully qualified name of the field 140 * @param type the boxed type to which the offset value will be converted (must be 141 * {@link Integer} or {@link Long}) 142 * @param cppType if non-null, the expected C++ type of the field (e.g., {@code "HeapWord*"}) 143 * @return the offset in bytes of the requested field 144 * @throws JVMCIError if the field is static or not present 145 */ 146 public <T> T getFieldOffset(String name, Class<T> type, String cppType) { 147 return getFieldOffset0(name, type, null, cppType, null); 148 } 149 150 /** 151 * Gets the offset of a non-static C++ field. 152 * 153 * @param name fully qualified name of the field 154 * @param type the boxed type to which the offset value will be converted (must be 155 * {@link Integer} or {@link Long}) 156 * @return the offset in bytes of the requested field 157 * @throws JVMCIError if the field is static or not present 158 */ 159 public <T> T getFieldOffset(String name, Class<T> type) { 160 return getFieldOffset0(name, type, null, null, null); 161 } 162 163 private <T> T getFieldOffset0(String name, Class<T> type, T notPresent, String inCppType, String[] outCppType) { 164 assert type == Integer.class || type == Long.class; 165 VMField entry = getField(name, inCppType, notPresent == null); 166 if (entry == null) { 167 return notPresent; 168 } 169 if (entry.address != 0) { 170 throw new JVMCIError("cannot get offset of static field " + name); 171 } 172 if (outCppType != null) { 173 outCppType[0] = entry.type; 174 } 175 return type.cast(convertValue(name, type, entry.offset, inCppType)); 176 } 177 178 /** 179 * Gets the address of a static C++ field. 180 * 181 * @param name fully qualified name of the field 182 * @param cppType if non-null, the expected C++ type of the field (e.g., {@code "HeapWord*"}) 183 * @param notPresent if non-null and the field is not present then this value is returned 184 * @return the address of the requested field 185 * @throws JVMCIError if the field is not static or not present and {@code notPresent} is null 186 */ 187 public long getFieldAddress(String name, String cppType, Long notPresent) { 188 return getFieldAddress0(name, notPresent, cppType, null); 189 } 190 191 /** 192 * Gets the address of a static C++ field. 193 * 194 * @param name fully qualified name of the field 195 * @param notPresent if non-null and the field is not present then this value is returned 196 * @param outCppType if non-null, the C++ type of the field (e.g., {@code "HeapWord*"}) is 197 * returned in element 0 of this array 198 * @return the address of the requested field 199 * @throws JVMCIError if the field is not static or not present and {@code notPresent} is null 200 */ 201 public long getFieldAddress(String name, Long notPresent, String[] outCppType) { 202 return getFieldAddress0(name, notPresent, null, outCppType); 203 } 204 205 /** 206 * Gets the address of a static C++ field. 207 * 208 * @param name fully qualified name of the field 209 * @param cppType if non-null, the expected C++ type of the field (e.g., {@code "HeapWord*"}) 210 * @return the address of the requested field 211 * @throws JVMCIError if the field is not static or not present 212 */ 213 public long getFieldAddress(String name, String cppType) { 214 return getFieldAddress0(name, null, cppType, null); 215 } 216 217 private long getFieldAddress0(String name, Long notPresent, String inCppType, String[] outCppType) { 218 VMField entry = getField(name, inCppType, notPresent == null); 219 if (entry == null) { 220 return notPresent; 221 } 222 if (entry.address == 0) { 223 throw new JVMCIError(name + " is not a static field"); 224 } 225 if (outCppType != null) { 226 outCppType[0] = entry.type; 227 } 228 return entry.address; 229 } 230 231 /** 232 * Gets the value of a static C++ field. 233 * 234 * @param name fully qualified name of the field 235 * @param type the boxed type to which the constant value will be converted 236 * @param cppType if non-null, the expected C++ type of the field (e.g., {@code "HeapWord*"}) 237 * @param notPresent if non-null and the field is not present then this value is returned 238 * @return the value of the requested field 239 * @throws JVMCIError if the field is not static or not present and {@code notPresent} is null 240 */ 241 public <T> T getFieldValue(String name, Class<T> type, String cppType, T notPresent) { 242 return getFieldValue0(name, type, notPresent, cppType, null); 243 } 244 245 /** 246 * Gets the value of a static C++ field. 247 * 248 * @param name fully qualified name of the field 249 * @param type the boxed type to which the constant value will be converted 250 * @param cppType if non-null, the expected C++ type of the field (e.g., {@code "HeapWord*"}) 251 * @return the value of the requested field 252 * @throws JVMCIError if the field is not static or not present 253 */ 254 public <T> T getFieldValue(String name, Class<T> type, String cppType) { 255 return getFieldValue0(name, type, null, cppType, null); 256 } 257 258 /** 259 * Gets the value of a static C++ field. 260 * 261 * @param name fully qualified name of the field 262 * @param type the boxed type to which the constant value will be converted 263 * @param notPresent if non-null and the field is not present then this value is returned 264 * @param outCppType if non-null, the C++ type of the field (e.g., {@code "HeapWord*"}) is 265 * returned in element 0 of this array 266 * @return the value of the requested field 267 * @throws JVMCIError if the field is not static or not present and {@code notPresent} is null 268 */ 269 public <T> T getFieldValue(String name, Class<T> type, T notPresent, String[] outCppType) { 270 return getFieldValue0(name, type, notPresent, null, outCppType); 271 } 272 273 /** 274 * Gets the value of a static C++ field. 275 * 276 * @param name fully qualified name of the field 277 * @param type the boxed type to which the constant value will be converted 278 * @return the value of the requested field 279 * @throws JVMCIError if the field is not static or not present 280 */ 281 public <T> T getFieldValue(String name, Class<T> type) { 282 return getFieldValue0(name, type, null, null, null); 283 } 284 285 private <T> T getFieldValue0(String name, Class<T> type, T notPresent, String inCppType, String[] outCppType) { 286 VMField entry = getField(name, inCppType, notPresent == null); 287 if (entry == null) { 288 return notPresent; 289 } 290 if (entry.value == null) { 291 throw new JVMCIError(name + " is not a static field "); 292 } 293 if (outCppType != null) { 294 outCppType[0] = entry.type; 295 } 296 return type.cast(convertValue(name, type, entry.value, inCppType)); 297 } 298 299 /** 300 * Gets a C++ field. 301 * 302 * @param name fully qualified name of the field 303 * @param cppType if non-null, the expected C++ type of the field (e.g., {@code "HeapWord*"}) 304 * @param required specifies if the field must be present 305 * @return the field 306 * @throws JVMCIError if the field is not present and {@code required == true} 307 */ 308 private VMField getField(String name, String cppType, boolean required) { 309 VMField entry = store.vmFields.get(name); 310 if (entry == null) { 311 if (!required) { 312 return null; 313 } 314 throw missingEntry("field", name, store.vmFields.keySet()); 315 } 316 317 // Make sure the native type is still the type we expect. 318 if (cppType != null && !cppType.equals(entry.type)) { 319 throw new JVMCIError("expected type " + cppType + " but VM field " + name + " is of type " + entry.type); 320 } 321 return entry; 322 } 323 324 /** 325 * Gets a VM flag value. 326 * 327 * @param name name of the flag (e.g., {@code "CompileTheWorldStartAt"}) 328 * @param type the boxed type to which the flag's value will be converted 329 * @return the flag's value converted to {@code type} or {@code notPresent} if the flag is not 330 * present 331 * @throws JVMCIError if the flag is not present 332 */ 333 public <T> T getFlag(String name, Class<T> type) { 334 return getFlag(name, type, null); 338 * Gets a VM flag value. 339 * 340 * @param name name of the flag (e.g., {@code "CompileTheWorldStartAt"}) 341 * @param type the boxed type to which the flag's value will be converted 342 * @param notPresent if non-null and the flag is not present then this value is returned 343 * @return the flag's value converted to {@code type} or {@code notPresent} if the flag is not 344 * present 345 * @throws JVMCIError if the flag is not present and {@code notPresent == null} 346 */ 347 public <T> T getFlag(String name, Class<T> type, T notPresent) { 348 VMFlag entry = store.vmFlags.get(name); 349 Object value; 350 String cppType; 351 if (entry == null) { 352 // Fall back to VM call 353 value = store.compilerToVm.getFlagValue(name); 354 if (value == store.compilerToVm) { 355 if (notPresent != null) { 356 return notPresent; 357 } 358 throw missingEntry("flag", name, store.vmFlags.keySet()); 359 } else { 360 cppType = null; 361 } 362 } else { 363 value = entry.value; 364 cppType = entry.type; 365 } 366 return type.cast(convertValue(name, type, value, cppType)); 367 } 368 369 private JVMCIError missingEntry(String category, String name, Set<String> keys) { 370 throw new JVMCIError("expected VM %s not found in %s: %s%nAvailable values:%n %s", category, store, name, 371 keys.stream().sorted().collect(Collectors.joining(System.lineSeparator() + " "))); 372 } 373 374 private static <T> Object convertValue(String name, Class<T> toType, Object value, String cppType) throws JVMCIError { 375 if (toType == Boolean.class) { 376 if (value instanceof String) { 377 return Boolean.valueOf((String) value); 378 } else if (value instanceof Boolean) { 379 return value; 380 } else if (value instanceof Long) { 381 return ((long) value) != 0; 382 } 383 } else if (toType == Byte.class) { 384 if (value instanceof Long) { 385 return (byte) (long) value; 386 } 387 } else if (toType == Integer.class) { 388 if (value instanceof Integer) { 389 return value; 390 } else if (value instanceof Long) { 391 return (int) (long) value; 392 } 393 } else if (toType == String.class) { |