Skip to content

Commit ca8570b

Browse files
committed
Move SubstitutionInvocationPlugins to its own file.
1 parent 570067e commit ca8570b

File tree

2 files changed

+127
-88
lines changed

2 files changed

+127
-88
lines changed

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageGenerator.java

Lines changed: 1 addition & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -32,18 +32,15 @@
3232

3333
import java.io.IOException;
3434
import java.lang.annotation.Annotation;
35-
import java.lang.reflect.Executable;
3635
import java.lang.reflect.Method;
3736
import java.lang.reflect.Modifier;
38-
import java.lang.reflect.Type;
3937
import java.nio.file.FileSystems;
4038
import java.nio.file.Files;
4139
import java.nio.file.Path;
4240
import java.util.ArrayList;
4341
import java.util.Arrays;
4442
import java.util.Collection;
4543
import java.util.Collections;
46-
import java.util.Comparator;
4744
import java.util.EnumSet;
4845
import java.util.List;
4946
import java.util.ListIterator;
@@ -55,11 +52,8 @@
5552
import java.util.function.BooleanSupplier;
5653
import java.util.function.Function;
5754

58-
import org.graalvm.collections.EconomicMap;
5955
import org.graalvm.collections.EconomicSet;
60-
import org.graalvm.collections.MapCursor;
6156
import org.graalvm.collections.Pair;
62-
import org.graalvm.nativeimage.AnnotationAccess;
6357
import org.graalvm.nativeimage.ImageInfo;
6458
import org.graalvm.nativeimage.ImageSingletons;
6559
import org.graalvm.nativeimage.Platform;
@@ -258,6 +252,7 @@
258252
import com.oracle.svm.hosted.snippets.SubstrateGraphBuilderPlugins;
259253
import com.oracle.svm.hosted.substitute.AnnotationSubstitutionProcessor;
260254
import com.oracle.svm.hosted.substitute.DeletedFieldsPlugin;
255+
import com.oracle.svm.hosted.substitute.SubstitutionInvocationPlugins;
261256
import com.oracle.svm.hosted.util.CPUTypeAArch64;
262257
import com.oracle.svm.hosted.util.CPUTypeAMD64;
263258
import com.oracle.svm.hosted.util.CPUTypeRISCV64;
@@ -293,8 +288,6 @@
293288
import jdk.graal.compiler.nodes.graphbuilderconf.ClassInitializationPlugin;
294289
import jdk.graal.compiler.nodes.graphbuilderconf.GeneratedPluginFactory;
295290
import jdk.graal.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration;
296-
import jdk.graal.compiler.nodes.graphbuilderconf.InvocationPlugin;
297-
import jdk.graal.compiler.nodes.graphbuilderconf.InvocationPlugins;
298291
import jdk.graal.compiler.nodes.spi.CoreProviders;
299292
import jdk.graal.compiler.nodes.spi.LoweringProvider;
300293
import jdk.graal.compiler.nodes.spi.StampProvider;
@@ -1362,86 +1355,6 @@ protected boolean isStubBasedPluginsSupported() {
13621355
return !SubstrateOptions.useLLVMBackend();
13631356
}
13641357

