42
42
import org .graalvm .nativeimage .c .type .CCharPointer ;
43
43
import org .graalvm .nativeimage .c .type .WordPointer ;
44
44
import org .graalvm .word .ComparableWord ;
45
- import org .graalvm .word .LocationIdentity ;
46
45
import org .graalvm .word .Pointer ;
47
46
import org .graalvm .word .PointerBase ;
48
47
import org .graalvm .word .SignedWord ;
64
63
import com .oracle .svm .core .posix .PosixUtils ;
65
64
import com .oracle .svm .core .posix .headers .Fcntl ;
66
65
import com .oracle .svm .core .posix .headers .Unistd ;
67
- import com .oracle .svm .core .util .PointerUtils ;
68
66
67
+ import jdk .graal .compiler .nodes .NamedLocationIdentity ;
69
68
import jdk .graal .compiler .word .Word ;
70
69
71
70
/**
@@ -88,10 +87,9 @@ public class LinuxImageHeapProvider extends AbstractImageHeapProvider {
88
87
89
88
private static final CGlobalData <CCharPointer > PROC_SELF_MAPS = CGlobalDataFactory .createCString ("/proc/self/maps" );
90
89
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 );
95
93
private static final CGlobalData <WordPointer > CACHED_IMAGE_HEAP_OFFSET = CGlobalDataFactory .createWord ();
96
94
97
95
private static final int MAX_PATHLEN = 4096 ;
@@ -106,29 +104,15 @@ public boolean guaranteesHeapPreferredAddressSpaceAlignment() {
106
104
@ Override
107
105
@ Uninterruptible (reason = "Called during isolate initialization." )
108
106
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
-
118
107
/*
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.
125
111
*/
126
- if (fd .equal (UNASSIGNED_FD ) || firstIsolate ) {
112
+ SignedWord fd = CACHED_IMAGE_FD .get ().read ();
113
+ if (fd .equal (UNASSIGNED_FD )) {
127
114
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 );
132
116
if (previous .equal (fd )) {
133
117
fd = signed (opened );
134
118
} else {
@@ -139,45 +123,24 @@ public int initialize(Pointer reservedAddressSpace, UnsignedWord reservedSize, W
139
123
}
140
124
}
141
125
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
+ */
143
130
if (fd .equal (CANNOT_OPEN_FD )) {
144
131
return fallbackCopyingProvider .initialize (reservedAddressSpace , reservedSize , basePointer , endPointer );
145
132
}
146
133
147
134
boolean haveDynamicMethodResolution = DynamicMethodAddressResolutionHeapSupport .isEnabled ();
148
-
149
135
if (haveDynamicMethodResolution ) {
150
136
int res = DynamicMethodAddressResolutionHeapSupport .get ().initialize ();
151
137
if (res != CEntryPointErrors .NO_ERROR ) {
152
138
return res ;
153
139
}
154
140
}
155
141
156
- // If we are the first isolate and can use the existing image heap, do it.
157
142
UnsignedWord pageSize = VirtualMemoryProvider .get ().getGranularity ();
158
- Word imageHeapBegin = IMAGE_HEAP_BEGIN .get ();
159
143
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
- }
181
144
182
145
UnsignedWord preHeapRequiredBytes = WordFactory .zero ();
183
146
if (haveDynamicMethodResolution ) {
@@ -191,6 +154,7 @@ public int initialize(Pointer reservedAddressSpace, UnsignedWord reservedSize, W
191
154
Pointer heapBase ;
192
155
Pointer allocatedMemory = WordFactory .nullPointer ();
193
156
if (reservedAddressSpace .isNull ()) {
157
+ UnsignedWord alignment = WordFactory .unsigned (Heap .getHeap ().getPreferredAddressSpaceAlignment ());
194
158
heapBase = allocatedMemory = VirtualMemoryProvider .get ().reserve (totalAddressSpaceSize , alignment , false );
195
159
if (allocatedMemory .isNull ()) {
196
160
return CEntryPointErrors .RESERVE_ADDRESS_SPACE_FAILED ;
@@ -218,22 +182,21 @@ public int initialize(Pointer reservedAddressSpace, UnsignedWord reservedSize, W
218
182
219
183
// Create memory mappings from the image file.
220
184
UnsignedWord fileOffset = CACHED_IMAGE_HEAP_OFFSET .get ().read ();
221
- Pointer imageHeap = heapBase . add ( imageHeapOffsetInAddressSpace );
185
+ Pointer imageHeap = getImageHeapBegin ( heapBase );
222
186
imageHeap = VirtualMemoryProvider .get ().mapFile (imageHeap , imageHeapSizeInFile , fd , fileOffset , Access .READ );
223
187
if (imageHeap .isNull ()) {
224
188
freeImageHeap (allocatedMemory );
225
189
return CEntryPointErrors .MAP_HEAP_FAILED ;
226
190
}
227
191
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 );
231
195
if (relocatedValue .notEqual (mappedValue )) {
232
196
/*
233
197
* Addresses were relocated by dynamic linker, so copy them, but first remap the pages
234
198
* to avoid swapping them in from disk.
235
199
*/
236
- Pointer relocsBegin = imageHeap .add (IMAGE_HEAP_RELOCATABLE_BEGIN .get ().subtract (imageHeapBegin ));
237
200
UnsignedWord relocsSize = IMAGE_HEAP_RELOCATABLE_END .get ().subtract (IMAGE_HEAP_RELOCATABLE_BEGIN .get ());
238
201
if (!isAMultiple (relocsSize , pageSize )) {
239
202
freeImageHeap (allocatedMemory );
@@ -252,7 +215,7 @@ public int initialize(Pointer reservedAddressSpace, UnsignedWord reservedSize, W
252
215
}
253
216
254
217
// 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 () ));
256
219
UnsignedWord writableSize = IMAGE_HEAP_WRITABLE_END .get ().subtract (IMAGE_HEAP_WRITABLE_BEGIN .get ());
257
220
if (VirtualMemoryProvider .get ().protect (writableBegin , writableSize , Access .READ | Access .WRITE ) != 0 ) {
258
221
freeImageHeap (allocatedMemory );
0 commit comments