Skip to content

Commit 04b8225

Browse files
committed
Make sure the simulation of class initializer has finished before trying to fold a load field in inlining before analysis
1 parent a180d4f commit 04b8225

File tree

1 file changed

+30
-18
lines changed

1 file changed

+30
-18
lines changed

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/phases/InlineBeforeAnalysisGraphDecoderImpl.java

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2023, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -71,31 +71,43 @@ protected Node doCanonicalizeFixedNode(InlineBeforeAnalysisMethodScope methodSco
7171
private Node handleEnsureClassInitializedNode(EnsureClassInitializedNode node) {
7272
AnalysisType type = (AnalysisType) node.constantTypeOrNull(bb.getConstantReflectionProvider());
7373
if (type != null) {
74-
if (type.isReachable()) {
75-
/*
76-
* The class initializer is always analyzed for reachable types so that the
77-
* DynamicHub can be properly initialized. Avoid starting a second concurrent
78-
* analysis.
79-
*/
80-
type.getInitializeMetaDataTask().ensureDone();
81-
} else {
82-
/*
83-
* Even for types that are not yet reachable, we can analyze the class initializer.
84-
* If the type gets reachable later, the analysis results are re-used. Or the type
85-
* can remain unreachable throughout the whole analysis, because the Graal IR we are
86-
* decoding here could actually be dead code that is removed before building the
87-
* type flow graph.
88-
*/
89-
simulateClassInitializerSupport.trySimulateClassInitializer(bb, type);
90-
}
74+
processClassInitializer(type);
9175
if (simulateClassInitializerSupport.isClassInitializerSimulated(type) && !ClassInitializationSupport.singleton().requiresInitializationNodeForTypeReached(type)) {
9276
return null;
9377
}
9478
}
9579
return node;
9680
}
9781

82+
private void processClassInitializer(AnalysisType type) {
83+
if (type.isReachable()) {
84+
/*
85+
* The class initializer is always analyzed for reachable types so that the DynamicHub
86+
* can be properly initialized. Since, the simulation might already be in the progress
87+
* on another thread, we use ensureDone to avoid starting a second concurrent analysis.
88+
*/
89+
type.getInitializeMetaDataTask().ensureDone();
90+
} else {
91+
/*
92+
* Even for types that are not yet reachable, we can analyze the class initializer. If
93+
* the type gets reachable later, the analysis results are re-used. Or the type can
94+
* remain unreachable throughout the whole analysis, because the Graal IR we are
95+
* decoding here could actually be dead code that is removed before building the type
96+
* flow graph.
97+
*/
98+
simulateClassInitializerSupport.trySimulateClassInitializer(bb, type);
99+
}
100+
}
101+
98102
private Node handleLoadFieldNode(LoadFieldNode node) {
103+
var field = (AnalysisField) node.field();
104+
if (field.isStatic()) {
105+
/*
106+
* First, make sure the results of the simulation of the given class initializer are
107+
* available, compute them if necessary.
108+
*/
109+
processClassInitializer(field.getDeclaringClass());
110+
}
99111
ConstantNode canonicalized = simulateClassInitializerSupport.tryCanonicalize(bb, node);
100112
if (canonicalized != null) {
101113
return canonicalized;

0 commit comments

Comments
 (0)