Skip to content

Commit ed00168

Browse files
committed
Image heap provider fixes and cleanups.
1 parent 673d6c3 commit ed00168

File tree

4 files changed

+84
-114
lines changed

4 files changed

+84
-114
lines changed

substratevm/src/com.oracle.svm.core.posix/src/com/oracle/svm/core/posix/linux/LinuxImageHeapProvider.java

+23-51
Original file line numberDiff line numberDiff line change
@@ -90,32 +90,15 @@ public class LinuxImageHeapProvider extends AbstractImageHeapProvider {
9090
private static final SignedWord UNASSIGNED_FD = signed(-1);
9191
private static final SignedWord CANNOT_OPEN_FD = signed(-2);
9292
private static final CGlobalData<WordPointer> CACHED_IMAGE_FD = CGlobalDataFactory.createWord(UNASSIGNED_FD);
93-
private static final CGlobalData<WordPointer> CACHED_IMAGE_HEAP_OFFSET = CGlobalDataFactory.createWord();
93+
private static final CGlobalData<WordPointer> CACHED_IMAGE_HEAP_OFFSET_IN_FILE = CGlobalDataFactory.createWord();
94+
95+
private static final int MAX_PATHLEN = 4096;
9496

9597
@Override
9698
public boolean guaranteesHeapPreferredAddressSpaceAlignment() {
9799
return true;
98100
}
99101

100-
@Override
101-
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
102-
protected UnsignedWord getImageHeapAddressSpaceSize() {
103-
int imageHeapOffset = Heap.getHeap().getImageHeapOffsetInAddressSpace();
104-
assert imageHeapOffset >= 0;
105-
UnsignedWord size = WordFactory.unsigned(imageHeapOffset);
106-
size = size.add(getImageHeapSizeInFile(IMAGE_HEAP_BEGIN.get(), IMAGE_HEAP_END.get()));
107-
return size;
108-
}
109-
110-
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
111-
protected UnsignedWord getTotalRequiredAddressSpaceSize() {
112-
UnsignedWord size = getImageHeapAddressSpaceSize();
113-
if (DynamicMethodAddressResolutionHeapSupport.isEnabled()) {
114-
size = size.add(DynamicMethodAddressResolutionHeapSupport.get().getDynamicMethodAddressResolverPreHeapMemoryBytes());
115-
}
116-
return size;
117-
}
118-
119102
@Override
120103
@Uninterruptible(reason = "Called during isolate initialization.")
121104
public int initialize(Pointer reservedAddressSpace, UnsignedWord reservedSize, WordPointer basePointer, WordPointer endPointer) {
@@ -135,15 +118,14 @@ public int initialize(Pointer reservedAddressSpace, UnsignedWord reservedSize, W
135118
Pointer heapBase;
136119
Pointer selfReservedHeapBase;
137120
if (DynamicMethodAddressResolutionHeapSupport.isEnabled()) {
138-
UnsignedWord preHeapRequiredBytes = DynamicMethodAddressResolutionHeapSupport.get().getDynamicMethodAddressResolverPreHeapMemoryBytes();
121+
UnsignedWord preHeapRequiredBytes = getPreHeapAlignedSizeForDynamicMethodAddressResolver();
139122
if (selfReservedMemory.isNonNull()) {
140123
selfReservedHeapBase = selfReservedMemory.add(preHeapRequiredBytes);
141124
heapBase = selfReservedHeapBase;
142125
} else {
143126
heapBase = reservedAddressSpace.add(preHeapRequiredBytes);
144127
selfReservedHeapBase = WordFactory.nullPointer();
145128
}
146-
assert heapBase.isNonNull();
147129
remainingSize = remainingSize.subtract(preHeapRequiredBytes);
148130

149131
int error = DynamicMethodAddressResolutionHeapSupport.get().initialize();
@@ -152,8 +134,7 @@ public int initialize(Pointer reservedAddressSpace, UnsignedWord reservedSize, W
152134
return error;
153135
}
154136

155-
Pointer installOffset = heapBase.subtract(DynamicMethodAddressResolutionHeapSupport.get().getRequiredPreHeapMemoryInBytes());
156-
error = DynamicMethodAddressResolutionHeapSupport.get().install(installOffset);
137+
error = DynamicMethodAddressResolutionHeapSupport.get().install(heapBase);
157138
if (error != CEntryPointErrors.NO_ERROR) {
158139
freeImageHeap(selfReservedHeapBase);
159140
return error;
@@ -165,10 +146,10 @@ public int initialize(Pointer reservedAddressSpace, UnsignedWord reservedSize, W
165146

166147
int imageHeapOffsetInAddressSpace = Heap.getHeap().getImageHeapOffsetInAddressSpace();
167148
basePointer.write(heapBase);
168-
Pointer firstBase = heapBase.add(imageHeapOffsetInAddressSpace);
149+
Pointer imageHeapStart = heapBase.add(imageHeapOffsetInAddressSpace);
169150
remainingSize = remainingSize.subtract(imageHeapOffsetInAddressSpace);
170-
int result = initializeImageHeap(firstBase, remainingSize, endPointer,
171-
CACHED_IMAGE_FD.get(), CACHED_IMAGE_HEAP_OFFSET.get(), MAGIC.get(),
151+
int result = initializeImageHeap(imageHeapStart, remainingSize, endPointer,
152+
CACHED_IMAGE_FD.get(), CACHED_IMAGE_HEAP_OFFSET_IN_FILE.get(), MAGIC.get(),
172153
IMAGE_HEAP_BEGIN.get(), IMAGE_HEAP_END.get(),
173154
IMAGE_HEAP_RELOCATABLE_BEGIN.get(), IMAGE_HEAP_A_RELOCATABLE_POINTER.get(), IMAGE_HEAP_RELOCATABLE_END.get(),
174155
IMAGE_HEAP_WRITABLE_BEGIN.get(), IMAGE_HEAP_WRITABLE_END.get());
@@ -179,7 +160,7 @@ public int initialize(Pointer reservedAddressSpace, UnsignedWord reservedSize, W
179160
}
180161

181162
@Uninterruptible(reason = "Called during isolate initialization.")
182-
private int initializeImageHeap(Pointer imageHeap, UnsignedWord reservedSize, WordPointer endPointer, WordPointer cachedFd, WordPointer cachedOffset,
163+
private int initializeImageHeap(Pointer imageHeap, UnsignedWord reservedSize, WordPointer endPointer, WordPointer cachedFd, WordPointer cachedOffsetInFile,
183164
Pointer magicAddress, Word heapBeginSym, Word heapEndSym, Word heapRelocsSym, Pointer heapAnyRelocPointer, Word heapRelocsEndSym, Word heapWritableSym, Word heapWritableEndSym) {
184165
assert heapBeginSym.belowOrEqual(heapWritableSym) && heapWritableSym.belowOrEqual(heapWritableEndSym) && heapWritableEndSym.belowOrEqual(heapEndSym);
185166
assert heapBeginSym.belowOrEqual(heapRelocsSym) && heapRelocsSym.belowOrEqual(heapRelocsEndSym) && heapRelocsEndSym.belowOrEqual(heapEndSym);
@@ -193,7 +174,7 @@ private int initializeImageHeap(Pointer imageHeap, UnsignedWord reservedSize, Wo
193174
* step to avoid stalling threads.
194175
*/
195176
if (fd.equal(UNASSIGNED_FD)) {
196-
int opened = openImageFile(cachedOffset, heapBeginSym, heapRelocsSym, magicAddress);
177+
int opened = openImageFile(heapBeginSym, magicAddress, cachedOffsetInFile);
197178
SignedWord previous = ((Pointer) cachedFd).compareAndSwapWord(0, fd, signed(opened), LocationIdentity.ANY_LOCATION);
198179
if (previous.equal(fd)) {
199180
fd = signed(opened);
@@ -221,7 +202,7 @@ private int initializeImageHeap(Pointer imageHeap, UnsignedWord reservedSize, Wo
221202
}
222203

223204
// Create memory mappings from the image file.
224-
UnsignedWord fileOffset = cachedOffset.read();
205+
UnsignedWord fileOffset = cachedOffsetInFile.read();
225206
imageHeap = VirtualMemoryProvider.get().mapFile(imageHeap, imageHeapSize, fd, fileOffset, Access.READ);
226207
if (imageHeap.isNull()) {
227208
return CEntryPointErrors.MAP_HEAP_FAILED;
@@ -232,8 +213,8 @@ private int initializeImageHeap(Pointer imageHeap, UnsignedWord reservedSize, Wo
232213
ComparableWord mappedValue = imageHeap.readWord(heapAnyRelocPointer.subtract(heapBeginSym));
233214
if (relocatedValue.notEqual(mappedValue)) {
234215
/*
235-
* Addresses were relocated by dynamic linker, so copy them, but first remap the
236-
* pages to avoid swapping them in from disk.
216+
* Addresses were relocated by the dynamic linker, so copy them, but first remap the
217+
* pages as anonymous memory to avoid swapping in part of the image from disk.
237218
*/
238219
Pointer relocsBegin = imageHeap.add(heapRelocsSym.subtract(heapBeginSym));
239220
UnsignedWord relocsSize = heapRelocsEndSym.subtract(heapRelocsSym);
@@ -283,27 +264,24 @@ private static int initializeImageHeapByCopying(Pointer imageHeap, Word heapBegi
283264

284265
/**
285266
* Locate our image file, containing the image heap. Unfortunately we must open it by its path.
286-
*
287-
* NOTE: we look for the relocatables partition of the linker-mapped heap because it always
288-
* stays mapped, while the rest of the linker-mapped heap can be unmapped after tearing down the
289-
* first isolate. We do not use /proc/self/exe because it breaks with some tools like Valgrind.
267+
* We do not use /proc/self/exe because it breaks with some tools like Valgrind.
290268
*/
291269
@Uninterruptible(reason = "Called during isolate initialization.")
292-
private static int openImageFile(WordPointer cachedOffset, Word heapBeginSym, Word heapRelocsSym, Pointer magicAddress) {
270+
private static int openImageFile(Word heapBeginSym, Pointer magicAddress, WordPointer cachedImageHeapOffsetInFile) {
293271
final int failfd = (int) CANNOT_OPEN_FD.rawValue();
294272
int mapfd = Fcntl.NoTransitions.open(PROC_SELF_MAPS.get(), Fcntl.O_RDONLY(), 0);
295273
if (mapfd == -1) {
296274
return failfd;
297275
}
298-
final int bufferSize = 4096; // assumed MAX_PATHLEN
276+
final int bufferSize = MAX_PATHLEN;
299277
CCharPointer buffer = StackValue.get(bufferSize);
300278

301279
// The relocatables partition might stretch over two adjacent mappings due to permission
302280
// differences, so only locate the mapping for the first page of relocatables
303281
UnsignedWord pageSize = VirtualMemoryProvider.get().getGranularity();
304-
WordPointer relocsMappingStart = StackValue.get(WordPointer.class);
305-
WordPointer relocsMappingFileOffset = StackValue.get(WordPointer.class);
306-
boolean found = findMapping(mapfd, buffer, bufferSize, heapRelocsSym, heapRelocsSym.add(pageSize), relocsMappingStart, relocsMappingFileOffset, true);
282+
WordPointer imageHeapMappingStart = StackValue.get(WordPointer.class);
283+
WordPointer imageHeapMappingFileOffset = StackValue.get(WordPointer.class);
284+
boolean found = findMapping(mapfd, buffer, bufferSize, heapBeginSym, heapBeginSym.add(pageSize), imageHeapMappingStart, imageHeapMappingFileOffset, true);
307285
if (!found) {
308286
Unistd.NoTransitions.close(mapfd);
309287
return failfd;
@@ -321,10 +299,9 @@ private static int openImageFile(WordPointer cachedOffset, Word heapBeginSym, Wo
321299
return failfd;
322300
}
323301

324-
Word imageHeapRelocsOffset = heapRelocsSym.subtract(heapBeginSym);
325-
Word imageHeapOffset = heapRelocsSym.subtract(relocsMappingStart.read()).subtract(imageHeapRelocsOffset);
326-
UnsignedWord fileOffset = imageHeapOffset.add(relocsMappingFileOffset.read());
327-
cachedOffset.write(fileOffset);
302+
Word imageHeapOffsetInMapping = heapBeginSym.subtract(imageHeapMappingStart.read());
303+
UnsignedWord imageHeapOffsetInFile = imageHeapOffsetInMapping.add(imageHeapMappingFileOffset.read());
304+
cachedImageHeapOffsetInFile.write(imageHeapOffsetInFile);
328305
return opened;
329306
}
330307

@@ -368,17 +345,12 @@ public int freeImageHeap(PointerBase heapBase) {
368345
UnsignedWord totalAddressSpaceSize = getTotalRequiredAddressSpaceSize();
369346
Pointer addressSpaceStart = (Pointer) heapBase;
370347
if (DynamicMethodAddressResolutionHeapSupport.isEnabled()) {
371-
UnsignedWord preHeapRequiredBytes = DynamicMethodAddressResolutionHeapSupport.get().getDynamicMethodAddressResolverPreHeapMemoryBytes();
348+
UnsignedWord preHeapRequiredBytes = getPreHeapAlignedSizeForDynamicMethodAddressResolver();
372349
addressSpaceStart = addressSpaceStart.subtract(preHeapRequiredBytes);
373350
}
374351
if (VirtualMemoryProvider.get().free(addressSpaceStart, totalAddressSpaceSize) != 0) {
375352
return CEntryPointErrors.FREE_IMAGE_HEAP_FAILED;
376353
}
377354
return CEntryPointErrors.NO_ERROR;
378355
}
379-
380-
@Override
381-
protected UnsignedWord getImageHeapSizeInFile() {
382-
throw VMError.shouldNotReachHere("use the variant that takes pointers");
383-
}
384356
}

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/code/DynamicMethodAddressResolutionHeapSupport.java

+2-25
Original file line numberDiff line numberDiff line change
@@ -24,19 +24,11 @@
2424
*/
2525
package com.oracle.svm.core.code;
2626

27-
import static com.oracle.svm.core.util.PointerUtils.roundUp;
28-
29-
import jdk.graal.compiler.api.replacements.Fold;
30-
import org.graalvm.nativeimage.CurrentIsolate;
3127
import org.graalvm.nativeimage.ImageSingletons;
3228
import org.graalvm.word.Pointer;
33-
import org.graalvm.word.PointerBase;
3429
import org.graalvm.word.UnsignedWord;
35-
import org.graalvm.word.WordFactory;
3630

37-
import com.oracle.svm.core.Isolates;
38-
import com.oracle.svm.core.Uninterruptible;
39-
import com.oracle.svm.core.heap.Heap;
31+
import jdk.graal.compiler.api.replacements.Fold;
4032

4133
public abstract class DynamicMethodAddressResolutionHeapSupport {
4234

@@ -54,20 +46,5 @@ public static DynamicMethodAddressResolutionHeapSupport get() {
5446

5547
public abstract UnsignedWord getRequiredPreHeapMemoryInBytes();
5648

57-
public abstract int install(Pointer address);
58-
59-
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
60-
public UnsignedWord getDynamicMethodAddressResolverPreHeapMemoryBytes() {
61-
UnsignedWord requiredPreHeapMemoryInBytes = getRequiredPreHeapMemoryInBytes();
62-
/* Ensure there is enough space to properly align the heap */
63-
UnsignedWord heapAlignment = WordFactory.unsigned(Heap.getHeap().getPreferredAddressSpaceAlignment());
64-
return roundUp((PointerBase) requiredPreHeapMemoryInBytes, heapAlignment);
65-
}
66-
67-
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
68-
public Pointer getPreHeapMappingStartAddress() {
69-
UnsignedWord heapBase = (UnsignedWord) Isolates.getHeapBase(CurrentIsolate.getIsolate());
70-
return (Pointer) heapBase.subtract(getRequiredPreHeapMemoryInBytes());
71-
}
72-
49+
public abstract int install(Pointer heapBase);
7350
}

0 commit comments

Comments
 (0)