8282import com .oracle .svm .core .util .UnsignedUtils ;
8383import com .oracle .svm .core .util .VMError ;
8484
85+ import jdk .graal .compiler .nodes .NamedLocationIdentity ;
8586import jdk .graal .compiler .nodes .PauseNode ;
8687import jdk .graal .compiler .word .Word ;
8788
@@ -122,6 +123,14 @@ public class LinuxImageHeapProvider extends AbstractImageHeapProvider {
122123 */
123124 static final CGlobalData <WordPointer > CACHED_LAYERED_IMAGE_HEAP_ADDRESS_SPACE_SIZE = CGlobalDataFactory .createWord ();
124125
126+ private static final class ImageHeapPatchingState {
127+ static final Word UNINITIALIZED = Word .zero ();
128+ static final Word IN_PROGRESS = Word .unsigned (1 );
129+ static final Word SUCCESSFUL = Word .unsigned (2 );
130+ }
131+
132+ private static final CGlobalData <Word > IMAGE_HEAP_PATCHING_STATE = CGlobalDataFactory .createWord ();
133+
125134 @ Uninterruptible (reason = "Called from uninterruptible code." , mayBeInlined = true )
126135 private static UnsignedWord getLayeredImageHeapAddressSpaceSize () {
127136 // check if value is cached
@@ -167,6 +176,8 @@ protected int initializeLayeredImage(Pointer firstHeapStart, Pointer selfReserve
167176 int result = -1 ;
168177 UnsignedWord remainingSize = initialRemainingSize ;
169178
179+ patchLayeredImageHeap ();
180+
170181 int layerCount = 0 ;
171182 Pointer currentSection = ImageLayerSection .getInitialLayerSection ().get ();
172183 Pointer currentHeapStart = firstHeapStart ;
@@ -213,6 +224,47 @@ protected int initializeLayeredImage(Pointer firstHeapStart, Pointer selfReserve
213224 return result ;
214225 }
215226
227+ @ Uninterruptible (reason = "Thread state not yet set up." )
228+ public static void patchLayeredImageHeap () {
229+ Word heapPatchStateAddr = IMAGE_HEAP_PATCHING_STATE .get ();
230+ boolean firstIsolate = heapPatchStateAddr .logicCompareAndSwapWord (0 , ImageHeapPatchingState .UNINITIALIZED , ImageHeapPatchingState .IN_PROGRESS , NamedLocationIdentity .OFF_HEAP_LOCATION );
231+
232+ if (!firstIsolate ) {
233+ // spin-wait for first isolate
234+ Word state = heapPatchStateAddr .readWordVolatile (0 , LocationIdentity .ANY_LOCATION );
235+ while (state .equal (ImageHeapPatchingState .IN_PROGRESS )) {
236+ PauseNode .pause ();
237+ state = heapPatchStateAddr .readWordVolatile (0 , LocationIdentity .ANY_LOCATION );
238+ }
239+
240+ /* Patching has already been successfully completed, nothing needs to be done. */
241+ return ;
242+ }
243+
244+ Pointer currentSection = ImageLayerSection .getInitialLayerSection ().get ();
245+ Word heapBegin = currentSection .readWord (ImageLayerSection .getEntryOffset (HEAP_BEGIN ));
246+
247+ Word patches = ImageLayerSection .getHeapRelativeRelocationsStart ().get ();
248+ int endOffset = Integer .BYTES + (patches .readInt (0 ) * Integer .BYTES );
249+
250+ int referenceSize = ConfigurationValues .getObjectLayout ().getReferenceSize ();
251+ int offset = Integer .BYTES ;
252+ while (offset < endOffset ) {
253+ int heapOffset = patches .readInt (offset );
254+ int referenceEncoding = patches .readInt (offset + Integer .BYTES );
255+
256+ if (referenceSize == 4 ) {
257+ heapBegin .writeInt (heapOffset , referenceEncoding );
258+ } else {
259+ heapBegin .writeLong (heapOffset , referenceEncoding );
260+ }
261+
262+ offset += 2 * Integer .BYTES ;
263+ }
264+
265+ heapPatchStateAddr .writeWordVolatile (0 , ImageHeapPatchingState .SUCCESSFUL );
266+ }
267+
216268 @ Override
217269 @ Uninterruptible (reason = "Called during isolate initialization." )
218270 public int initialize (Pointer reservedAddressSpace , UnsignedWord reservedSize , WordPointer basePointer , WordPointer endPointer ) {
@@ -262,7 +314,9 @@ public int initialize(Pointer reservedAddressSpace, UnsignedWord reservedSize, W
262314 basePointer .write (heapBase );
263315 Pointer imageHeapStart = heapBase .add (imageHeapOffsetInAddressSpace );
264316 remainingSize = remainingSize .subtract (imageHeapOffsetInAddressSpace );
265- if (!ImageLayerBuildingSupport .buildingImageLayer ()) {
317+ if (ImageLayerBuildingSupport .buildingImageLayer ()) {
318+ return initializeLayeredImage (imageHeapStart , selfReservedHeapBase , remainingSize , endPointer );
319+ } else {
266320 int result = initializeImageHeap (imageHeapStart , remainingSize , endPointer ,
267321 CACHED_IMAGE_FD .get (), CACHED_IMAGE_HEAP_OFFSET .get (), CACHED_IMAGE_HEAP_RELOCATIONS .get (), MAGIC .get (),
268322 IMAGE_HEAP_BEGIN .get (), IMAGE_HEAP_END .get (),
@@ -272,8 +326,6 @@ public int initialize(Pointer reservedAddressSpace, UnsignedWord reservedSize, W
272326 freeImageHeap (selfReservedHeapBase );
273327 }
274328 return result ;
275- } else {
276- return initializeLayeredImage (imageHeapStart , selfReservedHeapBase , remainingSize , endPointer );
277329 }
278330 }
279331
0 commit comments