|
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