Skip to content

Commit 5a4d449

Browse files
committed
Use strict constant analysis for automatic serialization registrations.
1 parent 2218c53 commit 5a4d449

File tree

1 file changed

+62
-17
lines changed

1 file changed

+62
-17
lines changed

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/snippets/SubstrateGraphBuilderPlugins.java

Lines changed: 62 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,13 @@
3636
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
3737
import java.util.concurrent.atomic.AtomicLongFieldUpdater;
3838
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
39+
import java.util.function.BooleanSupplier;
40+
import java.util.function.Predicate;
3941
import java.util.stream.Stream;
4042

43+
import com.oracle.svm.hosted.strictconstantanalysis.ConstantExpressionRegistry;
44+
import com.oracle.svm.hosted.strictconstantanalysis.InferredDynamicAccessLoggingFeature;
45+
import com.oracle.svm.hosted.strictconstantanalysis.StrictConstantAnalysisFeature;
4146
import org.graalvm.nativeimage.AnnotationAccess;
4247
import org.graalvm.nativeimage.ImageInfo;
4348
import org.graalvm.nativeimage.ImageSingletons;
@@ -248,12 +253,25 @@ public boolean isDecorator() {
248253

249254
@Override
250255
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode patternNode) {
251-
String pattern = asConstantObject(b, String.class, patternNode);
252-
if (pattern != null) {
256+
Predicate<ConstantExpressionRegistry> strictModeRoutine = (registry) -> {
257+
String pattern = registry.getArgument(b.getMethod(), b.bci(), targetMethod, 0, String.class);
258+
if (pattern == null) {
259+
return false;
260+
}
253261
b.add(ReachabilityRegistrationNode.create(() -> parsePatternAndRegister(loader, pattern), reason));
262+
InferredDynamicAccessLoggingFeature.logRegistration(b, reason, targetMethod, null, new Object[]{pattern});
254263
return true;
255-
}
256-
return false;
264+
};
265+
BooleanSupplier graphModeRoutine = () -> {
266+
String pattern = asConstantObject(b, String.class, patternNode);
267+
if (pattern == null) {
268+
return false;
269+
}
270+
b.add(ReachabilityRegistrationNode.create(() -> parsePatternAndRegister(loader, pattern), reason));
271+
InferredDynamicAccessLoggingFeature.logRegistration(b, reason, targetMethod, null, new Object[]{pattern});
272+
return true;
273+
};
274+
return StrictConstantAnalysisFeature.tryToInfer(strictModeRoutine, graphModeRoutine);
257275
}
258276
});
259277

@@ -267,12 +285,15 @@ public boolean isDecorator() {
267285

268286
@Override
269287
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode clazzNode) {
270-
Class<?> clazz = asConstantObject(b, Class.class, clazzNode);
271-
if (clazz != null) {
272-
b.add(ReachabilityRegistrationNode.create(() -> RuntimeSerialization.register(clazz), reason));
273-
return true;
274-
}
275-
return false;
288+
Predicate<ConstantExpressionRegistry> strictModeRoutine = (registry) -> {
289+
Class<?> clazz = registry.getArgument(b.getMethod(), b.bci(), targetMethod, 0, Class.class);
290+
return tryToRegisterForSerialization(b, reason, targetMethod, clazz);
291+
};
292+
BooleanSupplier graphModeRoutine = () -> {
293+
Class<?> clazz = asConstantObject(b, Class.class, clazzNode);
294+
return tryToRegisterForSerialization(b, reason, targetMethod, clazz);
295+
};
296+
return StrictConstantAnalysisFeature.tryToInfer(strictModeRoutine, graphModeRoutine);
276297
}
277298
});
278299

@@ -284,19 +305,41 @@ public boolean isDecorator() {
284305

285306
@Override
286307
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode clazzNode, ValueNode constructorNode) {
287-
var clazz = asConstantObject(b, Class.class, clazzNode);
288-
var constructor = asConstantObject(b, Constructor.class, constructorNode);
289-
if (clazz != null && constructor != null) {
290-
b.add(ReachabilityRegistrationNode.create(() -> RuntimeSerialization.register(clazz), reason));
291-
return true;
292-
}
293-
return false;
308+
Predicate<ConstantExpressionRegistry> strictModeRoutine = (registry) -> {
309+
Class<?> clazz = registry.getArgument(b.getMethod(), b.bci(), targetMethod, 0, Class.class);
310+
Constructor<?> constructor = registry.getArgument(b.getMethod(), b.bci(), targetMethod, 1, Constructor.class);
311+
return tryToRegisterForSerialization(b, reason, targetMethod, clazz, constructor);
312+
};
313+
BooleanSupplier graphModeRoutine = () -> {
314+
Class<?> clazz = asConstantObject(b, Class.class, clazzNode);
315+
Constructor<?> constructor = asConstantObject(b, Constructor.class, constructorNode);
316+
return tryToRegisterForSerialization(b, reason, targetMethod, clazz, constructor);
317+
};
318+
return StrictConstantAnalysisFeature.tryToInfer(strictModeRoutine, graphModeRoutine);
294319
}
295320
});
296321
}
297322
}
298323
}
299324

325+
private static boolean tryToRegisterForSerialization(GraphBuilderContext b, ParsingReason reason, ResolvedJavaMethod targetMethod, Class<?> clazz) {
326+
if (clazz == null) {
327+
return false;
328+
}
329+
b.add(ReachabilityRegistrationNode.create(() -> RuntimeSerialization.register(clazz), reason));
330+
InferredDynamicAccessLoggingFeature.logRegistration(b, reason, targetMethod, InferredDynamicAccessLoggingFeature.ignoredArgument(), new Object[]{clazz});
331+
return true;
332+
}
333+
334+
private static boolean tryToRegisterForSerialization(GraphBuilderContext b, ParsingReason reason, ResolvedJavaMethod targetMethod, Class<?> clazz, Constructor<?> constructor) {
335+
if (clazz == null || constructor == null) {
336+
return false;
337+
}
338+
b.add(ReachabilityRegistrationNode.create(() -> RuntimeSerialization.register(clazz), reason));
339+
InferredDynamicAccessLoggingFeature.logRegistration(b, reason, targetMethod, InferredDynamicAccessLoggingFeature.ignoredArgument(), new Object[]{clazz, constructor});
340+
return true;
341+
}
342+
300343
public static <T> T asConstantObject(GraphBuilderContext b, Class<T> type, ValueNode node) {
301344
return StandardGraphBuilderPlugins.asConstantObject(b, type, node);
302345
}
@@ -686,6 +729,8 @@ private static FixedNode unwrapNode(FixedNode node) {
686729
} else if (successor instanceof AbstractBeginNode) {
687730
/* Useless block begins can occur during parsing or graph decoding. */
688731
successor = ((AbstractBeginNode) successor).next();
732+
} else if (successor instanceof ReachabilityRegistrationNode) {
733+
successor = ((ReachabilityRegistrationNode) successor).next();
689734
} else {
690735
return successor;
691736
}

0 commit comments

Comments
 (0)