1 /* 2 * Copyright (c) 2011, 2012, 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 com.oracle.graal.hotspot; 24 25 import static com.oracle.graal.graph.UnsafeAccess.*; 26 27 import java.lang.reflect.*; 28 import java.util.*; 29 30 import com.oracle.graal.api.code.*; 31 import com.oracle.graal.api.meta.*; 32 import com.oracle.graal.api.runtime.*; 33 import com.oracle.graal.compiler.target.*; 34 import com.oracle.graal.hotspot.bridge.*; 35 import com.oracle.graal.hotspot.logging.*; 36 import com.oracle.graal.hotspot.meta.*; 37 import com.oracle.graal.nodes.spi.*; 38 import com.oracle.graal.phases.*; 39 40 /** 41 * Singleton class holding the instance of the {@link GraalRuntime}. 42 * 43 * The platform specific subclass is created by a call from the C++ HotSpot code. 44 */ 45 public abstract class HotSpotGraalRuntime implements GraalRuntime { 46 47 private static HotSpotGraalRuntime instance; 48 49 /** 50 * Gets the singleton runtime instance object. 51 */ 52 public static HotSpotGraalRuntime getInstance() { 53 return instance; 54 } 55 56 /** 57 * Called by the platform specific class exactly once to register the singleton instance. 58 */ 59 protected static void setInstance(HotSpotGraalRuntime runtime) { 60 assert instance == null : "runtime already registered"; 61 instance = runtime; 62 63 // Do deferred initialization 64 65 // Proxies for the VM/Compiler interfaces cannot be initialized 66 // in the constructor as proxy creation causes static 67 // initializers to be executed for all the types involved in the 68 // proxied methods. Some of these static initializers (e.g. in 69 // HotSpotMethodData) rely on the above instance field being set 70 // to retrieve config details. 71 VMToCompiler toCompiler = runtime.vmToCompiler; 72 CompilerToVM toVM = runtime.compilerToVm; 73 74 if (CountingProxy.ENABLED) { 75 toCompiler = CountingProxy.getProxy(VMToCompiler.class, toCompiler); 76 toVM = CountingProxy.getProxy(CompilerToVM.class, toVM); 77 } 78 if (Logger.ENABLED) { 79 toCompiler = LoggingProxy.getProxy(VMToCompiler.class, toCompiler); 80 toVM = LoggingProxy.getProxy(CompilerToVM.class, toVM); 81 } 82 83 runtime.vmToCompiler = toCompiler; 84 runtime.compilerToVm = toVM; 85 } 86 87 private static Kind wordKind; 88 89 /** 90 * Gets the kind of a word value. 91 */ 92 public static Kind wordKind() { 93 assert wordKind != null; 94 return wordKind; 95 } 96 97 /** 98 * Reads a word value from a given address. 99 */ 100 public static long unsafeReadWord(long address) { 101 if (wordKind == Kind.Long) { 102 return unsafe.getLong(address); 103 } 104 return unsafe.getInt(address); 105 } 106 107 /** 108 * Reads a word value from a given object. 109 */ 110 public static long unsafeReadWord(Object object, long offset) { 111 if (wordKind == Kind.Long) { 112 return unsafe.getLong(object, offset); 113 } 114 return unsafe.getInt(object, offset); 115 } 116 117 protected/* final */CompilerToVM compilerToVm; 118 protected/* final */VMToCompiler vmToCompiler; 119 120 protected final HotSpotRuntime runtime; 121 protected final TargetDescription target; 122 protected final Replacements replacements; 123 124 private HotSpotRuntimeInterpreterInterface runtimeInterpreterInterface; 125 private volatile HotSpotGraphCache cache; 126 127 protected final HotSpotVMConfig config; 128 private final HotSpotBackend backend; 129 130 protected HotSpotGraalRuntime() { 131 CompilerToVM toVM = new CompilerToVMImpl(); 132 133 // initialize VmToCompiler 134 VMToCompiler toCompiler = new VMToCompilerImpl(this); 135 136 compilerToVm = toVM; 137 vmToCompiler = toCompiler; 138 config = new HotSpotVMConfig(); 139 compilerToVm.initializeConfiguration(config); 140 config.check(); 141 142 // Set some global options: 143 GraalOptions.HotSpotPrintCompilation = config.printCompilation; 144 GraalOptions.HotSpotPrintInlining = config.printInlining; 145 146 if (Boolean.valueOf(System.getProperty("graal.printconfig"))) { 147 printConfig(config); 148 } 149 150 target = createTarget(); 151 assert wordKind == null || wordKind.equals(target.wordKind); 152 wordKind = target.wordKind; 153 154 runtime = createRuntime(); 155 156 // Replacements cannot have speculative optimizations since they have 157 // to be valid for the entire run of the VM. 158 Assumptions assumptions = new Assumptions(false); 159 replacements = new HotSpotReplacementsImpl(runtime, assumptions, runtime.getGraalRuntime().getTarget()); 160 161 backend = createBackend(); 162 GraalOptions.StackShadowPages = config.stackShadowPages; 163 if (GraalOptions.CacheGraphs) { 164 cache = new HotSpotGraphCache(); 165 } 166 } 167 168 private static void printConfig(HotSpotVMConfig config) { 169 Field[] fields = config.getClass().getDeclaredFields(); 170 Map<String, Field> sortedFields = new TreeMap<>(); 171 for (Field f : fields) { 172 f.setAccessible(true); 173 sortedFields.put(f.getName(), f); 174 } 175 for (Field f : sortedFields.values()) { 176 try { 177 Logger.info(String.format("%9s %-40s = %s", f.getType().getSimpleName(), f.getName(), Logger.pretty(f.get(config)))); 178 } catch (Exception e) { 179 } 180 } 181 } 182 183 protected abstract TargetDescription createTarget(); 184 185 protected abstract HotSpotBackend createBackend(); 186 187 protected abstract HotSpotRuntime createRuntime(); 188 189 public HotSpotVMConfig getConfig() { 190 return config; 191 } 192 193 public TargetDescription getTarget() { 194 return target; 195 } 196 197 public HotSpotGraphCache getCache() { 198 return cache; 199 } 200 201 public CompilerToVM getCompilerToVM() { 202 return compilerToVm; 203 } 204 205 public VMToCompiler getVMToCompiler() { 206 return vmToCompiler; 207 } 208 209 public JavaType lookupType(String name, HotSpotResolvedObjectType accessingClass, boolean eagerResolve) { 210 if (name.length() == 1 && vmToCompiler instanceof VMToCompilerImpl) { 211 VMToCompilerImpl impl = (VMToCompilerImpl) vmToCompiler; 212 Kind kind = Kind.fromPrimitiveOrVoidTypeChar(name.charAt(0)); 213 switch (kind) { 214 case Boolean: 215 return impl.typeBoolean; 216 case Byte: 217 return impl.typeByte; 218 case Char: 219 return impl.typeChar; 220 case Double: 221 return impl.typeDouble; 222 case Float: 223 return impl.typeFloat; 224 case Illegal: 225 break; 226 case Int: 227 return impl.typeInt; 228 case Long: 229 return impl.typeLong; 230 case Object: 231 break; 232 case Short: 233 return impl.typeShort; 234 case Void: 235 return impl.typeVoid; 236 } 237 } 238 return compilerToVm.lookupType(name, accessingClass, eagerResolve); 239 } 240 241 public HotSpotRuntimeInterpreterInterface getRuntimeInterpreterInterface() { 242 if (runtimeInterpreterInterface == null) { 243 runtimeInterpreterInterface = new HotSpotRuntimeInterpreterInterface(getRuntime()); 244 } 245 return runtimeInterpreterInterface; 246 } 247 248 public HotSpotRuntime getRuntime() { 249 return runtime; 250 } 251 252 public Replacements getReplacements() { 253 return replacements; 254 } 255 256 public void evictDeoptedGraphs() { 257 if (cache != null) { 258 long[] deoptedGraphs = getCompilerToVM().getDeoptedLeafGraphIds(); 259 if (deoptedGraphs != null) { 260 if (deoptedGraphs.length == 0) { 261 cache.clear(); 262 } else { 263 cache.removeGraphs(deoptedGraphs); 264 } 265 } 266 } 267 } 268 269 @Override 270 public String getName() { 271 return getClass().getSimpleName(); 272 } 273 274 @SuppressWarnings("unchecked") 275 @Override 276 public <T> T getCapability(Class<T> clazz) { 277 if (clazz == GraalCodeCacheProvider.class || clazz == CodeCacheProvider.class || clazz == MetaAccessProvider.class) { 278 return (T) getRuntime(); 279 } 280 if (clazz == DisassemblerProvider.class || clazz == BytecodeDisassemblerProvider.class) { 281 return (T) getRuntime(); 282 } 283 if (clazz == HotSpotRuntime.class) { 284 return (T) runtime; 285 } 286 if (clazz == Replacements.class) { 287 return (T) replacements; 288 } 289 if (clazz == Backend.class) { 290 return (T) getBackend(); 291 } 292 return null; 293 } 294 295 public HotSpotBackend getBackend() { 296 return backend; 297 } 298 }