< prev index next >

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

Print this page




   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 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;
  77 
  78         static {
  79             try (InitTimer t = timer("HotSpotJVMCIRuntime.<init>")) {
  80                 instance = new HotSpotJVMCIRuntime();
  81             }
  82         }
  83     }
  84 
  85     /**
  86      * Gets the singleton {@link HotSpotJVMCIRuntime} object.
  87      */
  88     public static HotSpotJVMCIRuntime runtime() {
  89         JVMCI.initialize();
  90         return DelayedInit.instance;
  91     }
  92 


 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 final JVMCICompilerFactory compilerFactory;
 208     private final HotSpotJVMCICompilerFactory hsCompilerFactory;
 209     private volatile JVMCICompiler compiler;
 210     protected final JVMCIMetaAccessContext metaAccessContext;
 211 
 212     /**
 213      * Stores the result of {@link HotSpotJVMCICompilerFactory#getCompilationLevelAdjustment} so
 214      * that it can be read from the VM.
 215      */
 216     @SuppressWarnings("unused") private final int compilationLevelAdjustment;
 217 
 218     private final Map<Class<? extends Architecture>, JVMCIBackend> backends = new HashMap<>();
 219 
 220     private final Iterable<HotSpotVMEventListener> vmEventListeners;
 221 
 222     /**
 223      * Stores the result of {@link HotSpotJVMCICompilerFactory#getTrivialPrefixes()} so that it can
 224      * be read from the VM.
 225      */
 226     @SuppressWarnings("unused") private final String[] trivialPrefixes;
 227 
 228     @SuppressWarnings("try")
 229     private HotSpotJVMCIRuntime() {
 230         compilerToVm = new CompilerToVM();
 231 
 232         try (InitTimer t = timer("HotSpotVMConfig<init>")) {
 233             config = new HotSpotVMConfig(compilerToVm);
 234         }
 235 
 236         String hostArchitecture = config.getHostArchitectureName();
 237 
 238         HotSpotJVMCIBackendFactory factory;
 239         try (InitTimer t = timer("find factory:", hostArchitecture)) {
 240             factory = findFactory(hostArchitecture);
 241         }
 242 
 243         try (InitTimer t = timer("create JVMCI backend:", hostArchitecture)) {
 244             hostBackend = registerBackend(factory.createJVMCIBackend(this, null));
 245         }
 246 
 247         vmEventListeners = Services.load(HotSpotVMEventListener.class);
 248 
 249         JVMCIMetaAccessContext context = null;
 250         for (HotSpotVMEventListener vmEventListener : vmEventListeners) {
 251             context = vmEventListener.createMetaAccessContext(this);
 252             if (context != null) {
 253                 break;
 254             }
 255         }
 256         if (context == null) {
 257             context = new HotSpotJVMCIMetaAccessContext();
 258         }
 259         metaAccessContext = context;
 260 
 261         boolean printFlags = Option.PrintFlags.getBoolean();
 262         boolean showFlags = Option.ShowFlags.getBoolean();
 263         if (printFlags || showFlags) {
 264             Option.printFlags(System.out);
 265             if (printFlags) {
 266                 System.exit(0);
 267             }
 268         }
 269 
 270         if (Option.PrintConfig.getBoolean()) {
 271             printConfig(config, compilerToVm);
 272         }
 273 
 274         compilerFactory = HotSpotJVMCICompilerConfig.getCompilerFactory();
 275         if (compilerFactory instanceof HotSpotJVMCICompilerFactory) {
 276             hsCompilerFactory = (HotSpotJVMCICompilerFactory) compilerFactory;
 277             trivialPrefixes = hsCompilerFactory.getTrivialPrefixes();
 278             compilationLevelAdjustment = hsCompilerFactory.getCompilationLevelAdjustment(config);
 279         } else {


 285 
 286     private JVMCIBackend registerBackend(JVMCIBackend backend) {
 287         Class<? extends Architecture> arch = backend.getCodeCache().getTarget().arch.getClass();
 288         JVMCIBackend oldValue = backends.put(arch, backend);
 289         assert oldValue == null : "cannot overwrite existing backend for architecture " + arch.getSimpleName();
 290         return backend;
 291     }
 292 
 293     public ResolvedJavaType fromClass(Class<?> javaClass) {
 294         return metaAccessContext.fromClass(javaClass);
 295     }
 296 
 297     public HotSpotVMConfig getConfig() {
 298         return config;
 299     }
 300 
 301     public CompilerToVM getCompilerToVM() {
 302         return compilerToVm;
 303     }
 304 
 305     public JVMCIMetaAccessContext getMetaAccessContext() {
 306         return metaAccessContext;
 307     }
 308 
 309     public JVMCICompiler getCompiler() {
 310         if (compiler == null) {
 311             synchronized (this) {
 312                 if (compiler == null) {
 313                     compiler = compilerFactory.createCompiler(this);
 314                 }
 315             }
 316         }
 317         return compiler;
 318     }
 319 
 320     public JavaType lookupType(String name, HotSpotResolvedObjectType accessingType, boolean resolve) {
 321         Objects.requireNonNull(accessingType, "cannot resolve type without an accessing class");
 322         // If the name represents a primitive type we can short-circuit the lookup.
 323         if (name.length() == 1) {
 324             JavaKind kind = JavaKind.fromPrimitiveOrVoidTypeChar(name.charAt(0));
 325             return fromClass(kind.toJavaClass());
 326         }
 327 
 328         // Resolve non-primitive types in the VM.


 344         assert arch != Architecture.class;
 345         return backends.get(arch);
 346     }
 347 
 348     public Map<Class<? extends Architecture>, JVMCIBackend> getJVMCIBackends() {
 349         return Collections.unmodifiableMap(backends);
 350     }
 351 
 352     /**
 353      * Called from the VM.
 354      */
 355     @SuppressWarnings({"unused"})
 356     private int adjustCompilationLevel(Class<?> declaringClass, String name, String signature, boolean isOsr, int level) {
 357         return hsCompilerFactory.adjustCompilationLevel(config, declaringClass, name, signature, isOsr, level);
 358     }
 359 
 360     /**
 361      * Called from the VM.
 362      */
 363     @SuppressWarnings({"unused"})
 364     private CompilationRequestResult compileMethod(HotSpotResolvedJavaMethod method, int entryBCI, long jvmciEnv, int id) {
 365         CompilationRequestResult result = getCompiler().compileMethod(new HotSpotCompilationRequest(method, entryBCI, jvmciEnv, id));
 366         assert result != null : "compileMethod must always return something";
 367         return result;














 368     }
 369 
 370     /**
 371      * Shuts down the runtime.
 372      *
 373      * Called from the VM.
 374      */
 375     @SuppressWarnings({"unused"})
 376     private void shutdown() throws Exception {
 377         for (HotSpotVMEventListener vmEventListener : vmEventListeners) {
 378             vmEventListener.notifyShutdown();
 379         }
 380     }
 381 
 382     /**
 383      * Notify on completion of a bootstrap.
 384      *
 385      * Called from the VM.
 386      */
 387     @SuppressWarnings({"unused"})




   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 static jdk.vm.ci.common.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.internal.misc.VM;
  41 import jdk.vm.ci.code.Architecture;
  42 import jdk.vm.ci.code.CompilationRequestResult;
  43 import jdk.vm.ci.code.CompiledCode;
  44 import jdk.vm.ci.code.InstalledCode;
  45 import jdk.vm.ci.common.InitTimer;
  46 import jdk.vm.ci.common.JVMCIError;
  47 import jdk.vm.ci.hotspot.services.HotSpotJVMCICompilerFactory;
  48 import jdk.vm.ci.hotspot.services.HotSpotVMEventListener;



  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.runtime.services.JVMCICompilerFactory;
  56 import jdk.vm.ci.services.Services;



  57 
  58 /**
  59  * HotSpot implementation of a JVMCI runtime.
  60  *
  61  * The initialization of this class is very fragile since it's initialized both through
  62  * {@link JVMCI#initialize()} or through calling {@link HotSpotJVMCIRuntime#runtime()} and
  63  * {@link HotSpotJVMCIRuntime#runtime()} is also called by {@link JVMCI#initialize()}. So this class
  64  * can't have a static initializer and any required initialization must be done as part of
  65  * {@link #runtime()}. This allows the initialization to funnel back through
  66  * {@link JVMCI#initialize()} without deadlocking.
  67  */
  68 public final class HotSpotJVMCIRuntime implements HotSpotJVMCIRuntimeProvider {
  69 
  70     @SuppressWarnings("try")
  71     static class DelayedInit {
  72         private static final HotSpotJVMCIRuntime instance;
  73 
  74         static {
  75             try (InitTimer t = timer("HotSpotJVMCIRuntime.<init>")) {
  76                 instance = new HotSpotJVMCIRuntime();
  77             }
  78         }
  79     }
  80 
  81     /**
  82      * Gets the singleton {@link HotSpotJVMCIRuntime} object.
  83      */
  84     public static HotSpotJVMCIRuntime runtime() {
  85         JVMCI.initialize();
  86         return DelayedInit.instance;
  87     }
  88 


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










 246 
 247         boolean printFlags = Option.PrintFlags.getBoolean();
 248         boolean showFlags = Option.ShowFlags.getBoolean();
 249         if (printFlags || showFlags) {
 250             Option.printFlags(System.out);
 251             if (printFlags) {
 252                 System.exit(0);
 253             }
 254         }
 255 
 256         if (Option.PrintConfig.getBoolean()) {
 257             printConfig(config, compilerToVm);
 258         }
 259 
 260         compilerFactory = HotSpotJVMCICompilerConfig.getCompilerFactory();
 261         if (compilerFactory instanceof HotSpotJVMCICompilerFactory) {
 262             hsCompilerFactory = (HotSpotJVMCICompilerFactory) compilerFactory;
 263             trivialPrefixes = hsCompilerFactory.getTrivialPrefixes();
 264             compilationLevelAdjustment = hsCompilerFactory.getCompilationLevelAdjustment(config);
 265         } else {


 271 
 272     private JVMCIBackend registerBackend(JVMCIBackend backend) {
 273         Class<? extends Architecture> arch = backend.getCodeCache().getTarget().arch.getClass();
 274         JVMCIBackend oldValue = backends.put(arch, backend);
 275         assert oldValue == null : "cannot overwrite existing backend for architecture " + arch.getSimpleName();
 276         return backend;
 277     }
 278 
 279     public ResolvedJavaType fromClass(Class<?> javaClass) {
 280         return metaAccessContext.fromClass(javaClass);
 281     }
 282 
 283     public HotSpotVMConfig getConfig() {
 284         return config;
 285     }
 286 
 287     public CompilerToVM getCompilerToVM() {
 288         return compilerToVm;
 289     }
 290 




 291     public JVMCICompiler getCompiler() {
 292         if (compiler == null) {
 293             synchronized (this) {
 294                 if (compiler == null) {
 295                     compiler = compilerFactory.createCompiler(this);
 296                 }
 297             }
 298         }
 299         return compiler;
 300     }
 301 
 302     public JavaType lookupType(String name, HotSpotResolvedObjectType accessingType, boolean resolve) {
 303         Objects.requireNonNull(accessingType, "cannot resolve type without an accessing class");
 304         // If the name represents a primitive type we can short-circuit the lookup.
 305         if (name.length() == 1) {
 306             JavaKind kind = JavaKind.fromPrimitiveOrVoidTypeChar(name.charAt(0));
 307             return fromClass(kind.toJavaClass());
 308         }
 309 
 310         // Resolve non-primitive types in the VM.


 326         assert arch != Architecture.class;
 327         return backends.get(arch);
 328     }
 329 
 330     public Map<Class<? extends Architecture>, JVMCIBackend> getJVMCIBackends() {
 331         return Collections.unmodifiableMap(backends);
 332     }
 333 
 334     /**
 335      * Called from the VM.
 336      */
 337     @SuppressWarnings({"unused"})
 338     private int adjustCompilationLevel(Class<?> declaringClass, String name, String signature, boolean isOsr, int level) {
 339         return hsCompilerFactory.adjustCompilationLevel(config, declaringClass, name, signature, isOsr, level);
 340     }
 341 
 342     /**
 343      * Called from the VM.
 344      */
 345     @SuppressWarnings({"unused"})
 346     private HotSpotCompilationRequestResult compileMethod(HotSpotResolvedJavaMethod method, int entryBCI, long jvmciEnv, int id) {
 347         CompilationRequestResult result = getCompiler().compileMethod(new HotSpotCompilationRequest(method, entryBCI, jvmciEnv, id));
 348         assert result != null : "compileMethod must always return something";
 349         HotSpotCompilationRequestResult hsResult;
 350         if (result instanceof HotSpotCompilationRequestResult) {
 351             hsResult = (HotSpotCompilationRequestResult) result;
 352         } else {
 353             Object failure = result.getFailure();
 354             if (failure != null) {
 355                 boolean retry = false; // Be conservative with unknown compiler
 356                 hsResult = HotSpotCompilationRequestResult.failure(failure.toString(), retry);
 357             } else {
 358                 int inlinedBytecodes = -1;
 359                 hsResult = HotSpotCompilationRequestResult.success(inlinedBytecodes);
 360             }
 361         }
 362 
 363         return hsResult;
 364     }
 365 
 366     /**
 367      * Shuts down the runtime.
 368      *
 369      * Called from the VM.
 370      */
 371     @SuppressWarnings({"unused"})
 372     private void shutdown() throws Exception {
 373         for (HotSpotVMEventListener vmEventListener : vmEventListeners) {
 374             vmEventListener.notifyShutdown();
 375         }
 376     }
 377 
 378     /**
 379      * Notify on completion of a bootstrap.
 380      *
 381      * Called from the VM.
 382      */
 383     @SuppressWarnings({"unused"})


< prev index next >