Skip to content

Commit

Permalink
do not intrinsify boxing if box type is uninitialized (GR-44739)
Browse files Browse the repository at this point in the history
  • Loading branch information
dougxc committed Mar 31, 2023
1 parent 6adc960 commit 5923501
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,11 @@ protected boolean isPrimitiveBoxingCacheField(ResolvedJavaField field) {
if (isArray(field) && field.isFinal() && field.getName().equals("cache")) {
ResolvedJavaType type = field.getDeclaringClass();
String typeName = type.getName();
if (typeName.equals("Ljava/lang/Character$CharacterCache;") || typeName.equals("Ljava/lang/Byte$ByteCache;") || typeName.equals("Ljava/lang/Short$ShortCache;") ||
typeName.equals("Ljava/lang/Integer$IntegerCache;") || typeName.equals("Ljava/lang/Long$LongCache;")) {
if (typeName.equals("Ljava/lang/Character$CharacterCache;") ||
typeName.equals("Ljava/lang/Byte$ByteCache;") ||
typeName.equals("Ljava/lang/Short$ShortCache;") ||
typeName.equals("Ljava/lang/Integer$IntegerCache;") ||
typeName.equals("Ljava/lang/Long$LongCache;")) {
return true;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -230,19 +230,24 @@ public Templates(OptionValues options, Group.Factory factory, Providers provider
valueCounter = new SnippetCounter(group, "<kind>Value", "unbox intrinsification");
}

private static LocationIdentity getCacheLocation(CoreProviders providers, JavaKind kind) {
static Class<?> getCacheClass(JavaKind kind) {
Class<?>[] innerClasses = null;
try {
innerClasses = kind.toBoxedJavaClass().getDeclaredClasses();
if (innerClasses == null || innerClasses.length == 0) {
throw GraalError.shouldNotReachHere("Inner classes must exist"); // ExcludeFromJacocoGeneratedReport
innerClasses = kind.toBoxedJavaClass().getDeclaredClasses();
for (Class<?> innerClass : innerClasses) {
if (innerClass.getSimpleName().equals(kind.toBoxedJavaClass().getSimpleName() + "Cache")) {
return innerClass;
}
for (Class<?> innerClass : innerClasses) {
if (innerClass.getName().endsWith("Cache")) {
return new FieldLocationIdentity(providers.getMetaAccess().lookupJavaField(innerClass.getDeclaredField("cache")));
}
}
throw GraalError.shouldNotReachHere("No cache inner class found"); // ExcludeFromJacocoGeneratedReport
}
return null;
}

private static LocationIdentity getCacheLocation(CoreProviders providers, JavaKind kind) {
Class<?> cacheClass = getCacheClass(kind);
if (cacheClass == null) {
throw GraalError.shouldNotReachHere(String.format("Cache class for %s not found", kind)); // ExcludeFromJacocoGeneratedReport
}
try {
return new FieldLocationIdentity(providers.getMetaAccess().lookupJavaField(cacheClass.getDeclaredField("cache")));
} catch (Throwable e) {
throw GraalError.shouldNotReachHere(e); // ExcludeFromJacocoGeneratedReport
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import static org.graalvm.compiler.core.common.memory.MemoryOrderMode.RELEASE;
import static org.graalvm.compiler.core.common.memory.MemoryOrderMode.VOLATILE;
import static org.graalvm.compiler.nodes.NamedLocationIdentity.OFF_HEAP_LOCATION;
import static org.graalvm.compiler.replacements.BoxingSnippets.Templates.getCacheClass;
import static org.graalvm.compiler.replacements.nodes.AESNode.CryptMode.DECRYPT;
import static org.graalvm.compiler.replacements.nodes.AESNode.CryptMode.ENCRYPT;

Expand All @@ -41,6 +42,8 @@
import java.lang.reflect.Type;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.EnumMap;
import java.util.Map;
import java.util.Objects;
import java.util.function.BiFunction;

Expand Down Expand Up @@ -1310,17 +1313,44 @@ public static class BoxPlugin extends InvocationPlugin {
this.kind = kind;
}

static final Map<JavaKind, Class<?>> boxClassToCacheClass = new EnumMap<>(Map.of(
JavaKind.Boolean, Boolean.class,
JavaKind.Char, getCacheClass(JavaKind.Char),
JavaKind.Byte, getCacheClass(JavaKind.Byte),
JavaKind.Short, getCacheClass(JavaKind.Short),
JavaKind.Int, getCacheClass(JavaKind.Int),
JavaKind.Long, getCacheClass(JavaKind.Long)));

private boolean isCacheTypeInitialized(MetaAccessProvider metaAccess) {
Class<?> cacheClass = boxClassToCacheClass.get(kind);
if (cacheClass != null) {
ResolvedJavaType cacheType = metaAccess.lookupJavaType(cacheClass);
if (!cacheType.isInitialized()) {
return false;
}
}
return true;
}

@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) {
MetaAccessProvider metaAccess = b.getMetaAccess();
if (b.parsingIntrinsic()) {
ResolvedJavaMethod rootMethod = b.getGraph().method();
if (b.getMetaAccess().lookupJavaType(BoxingSnippets.class).isAssignableFrom(rootMethod.getDeclaringClass())) {
if (metaAccess.lookupJavaType(BoxingSnippets.class).isAssignableFrom(rootMethod.getDeclaringClass())) {
// Disable invocation plugins for boxing snippets so that the
// original JDK methods are inlined
return false;
}
}
ResolvedJavaType resultType = b.getMetaAccess().lookupJavaType(kind.toBoxedJavaClass());
ResolvedJavaType resultType = metaAccess.lookupJavaType(kind.toBoxedJavaClass());

// Cannot perform boxing if the box type or its cache (if any) is not initialized
// or failed during initialization (e.g. StackOverflowError in LongCache.<clinit>).
if (!resultType.isInitialized() || !isCacheTypeInitialized(metaAccess)) {
return false;
}

b.addPush(JavaKind.Object, BoxNode.create(value, resultType, kind));
return true;
}
Expand Down

0 comments on commit 5923501

Please sign in to comment.