1365-
@Platforms(Platform.HOSTED_ONLY.class)
1366-
static class SubstitutionInvocationPlugins extends InvocationPlugins {
1367-
1368-
private final AnnotationSubstitutionProcessor annotationSubstitutionProcessor;
1369-
private EconomicMap<String, Integer> missingIntrinsicMetrics;
1370-
1371-
SubstitutionInvocationPlugins(AnnotationSubstitutionProcessor annotationSubstitutionProcessor) {
1372-
this.annotationSubstitutionProcessor = annotationSubstitutionProcessor;
1373-
this.missingIntrinsicMetrics = null;
1374-
}
1375-
1376-
@Override
1377-
protected void register(Type declaringClass, InvocationPlugin plugin, boolean allowOverwrite) {
1378-
Type targetClass;
1379-
if (declaringClass instanceof Class<?> annotatedClass) {
1380-
targetClass = annotationSubstitutionProcessor.getTargetClass(annotatedClass);
1381-
if (targetClass != declaringClass) {
1382-
/* Found a target class. Check if it is included. */
1383-
Executable annotatedMethod = plugin.name.equals("<init>") ? resolveConstructor(annotatedClass, plugin) : resolveMethod(annotatedClass, plugin);
1384-
String originalName = annotationSubstitutionProcessor.findOriginalElementName(annotatedMethod, (Class<?>) targetClass);
1385-
if (originalName == null) {
1386-
/*
1387-
* If the name is null, the element should not be substituted. Thus, we
1388-
* should also not register the invocation plugin.
1389-
*/
1390-
return;
1391-
}
1392-
if (!originalName.equals(plugin.name)) {
1393-
throw VMError.unimplemented(String.format("""
1394-
InvocationPlugins cannot yet deal with substitution methods that set the target name via the @TargetElement(name = ...) property.
1395-
Annotated method "%s" vs target method "%s".""", plugin.name, originalName));
1396-
}
1397-
}
1398-
} else {
1399-
targetClass = declaringClass;
1400-
}
1401-
super.register(targetClass, plugin, allowOverwrite);
1402-
}
1403-
1404-
@Override
1405-
public void notifyNoPlugin(ResolvedJavaMethod targetMethod, OptionValues options) {
1406-
if (Options.WarnMissingIntrinsic.getValue(options)) {
1407-
for (Class<?> annotationType : AnnotationAccess.getAnnotationTypes(targetMethod)) {
1408-
if (ClassUtil.getUnqualifiedName(annotationType).contains("IntrinsicCandidate")) {
1409-
String method = String.format("%s.%s%s", targetMethod.getDeclaringClass().toJavaName().replace('.', '/'), targetMethod.getName(),
1410-
targetMethod.getSignature().toMethodDescriptor());
1411-
synchronized (this) {
1412-
if (missingIntrinsicMetrics == null) {
1413-
missingIntrinsicMetrics = EconomicMap.create();
1414-
try {
1415-
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
1416-
if (missingIntrinsicMetrics.size() > 0) {
1417-
System.out.format("[Warning] Missing intrinsics found: %d%n", missingIntrinsicMetrics.size());
1418-
List<Pair<String, Integer>> data = new ArrayList<>();
1419-
final MapCursor<String, Integer> cursor = missingIntrinsicMetrics.getEntries();
1420-
while (cursor.advance()) {
1421-
data.add(Pair.create(cursor.getKey(), cursor.getValue()));
1422-
}
1423-
data.stream().sorted(Comparator.comparing(Pair::getRight, Comparator.reverseOrder())).forEach(
1424-
pair -> System.out.format(" - %d occurrences during parsing: %s%n", pair.getRight(), pair.getLeft()));
1425-
}
1426-
}));
1427-
} catch (IllegalStateException e) {
1428-
// shutdown in progress, no need to register the hook
1429-
}
1430-
}
1431-
if (missingIntrinsicMetrics.containsKey(method)) {
1432-
missingIntrinsicMetrics.put(method, missingIntrinsicMetrics.get(method) + 1);
1433-
} else {
1434-
System.out.format("[Warning] Missing intrinsic %s found during parsing.%n", method);
1435-
missingIntrinsicMetrics.put(method, 1);
1436-
}
1437-
}
1438-
break;
1439-
}
1440-
}
1441-
}
1442-
}
1443-
}
1444-
14451358
public static void registerGraphBuilderPlugins(FeatureHandler featureHandler, RuntimeConfiguration runtimeConfig, HostedProviders providers, AnalysisMetaAccess aMetaAccess,
14461359
AnalysisUniverse aUniverse, NativeLibraries nativeLibs, ImageClassLoader loader, ParsingReason reason,
14471360
AnnotationSubstitutionProcessor annotationSubstitutionProcessor, ClassInitializationPlugin classInitializationPlugin,
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
/*
2+
* Copyright (c) 2024, 2024, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
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. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
package com.oracle.svm.hosted.substitute;
26+
27+
import java.lang.reflect.Executable;
28+
import java.lang.reflect.Type;
29+
import java.util.ArrayList;
30+
import java.util.Comparator;
31+
import java.util.List;
32+
33+
import org.graalvm.collections.EconomicMap;
34+
import org.graalvm.collections.MapCursor;
35+
import org.graalvm.collections.Pair;
36+
import org.graalvm.nativeimage.AnnotationAccess;
37+
import org.graalvm.nativeimage.Platform;
38+
import org.graalvm.nativeimage.Platforms;
39+
40+
import com.oracle.svm.core.util.VMError;
41+
import com.oracle.svm.util.ClassUtil;
42+
43+
import jdk.graal.compiler.nodes.graphbuilderconf.InvocationPlugin;
44+
import jdk.graal.compiler.nodes.graphbuilderconf.InvocationPlugins;
45+
import jdk.graal.compiler.options.OptionValues;
46+
import jdk.vm.ci.meta.ResolvedJavaMethod;
47+
48+
@Platforms(Platform.HOSTED_ONLY.class)
49+
public class SubstitutionInvocationPlugins extends InvocationPlugins {
50+
51+
private final AnnotationSubstitutionProcessor annotationSubstitutionProcessor;
52+
private EconomicMap<String, Integer> missingIntrinsicMetrics;
53+
54+
public SubstitutionInvocationPlugins(AnnotationSubstitutionProcessor annotationSubstitutionProcessor) {
55+
this.annotationSubstitutionProcessor = annotationSubstitutionProcessor;
56+
this.missingIntrinsicMetrics = null;
57+
}
58+
59+
@Override
60+
protected void register(Type declaringClass, InvocationPlugin plugin, boolean allowOverwrite) {
61+
Type targetClass;
62+
if (declaringClass instanceof Class<?> annotatedClass) {
63+
targetClass = annotationSubstitutionProcessor.getTargetClass(annotatedClass);
64+
if (targetClass != declaringClass) {
65+
/* Found a target class. Check if it is included. */
66+
Executable annotatedMethod = plugin.name.equals("<init>") ? resolveConstructor(annotatedClass, plugin) : resolveMethod(annotatedClass, plugin);
67+
String originalName = annotationSubstitutionProcessor.findOriginalElementName(annotatedMethod, (Class<?>) targetClass);
68+
if (originalName == null) {
69+
/*
70+
* If the name is null, the element should not be substituted. Thus, we should
71+
* also not register the invocation plugin.
72+
*/
73+
return;
74+
}
75+
if (!originalName.equals(plugin.name)) {
76+
throw VMError.unimplemented(String.format("""
77+
InvocationPlugins cannot yet deal with substitution methods that set the target name via the @TargetElement(name = ...) property.
78+
Annotated method "%s" vs target method "%s".""", plugin.name, originalName));
79+
}
80+
}
81+
} else {
82+
targetClass = declaringClass;
83+
}
84+
super.register(targetClass, plugin, allowOverwrite);
85+
}
86+
87+
@Override
88+
public void notifyNoPlugin(ResolvedJavaMethod targetMethod, OptionValues options) {
89+
if (Options.WarnMissingIntrinsic.getValue(options)) {
90+
for (Class<?> annotationType : AnnotationAccess.getAnnotationTypes(targetMethod)) {
91+
if (ClassUtil.getUnqualifiedName(annotationType).contains("IntrinsicCandidate")) {
92+
String method = String.format("%s.%s%s", targetMethod.getDeclaringClass().toJavaName().replace('.', '/'), targetMethod.getName(),
93+
targetMethod.getSignature().toMethodDescriptor());
94+
synchronized (this) {
95+
if (missingIntrinsicMetrics == null) {
96+
missingIntrinsicMetrics = EconomicMap.create();
97+
try {
98+
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
99+
if (missingIntrinsicMetrics.size() > 0) {
100+
System.out.format("[Warning] Missing intrinsics found: %d%n", missingIntrinsicMetrics.size());
101+
List<Pair<String, Integer>> data = new ArrayList<>();
102+
final MapCursor<String, Integer> cursor = missingIntrinsicMetrics.getEntries();
103+
while (cursor.advance()) {
104+
data.add(Pair.create(cursor.getKey(), cursor.getValue()));
105+
}
106+
data.stream().sorted(Comparator.comparing(Pair::getRight, Comparator.reverseOrder())).forEach(
107+
pair -> System.out.format(" - %d occurrences during parsing: %s%n", pair.getRight(), pair.getLeft()));
108+
}
109+
}));
110+
} catch (IllegalStateException e) {
111+
// shutdown in progress, no need to register the hook
112+
}
113+
}
114+
if (missingIntrinsicMetrics.containsKey(method)) {
115+
missingIntrinsicMetrics.put(method, missingIntrinsicMetrics.get(method) + 1);
116+
} else {
117+
System.out.format("[Warning] Missing intrinsic %s found during parsing.%n", method);
118+
missingIntrinsicMetrics.put(method, 1);
119+
}
120+
}
121+
break;
122+
}
123+
}
124+
}
125+
}
126+
}

0 commit comments

Comments
 (0)