use of org.graalvm.word.UnsignedWord 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.UnsignedWord in project graal by oracle.
the class FirstObjectTable method entryToMemoryOffset.
/**
* Turn a table entry into a memory offset. This only handles memory offset entries.
*/
private static UnsignedWord entryToMemoryOffset(int entry) {
/* Negate the entry to a magnitude and scale it to an offset. */
assert isMemoryOffsetEntry(entry) : "Entry out of bounds.";
final UnsignedWord entryUnsigned = WordFactory.unsigned(-entry);
final UnsignedWord result = entryUnsigned.multiply(memoryOffsetScale());
assert (result.belowThan(MEMORY_BYTES_PER_ENTRY)) : "Entry out of bounds.";
return result;
}
use of org.graalvm.word.UnsignedWord 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.UnsignedWord in project graal by oracle.
the class FirstObjectTable method setTableForObjectUnchecked.
private static void setTableForObjectUnchecked(Pointer table, Pointer memory, Pointer start, Pointer end) {
/* Find the table entry for the start of the object. */
assert memory.belowOrEqual(start) : "memory.belowOrEqual(start)";
assert start.belowThan(end) : "start.belowThan(end)";
final UnsignedWord startOffset = start.subtract(memory);
/* The argument "end" is just past the real end of the object, so back it up one byte. */
final UnsignedWord endOffset = end.subtract(1).subtract(memory);
final UnsignedWord startIndex = memoryOffsetToIndex(startOffset);
final UnsignedWord endIndex = memoryOffsetToIndex(endOffset);
final UnsignedWord startMemoryOffset = indexToMemoryOffset(startIndex);
if (startIndex.equal(endIndex) && startOffset.unsignedRemainder(MEMORY_BYTES_PER_ENTRY).notEqual(0)) {
/* The object does not cross, or start on, a card boundary: nothing to do. */
return;
}
/* Fill in one or more table entries. */
final UnsignedWord memoryOffsetIndex;
if (startOffset.equal(startMemoryOffset)) {
/* The startOffset is at the beginning of the memory for startIndex. */
/* The memory offset entry is a 0 at startIndex. */
memoryOffsetIndex = startIndex;
setEntryAtIndex(table, memoryOffsetIndex, 0);
} else {
/*
* The startOffset is in the middle of the memory for startIndex. That is, before the
* memory for startIndex+1.
*/
memoryOffsetIndex = startIndex.add(1);
final UnsignedWord memoryIndexOffset = indexToMemoryOffset(memoryOffsetIndex);
final int entry = memoryOffsetToEntry(memoryIndexOffset.subtract(startOffset));
setEntryAtIndex(table, memoryOffsetIndex, entry);
}
/*
* Fill from memoryOffsetIndex towards endIndex with offset entries referring back to
* memoryOffsetIndex.
*/
/* - First, as many linear offsets as are needed, or as I can have. */
final UnsignedWord linearIndexMax = UnsignedUtils.min(endIndex, memoryOffsetIndex.add(LINEAR_OFFSET_MAX));
/* - - Step entryIndex and entry linearly. */
UnsignedWord entryIndex = memoryOffsetIndex.add(1);
int entry = LINEAR_OFFSET_MIN;
while (entryIndex.belowOrEqual(linearIndexMax)) {
setEntryAtIndex(table, entryIndex, entry);
entryIndex = entryIndex.add(1);
entry += 1;
}
/* - Next, as many exponential offsets as are needed. */
/*
* -- Step entryIndex by 1 (then bias it) while stepping the unbiased entry exponentially.
*/
int unbiasedExponent = EXPONENT_MIN;
while (entryIndex.belowOrEqual(endIndex)) {
/* There are 2^N entries with the exponent N. */
for (int count = 0; count < (1 << unbiasedExponent); count += 1) {
final int biasedEntry = biasExponent(unbiasedExponent);
setEntryAtIndex(table, entryIndex, biasedEntry);
entryIndex = entryIndex.add(1);
/* I might be done. */
if (!entryIndex.belowOrEqual(endIndex)) {
break;
}
}
unbiasedExponent += 1;
}
}
use of org.graalvm.word.UnsignedWord in project graal by oracle.
the class FirstObjectTable method verify.
/**
* Verify a FirstObjectTable.
*/
protected static boolean verify(Pointer tableStart, Pointer memoryStart, Pointer memoryLimit) {
/*
* Walk the table checking that I can find the start of the object that crosses onto this
* entry.
*/
final Log trace = HeapImpl.getHeapImpl().getHeapVerifierImpl().getTraceLog().string("[FirstObjectTable.verify:");
trace.string(" tableStart: ").hex(tableStart).string(" memoryStart: ").hex(memoryStart).string(" memoryLimit: ").hex(memoryLimit);
final UnsignedWord indexLimit = getTableSizeForMemoryPointers(memoryStart, memoryLimit);
for (UnsignedWord index = WordFactory.unsigned(0); index.belowThan(indexLimit); index = index.add(1)) {
trace.newline().string(" FirstObjectTable.verify: index: ").unsigned(index).newline();
final Pointer objStart = getPreciseFirstObjectPointer(tableStart, memoryStart, memoryLimit, index);
trace.string(" objStart: ").hex(objStart).newline();
if (objStart.belowThan(memoryStart)) {
/* Map points below memory. */
trace.string(" FirstObjectTable.verify: objStart.belowThan(memoryStart) => false]").newline();
return false;
}
if (memoryLimit.belowOrEqual(objStart)) {
/* Map points above memory. */
trace.string(" FirstObjectTable.verify: memoryLimit.belowOrEqual(objStart) => false]").newline();
return false;
}
if (!HeapImpl.getHeapImpl().getHeapVerifierImpl().verifyObjectAt(objStart)) {
/* Bad object. */
final Log witness = HeapImpl.getHeapImpl().getHeapVerifierImpl().getWitnessLog().string("[FirstObjectTable.verify:");
witness.string(" tableStart: ").hex(tableStart).string(" memoryStart: ").hex(memoryStart).string(" memoryLimit: ").hex(memoryLimit);
witness.string(" objStart: ").hex(objStart).string(" fails to verify").string("]").newline();
return false;
}
/* Check that the object crosses onto this entry. */
/*
* - Things are okay if ((objStart <= entryStart) && (entryStart < objEnd)) so I need to
* return false if either of those conditions is false
*/
final Pointer entryStart = memoryStart.add(indexToMemoryOffset(index));
trace.string(" entryStart: ").hex(entryStart);
if (!(objStart.belowOrEqual(entryStart))) {
/* Object doesn't start before this entry. */
final Log witness = HeapImpl.getHeapImpl().getHeapVerifierImpl().getWitnessLog().string("[FirstObjectTable.verify:");
witness.string(" tableStart: ").hex(tableStart).string(" memoryStart: ").hex(memoryStart).string(" memoryLimit: ").hex(memoryLimit);
witness.string(" objStart: ").hex(objStart).string(" entryStart: ").hex(entryStart).string(" !(objStart.belowOrEqual(entryStart))").string("]").newline();
return false;
}
final Object obj = objStart.toObject();
final Pointer objEnd = LayoutEncoding.getObjectEnd(obj);
trace.string(" ");
trace.string(obj.getClass().getName());
trace.string(" objEnd: ").hex(objEnd);
if (!(entryStart.belowThan(objEnd))) {
/* Object doesn't continue onto this entry. */
final Log witness = HeapImpl.getHeapImpl().getHeapVerifierImpl().getWitnessLog().string("[FirstObjectTable.verify:");
witness.string(" tableStart: ").hex(tableStart).string(" memoryStart: ").hex(memoryStart).string(" memoryLimit: ").hex(memoryLimit);
witness.string(" objEnd: ").hex(objEnd).string(" entryStart: ").hex(entryStart).string(" !(entryStart.belowThan(objEnd))").string("]").newline();
return false;
}
}
trace.string(" => true]").newline();
return true;
}
Aggregations