|
33 | 33 | import static org.graalvm.compiler.core.common.memory.MemoryOrderMode.RELEASE; |
34 | 34 | import static org.graalvm.compiler.core.common.memory.MemoryOrderMode.VOLATILE; |
35 | 35 | import static org.graalvm.compiler.nodes.NamedLocationIdentity.OFF_HEAP_LOCATION; |
| 36 | +import static org.graalvm.compiler.replacements.BoxingSnippets.Templates.getCacheClass; |
36 | 37 | import static org.graalvm.compiler.replacements.nodes.AESNode.CryptMode.DECRYPT; |
37 | 38 | import static org.graalvm.compiler.replacements.nodes.AESNode.CryptMode.ENCRYPT; |
38 | 39 |
|
|
41 | 42 | import java.lang.reflect.Type; |
42 | 43 | import java.math.BigInteger; |
43 | 44 | import java.util.Arrays; |
| 45 | +import java.util.EnumMap; |
| 46 | +import java.util.Map; |
44 | 47 | import java.util.Objects; |
45 | 48 | import java.util.function.BiFunction; |
46 | 49 |
|
@@ -1310,17 +1313,44 @@ public static class BoxPlugin extends InvocationPlugin { |
1310 | 1313 | this.kind = kind; |
1311 | 1314 | } |
1312 | 1315 |
|
| 1316 | + static final Map<JavaKind, Class<?>> boxClassToCacheClass = new EnumMap<>(Map.of( |
| 1317 | + JavaKind.Boolean, Boolean.class, |
| 1318 | + JavaKind.Char, getCacheClass(JavaKind.Char), |
| 1319 | + JavaKind.Byte, getCacheClass(JavaKind.Byte), |
| 1320 | + JavaKind.Short, getCacheClass(JavaKind.Short), |
| 1321 | + JavaKind.Int, getCacheClass(JavaKind.Int), |
| 1322 | + JavaKind.Long, getCacheClass(JavaKind.Long))); |
| 1323 | + |
| 1324 | + private boolean isCacheTypeInitialized(MetaAccessProvider metaAccess) { |
| 1325 | + Class<?> cacheClass = boxClassToCacheClass.get(kind); |
| 1326 | + if (cacheClass != null) { |
| 1327 | + ResolvedJavaType cacheType = metaAccess.lookupJavaType(cacheClass); |
| 1328 | + if (!cacheType.isInitialized()) { |
| 1329 | + return false; |
| 1330 | + } |
| 1331 | + } |
| 1332 | + return true; |
| 1333 | + } |
| 1334 | + |
1313 | 1335 | @Override |
1314 | 1336 | public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) { |
| 1337 | + MetaAccessProvider metaAccess = b.getMetaAccess(); |
1315 | 1338 | if (b.parsingIntrinsic()) { |
1316 | 1339 | ResolvedJavaMethod rootMethod = b.getGraph().method(); |
1317 | | - if (b.getMetaAccess().lookupJavaType(BoxingSnippets.class).isAssignableFrom(rootMethod.getDeclaringClass())) { |
| 1340 | + if (metaAccess.lookupJavaType(BoxingSnippets.class).isAssignableFrom(rootMethod.getDeclaringClass())) { |
1318 | 1341 | // Disable invocation plugins for boxing snippets so that the |
1319 | 1342 | // original JDK methods are inlined |
1320 | 1343 | return false; |
1321 | 1344 | } |
1322 | 1345 | } |
1323 | | - ResolvedJavaType resultType = b.getMetaAccess().lookupJavaType(kind.toBoxedJavaClass()); |
| 1346 | + ResolvedJavaType resultType = metaAccess.lookupJavaType(kind.toBoxedJavaClass()); |
| 1347 | + |
| 1348 | + // Cannot perform boxing if the box type or its cache (if any) is not initialized |
| 1349 | + // or failed during initialization (e.g. StackOverflowError in LongCache.<clinit>). |
| 1350 | + if (!resultType.isInitialized() || !isCacheTypeInitialized(metaAccess)) { |
| 1351 | + return false; |
| 1352 | + } |
| 1353 | + |
1324 | 1354 | b.addPush(JavaKind.Object, BoxNode.create(value, resultType, kind)); |
1325 | 1355 | return true; |
1326 | 1356 | } |
|
0 commit comments