|
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