|
1 | 1 | /* |
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. |
3 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 | 4 | * |
5 | 5 | * This code is free software; you can redistribute it and/or modify it |
@@ -71,31 +71,43 @@ protected Node doCanonicalizeFixedNode(InlineBeforeAnalysisMethodScope methodSco |
71 | 71 | private Node handleEnsureClassInitializedNode(EnsureClassInitializedNode node) { |
72 | 72 | AnalysisType type = (AnalysisType) node.constantTypeOrNull(bb.getConstantReflectionProvider()); |
73 | 73 | 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); |
91 | 75 | if (simulateClassInitializerSupport.isClassInitializerSimulated(type) && !ClassInitializationSupport.singleton().requiresInitializationNodeForTypeReached(type)) { |
92 | 76 | return null; |
93 | 77 | } |
94 | 78 | } |
95 | 79 | return node; |
96 | 80 | } |
97 | 81 |
|
| 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 | + |
98 | 102 | 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 | + } |
99 | 111 | ConstantNode canonicalized = simulateClassInitializerSupport.tryCanonicalize(bb, node); |
100 | 112 | if (canonicalized != null) { |
101 | 113 | return canonicalized; |
|
0 commit comments