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 if (Boolean.valueOf(System.getProperty("graal.printconfig"))) { 143 printConfig(config); 144 } 145 146 target = createTarget(); 147 assert wordKind == null || wordKind.equals(target.wordKind); 148 wordKind = target.wordKind; 149 150 runtime = createRuntime(); 151 152 // Replacements cannot have speculative optimizations since they have 153 // to be valid for the entire run of the VM. 154 Assumptions assumptions = new Assumptions(false); 155 replacements = new HotSpotReplacementsImpl(runtime, assumptions, runtime.getGraalRuntime().getTarget()); 156 157 backend = createBackend(); 158 GraalOptions.StackShadowPages = config.stackShadowPages; 159 if (GraalOptions.CacheGraphs) { 160 cache = new HotSpotGraphCache(); 161 } 162 } 163 164 private static void printConfig(HotSpotVMConfig config) { 165 Field[] fields = config.getClass().getDeclaredFields(); 166 Map<String, Field> sortedFields = new TreeMap<>(); 167 for (Field f : fields) { 168 f.setAccessible(true); 169 sortedFields.put(f.getName(), f); 170 } 171 for (Field f : sortedFields.values()) { 172 try { 173 Logger.info(String.format("%9s %-40s = %s", f.getType().getSimpleName(), f.getName(), Logger.pretty(f.get(config)))); 174 } catch (Exception e) { 175 } 176 } 177 } 178 179 protected abstract TargetDescription createTarget(); 180 181 protected abstract HotSpotBackend createBackend(); 182 183 protected abstract HotSpotRuntime createRuntime(); 184 185 public HotSpotVMConfig getConfig() { 186 return config; 187 } 188 189 public TargetDescription getTarget() { 190 return target; 191 } 192 193 public HotSpotGraphCache getCache() { 194 return cache; 195 } 196 197 public CompilerToVM getCompilerToVM() { 198 return compilerToVm; 199 } 200 201 public VMToCompiler getVMToCompiler() { 202 return vmToCompiler; 203 } 204 205 public JavaType lookupType(String name, HotSpotResolvedObjectType accessingClass, boolean eagerResolve) { 206 if (name.length() == 1 && vmToCompiler instanceof VMToCompilerImpl) { 207 VMToCompilerImpl impl = (VMToCompilerImpl) vmToCompiler; 208 Kind kind = Kind.fromPrimitiveOrVoidTypeChar(name.charAt(0)); 209 switch (kind) { 210 case Boolean: 211 return impl.typeBoolean; 212 case Byte: 213 return impl.typeByte; 214 case Char: 215 return impl.typeChar; 216 case Double: 217 return impl.typeDouble; 218 case Float: 219 return impl.typeFloat; 220 case Illegal: 221 break; 222 case Int: 223 return impl.typeInt; 224 case Long: 225 return impl.typeLong; 226 case Object: 227 break; 228 case Short: 229 return impl.typeShort; 230 case Void: 231 return impl.typeVoid; 232 } 233 } 234 return compilerToVm.lookupType(name, accessingClass, eagerResolve); 235 } 236 237 public HotSpotRuntimeInterpreterInterface getRuntimeInterpreterInterface() { 238 if (runtimeInterpreterInterface == null) { 239 runtimeInterpreterInterface = new HotSpotRuntimeInterpreterInterface(getRuntime()); 240 } 241 return runtimeInterpreterInterface; 242 } 243 244 public HotSpotRuntime getRuntime() { 245 return runtime; 246 } 247 248 public Replacements getReplacements() { 249 return replacements; 250 } 251 252 public void evictDeoptedGraphs() { 253 if (cache != null) { 254 long[] deoptedGraphs = getCompilerToVM().getDeoptedLeafGraphIds(); 255 if (deoptedGraphs != null) { 256 if (deoptedGraphs.length == 0) { 257 cache.clear(); 258 } else { 259 cache.removeGraphs(deoptedGraphs); 260 } 261 } 262 } 263 } 264 265 @Override 266 public String getName() { 267 return getClass().getSimpleName(); 268 } 269 270 @SuppressWarnings("unchecked") 271 @Override 272 public <T> T getCapability(Class<T> clazz) { 273 if (clazz == GraalCodeCacheProvider.class || clazz == CodeCacheProvider.class || clazz == MetaAccessProvider.class) { 274 return (T) getRuntime(); 275 } 276 if (clazz == DisassemblerProvider.class || clazz == BytecodeDisassemblerProvider.class) { 277 return (T) getRuntime(); 278 } 279 if (clazz == HotSpotRuntime.class) { 280 return (T) runtime; 281 } 282 if (clazz == Replacements.class) { 283 return (T) replacements; 284 } 285 if (clazz == Backend.class) { 286 return (T) getBackend(); 287 } 288 return null; 289 } 290 291 public HotSpotBackend getBackend() { 292 return backend; 293 } 294 }