|
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