4242import  org .graalvm .nativeimage .c .type .CCharPointer ;
4343import  org .graalvm .nativeimage .c .type .WordPointer ;
4444import  org .graalvm .word .ComparableWord ;
45- import  org .graalvm .word .LocationIdentity ;
4645import  org .graalvm .word .Pointer ;
4746import  org .graalvm .word .PointerBase ;
4847import  org .graalvm .word .SignedWord ;
6463import  com .oracle .svm .core .posix .PosixUtils ;
6564import  com .oracle .svm .core .posix .headers .Fcntl ;
6665import  com .oracle .svm .core .posix .headers .Unistd ;
67- import  com .oracle .svm .core .util .PointerUtils ;
6866
67+ import  jdk .graal .compiler .nodes .NamedLocationIdentity ;
6968import  jdk .graal .compiler .word .Word ;
7069
7170/** 
@@ -88,10 +87,9 @@ public class LinuxImageHeapProvider extends AbstractImageHeapProvider {
8887
8988    private  static  final  CGlobalData <CCharPointer > PROC_SELF_MAPS  = CGlobalDataFactory .createCString ("/proc/self/maps" );
9089
91-     private  static  final  SignedWord  FIRST_ISOLATE_FD  = signed (-1 );
92-     private  static  final  SignedWord  UNASSIGNED_FD  = signed (-2 );
93-     private  static  final  SignedWord  CANNOT_OPEN_FD  = signed (-3 );
94-     private  static  final  CGlobalData <WordPointer > CACHED_IMAGE_FD  = CGlobalDataFactory .createWord (FIRST_ISOLATE_FD );
90+     private  static  final  SignedWord  UNASSIGNED_FD  = signed (-1 );
91+     private  static  final  SignedWord  CANNOT_OPEN_FD  = signed (-2 );
92+     private  static  final  CGlobalData <WordPointer > CACHED_IMAGE_FD  = CGlobalDataFactory .createWord (UNASSIGNED_FD );
9593    private  static  final  CGlobalData <WordPointer > CACHED_IMAGE_HEAP_OFFSET  = CGlobalDataFactory .createWord ();
9694
9795    private  static  final  int  MAX_PATHLEN  = 4096 ;
@@ -106,29 +104,15 @@ public boolean guaranteesHeapPreferredAddressSpaceAlignment() {
106104    @ Override 
107105    @ Uninterruptible (reason  = "Called during isolate initialization." )
108106    public  int  initialize (Pointer  reservedAddressSpace , UnsignedWord  reservedSize , WordPointer  basePointer , WordPointer  endPointer ) {
109-         // If we are the first isolate, we might be able to use the existing image heap (see below) 
110-         SignedWord  fd  = CACHED_IMAGE_FD .get ().read ();
111-         boolean  firstIsolate  = false ;
112-         if  (fd .equal (FIRST_ISOLATE_FD )) {
113-             SignedWord  previous  = ((Pointer ) CACHED_IMAGE_FD .get ()).compareAndSwapWord (0 , FIRST_ISOLATE_FD , UNASSIGNED_FD , LocationIdentity .ANY_LOCATION );
114-             firstIsolate  = previous .equal (FIRST_ISOLATE_FD );
115-             fd  = firstIsolate  ? UNASSIGNED_FD  : previous ;
116-         }
117- 
118107        /* 
119-          * If we haven't already, find and open the image file. Even if we are the first isolate, 
120-          * this is necessary because if we fail, we need to leave the loaded image heap in pristine 
121-          * condition so we can use it to spawn isolates by copying it. 
122-          * 
123-          * We cache the file descriptor and the determined offset in the file for subsequent isolate 
124-          * initializations. We intentionally allow racing in this step to avoid stalling threads. 
108+          * Find and open the image file. We cache the file descriptor and the determined offset in 
109+          * the file for subsequent isolate initializations. We intentionally allow racing in this 
110+          * step to avoid stalling threads. 
125111         */ 
126-         if  (fd .equal (UNASSIGNED_FD ) || firstIsolate ) {
112+         SignedWord  fd  = CACHED_IMAGE_FD .get ().read ();
113+         if  (fd .equal (UNASSIGNED_FD )) {
127114            int  opened  = openImageFile ();
128-             /* 
129-              * Pointer cas operations are volatile accesses and prevent code reorderings. 
130-              */ 
131-             SignedWord  previous  = ((Pointer ) CACHED_IMAGE_FD .get ()).compareAndSwapWord (0 , fd , signed (opened ), LocationIdentity .ANY_LOCATION );
115+             SignedWord  previous  = ((Pointer ) CACHED_IMAGE_FD .get ()).compareAndSwapWord (0 , fd , signed (opened ), NamedLocationIdentity .OFF_HEAP_LOCATION );
132116            if  (previous .equal (fd )) {
133117                fd  = signed (opened );
134118            } else  {
@@ -139,45 +123,24 @@ public int initialize(Pointer reservedAddressSpace, UnsignedWord reservedSize, W
139123            }
140124        }
141125
142-         // If we cannot find or open the image file, fall back to copy it from memory. 
126+         /* 
127+          * If we cannot find or open the image file, fall back to copy it from memory (the image 
128+          * heap must be in pristine condition for that). 
129+          */ 
143130        if  (fd .equal (CANNOT_OPEN_FD )) {
144131            return  fallbackCopyingProvider .initialize (reservedAddressSpace , reservedSize , basePointer , endPointer );
145132        }
146133
147134        boolean  haveDynamicMethodResolution  = DynamicMethodAddressResolutionHeapSupport .isEnabled ();
148- 
149135        if  (haveDynamicMethodResolution ) {
150136            int  res  = DynamicMethodAddressResolutionHeapSupport .get ().initialize ();
151137            if  (res  != CEntryPointErrors .NO_ERROR ) {
152138                return  res ;
153139            }
154140        }
155141
156-         // If we are the first isolate and can use the existing image heap, do it. 
157142        UnsignedWord  pageSize  = VirtualMemoryProvider .get ().getGranularity ();
158-         Word  imageHeapBegin  = IMAGE_HEAP_BEGIN .get ();
159143        UnsignedWord  imageHeapSizeInFile  = getImageHeapSizeInFile ();
160-         int  imageHeapOffsetInAddressSpace  = Heap .getHeap ().getImageHeapOffsetInAddressSpace ();
161-         UnsignedWord  alignment  = WordFactory .unsigned (Heap .getHeap ().getPreferredAddressSpaceAlignment ());
162-         if  (firstIsolate  && reservedAddressSpace .isNull () && PointerUtils .isAMultiple (imageHeapBegin , alignment ) && imageHeapOffsetInAddressSpace  == 0  && !haveDynamicMethodResolution ) {
163-             // Mark the whole image heap as read only. 
164-             if  (VirtualMemoryProvider .get ().protect (imageHeapBegin , imageHeapSizeInFile , Access .READ ) != 0 ) {
165-                 return  CEntryPointErrors .PROTECT_HEAP_FAILED ;
166-             }
167- 
168-             // Unprotect writable pages. 
169-             Pointer  writableBegin  = IMAGE_HEAP_WRITABLE_BEGIN .get ();
170-             UnsignedWord  writableSize  = IMAGE_HEAP_WRITABLE_END .get ().subtract (writableBegin );
171-             if  (VirtualMemoryProvider .get ().protect (writableBegin , writableSize , Access .READ  | Access .WRITE ) != 0 ) {
172-                 return  CEntryPointErrors .PROTECT_HEAP_FAILED ;
173-             }
174- 
175-             basePointer .write (imageHeapBegin );
176-             if  (endPointer .isNonNull ()) {
177-                 endPointer .write (IMAGE_HEAP_END .get ());
178-             }
179-             return  CEntryPointErrors .NO_ERROR ;
180-         }
181144
182145        UnsignedWord  preHeapRequiredBytes  = WordFactory .zero ();
183146        if  (haveDynamicMethodResolution ) {
@@ -191,6 +154,7 @@ public int initialize(Pointer reservedAddressSpace, UnsignedWord reservedSize, W
191154        Pointer  heapBase ;
192155        Pointer  allocatedMemory  = WordFactory .nullPointer ();
193156        if  (reservedAddressSpace .isNull ()) {
157+             UnsignedWord  alignment  = WordFactory .unsigned (Heap .getHeap ().getPreferredAddressSpaceAlignment ());
194158            heapBase  = allocatedMemory  = VirtualMemoryProvider .get ().reserve (totalAddressSpaceSize , alignment , false );
195159            if  (allocatedMemory .isNull ()) {
196160                return  CEntryPointErrors .RESERVE_ADDRESS_SPACE_FAILED ;
@@ -218,22 +182,21 @@ public int initialize(Pointer reservedAddressSpace, UnsignedWord reservedSize, W
218182
219183        // Create memory mappings from the image file. 
220184        UnsignedWord  fileOffset  = CACHED_IMAGE_HEAP_OFFSET .get ().read ();
221-         Pointer  imageHeap  = heapBase . add ( imageHeapOffsetInAddressSpace );
185+         Pointer  imageHeap  = getImageHeapBegin ( heapBase );
222186        imageHeap  = VirtualMemoryProvider .get ().mapFile (imageHeap , imageHeapSizeInFile , fd , fileOffset , Access .READ );
223187        if  (imageHeap .isNull ()) {
224188            freeImageHeap (allocatedMemory );
225189            return  CEntryPointErrors .MAP_HEAP_FAILED ;
226190        }
227191
228-         Pointer  relocPointer  = IMAGE_HEAP_A_RELOCATABLE_POINTER . get ();
229-         ComparableWord  relocatedValue  = relocPointer .readWord (0 );
230-         ComparableWord  mappedValue  = imageHeap .readWord (relocPointer . subtract ( imageHeapBegin ) );
192+         Pointer  relocsBegin  = imageHeap . add ( IMAGE_HEAP_RELOCATABLE_BEGIN . get (). subtract ( IMAGE_HEAP_BEGIN . get ()) );
193+         ComparableWord  relocatedValue  = IMAGE_HEAP_A_RELOCATABLE_POINTER . get () .readWord (0 );
194+         ComparableWord  mappedValue  = relocsBegin .readWord (0 );
231195        if  (relocatedValue .notEqual (mappedValue )) {
232196            /* 
233197             * Addresses were relocated by dynamic linker, so copy them, but first remap the pages 
234198             * to avoid swapping them in from disk. 
235199             */ 
236-             Pointer  relocsBegin  = imageHeap .add (IMAGE_HEAP_RELOCATABLE_BEGIN .get ().subtract (imageHeapBegin ));
237200            UnsignedWord  relocsSize  = IMAGE_HEAP_RELOCATABLE_END .get ().subtract (IMAGE_HEAP_RELOCATABLE_BEGIN .get ());
238201            if  (!isAMultiple (relocsSize , pageSize )) {
239202                freeImageHeap (allocatedMemory );
@@ -252,7 +215,7 @@ public int initialize(Pointer reservedAddressSpace, UnsignedWord reservedSize, W
252215        }
253216
254217        // Unprotect writable pages. 
255-         Pointer  writableBegin  = imageHeap .add (IMAGE_HEAP_WRITABLE_BEGIN .get ().subtract (imageHeapBegin ));
218+         Pointer  writableBegin  = imageHeap .add (IMAGE_HEAP_WRITABLE_BEGIN .get ().subtract (IMAGE_HEAP_BEGIN . get () ));
256219        UnsignedWord  writableSize  = IMAGE_HEAP_WRITABLE_END .get ().subtract (IMAGE_HEAP_WRITABLE_BEGIN .get ());
257220        if  (VirtualMemoryProvider .get ().protect (writableBegin , writableSize , Access .READ  | Access .WRITE ) != 0 ) {
258221            freeImageHeap (allocatedMemory );
0 commit comments