|
33 | 33 | import static com.oracle.svm.core.Isolates.IMAGE_HEAP_WRITABLE_END; |
34 | 34 | import static com.oracle.svm.core.Isolates.IMAGE_HEAP_WRITABLE_PATCHED_BEGIN; |
35 | 35 | import static com.oracle.svm.core.Isolates.IMAGE_HEAP_WRITABLE_PATCHED_END; |
| 36 | +import static com.oracle.svm.core.imagelayer.ImageLayerSection.SectionEntries.CODE_START; |
36 | 37 | import static com.oracle.svm.core.imagelayer.ImageLayerSection.SectionEntries.HEAP_BEGIN; |
37 | 38 | import static com.oracle.svm.core.imagelayer.ImageLayerSection.SectionEntries.HEAP_END; |
38 | 39 | import static com.oracle.svm.core.imagelayer.ImageLayerSection.SectionEntries.HEAP_RELOCATABLE_BEGIN; |
|
42 | 43 | import static com.oracle.svm.core.imagelayer.ImageLayerSection.SectionEntries.HEAP_WRITEABLE_PATCHED_BEGIN; |
43 | 44 | import static com.oracle.svm.core.imagelayer.ImageLayerSection.SectionEntries.HEAP_WRITEABLE_PATCHED_END; |
44 | 45 | import static com.oracle.svm.core.imagelayer.ImageLayerSection.SectionEntries.NEXT_SECTION; |
| 46 | +import static com.oracle.svm.core.imagelayer.ImageLayerSection.SectionEntries.VARIABLY_SIZED_DATA; |
45 | 47 | import static com.oracle.svm.core.posix.linux.ProcFSSupport.findMapping; |
46 | 48 | import static com.oracle.svm.core.util.PointerUtils.roundDown; |
47 | 49 | import static com.oracle.svm.core.util.UnsignedUtils.isAMultiple; |
48 | 50 | import static com.oracle.svm.core.util.UnsignedUtils.roundUp; |
49 | 51 | import static jdk.graal.compiler.word.Word.signed; |
| 52 | +import static jdk.graal.compiler.word.Word.unsigned; |
50 | 53 |
|
51 | 54 | import java.util.concurrent.ThreadLocalRandom; |
52 | 55 |
|
|
84 | 87 |
|
85 | 88 | import jdk.graal.compiler.nodes.NamedLocationIdentity; |
86 | 89 | import jdk.graal.compiler.nodes.PauseNode; |
| 90 | +import jdk.graal.compiler.replacements.nodes.CountTrailingZerosNode; |
87 | 91 | import jdk.graal.compiler.word.Word; |
88 | 92 |
|
89 | 93 | /** |
@@ -241,28 +245,91 @@ public static void patchLayeredImageHeap() { |
241 | 245 | return; |
242 | 246 | } |
243 | 247 |
|
244 | | - Pointer currentSection = ImageLayerSection.getInitialLayerSection().get(); |
245 | | - Word heapBegin = currentSection.readWord(ImageLayerSection.getEntryOffset(HEAP_BEGIN)); |
| 248 | + Pointer layerSection = ImageLayerSection.getInitialLayerSection().get(); |
| 249 | + Pointer initialLayerImageHeap = layerSection.readWord(ImageLayerSection.getEntryOffset(HEAP_BEGIN)); |
| 250 | + Pointer codeBase = layerSection.readWord(ImageLayerSection.getEntryOffset(CODE_START)); |
| 251 | + |
| 252 | + int referenceSize = ConfigurationValues.getObjectLayout().getReferenceSize(); |
| 253 | + while (layerSection.isNonNull()) { |
| 254 | + Pointer data = layerSection.add(ImageLayerSection.getEntryOffset(VARIABLY_SIZED_DATA)); |
| 255 | + int offset = 0; |
| 256 | + |
| 257 | + // Skip singletons table |
| 258 | + long singletonTableEntryCount = data.readLong(offset); |
| 259 | + UnsignedWord singletonTableAlignedSize = roundUp(unsigned(singletonTableEntryCount * referenceSize), unsigned(Long.BYTES)); |
| 260 | + offset += Long.BYTES + (int) singletonTableAlignedSize.rawValue(); |
| 261 | + |
| 262 | + Pointer layerHeapRelocs = layerSection.readWord(ImageLayerSection.getEntryOffset(HEAP_RELOCATABLE_BEGIN)); |
| 263 | + Pointer layerCode = layerSection.readWord(ImageLayerSection.getEntryOffset(CODE_START)); |
| 264 | + Word layerCodeOffsetToBase = (Word) layerCode.subtract(codeBase); |
| 265 | + offset = applyLayerCodePointerPatches(data, offset, layerHeapRelocs, layerCodeOffsetToBase); |
| 266 | + |
| 267 | + Word negativeCodeBase = Word.<Word> zero().subtract(codeBase); |
| 268 | + offset = applyLayerCodePointerPatches(data, offset, layerHeapRelocs, negativeCodeBase); |
| 269 | + |
| 270 | + applyLayerImageHeapRefPatches(data.add(offset), initialLayerImageHeap); |
| 271 | + |
| 272 | + layerSection = layerSection.readWord(ImageLayerSection.getEntryOffset(NEXT_SECTION)); |
| 273 | + } |
| 274 | + |
| 275 | + heapPatchStateAddr.writeWordVolatile(0, ImageHeapPatchingState.SUCCESSFUL); |
| 276 | + } |
246 | 277 |
|
247 | | - Word patches = ImageLayerSection.getHeapRelativeRelocationsStart().get(); |
248 | | - int endOffset = Integer.BYTES + (patches.readInt(0) * Integer.BYTES); |
| 278 | + @Uninterruptible(reason = "Thread state not yet set up.") |
| 279 | + private static int applyLayerCodePointerPatches(Pointer data, int startOffset, Pointer layerHeapRelocs, Word addend) { |
| 280 | + int wordSize = ConfigurationValues.getTarget().wordSize; |
| 281 | + |
| 282 | + int offset = startOffset; |
| 283 | + int bitmapWordCount = (int) data.readLong(offset); |
| 284 | + offset += Long.BYTES; |
| 285 | + if (addend.equal(0)) { |
| 286 | + offset += bitmapWordCount * Long.BYTES; |
| 287 | + return offset; |
| 288 | + } |
249 | 289 |
|
| 290 | + for (int i = 0; i < bitmapWordCount; i++) { |
| 291 | + long bits = data.readLong(offset); |
| 292 | + offset += Long.BYTES; |
| 293 | + int j = 0; // index of a 1-bit |
| 294 | + while (bits != 0) { |
| 295 | + int ntz = CountTrailingZerosNode.countLongTrailingZeros(bits); |
| 296 | + j += ntz; |
| 297 | + |
| 298 | + int at = (i * 64 + j) * wordSize; |
| 299 | + Word w = layerHeapRelocs.readWord(at); |
| 300 | + w = w.add(addend); |
| 301 | + layerHeapRelocs.writeWord(at, w); |
| 302 | + |
| 303 | + /* |
| 304 | + * Note that we must not shift by ntz+1 here because it can be 64, and according to |
| 305 | + * the Java Language Specification, 15.19. Shift Operators: If the promoted type of |
| 306 | + * the left-hand operand is long, then only the six lowest-order bits of the |
| 307 | + * right-hand operand are used as the shift distance. [..] The shift distance |
| 308 | + * actually used is therefore always in the range 0 to 63, inclusive. |
| 309 | + */ |
| 310 | + bits = (bits >>> ntz) >>> 1; |
| 311 | + j++; |
| 312 | + } |
| 313 | + } |
| 314 | + return offset; |
| 315 | + } |
| 316 | + |
| 317 | + @Uninterruptible(reason = "Thread state not yet set up.") |
| 318 | + private static void applyLayerImageHeapRefPatches(Pointer patches, Pointer layerImageHeap) { |
250 | 319 | int referenceSize = ConfigurationValues.getObjectLayout().getReferenceSize(); |
251 | | - int offset = Integer.BYTES; |
| 320 | + int count = (int) patches.readLong(0); |
| 321 | + int offset = Long.BYTES; |
| 322 | + int endOffset = offset + count * Integer.BYTES; |
252 | 323 | while (offset < endOffset) { |
253 | 324 | int heapOffset = patches.readInt(offset); |
254 | 325 | int referenceEncoding = patches.readInt(offset + Integer.BYTES); |
255 | | - |
| 326 | + offset += 2 * Integer.BYTES; |
256 | 327 | if (referenceSize == 4) { |
257 | | - heapBegin.writeInt(heapOffset, referenceEncoding); |
| 328 | + layerImageHeap.writeInt(heapOffset, referenceEncoding); |
258 | 329 | } else { |
259 | | - heapBegin.writeLong(heapOffset, referenceEncoding); |
| 330 | + layerImageHeap.writeLong(heapOffset, referenceEncoding); |
260 | 331 | } |
261 | | - |
262 | | - offset += 2 * Integer.BYTES; |
263 | 332 | } |
264 | | - |
265 | | - heapPatchStateAddr.writeWordVolatile(0, ImageHeapPatchingState.SUCCESSFUL); |
266 | 333 | } |
267 | 334 |
|
268 | 335 | @Override |
|
0 commit comments