346 public HotSpotVMConfig getConfig() {
347 return config;
348 }
349
350 public CompilerToVM getCompilerToVM() {
351 return compilerToVm;
352 }
353
354 // Non-volatile since multi-initialization is harmless
355 private Predicate<ResolvedJavaType> intrinsificationTrustPredicate;
356
357 /**
358 * Gets a predicate that determines if a given type can be considered trusted for the purpose of
359 * intrinsifying methods it declares.
360 *
361 * @param compilerLeafClasses classes in the leaves of the module graph comprising the JVMCI
362 * compiler.
363 */
364 public Predicate<ResolvedJavaType> getIntrinsificationTrustPredicate(Class<?>... compilerLeafClasses) {
365 if (intrinsificationTrustPredicate == null) {
366 intrinsificationTrustPredicate = new Predicate<ResolvedJavaType>() {
367 @Override
368 public boolean test(ResolvedJavaType type) {
369 if (type instanceof HotSpotResolvedJavaType) {
370 Class<?> mirror = getMirror((HotSpotResolvedJavaType) type);
371 Module module = mirror.getModule();
372 return getTrustedModules().contains(module);
373 } else {
374 return false;
375 }
376 }
377
378 private volatile Set<Module> trustedModules;
379
380 private Set<Module> getTrustedModules() {
381 Set<Module> modules = trustedModules;
382 if (modules == null) {
383 modules = new HashSet<>();
384 for (Class<?> compilerConfiguration : compilerLeafClasses) {
385 Module compilerConfigurationModule = compilerConfiguration.getModule();
386 if (compilerConfigurationModule.getDescriptor().isAutomatic()) {
387 throw new IllegalArgumentException(String.format("The module '%s' defining the Graal compiler configuration class '%s' must not be an automatic module",
388 compilerConfigurationModule.getName(), compilerConfiguration.getClass().getName()));
389 }
390 modules.add(compilerConfigurationModule);
396 }
397 }
398 }
399 trustedModules = modules;
400 }
401 return modules;
402 }
403 };
404 }
405 return intrinsificationTrustPredicate;
406 }
407
408 /**
409 * Get the {@link Class} corresponding to {@code type}.
410 *
411 * @param type the type for which a {@link Class} is requested
412 * @return the original Java class corresponding to {@code type} or {@code null} if this runtime
413 * does not support mapping {@link ResolvedJavaType} instances to {@link Class}
414 * instances
415 */
416 public Class<?> getMirror(ResolvedJavaType type) {
417 return ((HotSpotResolvedJavaType) type).mirror();
418 }
419
420 @Override
421 public JVMCICompiler getCompiler() {
422 if (compiler == null) {
423 synchronized (this) {
424 if (compiler == null) {
425 compiler = compilerFactory.createCompiler(this);
426 }
427 }
428 }
429 return compiler;
430 }
431
432 /**
433 * Converts a name to a Java type. This method attempts to resolve {@code name} to a
434 * {@link ResolvedJavaType}.
435 *
637
638 @Override
639 public void flush() throws IOException {
640 compilerToVm.flushDebugOutput();
641 }
642 };
643 }
644
645 /**
646 * Collects the current values of all JVMCI benchmark counters, summed up over all threads.
647 */
648 public long[] collectCounters() {
649 return compilerToVm.collectCounters();
650 }
651
652 /**
653 * The offset from the origin of an array to the first element.
654 *
655 * @return the offset in bytes
656 */
657 public int getArrayBaseOffset(JavaKind kind) {
658 switch (kind) {
659 case Boolean:
660 return Unsafe.ARRAY_BOOLEAN_BASE_OFFSET;
661 case Byte:
662 return Unsafe.ARRAY_BYTE_BASE_OFFSET;
663 case Char:
664 return Unsafe.ARRAY_CHAR_BASE_OFFSET;
665 case Short:
666 return Unsafe.ARRAY_SHORT_BASE_OFFSET;
667 case Int:
668 return Unsafe.ARRAY_INT_BASE_OFFSET;
669 case Long:
670 return Unsafe.ARRAY_LONG_BASE_OFFSET;
671 case Float:
672 return Unsafe.ARRAY_FLOAT_BASE_OFFSET;
673 case Double:
674 return Unsafe.ARRAY_DOUBLE_BASE_OFFSET;
675 case Object:
676 return Unsafe.ARRAY_OBJECT_BASE_OFFSET;
677 default:
678 throw new JVMCIError("%s", kind);
679 }
680
681 }
682
683 /**
684 * The scale used for the index when accessing elements of an array of this kind.
685 *
686 * @return the scale in order to convert the index into a byte offset
687 */
688 public int getArrayIndexScale(JavaKind kind) {
689 switch (kind) {
690 case Boolean:
691 return Unsafe.ARRAY_BOOLEAN_INDEX_SCALE;
692 case Byte:
693 return Unsafe.ARRAY_BYTE_INDEX_SCALE;
694 case Char:
695 return Unsafe.ARRAY_CHAR_INDEX_SCALE;
696 case Short:
697 return Unsafe.ARRAY_SHORT_INDEX_SCALE;
698 case Int:
699 return Unsafe.ARRAY_INT_INDEX_SCALE;
700 case Long:
701 return Unsafe.ARRAY_LONG_INDEX_SCALE;
702 case Float:
703 return Unsafe.ARRAY_FLOAT_INDEX_SCALE;
704 case Double:
705 return Unsafe.ARRAY_DOUBLE_INDEX_SCALE;
706 case Object:
707 return Unsafe.ARRAY_OBJECT_INDEX_SCALE;
742 *
743 * The implementation of the native {@code JCompile.compile0} method would be in the SVM library
744 * that contains the bulk of the JVMCI compiler. The {@code JCompile.compile0} implementation
745 * will be exported as the following JNI-compliant symbol:
746 *
747 * <pre>
748 * Java_com_jcompile_JCompile_compile0
749 * </pre>
750 *
751 * How the JVMCI compiler SVM library is built is outside the scope of this document.
752 *
753 * @see "https://docs.oracle.com/javase/10/docs/specs/jni/design.html#resolving-native-method-names"
754 *
755 * @throws NullPointerException if {@code clazz == null}
756 * @throws IllegalArgumentException if the current execution context is SVM or if {@code clazz}
757 * is {@link Class#isPrimitive()}
758 * @throws UnsatisfiedLinkError if the JVMCI SVM library is not available, a native method in
759 * {@code clazz} is already linked or the SVM JVMCI library does not contain a
760 * JNI-compliant symbol for a native method in {@code clazz}
761 */
762 public void registerNativeMethods(Class<?> clazz) {
763 throw new UnsatisfiedLinkError("SVM library is not available");
764 }
765 }
|
346 public HotSpotVMConfig getConfig() {
347 return config;
348 }
349
350 public CompilerToVM getCompilerToVM() {
351 return compilerToVm;
352 }
353
354 // Non-volatile since multi-initialization is harmless
355 private Predicate<ResolvedJavaType> intrinsificationTrustPredicate;
356
357 /**
358 * Gets a predicate that determines if a given type can be considered trusted for the purpose of
359 * intrinsifying methods it declares.
360 *
361 * @param compilerLeafClasses classes in the leaves of the module graph comprising the JVMCI
362 * compiler.
363 */
364 public Predicate<ResolvedJavaType> getIntrinsificationTrustPredicate(Class<?>... compilerLeafClasses) {
365 if (intrinsificationTrustPredicate == null) {
366 intrinsificationTrustPredicate = new Predicate<>() {
367 @Override
368 public boolean test(ResolvedJavaType type) {
369 if (type instanceof HotSpotResolvedJavaType) {
370 Class<?> mirror = getMirror(type);
371 Module module = mirror.getModule();
372 return getTrustedModules().contains(module);
373 } else {
374 return false;
375 }
376 }
377
378 private volatile Set<Module> trustedModules;
379
380 private Set<Module> getTrustedModules() {
381 Set<Module> modules = trustedModules;
382 if (modules == null) {
383 modules = new HashSet<>();
384 for (Class<?> compilerConfiguration : compilerLeafClasses) {
385 Module compilerConfigurationModule = compilerConfiguration.getModule();
386 if (compilerConfigurationModule.getDescriptor().isAutomatic()) {
387 throw new IllegalArgumentException(String.format("The module '%s' defining the Graal compiler configuration class '%s' must not be an automatic module",
388 compilerConfigurationModule.getName(), compilerConfiguration.getClass().getName()));
389 }
390 modules.add(compilerConfigurationModule);
396 }
397 }
398 }
399 trustedModules = modules;
400 }
401 return modules;
402 }
403 };
404 }
405 return intrinsificationTrustPredicate;
406 }
407
408 /**
409 * Get the {@link Class} corresponding to {@code type}.
410 *
411 * @param type the type for which a {@link Class} is requested
412 * @return the original Java class corresponding to {@code type} or {@code null} if this runtime
413 * does not support mapping {@link ResolvedJavaType} instances to {@link Class}
414 * instances
415 */
416 @SuppressWarnings("static-method")
417 public Class<?> getMirror(ResolvedJavaType type) {
418 return ((HotSpotResolvedJavaType) type).mirror();
419 }
420
421 @Override
422 public JVMCICompiler getCompiler() {
423 if (compiler == null) {
424 synchronized (this) {
425 if (compiler == null) {
426 compiler = compilerFactory.createCompiler(this);
427 }
428 }
429 }
430 return compiler;
431 }
432
433 /**
434 * Converts a name to a Java type. This method attempts to resolve {@code name} to a
435 * {@link ResolvedJavaType}.
436 *
638
639 @Override
640 public void flush() throws IOException {
641 compilerToVm.flushDebugOutput();
642 }
643 };
644 }
645
646 /**
647 * Collects the current values of all JVMCI benchmark counters, summed up over all threads.
648 */
649 public long[] collectCounters() {
650 return compilerToVm.collectCounters();
651 }
652
653 /**
654 * The offset from the origin of an array to the first element.
655 *
656 * @return the offset in bytes
657 */
658 @SuppressWarnings("static-method")
659 public int getArrayBaseOffset(JavaKind kind) {
660 switch (kind) {
661 case Boolean:
662 return Unsafe.ARRAY_BOOLEAN_BASE_OFFSET;
663 case Byte:
664 return Unsafe.ARRAY_BYTE_BASE_OFFSET;
665 case Char:
666 return Unsafe.ARRAY_CHAR_BASE_OFFSET;
667 case Short:
668 return Unsafe.ARRAY_SHORT_BASE_OFFSET;
669 case Int:
670 return Unsafe.ARRAY_INT_BASE_OFFSET;
671 case Long:
672 return Unsafe.ARRAY_LONG_BASE_OFFSET;
673 case Float:
674 return Unsafe.ARRAY_FLOAT_BASE_OFFSET;
675 case Double:
676 return Unsafe.ARRAY_DOUBLE_BASE_OFFSET;
677 case Object:
678 return Unsafe.ARRAY_OBJECT_BASE_OFFSET;
679 default:
680 throw new JVMCIError("%s", kind);
681 }
682
683 }
684
685 /**
686 * The scale used for the index when accessing elements of an array of this kind.
687 *
688 * @return the scale in order to convert the index into a byte offset
689 */
690 @SuppressWarnings("static-method")
691 public int getArrayIndexScale(JavaKind kind) {
692 switch (kind) {
693 case Boolean:
694 return Unsafe.ARRAY_BOOLEAN_INDEX_SCALE;
695 case Byte:
696 return Unsafe.ARRAY_BYTE_INDEX_SCALE;
697 case Char:
698 return Unsafe.ARRAY_CHAR_INDEX_SCALE;
699 case Short:
700 return Unsafe.ARRAY_SHORT_INDEX_SCALE;
701 case Int:
702 return Unsafe.ARRAY_INT_INDEX_SCALE;
703 case Long:
704 return Unsafe.ARRAY_LONG_INDEX_SCALE;
705 case Float:
706 return Unsafe.ARRAY_FLOAT_INDEX_SCALE;
707 case Double:
708 return Unsafe.ARRAY_DOUBLE_INDEX_SCALE;
709 case Object:
710 return Unsafe.ARRAY_OBJECT_INDEX_SCALE;
745 *
746 * The implementation of the native {@code JCompile.compile0} method would be in the SVM library
747 * that contains the bulk of the JVMCI compiler. The {@code JCompile.compile0} implementation
748 * will be exported as the following JNI-compliant symbol:
749 *
750 * <pre>
751 * Java_com_jcompile_JCompile_compile0
752 * </pre>
753 *
754 * How the JVMCI compiler SVM library is built is outside the scope of this document.
755 *
756 * @see "https://docs.oracle.com/javase/10/docs/specs/jni/design.html#resolving-native-method-names"
757 *
758 * @throws NullPointerException if {@code clazz == null}
759 * @throws IllegalArgumentException if the current execution context is SVM or if {@code clazz}
760 * is {@link Class#isPrimitive()}
761 * @throws UnsatisfiedLinkError if the JVMCI SVM library is not available, a native method in
762 * {@code clazz} is already linked or the SVM JVMCI library does not contain a
763 * JNI-compliant symbol for a native method in {@code clazz}
764 */
765 @SuppressWarnings({"static-method", "unused"})
766 public void registerNativeMethods(Class<?> clazz) {
767 throw new UnsatisfiedLinkError("SVM library is not available");
768 }
769 }
|