< prev index next >

src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java

Print this page




  25 import static jdk.vm.ci.inittimer.InitTimer.timer;
  26 
  27 import java.io.IOException;
  28 import java.io.OutputStream;
  29 import java.io.PrintStream;
  30 import java.lang.reflect.Array;
  31 import java.lang.reflect.Field;
  32 import java.lang.reflect.Method;
  33 import java.lang.reflect.Modifier;
  34 import java.util.Collections;
  35 import java.util.HashMap;
  36 import java.util.Map;
  37 import java.util.Objects;
  38 import java.util.TreeMap;
  39 
  40 import jdk.vm.ci.code.Architecture;
  41 import jdk.vm.ci.code.CompilationRequestResult;
  42 import jdk.vm.ci.code.CompiledCode;
  43 import jdk.vm.ci.code.InstalledCode;
  44 import jdk.vm.ci.common.JVMCIError;

  45 import jdk.vm.ci.hotspot.services.HotSpotVMEventListener;
  46 import jdk.vm.ci.inittimer.InitTimer;
  47 import jdk.vm.ci.inittimer.SuppressFBWarnings;
  48 import jdk.vm.ci.meta.JVMCIMetaAccessContext;
  49 import jdk.vm.ci.meta.JavaKind;
  50 import jdk.vm.ci.meta.JavaType;
  51 import jdk.vm.ci.meta.ResolvedJavaType;
  52 import jdk.vm.ci.runtime.JVMCI;
  53 import jdk.vm.ci.runtime.JVMCIBackend;
  54 import jdk.vm.ci.runtime.JVMCICompiler;

  55 import jdk.vm.ci.services.Services;
  56 import jdk.internal.misc.VM;
  57 
  58 //JaCoCo Exclude
  59 
  60 /**
  61  * HotSpot implementation of a JVMCI runtime.
  62  *
  63  * The initialization of this class is very fragile since it's initialized both through
  64  * {@link JVMCI#initialize()} or through calling {@link HotSpotJVMCIRuntime#runtime()} and
  65  * {@link HotSpotJVMCIRuntime#runtime()} is also called by {@link JVMCI#initialize()}. So this class
  66  * can't have a static initializer and any required initialization must be done as part of
  67  * {@link #runtime()}. This allows the initialization to funnel back through
  68  * {@link JVMCI#initialize()} without deadlocking.
  69  */
  70 public final class HotSpotJVMCIRuntime implements HotSpotJVMCIRuntimeProvider, HotSpotProxified {
  71 
  72     @SuppressWarnings("try")
  73     static class DelayedInit {
  74         private static final HotSpotJVMCIRuntime instance;


 187             if (factory.getArchitecture().equalsIgnoreCase(architecture)) {
 188                 return factory;
 189             }
 190         }
 191 
 192         throw new JVMCIError("No JVMCI runtime available for the %s architecture", architecture);
 193     }
 194 
 195     /**
 196      * Gets the kind of a word value on the {@linkplain #getHostJVMCIBackend() host} backend.
 197      */
 198     public static JavaKind getHostWordKind() {
 199         return runtime().getHostJVMCIBackend().getCodeCache().getTarget().wordJavaKind;
 200     }
 201 
 202     protected final CompilerToVM compilerToVm;
 203 
 204     protected final HotSpotVMConfig config;
 205     private final JVMCIBackend hostBackend;
 206 


 207     private volatile JVMCICompiler compiler;
 208     protected final JVMCIMetaAccessContext metaAccessContext;
 209 






 210     private final Map<Class<? extends Architecture>, JVMCIBackend> backends = new HashMap<>();
 211 
 212     private final Iterable<HotSpotVMEventListener> vmEventListeners;
 213 




 214     @SuppressWarnings("unused") private final String[] trivialPrefixes;
 215 
 216     @SuppressWarnings("try")
 217     private HotSpotJVMCIRuntime() {
 218         compilerToVm = new CompilerToVM();
 219 
 220         try (InitTimer t = timer("HotSpotVMConfig<init>")) {
 221             config = new HotSpotVMConfig(compilerToVm);
 222         }
 223 
 224         String hostArchitecture = config.getHostArchitectureName();
 225 
 226         HotSpotJVMCIBackendFactory factory;
 227         try (InitTimer t = timer("find factory:", hostArchitecture)) {
 228             factory = findFactory(hostArchitecture);
 229         }
 230 
 231         try (InitTimer t = timer("create JVMCI backend:", hostArchitecture)) {
 232             hostBackend = registerBackend(factory.createJVMCIBackend(this, null));
 233         }


 242             }
 243         }
 244         if (context == null) {
 245             context = new HotSpotJVMCIMetaAccessContext();
 246         }
 247         metaAccessContext = context;
 248 
 249         boolean printFlags = Option.PrintFlags.getBoolean();
 250         boolean showFlags = Option.ShowFlags.getBoolean();
 251         if (printFlags || showFlags) {
 252             Option.printFlags(System.out);
 253             if (printFlags) {
 254                 System.exit(0);
 255             }
 256         }
 257 
 258         if (Option.PrintConfig.getBoolean()) {
 259             printConfig(config, compilerToVm);
 260         }
 261 
 262         trivialPrefixes = HotSpotJVMCICompilerConfig.getCompilerFactory().getTrivialPrefixes();









 263     }
 264 
 265     private JVMCIBackend registerBackend(JVMCIBackend backend) {
 266         Class<? extends Architecture> arch = backend.getCodeCache().getTarget().arch.getClass();
 267         JVMCIBackend oldValue = backends.put(arch, backend);
 268         assert oldValue == null : "cannot overwrite existing backend for architecture " + arch.getSimpleName();
 269         return backend;
 270     }
 271 
 272     public ResolvedJavaType fromClass(Class<?> javaClass) {
 273         return metaAccessContext.fromClass(javaClass);
 274     }
 275 
 276     public HotSpotVMConfig getConfig() {
 277         return config;
 278     }
 279 
 280     public CompilerToVM getCompilerToVM() {
 281         return compilerToVm;
 282     }
 283 
 284     public JVMCIMetaAccessContext getMetaAccessContext() {
 285         return metaAccessContext;
 286     }
 287 
 288     public JVMCICompiler getCompiler() {
 289         if (compiler == null) {
 290             synchronized (this) {
 291                 if (compiler == null) {
 292                     compiler = HotSpotJVMCICompilerConfig.getCompilerFactory().createCompiler(this);
 293                 }
 294             }
 295         }
 296         return compiler;
 297     }
 298 
 299     public JavaType lookupType(String name, HotSpotResolvedObjectType accessingType, boolean resolve) {
 300         Objects.requireNonNull(accessingType, "cannot resolve type without an accessing class");
 301         // If the name represents a primitive type we can short-circuit the lookup.
 302         if (name.length() == 1) {
 303             JavaKind kind = JavaKind.fromPrimitiveOrVoidTypeChar(name.charAt(0));
 304             return fromClass(kind.toJavaClass());
 305         }
 306 
 307         // Resolve non-primitive types in the VM.
 308         HotSpotResolvedObjectTypeImpl hsAccessingType = (HotSpotResolvedObjectTypeImpl) accessingType;
 309         final HotSpotResolvedObjectTypeImpl klass = compilerToVm.lookupType(name, hsAccessingType.mirror(), resolve);
 310 
 311         if (klass == null) {
 312             assert resolve == false;


 315         return klass;
 316     }
 317 
 318     public JVMCIBackend getHostJVMCIBackend() {
 319         return hostBackend;
 320     }
 321 
 322     public <T extends Architecture> JVMCIBackend getJVMCIBackend(Class<T> arch) {
 323         assert arch != Architecture.class;
 324         return backends.get(arch);
 325     }
 326 
 327     public Map<Class<? extends Architecture>, JVMCIBackend> getJVMCIBackends() {
 328         return Collections.unmodifiableMap(backends);
 329     }
 330 
 331     /**
 332      * Called from the VM.
 333      */
 334     @SuppressWarnings({"unused"})








 335     private CompilationRequestResult compileMethod(HotSpotResolvedJavaMethod method, int entryBCI, long jvmciEnv, int id) {
 336         CompilationRequestResult result = getCompiler().compileMethod(new HotSpotCompilationRequest(method, entryBCI, jvmciEnv, id));
 337         assert result != null : "compileMethod must always return something";
 338         return result;
 339     }
 340 
 341     /**
 342      * Shuts down the runtime.
 343      *
 344      * Called from the VM.
 345      */
 346     @SuppressWarnings({"unused"})
 347     private void shutdown() throws Exception {
 348         for (HotSpotVMEventListener vmEventListener : vmEventListeners) {
 349             vmEventListener.notifyShutdown();
 350         }
 351     }
 352 
 353     /**
 354      * Notify on successful install into the CodeCache.




  25 import static jdk.vm.ci.inittimer.InitTimer.timer;
  26 
  27 import java.io.IOException;
  28 import java.io.OutputStream;
  29 import java.io.PrintStream;
  30 import java.lang.reflect.Array;
  31 import java.lang.reflect.Field;
  32 import java.lang.reflect.Method;
  33 import java.lang.reflect.Modifier;
  34 import java.util.Collections;
  35 import java.util.HashMap;
  36 import java.util.Map;
  37 import java.util.Objects;
  38 import java.util.TreeMap;
  39 
  40 import jdk.vm.ci.code.Architecture;
  41 import jdk.vm.ci.code.CompilationRequestResult;
  42 import jdk.vm.ci.code.CompiledCode;
  43 import jdk.vm.ci.code.InstalledCode;
  44 import jdk.vm.ci.common.JVMCIError;
  45 import jdk.vm.ci.hotspot.services.HotSpotJVMCICompilerFactory;
  46 import jdk.vm.ci.hotspot.services.HotSpotVMEventListener;
  47 import jdk.vm.ci.inittimer.InitTimer;
  48 import jdk.vm.ci.inittimer.SuppressFBWarnings;
  49 import jdk.vm.ci.meta.JVMCIMetaAccessContext;
  50 import jdk.vm.ci.meta.JavaKind;
  51 import jdk.vm.ci.meta.JavaType;
  52 import jdk.vm.ci.meta.ResolvedJavaType;
  53 import jdk.vm.ci.runtime.JVMCI;
  54 import jdk.vm.ci.runtime.JVMCIBackend;
  55 import jdk.vm.ci.runtime.JVMCICompiler;
  56 import jdk.vm.ci.runtime.services.JVMCICompilerFactory;
  57 import jdk.vm.ci.services.Services;
  58 import jdk.internal.misc.VM;
  59 
  60 //JaCoCo Exclude
  61 
  62 /**
  63  * HotSpot implementation of a JVMCI runtime.
  64  *
  65  * The initialization of this class is very fragile since it's initialized both through
  66  * {@link JVMCI#initialize()} or through calling {@link HotSpotJVMCIRuntime#runtime()} and
  67  * {@link HotSpotJVMCIRuntime#runtime()} is also called by {@link JVMCI#initialize()}. So this class
  68  * can't have a static initializer and any required initialization must be done as part of
  69  * {@link #runtime()}. This allows the initialization to funnel back through
  70  * {@link JVMCI#initialize()} without deadlocking.
  71  */
  72 public final class HotSpotJVMCIRuntime implements HotSpotJVMCIRuntimeProvider, HotSpotProxified {
  73 
  74     @SuppressWarnings("try")
  75     static class DelayedInit {
  76         private static final HotSpotJVMCIRuntime instance;


 189             if (factory.getArchitecture().equalsIgnoreCase(architecture)) {
 190                 return factory;
 191             }
 192         }
 193 
 194         throw new JVMCIError("No JVMCI runtime available for the %s architecture", architecture);
 195     }
 196 
 197     /**
 198      * Gets the kind of a word value on the {@linkplain #getHostJVMCIBackend() host} backend.
 199      */
 200     public static JavaKind getHostWordKind() {
 201         return runtime().getHostJVMCIBackend().getCodeCache().getTarget().wordJavaKind;
 202     }
 203 
 204     protected final CompilerToVM compilerToVm;
 205 
 206     protected final HotSpotVMConfig config;
 207     private final JVMCIBackend hostBackend;
 208 
 209     private final JVMCICompilerFactory compilerFactory;
 210     private final HotSpotJVMCICompilerFactory hsCompilerFactory;
 211     private volatile JVMCICompiler compiler;
 212     protected final JVMCIMetaAccessContext metaAccessContext;
 213 
 214     /**
 215      * Stores the result of {@link HotSpotJVMCICompilerFactory#getCompilationLevelAdjustment} so
 216      * that it can be read from the VM.
 217      */
 218     @SuppressWarnings("unused") private final int compilationLevelAdjustment;
 219 
 220     private final Map<Class<? extends Architecture>, JVMCIBackend> backends = new HashMap<>();
 221 
 222     private final Iterable<HotSpotVMEventListener> vmEventListeners;
 223 
 224     /**
 225      * Stores the result of {@link HotSpotJVMCICompilerFactory#getTrivialPrefixes()} so that it can
 226      * be read from the VM.
 227      */
 228     @SuppressWarnings("unused") private final String[] trivialPrefixes;
 229 
 230     @SuppressWarnings("try")
 231     private HotSpotJVMCIRuntime() {
 232         compilerToVm = new CompilerToVM();
 233 
 234         try (InitTimer t = timer("HotSpotVMConfig<init>")) {
 235             config = new HotSpotVMConfig(compilerToVm);
 236         }
 237 
 238         String hostArchitecture = config.getHostArchitectureName();
 239 
 240         HotSpotJVMCIBackendFactory factory;
 241         try (InitTimer t = timer("find factory:", hostArchitecture)) {
 242             factory = findFactory(hostArchitecture);
 243         }
 244 
 245         try (InitTimer t = timer("create JVMCI backend:", hostArchitecture)) {
 246             hostBackend = registerBackend(factory.createJVMCIBackend(this, null));
 247         }


 256             }
 257         }
 258         if (context == null) {
 259             context = new HotSpotJVMCIMetaAccessContext();
 260         }
 261         metaAccessContext = context;
 262 
 263         boolean printFlags = Option.PrintFlags.getBoolean();
 264         boolean showFlags = Option.ShowFlags.getBoolean();
 265         if (printFlags || showFlags) {
 266             Option.printFlags(System.out);
 267             if (printFlags) {
 268                 System.exit(0);
 269             }
 270         }
 271 
 272         if (Option.PrintConfig.getBoolean()) {
 273             printConfig(config, compilerToVm);
 274         }
 275 
 276         compilerFactory = HotSpotJVMCICompilerConfig.getCompilerFactory();
 277         if (compilerFactory instanceof HotSpotJVMCICompilerFactory) {
 278             hsCompilerFactory = (HotSpotJVMCICompilerFactory) compilerFactory;
 279             trivialPrefixes = hsCompilerFactory.getTrivialPrefixes();
 280             compilationLevelAdjustment = hsCompilerFactory.getCompilationLevelAdjustment(config);
 281         } else {
 282             hsCompilerFactory = null;
 283             trivialPrefixes = null;
 284             compilationLevelAdjustment = 0;
 285         }
 286     }
 287 
 288     private JVMCIBackend registerBackend(JVMCIBackend backend) {
 289         Class<? extends Architecture> arch = backend.getCodeCache().getTarget().arch.getClass();
 290         JVMCIBackend oldValue = backends.put(arch, backend);
 291         assert oldValue == null : "cannot overwrite existing backend for architecture " + arch.getSimpleName();
 292         return backend;
 293     }
 294 
 295     public ResolvedJavaType fromClass(Class<?> javaClass) {
 296         return metaAccessContext.fromClass(javaClass);
 297     }
 298 
 299     public HotSpotVMConfig getConfig() {
 300         return config;
 301     }
 302 
 303     public CompilerToVM getCompilerToVM() {
 304         return compilerToVm;
 305     }
 306 
 307     public JVMCIMetaAccessContext getMetaAccessContext() {
 308         return metaAccessContext;
 309     }
 310 
 311     public JVMCICompiler getCompiler() {
 312         if (compiler == null) {
 313             synchronized (this) {
 314                 if (compiler == null) {
 315                     compiler = compilerFactory.createCompiler(this);
 316                 }
 317             }
 318         }
 319         return compiler;
 320     }
 321 
 322     public JavaType lookupType(String name, HotSpotResolvedObjectType accessingType, boolean resolve) {
 323         Objects.requireNonNull(accessingType, "cannot resolve type without an accessing class");
 324         // If the name represents a primitive type we can short-circuit the lookup.
 325         if (name.length() == 1) {
 326             JavaKind kind = JavaKind.fromPrimitiveOrVoidTypeChar(name.charAt(0));
 327             return fromClass(kind.toJavaClass());
 328         }
 329 
 330         // Resolve non-primitive types in the VM.
 331         HotSpotResolvedObjectTypeImpl hsAccessingType = (HotSpotResolvedObjectTypeImpl) accessingType;
 332         final HotSpotResolvedObjectTypeImpl klass = compilerToVm.lookupType(name, hsAccessingType.mirror(), resolve);
 333 
 334         if (klass == null) {
 335             assert resolve == false;


 338         return klass;
 339     }
 340 
 341     public JVMCIBackend getHostJVMCIBackend() {
 342         return hostBackend;
 343     }
 344 
 345     public <T extends Architecture> JVMCIBackend getJVMCIBackend(Class<T> arch) {
 346         assert arch != Architecture.class;
 347         return backends.get(arch);
 348     }
 349 
 350     public Map<Class<? extends Architecture>, JVMCIBackend> getJVMCIBackends() {
 351         return Collections.unmodifiableMap(backends);
 352     }
 353 
 354     /**
 355      * Called from the VM.
 356      */
 357     @SuppressWarnings({"unused"})
 358     private int adjustCompilationLevel(Class<?> declaringClass, String name, String signature, boolean isOsr, int level) {
 359         return hsCompilerFactory.adjustCompilationLevel(config, declaringClass, name, signature, isOsr, level);
 360     }
 361 
 362     /**
 363      * Called from the VM.
 364      */
 365     @SuppressWarnings({"unused"})
 366     private CompilationRequestResult compileMethod(HotSpotResolvedJavaMethod method, int entryBCI, long jvmciEnv, int id) {
 367         CompilationRequestResult result = getCompiler().compileMethod(new HotSpotCompilationRequest(method, entryBCI, jvmciEnv, id));
 368         assert result != null : "compileMethod must always return something";
 369         return result;
 370     }
 371 
 372     /**
 373      * Shuts down the runtime.
 374      *
 375      * Called from the VM.
 376      */
 377     @SuppressWarnings({"unused"})
 378     private void shutdown() throws Exception {
 379         for (HotSpotVMEventListener vmEventListener : vmEventListeners) {
 380             vmEventListener.notifyShutdown();
 381         }
 382     }
 383 
 384     /**
 385      * Notify on successful install into the CodeCache.


< prev index next >