Skip to content

Commit 69d3c62

Browse files
committed
[GR-53508] Refactor cross layer calls and link base layer .so.
PullRequest: graal/17561
2 parents 5f68ad3 + dd58510 commit 69d3c62

File tree

16 files changed

+230
-71
lines changed

16 files changed

+230
-71
lines changed

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/heap/ImageLayerLoader.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,10 @@ public ImageLayerLoader(ImageLayerSnapshotUtil imageLayerSnapshotUtil, List<Path
261261
this.loadPaths = loadPaths;
262262
}
263263

264+
public List<Path> getLoadPaths() {
265+
return loadPaths;
266+
}
267+
264268
public void setUniverse(AnalysisUniverse newUniverse) {
265269
this.universe = newUniverse;
266270
}

substratevm/src/com.oracle.svm.core.graal.amd64/src/com/oracle/svm/core/graal/amd64/SubstrateAMD64Backend.java

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
import java.util.EnumSet;
4444
import java.util.function.BiConsumer;
4545

46+
import com.oracle.svm.core.graal.code.CGlobalDataInfo;
4647
import org.graalvm.collections.EconomicMap;
4748
import org.graalvm.nativeimage.ImageSingletons;
4849

@@ -53,6 +54,7 @@
5354
import com.oracle.svm.core.SubstrateOptions;
5455
import com.oracle.svm.core.SubstrateUtil;
5556
import com.oracle.svm.core.amd64.AMD64CPUFeatureAccess;
57+
import com.oracle.svm.core.code.BaseLayerMethodAccessor;
5658
import com.oracle.svm.core.config.ConfigurationValues;
5759
import com.oracle.svm.core.cpufeature.Stubs;
5860
import com.oracle.svm.core.deopt.Deoptimizer;
@@ -79,7 +81,6 @@
7981
import com.oracle.svm.core.graal.nodes.ComputedIndirectCallTargetNode.Computation;
8082
import com.oracle.svm.core.graal.nodes.ComputedIndirectCallTargetNode.FieldLoad;
8183
import com.oracle.svm.core.graal.nodes.ComputedIndirectCallTargetNode.FieldLoadIfZero;
82-
import com.oracle.svm.core.graal.snippets.NonSnippetLowerings;
8384
import com.oracle.svm.core.heap.ReferenceAccess;
8485
import com.oracle.svm.core.heap.SubstrateReferenceMapBuilder;
8586
import com.oracle.svm.core.meta.CompressedNullConstant;
@@ -200,7 +201,6 @@
200201
import jdk.vm.ci.meta.JavaConstant;
201202
import jdk.vm.ci.meta.JavaKind;
202203
import jdk.vm.ci.meta.JavaType;
203-
import jdk.vm.ci.meta.ResolvedJavaField;
204204
import jdk.vm.ci.meta.ResolvedJavaMethod;
205205
import jdk.vm.ci.meta.Value;
206206

