|
40 | 40 | import org.graalvm.nativeimage.ImageSingletons; |
41 | 41 |
|
42 | 42 | import com.oracle.graal.pointsto.meta.AnalysisType; |
| 43 | +import com.oracle.svm.core.CGlobalDataPointerSingleton; |
43 | 44 | import com.oracle.svm.core.ParsingReason; |
44 | 45 | import com.oracle.svm.core.c.BoxedRelocatedPointer; |
45 | 46 | import com.oracle.svm.core.c.CGlobalData; |
|
50 | 51 | import com.oracle.svm.core.feature.InternalFeature; |
51 | 52 | import com.oracle.svm.core.graal.code.CGlobalDataInfo; |
52 | 53 | import com.oracle.svm.core.graal.nodes.CGlobalDataLoadAddressNode; |
| 54 | +import com.oracle.svm.core.imagelayer.DynamicImageLayerInfo; |
53 | 55 | import com.oracle.svm.core.imagelayer.ImageLayerBuildingSupport; |
54 | 56 | import com.oracle.svm.core.traits.BuiltinTraits.BuildtimeAccessOnly; |
55 | 57 | import com.oracle.svm.core.traits.BuiltinTraits.NoLayeredCallbacks; |
56 | 58 | import com.oracle.svm.core.traits.SingletonLayeredInstallationKind.Independent; |
57 | 59 | import com.oracle.svm.core.traits.SingletonTraits; |
58 | 60 | import com.oracle.svm.core.util.VMError; |
| 61 | +import com.oracle.svm.hosted.FeatureImpl; |
59 | 62 | import com.oracle.svm.hosted.image.RelocatableBuffer; |
60 | 63 | import com.oracle.svm.hosted.imagelayer.CodeLocation; |
| 64 | +import com.oracle.svm.hosted.imagelayer.LoadImageSingletonFeature; |
61 | 65 | import com.oracle.svm.hosted.meta.HostedSnippetReflectionProvider; |
62 | 66 | import com.oracle.svm.util.ReflectionUtil; |
63 | 67 |
|
|
90 | 94 | import jdk.graal.compiler.nodes.graphbuilderconf.InvocationPlugin.RequiredInvocationPlugin; |
91 | 95 | import jdk.graal.compiler.nodes.graphbuilderconf.InvocationPlugins.Registration; |
92 | 96 | import jdk.graal.compiler.nodes.java.LoadFieldNode; |
| 97 | +import jdk.graal.compiler.nodes.java.LoadIndexedNode; |
93 | 98 | import jdk.graal.compiler.nodes.memory.ReadNode; |
94 | 99 | import jdk.graal.compiler.nodes.memory.address.OffsetAddressNode; |
95 | 100 | import jdk.graal.compiler.phases.util.Providers; |
96 | 101 | import jdk.vm.ci.meta.JavaConstant; |
| 102 | +import jdk.vm.ci.meta.JavaKind; |
97 | 103 | import jdk.vm.ci.meta.ResolvedJavaField; |
98 | 104 | import jdk.vm.ci.meta.ResolvedJavaMethod; |
99 | 105 | import jdk.vm.ci.meta.ResolvedJavaType; |
|
103 | 109 | public class CGlobalDataFeature implements InternalFeature { |
104 | 110 |
|
105 | 111 | private final Method getCGlobalDataInfoMethod = ReflectionUtil.lookupMethod(CGlobalDataNonConstantRegistry.class, "getCGlobalDataInfo", CGlobalDataImpl.class); |
| 112 | + private final Field layerNumField = ReflectionUtil.lookupField(CGlobalDataInfo.class, "layerNum"); |
| 113 | + private final Field cGlobalDataRuntimeBaseAddressField = ReflectionUtil.lookupField(CGlobalDataPointerSingleton.class, "cGlobalDataRuntimeBaseAddress"); |
106 | 114 | private final Field offsetField = ReflectionUtil.lookupField(CGlobalDataInfo.class, "offset"); |
107 | 115 | private final Field isSymbolReferenceField = ReflectionUtil.lookupField(CGlobalDataInfo.class, "isSymbolReference"); |
108 | 116 | private final Field baseHolderPointerField = ReflectionUtil.lookupField(BoxedRelocatedPointer.class, "pointer"); |
@@ -132,6 +140,17 @@ public void duringSetup(DuringSetupAccess a) { |
132 | 140 | a.registerObjectReplacer(this::replaceObject); |
133 | 141 | } |
134 | 142 |
|
| 143 | + @Override |
| 144 | + public void beforeAnalysis(BeforeAnalysisAccess access) { |
| 145 | + if (ImageLayerBuildingSupport.buildingImageLayer()) { |
| 146 | + /* |
| 147 | + * The non-constant registry needs to be rescanned in layered images to make sure it is |
| 148 | + * always reachable in every layer and that all the data is properly tracked. |
| 149 | + */ |
| 150 | + ((FeatureImpl.BeforeAnalysisAccessImpl) access).rescanObject(nonConstantRegistry); |
| 151 | + } |
| 152 | + } |
| 153 | + |
135 | 154 | @Override |
136 | 155 | public void afterHeapLayout(AfterHeapLayoutAccess access) { |
137 | 156 | layout(); |
@@ -180,8 +199,39 @@ public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Rec |
180 | 199 | } |
181 | 200 | } |
182 | 201 |
|
183 | | - JavaConstant baseHolderConstant = providers.getSnippetReflection().forObject(CGlobalDataInfo.CGLOBALDATA_RUNTIME_BASE_ADDRESS); |
184 | | - ConstantNode baseHolder = ConstantNode.forConstant(baseHolderConstant, b.getMetaAccess(), b.getGraph()); |
| 202 | + ValueNode baseHolder; |
| 203 | + if (ImageLayerBuildingSupport.buildingImageLayer()) { |
| 204 | + /* |
| 205 | + * When building layered images, each layer has its own CGlobalData base |
| 206 | + * pointer, meaning the one associated with this specific CGlobalDataInfo |
| 207 | + * needs to be used. |
| 208 | + */ |
| 209 | + JavaConstant cGlobalDataPointerSingletonClass = providers.getSnippetReflection().forObject(CGlobalDataPointerSingleton.class); |
| 210 | + ConstantNode classConstant = ConstantNode.forConstant(cGlobalDataPointerSingletonClass, b.getMetaAccess(), b.getGraph()); |
| 211 | + |
| 212 | + /* Load the array containing all the singletons. */ |
| 213 | + ValueNode layers = b.add(ImageSingletons.lookup(LoadImageSingletonFeature.class).loadMultiLayeredImageSingleton(b, classConstant)); |
| 214 | + |
| 215 | + /* |
| 216 | + * Get the layer number of the CGlobalDataInfo to get the index to use in |
| 217 | + * the singleton array. |
| 218 | + */ |
| 219 | + ValueNode layerNum = b.add(LoadFieldNode.create(b.getAssumptions(), info, b.getMetaAccess().lookupJavaField(layerNumField))); |
| 220 | + |
| 221 | + /* Use the layer number to get the corresponding singleton. */ |
| 222 | + ValueNode singleton = b.add(LoadIndexedNode.create(b.getAssumptions(), layers, layerNum, null, JavaKind.Object, b.getMetaAccess(), b.getConstantReflection())); |
| 223 | + |
| 224 | + /* Get the CGlobalData base pointer from the singleton. */ |
| 225 | + baseHolder = b.add(LoadFieldNode.create(b.getAssumptions(), singleton, b.getMetaAccess().lookupJavaField(cGlobalDataRuntimeBaseAddressField))); |
| 226 | + } else { |
| 227 | + /* |
| 228 | + * In standalone image, there is only one CGlobalData base pointer, so there |
| 229 | + * is no need to have a custom access. |
| 230 | + */ |
| 231 | + JavaConstant baseHolderConstant = providers.getSnippetReflection().forObject(CGlobalDataPointerSingleton.currentLayer().getRuntimeBaseAddress()); |
| 232 | + baseHolder = ConstantNode.forConstant(baseHolderConstant, b.getMetaAccess(), b.getGraph()); |
| 233 | + } |
| 234 | + |
185 | 235 | ResolvedJavaField holderPointerField = providers.getMetaAccess().lookupJavaField(baseHolderPointerField); |
186 | 236 | StampPair pointerStamp = StampPair.createSingle(providers.getWordTypes().getWordStamp((ResolvedJavaType) holderPointerField.getType())); |
187 | 237 | LoadFieldNode baseAddress = b.add(LoadFieldNode.createOverrideStamp(pointerStamp, baseHolder, holderPointerField)); |
@@ -270,7 +320,7 @@ CGlobalDataInfo createCGlobalDataInfo(CGlobalDataImpl<?> data, boolean definedAs |
270 | 320 | "We currently do not allow CGlobalData code locations to be in a hidden class. Please adapt the code accordingly. Location: %s", |
271 | 321 | data.codeLocation); |
272 | 322 | } |
273 | | - CGlobalDataInfo cGlobalDataInfo = new CGlobalDataInfo(data, definedAsGlobalInPriorLayer); |
| 323 | + CGlobalDataInfo cGlobalDataInfo = new CGlobalDataInfo(data, definedAsGlobalInPriorLayer, DynamicImageLayerInfo.getCurrentLayerNumber()); |
274 | 324 | if (data.nonConstant) { |
275 | 325 | nonConstantRegistry.registerNonConstantSymbol(cGlobalDataInfo); |
276 | 326 | } |
|
0 commit comments