Skip to content

Commit ae461b2

Browse files
committed
More variants of getSizeFromObject and getObjectEnd based on usage for safety.
1 parent 4081514 commit ae461b2

File tree

10 files changed

+40
-29
lines changed

10 files changed

+40
-29
lines changed

substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/GreyToBlackObjRefVisitor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ public boolean visitObjectReferenceInline(Pointer objRef, int innerOffset, boole
101101

102102
// Promote the Object if necessary, making it at least grey, and ...
103103
Object obj = p.toObject();
104-
assert innerOffset < LayoutEncoding.getSizeFromObject(obj).rawValue();
104+
assert innerOffset < LayoutEncoding.getSizeFromObjectInGC(obj).rawValue();
105105
Object copy = GCImpl.getGCImpl().promoteObject(obj, header);
106106
if (copy != obj) {
107107
// ... update the reference to point to the copy, making the reference black.

substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/ImageHeapInfo.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,11 +196,11 @@ public UnalignedHeader getFirstWritableUnalignedChunk() {
196196
}
197197

198198
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
199-
private static Word getObjectEnd(Object obj) {
199+
private static Pointer getObjectEnd(Object obj) {
200200
if (obj == null) {
201201
return WordFactory.nullPointer();
202202
}
203-
return Word.objectToUntrackedPointer(obj).add(LayoutEncoding.getSizeFromObject(obj));
203+
return LayoutEncoding.getImageHeapObjectEnd(obj);
204204
}
205205

206206
@SuppressWarnings("unchecked")

substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/ImageHeapWalker.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ private static boolean walkPartitionInline(Object firstObject, Object lastObject
119119
} else if (!visitor.visitObject(currentObject)) {
120120
return false;
121121
}
122-
current = LayoutEncoding.getObjectEnd(current.toObject());
122+
current = LayoutEncoding.getImageHeapObjectEnd(current.toObject());
123123
}
124124
if (HeapImpl.usesImageHeapChunks() && current.belowThan(lastPointer)) {
125125
currentChunk = HeapChunk.getNext(currentChunk);
@@ -157,7 +157,7 @@ public UnsignedWord getSize(ImageHeapInfo info) {
157157
if (firstStart.isNull()) { // no objects
158158
return WordFactory.zero();
159159
}
160-
Pointer lastEnd = LayoutEncoding.getObjectEnd(getLastObject(info));
160+
Pointer lastEnd = LayoutEncoding.getImageHeapObjectEnd(getLastObject(info));
161161
return lastEnd.subtract(firstStart);
162162
}
163163

substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/remset/AlignedChunkRememberedSet.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ public static void enableRememberedSetForObject(AlignedHeader chunk, Object obj)
8585
Pointer fotStart = getFirstObjectTableStart(chunk);
8686
Pointer objectsStart = AlignedHeapChunk.getObjectsStart(chunk);
8787
Pointer startOffset = Word.objectToUntrackedPointer(obj).subtract(objectsStart);
88-
Pointer endOffset = LayoutEncoding.getObjectEnd(obj).subtract(objectsStart);
88+
Pointer endOffset = LayoutEncoding.getObjectEndInGC(obj).subtract(objectsStart);
8989
FirstObjectTable.setTableForObject(fotStart, startOffset, endOffset);
9090
ObjectHeaderImpl.setRememberedSetBit(obj);
9191
}
@@ -101,7 +101,7 @@ public static void enableRememberedSet(AlignedHeader chunk) {
101101
while (offset.belowThan(top)) {
102102
Object obj = offset.toObject();
103103
enableRememberedSetForObject(chunk, obj);
104-
offset = offset.add(LayoutEncoding.getSizeFromObject(obj));
104+
offset = offset.add(LayoutEncoding.getSizeFromObjectInGC(obj));
105105
}
106106
}
107107

substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/remset/CardTable.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ public static boolean verify(Pointer cardTableStart, Pointer objectsStart, Point
160160
success &= verifyReferent(ref, cardTableStart, objectsStart);
161161
}
162162
}
163-
curPtr = LayoutEncoding.getObjectEnd(obj);
163+
curPtr = LayoutEncoding.getObjectEndInGC(obj);
164164
}
165165
return success;
166166
}

substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/remset/FirstObjectTable.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ public static Pointer getFirstObjectImprecise(Pointer tableStart, Pointer object
239239
// If the object starts before the memory for this index, skip over it.
240240
if (firstObject.belowThan(indexedMemoryStart)) {
241241
Object crossingObject = firstObject.toObject();
242-
result = LayoutEncoding.getObjectEnd(crossingObject);
242+
result = LayoutEncoding.getObjectEndInGC(crossingObject);
243243
} else {
244244
assert firstObject.equal(indexedMemoryStart) : "preciseFirstPointer.equal(indexedMemoryStart)";
245245
result = indexedMemoryStart;
@@ -308,7 +308,7 @@ public static boolean verify(Pointer tableStart, Pointer objectsStart, Pointer o
308308
}
309309

310310
Object obj = objStart.toObject();
311-
Pointer objEnd = LayoutEncoding.getObjectEnd(obj);
311+
Pointer objEnd = LayoutEncoding.getObjectEndInGC(obj);
312312
if (!entryStart.belowThan(objEnd)) {
313313
Log.log().string("The first object table entry at index ").unsigned(index).string(" points to an object is not crossing nor starting at a card boundary: obj: ").zhex(objStart)
314314
.string(" - ").zhex(objEnd).string(", chunk: ").zhex(objectsStart).string(" - ").zhex(objectsLimit).newline();

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/heap/ClassHistogramVisitor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public boolean visitObject(Object o) {
4747
return false;
4848
}
4949
entry.instanceCount++;
50-
entry.instanceSpace += LayoutEncoding.getSizeFromObject(o).rawValue();
50+
entry.instanceSpace += LayoutEncoding.getMomentarySizeFromObject(o).rawValue();
5151
return true;
5252
}
5353

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/heapdump/HeapDumpUtils.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,7 @@ public long sizeOf(Object obj) {
325325
if (obj == null) {
326326
result = 0;
327327
} else {
328-
final UnsignedWord objectSize = LayoutEncoding.getSizeFromObject(obj);
328+
final UnsignedWord objectSize = LayoutEncoding.getMomentarySizeFromObject(obj);
329329
result = objectSize.rawValue();
330330
}
331331
return result;

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/hub/LayoutEncoding.java

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -310,21 +310,27 @@ public static int getOptionalIdentityHashOffset(Object obj) {
310310
}
311311
}
312312

313-
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
313+
@Uninterruptible(reason = "Prevent a GC moving the object or interfering with its identity hash state.", callerMustBe = true)
314314
public static UnsignedWord getSizeFromObject(Object obj) {
315-
return getSizeFromObject(obj, false);
315+
boolean withOptionalIdHashField = !ConfigurationValues.getObjectLayout().hasFixedIdentityHashField() && checkOptionalIdentityHashField(obj);
316+
return getSizeFromObjectInline(obj, withOptionalIdHashField);
316317
}
317318

318-
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
319-
public static UnsignedWord getSizeFromObject(Object obj, boolean addOptionalIdHashField) {
320-
boolean withOptionalIdHashField = addOptionalIdHashField ||
321-
(!ConfigurationValues.getObjectLayout().hasFixedIdentityHashField() && checkOptionalIdentityHashFieldUninterruptibly(obj));
322-
return getSizeFromObjectInline(obj, withOptionalIdHashField);
319+
public static UnsignedWord getSizeFromObjectAddOptionalIdHashField(Object obj) {
320+
return getSizeFromObjectInline(obj, true);
323321
}
324322

325-
@Uninterruptible(reason = "Prevent a GC moving the object or interfering with its identity hash state.")
326-
private static boolean checkOptionalIdentityHashFieldUninterruptibly(Object obj) {
327-
return checkOptionalIdentityHashField(obj);
323+
/**
324+
* Returns the size of the object in the instant of the call, which can have already become
325+
* stale after returning. This can be useful for diagnostic output.
326+
*/
327+
@Uninterruptible(reason = "Caller is aware the value can be stale, but required by callee.")
328+
public static UnsignedWord getMomentarySizeFromObject(Object obj) {
329+
return getSizeFromObject(obj);
330+
}
331+
332+
public static UnsignedWord getSizeFromObjectInGC(Object obj) {
333+
return getSizeFromObjectInlineInGC(obj);
328334
}
329335

330336
@AlwaysInline("GC performance")
@@ -339,7 +345,7 @@ public static UnsignedWord getSizeFromObjectInlineInGC(Object obj, boolean addOp
339345
return getSizeFromObjectInline(obj, withOptionalIdHashField);
340346
}
341347

342-
@AlwaysInline("GC performance")
348+
@AlwaysInline("Actual inlining decided by callers.")
343349
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
344350
private static UnsignedWord getSizeFromObjectInline(Object obj, boolean withOptionalIdHashField) {
345351
DynamicHub hub = KnownIntrinsics.readHub(obj);
@@ -359,15 +365,20 @@ private static boolean checkOptionalIdentityHashField(Object obj) {
359365
return oh.hasOptionalIdentityHashField(header);
360366
}
361367

362-
/** Returns the end of the Object when the call started, e.g., for logging. */
363-
public static Pointer getObjectEnd(Object obj) {
364-
UnsignedWord size = getSizeFromObject(obj);
365-
return Word.objectToUntrackedPointer(obj).add(size);
368+
public static Pointer getObjectEndInGC(Object obj) {
369+
return getObjectEndInlineInGC(obj);
366370
}
367371

368372
@AlwaysInline("GC performance")
369373
public static Pointer getObjectEndInlineInGC(Object obj) {
370-
UnsignedWord size = getSizeFromObjectInlineInGC(obj);
374+
UnsignedWord size = getSizeFromObjectInlineInGC(obj, false);
375+
return Word.objectToUntrackedPointer(obj).add(size);
376+
}
377+
378+
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
379+
public static Pointer getImageHeapObjectEnd(Object obj) {
380+
// Image heap objects never move and always have an identity hash code field.
381+
UnsignedWord size = getSizeFromObjectInline(obj, true);
371382
return Word.objectToUntrackedPointer(obj).add(size);
372383
}
373384

substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/meta/SubstrateMemoryAccessProviderImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ private static JavaConstant readPrimitiveChecked(JavaKind kind, Constant baseCon
150150
} else if (displacement <= 0) {
151151
/* Trying to read before the object, or the hub. No need to look into the object. */
152152
return null;
153-
} else if (WordFactory.unsigned(displacement + bits / 8).aboveThan(LayoutEncoding.getSizeFromObject(baseObject))) {
153+
} else if (WordFactory.unsigned(displacement + bits / 8).aboveThan(LayoutEncoding.getMomentarySizeFromObject(baseObject))) {
154154
/* Trying to read after the end of the object. */
155155
return null;
156156
}

0 commit comments

Comments
 (0)