@@ -669,16 +669,15 @@ protected Value emitIndirectForeignCallAddress(ForeignCallLinkage linkage) {
669669
SubstrateForeignCallLinkage callTarget = (SubstrateForeignCallLinkage) linkage;
670670
SharedMethod targetMethod = (SharedMethod) callTarget.getMethod();
671671
if (SubstrateUtil.HOSTED && targetMethod.forceIndirectCall()) {
672-
// Emit a load for the BoxedRelocatedPointer.pointer field holding the
673-
// MethodPointer to the target method
674-
ResolvedJavaField boxedPointerField = getMetaAccess().lookupJavaField(NonSnippetLowerings.boxedRelocatedPointerField);
675-
int displacement = boxedPointerField.getOffset();
676-
JavaConstant boxedPointerBase = targetMethod.getMethodPointer();
677-
RegisterValue heapBaseRegister = ReservedRegisters.singleton().getHeapBaseRegister().asValue();
678-
AMD64AddressValue boxedRelocatedPointerBaseAddress = new AMD64AddressValue(getLIRKindTool().getWordKind(), heapBaseRegister, Value.ILLEGAL,
679-
Stride.S1, displacement + SubstrateAMD64Backend.addressDisplacement(boxedPointerBase, getConstantReflection()),
680-
SubstrateAMD64Backend.addressDisplacementAnnotation(boxedPointerBase));
681-
return getArithmetic().emitLoad(getLIRKindTool().getWordKind(), boxedRelocatedPointerBaseAddress, null, MemoryOrderMode.PLAIN, MemoryExtendKind.DEFAULT);
672+
/*
673+
* Load the absolute address of the target method from the method entry stored in
674+
* the data section.
675+
*/
676+
CGlobalDataInfo methodDataInfo = BaseLayerMethodAccessor.singleton().getMethodData(targetMethod);
677+
AllocatableValue methodPointerAddress = newVariable(getLIRKindTool().getWordKind());
678+
append(new AMD64CGlobalDataLoadAddressOp(methodDataInfo, methodPointerAddress));
679+
AMD64AddressValue methodTableEntryAddress = new AMD64AddressValue(getLIRKindTool().getWordKind(), methodPointerAddress, Value.ILLEGAL, Stride.S1, 0);
680+
return getArithmetic().emitLoad(getLIRKindTool().getWordKind(), methodTableEntryAddress, null, MemoryOrderMode.PLAIN, MemoryExtendKind.DEFAULT);
682681
}
683682
if (!shouldEmitOnlyIndirectCalls()) {
684683
return null;

substratevm/src/com.oracle.svm.core.graal.llvm/src/com/oracle/svm/core/graal/llvm/LLVMNativeImageCodeCache.java

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import static com.oracle.svm.core.graal.llvm.LLVMToolchainUtils.llvmLink;
3030
import static com.oracle.svm.core.graal.llvm.LLVMToolchainUtils.llvmOptimize;
3131
import static com.oracle.svm.core.graal.llvm.LLVMToolchainUtils.nativeLink;
32+
import static com.oracle.svm.core.util.VMError.intentionallyUnimplemented;
3233
import static com.oracle.svm.core.util.VMError.shouldNotReachHereUnexpectedInput;
3334
import static com.oracle.svm.hosted.image.NativeImage.RWDATA_CGLOBALS_PARTITION_OFFSET;
3435

@@ -46,11 +47,6 @@
4647
import java.util.stream.IntStream;
4748

4849
import org.graalvm.collections.Pair;
49-
import jdk.graal.compiler.code.CompilationResult;
50-
import jdk.graal.compiler.core.common.NumUtil;
51-
import jdk.graal.compiler.debug.DebugContext;
52-
import jdk.graal.compiler.debug.GraalError;
53-
import jdk.graal.compiler.debug.Indent;
5450
import org.graalvm.nativeimage.Platform;
5551
import org.graalvm.nativeimage.Platforms;
5652

@@ -78,6 +74,11 @@
7874
import com.oracle.svm.hosted.image.RelocatableBuffer;
7975
import com.oracle.svm.hosted.meta.HostedMethod;
8076

77+
import jdk.graal.compiler.code.CompilationResult;
78+
import jdk.graal.compiler.core.common.NumUtil;
79+
import jdk.graal.compiler.debug.DebugContext;
80+
import jdk.graal.compiler.debug.GraalError;
81+
import jdk.graal.compiler.debug.Indent;
8182
import jdk.vm.ci.code.site.Call;
8283
import jdk.vm.ci.code.site.DataPatch;
8384
import jdk.vm.ci.code.site.DataSectionReference;
@@ -317,6 +318,11 @@ public void patchMethods(DebugContext debug, RelocatableBuffer relocs, ObjectFil
317318
@Override
318319
public NativeTextSectionImpl getTextSectionImpl(RelocatableBuffer buffer, ObjectFile objectFile, NativeImageCodeCache codeCache) {
319320
return new NativeTextSectionImpl(buffer, objectFile, codeCache) {
321+
@Override
322+
protected void defineBaseLayerMethodSymbol(String name, Element section, HostedMethod method) {
323+
throw intentionallyUnimplemented(); // ExcludeFromJacocoGeneratedReport
324+
}
325+
320326
@Override
321327
protected void defineMethodSymbol(String name, boolean global, Element section, HostedMethod method, CompilationResult result) {
322328
ObjectFile.Symbol symbol = objectFile.createUndefinedSymbol(name, 0, true);

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
*/
2525
package com.oracle.svm.core;
2626

27+
import static com.oracle.svm.core.Containers.Options.UseContainerSupport;
2728
import static com.oracle.svm.core.option.RuntimeOptionKey.RuntimeOptionKeyFlag.Immutable;
2829
import static com.oracle.svm.core.option.RuntimeOptionKey.RuntimeOptionKeyFlag.RelevantForCompilationIsolates;
2930
import static jdk.graal.compiler.core.common.SpectrePHTMitigations.None;
@@ -113,6 +114,12 @@ protected void onValueUpdate(EconomicMap<OptionKey<?>, Object> values, Boolean o
113114
PersistImageLayerSingletons.update(values, newValue);
114115
DeleteLocalSymbols.update(values, !newValue);
115116
StripDebugInfo.update(values, !newValue);
117+
InternalSymbolsAreGlobal.update(values, newValue);
118+
AOTTrivialInline.update(values, !newValue);
119+
if (imageLayerEnabledHandler != null) {
120+
imageLayerEnabledHandler.onOptionEnabled(values);
121+
}
122+
UseContainerSupport.update(values, !newValue);
116123
}
117124
};
118125

@@ -707,6 +714,10 @@ public static boolean useLIRBackend() {
707714
*/
708715
@Option(help = "Use linker option to prevent unreferenced symbols in image.")//
709716
public static final HostedOptionKey<Boolean> RemoveUnusedSymbols = new HostedOptionKey<>(OS.getCurrent() != OS.DARWIN);
717+
@Option(help = "Keep all undefined symbols.")//
718+
public static final HostedOptionKey<Boolean> PreserveUndefinedSymbols = new HostedOptionKey<>(false);
719+
@Option(help = "Ignore undefined symbols referenced from the built image.")//
720+
public static final HostedOptionKey<Boolean> IgnoreUndefinedReferences = new HostedOptionKey<>(false);
710721
@Option(help = "Use linker option to remove all local symbols from image.")//
711722
public static final HostedOptionKey<Boolean> DeleteLocalSymbols = new HostedOptionKey<>(true);
712723
@Option(help = "Compatibility option to make symbols used for the image heap global. " +
@@ -1133,6 +1144,10 @@ public static boolean closedTypeWorld() {
11331144
public void update(EconomicMap<OptionKey<?>, Object> values, Object boxedValue) {
11341145
super.update(values, boxedValue);
11351146
ClosedTypeWorld.update(values, false);
1147+
PreserveUndefinedSymbols.update(values, true);
1148+
/* Ignore any potential undefined references caused by inlining in base layer. */
1149+
IgnoreUndefinedReferences.update(values, true);
1150+
AOTTrivialInline.update(values, false);
11361151
if (imageLayerEnabledHandler != null) {
11371152
imageLayerEnabledHandler.onOptionEnabled(values);
11381153
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Copyright (c) 2024, 2024, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
package com.oracle.svm.core.code;
26+
27+
import org.graalvm.nativeimage.ImageSingletons;
28+
29+
import com.oracle.svm.core.graal.code.CGlobalDataInfo;
30+
import com.oracle.svm.core.meta.SharedMethod;
31+
32+
public interface BaseLayerMethodAccessor {
33+
CGlobalDataInfo getMethodData(SharedMethod method);
34+
35+
static BaseLayerMethodAccessor singleton() {
36+
return ImageSingletons.lookup(BaseLayerMethodAccessor.class);
37+
}
38+
}

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/graal/snippets/NonSnippetLowerings.java

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,13 @@
3939
import com.oracle.svm.core.SubstrateOptions;
4040
import com.oracle.svm.core.SubstrateUtil;
4141
import com.oracle.svm.core.c.BoxedRelocatedPointer;
42+
import com.oracle.svm.core.code.BaseLayerMethodAccessor;
4243
import com.oracle.svm.core.config.ConfigurationValues;
44+
import com.oracle.svm.core.graal.code.CGlobalDataInfo;
4345
import com.oracle.svm.core.graal.code.SubstrateBackend;
4446
import com.oracle.svm.core.graal.meta.KnownOffsets;
4547
import com.oracle.svm.core.graal.meta.RuntimeConfiguration;
48+
import com.oracle.svm.core.graal.nodes.CGlobalDataLoadAddressNode;
4649
import com.oracle.svm.core.graal.nodes.LoadOpenTypeWorldDispatchTableStartingOffset;
4750
import com.oracle.svm.core.graal.nodes.LoweredDeadEndNode;
4851
import com.oracle.svm.core.graal.nodes.ThrowBytecodeExceptionNode;
@@ -109,7 +112,6 @@
109112
import jdk.vm.ci.meta.JavaConstant;
110113
import jdk.vm.ci.meta.JavaKind;
111114
import jdk.vm.ci.meta.JavaType;
112-
import jdk.vm.ci.meta.ResolvedJavaField;
113115
import jdk.vm.ci.meta.ResolvedJavaMethod;
114116

115117
public abstract class NonSnippetLowerings {
@@ -369,18 +371,15 @@ public void lower(FixedNode node, LoweringTool tool) {
369371
targetMethod = implementations[0];
370372
}
371373

372-
if (targetMethod.forceIndirectCall()) {
374+
if (SubstrateUtil.HOSTED && targetMethod.forceIndirectCall()) {
373375
/*
374-
* Lower cross layer boundary direct calls to indirect calls. First emit a
375-
* load for the BoxedRelocatedPointer.pointer field holding the
376-
* MethodPointer to the target method, then emit an indirect call to that
377-
* pointer.
376+
* Lower cross layer boundary direct calls to indirect calls. First load the
377+
* target method absolute address from the method entry stored in the data
378+
* section. Then call that address indirectly.
378379
*/
379-
ResolvedJavaField boxedPointerField = tool.getMetaAccess().lookupJavaField(NonSnippetLowerings.boxedRelocatedPointerField);
380-
ConstantNode boxedPointerFieldOffset = ConstantNode.forIntegerKind(ConfigurationValues.getWordKind(), boxedPointerField.getOffset(), graph);
381-
ConstantNode boxedPointerBase = ConstantNode.forConstant(targetMethod.getMethodPointer(), tool.getMetaAccess(), graph);
380+
CGlobalDataInfo methodDataInfo = BaseLayerMethodAccessor.singleton().getMethodData(targetMethod);
381+
AddressNode methodPointerAddress = graph.addOrUniqueWithInputs(OffsetAddressNode.create(new CGlobalDataLoadAddressNode(methodDataInfo)));
382382

383-
AddressNode methodPointerAddress = graph.unique(new OffsetAddressNode(boxedPointerBase, boxedPointerFieldOffset));
384383
/*
385384
* Use the ANY location identity to prevent ReadNode.canonicalizeRead() to
386385
* try to constant fold the method address.

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/meta/SharedMethod.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
import com.oracle.svm.core.graal.code.SubstrateCallingConventionKind;
3131
import com.oracle.svm.core.graal.code.SubstrateCallingConventionType;
3232

33-
import jdk.vm.ci.meta.JavaConstant;
3433
import jdk.vm.ci.meta.ResolvedJavaMethod;
3534

3635
/**
@@ -84,7 +83,4 @@ public interface SharedMethod extends ResolvedJavaMethod {
8483

8584
/** Always call this method indirectly, even if it is normally called directly. */
8685
boolean forceIndirectCall();
87-
88-
/** Return a boxed pointer to this method. */
89-
JavaConstant getMethodPointer();
9086
}

substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/meta/SubstrateMethod.java

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@
6060
import jdk.vm.ci.meta.ConstantPool;
6161
import jdk.vm.ci.meta.DefaultProfilingInfo;
6262
import jdk.vm.ci.meta.ExceptionHandler;
63-
import jdk.vm.ci.meta.JavaConstant;
6463
import jdk.vm.ci.meta.LineNumberTable;
6564
import jdk.vm.ci.meta.LocalVariableTable;
6665
import jdk.vm.ci.meta.ProfilingInfo;
@@ -230,11 +229,6 @@ public boolean forceIndirectCall() {
230229
return false;
231230
}
232231

233-
@Override
234-
public JavaConstant getMethodPointer() {
235-
throw VMError.intentionallyUnimplemented(); // ExcludeFromJacocoGeneratedReport
236-
}
237-
238232
@Override
239233
public int getEncodedGraphStartOffset() {
240234
return encodedGraphStartOffset;

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageGenerator.java

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1299,7 +1299,25 @@ protected NativeLibraries setupNativeLibraries(HostedProviders providers, CEnumC
12991299
if (CAnnotationProcessorCache.Options.ExitAfterCAPCache.getValue()) {
13001300
throw new InterruptImageBuilding("Exiting image generation because of " + SubstrateOptionsParser.commandArgument(CAnnotationProcessorCache.Options.ExitAfterCAPCache, "+"));
13011301
}
1302-
1302+
if (SVMImageLayerSupport.singleton().hasLoader()) {
1303+
for (Path layerPath : SVMImageLayerSupport.singleton().getLoader().getLoadPaths()) {
1304+
Path snapshotFileName = layerPath.getFileName();
1305+
if (snapshotFileName != null) {
1306+
String layerName = snapshotFileName.toString().split(ImageLayerSnapshotUtil.FILE_NAME_PREFIX)[1].split(ImageLayerSnapshotUtil.FILE_EXTENSION)[0].trim();
1307+
/*
1308+
* This currently assumes lib{layer}.so is in the same dir as the layer
1309+
* snapshot. GR-53663 will create a proper bundle that contains both files.
1310+
*/
1311+
Path layerPathDir = layerPath.getParent();
1312+
if (layerPathDir != null && layerName.startsWith("lib") && Files.exists(layerPathDir.resolve(layerName + ".so"))) {
1313+
nativeLibs.getLibraryPaths().add(layerPathDir.toString());
1314+
nativeLibs.addDynamicNonJniLibrary(layerName.split("lib")[1]);
1315+
} else {
1316+
throw VMError.shouldNotReachHere("Missing " + layerName + ".so. It must be placed in the same dir as the layer snapshot.");
1317+
}
1318+
}
1319+
}
1320+
}
13031321
return nativeLibs;
13041322
}
13051323
}

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/SVMImageLayerSupport.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ public static SVMImageLayerSupport singleton() {
5252
return ImageSingletons.lookup(SVMImageLayerSupport.class);
5353
}
5454

55+
public boolean hasLoader() {
56+
return loader != null;
57+
}
58+
5559
public SVMImageLayerLoader getLoader() {
5660
return loader;
5761
}

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/AbstractImage.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ public enum NativeImageKind {
5454
IMAGE_LAYER(false, true) {
5555
@Override
5656
public String getFilenameSuffix() {
57-
return ".gso"; // Graal shared object
57+
return ".so";
5858
}
5959
},
6060
SHARED_LIBRARY(false) {

0 commit comments

Comments
 (0)