use of org.graalvm.word.Pointer in project graal by oracle.
the class AlignedHeapChunkMemoryWalkerAccessFeature method walkDirtyObjectsOfAlignedHeapChunk.
/**
* Walk the dirty Objects in this chunk, passing each to a Visitor.
*/
static boolean walkDirtyObjectsOfAlignedHeapChunk(AlignedHeader that, ObjectVisitor visitor, boolean clean) {
final Log trace = Log.noopLog().string("[AlignedHeapChunk.walkDirtyObjects:");
trace.string(" that: ").hex(that).string(" clean: ").bool(clean);
/* Iterate through the cards looking for dirty cards. */
final Pointer cardTableStart = getCardTableStart(that);
final Pointer fotStart = getFirstObjectTableStart(that);
final Pointer objectsStart = getAlignedHeapChunkStart(that);
final Pointer objectsLimit = that.getTop();
final UnsignedWord memorySize = objectsLimit.subtract(objectsStart);
final UnsignedWord indexLimit = CardTable.indexLimitForMemorySize(memorySize);
trace.string(" objectsStart: ").hex(objectsStart).string(" objectsLimit: ").hex(objectsLimit).string(" indexLimit: ").unsigned(indexLimit);
for (UnsignedWord index = WordFactory.zero(); index.belowThan(indexLimit); index = index.add(1)) {
trace.newline().string(" ").string(" index: ").unsigned(index);
/* If the card is dirty, visit the objects it covers. */
if (CardTable.isDirtyEntryAtIndex(cardTableStart, index)) {
final Pointer cardLimit = CardTable.indexToMemoryPointer(objectsStart, index.add(1));
final Pointer crossingOntoPointer = FirstObjectTable.getPreciseFirstObjectPointer(fotStart, objectsStart, objectsLimit, index);
final Object crossingOntoObject = crossingOntoPointer.toObject();
if (trace.isEnabled()) {
final Pointer cardStart = CardTable.indexToMemoryPointer(objectsStart, index);
trace.string(" ").string(" cardStart: ").hex(cardStart);
trace.string(" cardLimit: ").hex(cardLimit);
trace.string(" crossingOntoObject: ").object(crossingOntoObject);
trace.string(" end: ").hex(LayoutEncoding.getObjectEnd(crossingOntoObject));
if (LayoutEncoding.isArray(crossingOntoObject)) {
trace.string(" array length: ").signed(KnownIntrinsics.readArrayLength(crossingOntoObject));
}
}
trace.newline();
/*
* Iterate through the objects on that card. Find the start of the
* imprecisely-marked card.
*/
final Pointer impreciseStart = FirstObjectTable.getImpreciseFirstObjectPointer(fotStart, objectsStart, objectsLimit, index);
/*
* Walk the objects to the end of an object, even if that is past cardLimit, because
* these are imprecise cards.
*/
Pointer ptr = impreciseStart;
final Pointer walkLimit = PointerUtils.min(cardLimit, objectsLimit);
trace.string(" ");
trace.string(" impreciseStart: ").hex(impreciseStart);
trace.string(" walkLimit: ").hex(walkLimit);
while (ptr.belowThan(walkLimit)) {
trace.newline().string(" ");
trace.string(" ptr: ").hex(ptr);
final Object obj = ptr.toObject();
final Pointer objEnd = LayoutEncoding.getObjectEnd(obj);
trace.string(" obj: ").object(obj);
trace.string(" objEnd: ").hex(objEnd);
/* Visit the object. */
if (!visitor.visitObjectInline(obj)) {
final Log failureLog = Log.log().string("[AlignedHeapChunk.walkDirtyObjects:");
failureLog.string(" visitor.visitObject fails").string(" obj: ").object(obj).string("]").newline();
return false;
}
ptr = objEnd;
}
if (clean) {
CardTable.cleanEntryAtIndex(cardTableStart, index);
}
}
}
trace.string("]").newline();
return true;
}
use of org.graalvm.word.Pointer in project graal by oracle.
the class CardTable method verifyCleanCards.
/*
* Verification.
*/
/**
* Check that every clean card indicates an object with no pointers to young space.
*/
private static boolean verifyCleanCards(Pointer ctStart, Pointer fotStart, Pointer objectsStart, Pointer objectsLimit) {
final Log trace = Log.noopLog().string("[CardTable.verifyCleanCards:");
trace.string(" ctStart: ").hex(ctStart).string(" fotStart: ").hex(fotStart).string(" objectsStart: ").hex(objectsStart).string(" objectsLimit: ").hex(objectsLimit);
/* Walk the remembered set entries. */
final UnsignedWord indexLimit = FirstObjectTable.getTableSizeForMemoryPointers(objectsStart, objectsLimit);
for (UnsignedWord index = WordFactory.zero(); index.belowThan(indexLimit); index = index.add(1)) {
trace.newline().string(" index: ").unsigned(index);
if (FirstObjectTable.isUninitializedIndex(fotStart, index)) {
final Log failure = Log.log().string("[CardTable.verifyCleanCards: ");
failure.string(" reached uninitialized first object table entry").string("]").newline();
return false;
}
final boolean isClean = isCleanEntryAtIndex(ctStart, index);
if (!isClean) {
continue;
}
/* Find the imprecise bounds represented by the card. */
final Pointer impreciseStart = FirstObjectTable.getImpreciseFirstObjectPointer(fotStart, objectsStart, objectsLimit, index);
final Pointer cardLimit = indexToMemoryPointer(objectsStart, index.add(1));
final Pointer walkLimit = PointerUtils.min(cardLimit, objectsLimit);
trace.string(" impreciseStart: ").hex(impreciseStart).string(" cardLimit: ").hex(cardLimit).string(" walkLimit: ").hex(walkLimit);
/*
* Walk the objects to the end of an object, even if that is past cardLimit, because
* these are imprecise cards.
*/
Pointer ptr = impreciseStart;
while (ptr.belowThan(walkLimit)) {
trace.newline().string(" ").string(" ptr: ").hex(ptr);
final Object obj = ptr.toObject();
trace.string(" obj: ").object(obj);
if (LayoutEncoding.isArray(obj)) {
trace.string(" length: ").signed(KnownIntrinsics.readArrayLength(obj));
}
final boolean containsYoung = getReferenceToYoungObjectVisitor().containsReferenceToYoungObject(obj);
/* Return early on failure. */
if (containsYoung) {
/* { WITNESS */
final boolean witnessForDebugging = true;
final Log witness = (witnessForDebugging ? Log.log() : HeapImpl.getHeapImpl().getHeapVerifierImpl().getTraceLog());
witness.string("[CardTable.verifyCleanCards:").string(" objectsStart: ").hex(objectsStart).string(" objectsLimit: ").hex(objectsLimit).string(" indexLimit: ").unsigned(indexLimit).newline();
witness.string(" index: ").unsigned(index);
final Pointer cardStart = indexToMemoryPointer(objectsStart, index);
witness.string(" cardStart: ").hex(cardStart).string(" cardLimit: ").hex(cardLimit).string(" walkLimit: ").hex(walkLimit).string(" fotEntry: ");
FirstObjectTable.TestingBackDoor.indexToLog(fotStart, witness, index);
witness.string(" isClean: ").bool(isClean).newline();
final Pointer crossingOntoPointer = FirstObjectTable.getPreciseFirstObjectPointer(fotStart, objectsStart, objectsLimit, index);
final Object crossingOntoObject = crossingOntoPointer.toObject();
witness.string(" crossingOntoObject: ").object(crossingOntoObject).string(" end: ").hex(LayoutEncoding.getObjectEnd(crossingOntoObject));
if (LayoutEncoding.isArray(crossingOntoObject)) {
witness.string(" array length: ").signed(KnownIntrinsics.readArrayLength(crossingOntoObject));
}
witness.string(" impreciseStart: ").hex(impreciseStart).newline();
witness.string(" obj: ").object(obj).string(" end: ").hex(LayoutEncoding.getObjectEnd(obj));
if (LayoutEncoding.isArray(obj)) {
witness.string(" array length: ").signed(KnownIntrinsics.readArrayLength(obj));
}
witness.newline();
HeapChunk.Header<?> objChunk = AlignedHeapChunk.getEnclosingAlignedHeapChunk(obj);
witness.string(" objChunk: ").hex(objChunk).string(" objChunk space: ").string(objChunk.getSpace().getName()).string(" contains young: ").bool(containsYoung).newline();
/* Repeat the search for old-to-young references, this time as a witness. */
getReferenceToYoungObjectVisitor().witnessReferenceToYoungObject(obj);
witness.string(" returns false for index: ").unsigned(index).string("]").newline();
/* } WITNESS */
return false;
}
ptr = LayoutEncoding.getObjectEnd(obj);
}
}
trace.string("]").newline();
return true;
}
use of org.graalvm.word.Pointer in project graal by oracle.
the class DiscoverableReferenceProcessing method processReferent.
/**
* Determine if a referent is live, and adjust it as necessary.
*/
private static boolean processReferent(DiscoverableReference dr) {
final Log trace = Log.noopLog().string("[DiscoverableReference.processReferent:").string(" this: ").object(dr);
final Pointer refPointer = dr.getReferentPointer();
trace.string(" referent: ").hex(refPointer);
if (refPointer.isNull()) {
/* If the referent is null don't look at it further. */
trace.string(" null referent").string("]").newline();
return false;
}
/* Read the header. */
final UnsignedWord header = ObjectHeader.readHeaderFromPointer(refPointer);
/* It might be a forwarding pointer. */
if (ObjectHeaderImpl.getObjectHeaderImpl().isForwardedHeader(header)) {
/* If the referent got forwarded, then update the referent. */
final Pointer forwardedPointer = ObjectHeaderImpl.getObjectHeaderImpl().getForwardingPointer(header);
dr.setReferentPointer(forwardedPointer);
trace.string(" forwarded header: updated referent: ").hex(forwardedPointer).string("]").newline();
return true;
}
/*
* It's a real object. See if the referent has survived.
*/
final Object refObject = refPointer.toObject();
if (HeapImpl.getHeapImpl().hasSurvivedThisCollection(refObject)) {
/* The referent has survived, it does not need to be updated. */
trace.string(" referent will survive: not updated").string("]").newline();
return true;
}
/*
* Otherwise, referent has not survived.
*
* Note that we must use the Object-level store here, not the Pointer-level store: the
* static analysis must see that the field can be null. This means that we get a write
* barrier for this store.
*/
dr.clear();
trace.string(" has not survived: nulled referent").string("]").newline();
return false;
}
use of org.graalvm.word.Pointer in project graal by oracle.
the class FirstObjectTable method getPreciseFirstObjectPointer.
/**
* Return a Pointer to an object that could be precisely marked by this card.
*
* For a precise mark, this means I have to back up to the start of the object that crosses onto
* (or starts) this entry.
*
* @param tableStart The start of the first object table.
* @param memoryStart The start of the memory region corresponding to the first object table.
* @param memoryLimit The end of the memory region corresponding to the first object table.
* @param index The index into the first object table.
* @return A Pointer to first object that could be precisely marked at this index.
*/
protected static Pointer getPreciseFirstObjectPointer(Pointer tableStart, Pointer memoryStart, Pointer memoryLimit, UnsignedWord index) {
final Log trace = Log.noopLog().string("[FirstObjectTable.getPreciseFirstObjectPointer:").string(" index: ").unsigned(index);
UnsignedWord currentIndex = index;
int currentEntry = getEntryAtIndex(tableStart, currentIndex);
if (trace.isEnabled()) {
trace.string(" entry: ");
entryToLog(trace, currentEntry);
}
assert (currentEntry != UNINITIALIZED_ENTRY) : "uninitialized first object table entry";
if (MEMORY_OFFSET_MAX < currentEntry) {
/* The current entry is an entry offset. */
while (LINEAR_OFFSET_MAX < currentEntry) {
/* The current entry is a exponential offset. */
/* - Subtract off the bias to get the exponent. */
final int exponent = unbiasExponent(currentEntry);
/* - Compute 2^exponent. */
final UnsignedWord deltaIndex = exponentToOffset(exponent);
/* - Adjust the current index. */
currentIndex = indexMinusDelta(currentIndex, deltaIndex);
/* - Get the entry at the new index. */
currentEntry = getEntryAtIndex(tableStart, currentIndex);
}
if (MEMORY_OFFSET_MAX < currentEntry) {
/* The current entry is a linear offset. */
currentIndex = currentIndex.subtract(currentEntry);
currentEntry = getEntryAtIndex(tableStart, currentIndex);
}
}
/* The current entry is a memory offset. */
final Pointer result = getPointerAtOffset(memoryStart, currentIndex, currentEntry);
trace.string(" returns: ").hex(result);
assert memoryStart.belowOrEqual(result) : "memoryStart.belowOrEqual(result)";
assert result.belowThan(memoryLimit) : "result.belowThan(memoryLimit)";
trace.string("]").newline();
return result;
}
use of org.graalvm.word.Pointer in project graal by oracle.
the class FirstObjectTable method getImpreciseFirstObjectPointer.
/**
* Return a Pointer into a memory region indicated by the entry at a given index.
*
* For an imprecise mark, this means I can skip past any object that crosses onto this entry.
*
* @param tableStart The start of the first object table.
* @param memoryStart The start of the memory region corresponding to the first object table.
* @param memoryLimit The end of the memory region corresponding to the first object table.
* @param index The index into the first object table.
* @return A Pointer to the first object that could be imprecisely marked at this index. Returns
* the null Pointer if no object could be imprecisely marked at this index, e.g., if the
* object that crosses onto this card either also crosses off of this card, or runs up
* to the memory limit.
*/
protected static Pointer getImpreciseFirstObjectPointer(Pointer tableStart, Pointer memoryStart, Pointer memoryLimit, UnsignedWord index) {
final Log trace = Log.noopLog().string("[FirstObjectTable.getImpreciseFirstObjectPointer:");
trace.string(" tableStart: ").hex(tableStart).string(" memoryStart: ").hex(memoryStart).string(" memoryLimit: ").hex(memoryLimit).string(" index: ").unsigned(index).newline();
final Pointer preciseFirstPointer = getPreciseFirstObjectPointer(tableStart, memoryStart, memoryLimit, index);
/* If the object starts before the memory for this index, skip over it. */
final Pointer indexedMemoryStart = indexToMemoryPointer(index, memoryStart);
final Pointer result;
if (preciseFirstPointer.belowThan(indexedMemoryStart)) {
final Object crossingObject = preciseFirstPointer.toObject();
result = LayoutEncoding.getObjectEnd(crossingObject);
} else {
assert preciseFirstPointer.equal(indexedMemoryStart) : "preciseFirstPointer.equal(indexedMemoryStart)";
result = indexedMemoryStart;
}
trace.string(" returns: ").hex(result);
assert memoryStart.belowOrEqual(result) : "memoryStart.belowOrEqual(result)";
assert result.belowOrEqual(memoryLimit) : "result.belowOrEqual(memoryLimit)";
trace.string("]").newline();
return result;
}
Aggregations