use of org.vmmagic.unboxed.ObjectReference in project JikesRVM by JikesRVM.
the class MarkCompactCollector method calculateForwardingPointers.
/* ***************************************************************************************** */
/**
* Perform a linear scan through the objects allocated by this bump pointer,
* calculating where each live object will be post collection.<p>
*
* We maintain two cursors, {@code fromCursor} and {@code toCursor}, and simulate
* copying live objects from the former to the latter. Initially, the cursors
* point to the first region in this collector's local list, and increment in
* lockstep until the first dead object is encountered. After that, the to cursor
* trails the from cursor.<p>
*
* The outer loop advances the 'from' pointer
*/
public void calculateForwardingPointers() {
if (regions.isZero()) {
regions = space.getNextRegion();
}
if (regions.isZero())
return;
fromCursor.init(regions);
toCursor.init(regions);
if (VM.VERIFY_ASSERTIONS)
VM.assertions._assert(true);
/* Loop through active regions or until the last region */
while (fromCursor.isValid()) {
if (VERBOSE) {
fromCursor.print();
toCursor.print();
}
/* Loop through the objects in the current 'from' region */
while (fromCursor.hasMoreObjects()) {
ObjectReference current = fromCursor.advanceToObject();
fromCursor.advanceToObjectEnd(current);
if (MarkCompactSpace.toBeCompacted(current)) {
if (VM.VERIFY_ASSERTIONS)
VM.assertions._assert(MarkCompactSpace.getForwardingPointer(current).isNull());
// Fake - allocate it.
int size = VM.objectModel.getSizeWhenCopied(current);
int align = VM.objectModel.getAlignWhenCopied(current);
int offset = VM.objectModel.getAlignOffsetWhenCopied(current);
// Move to the (aligned) start of the next object
toCursor.incTo(Allocator.alignAllocationNoFill(toCursor.get(), align, offset));
/*
* If we're allocating into separate regions, and we've allocated beyond the end of the
* current region, advance to the next one. We always allocate into regions we have
* scanned in this collector.
*/
if (!toCursor.sameRegion(fromCursor) && !toCursor.isAvailable(size)) {
// The 'to' pointer always trails the 'from' pointer, guaranteeing that
// there's a next region to advance to.
toCursor.advanceToNextRegion();
toCursor.incTo(Allocator.alignAllocationNoFill(toCursor.get(), align, offset));
}
ObjectReference target = VM.objectModel.getReferenceWhenCopiedTo(current, toCursor.get());
if (toCursor.sameRegion(fromCursor) && target.toAddress().GE(current.toAddress())) {
// Don't move the object.
MarkCompactSpace.setForwardingPointer(current, current);
toCursor.incTo(VM.objectModel.getObjectEndAddress(current));
} else {
MarkCompactSpace.setForwardingPointer(current, target);
toCursor.inc(size);
}
}
}
fromCursor.advanceToNextForwardableRegion(space);
}
}
use of org.vmmagic.unboxed.ObjectReference in project JikesRVM by JikesRVM.
the class StackFrame method getInternal.
/**
* Read a value from a stack frame slot. If the slot contains an object
* reference, this may involve reading the shadow stack and updating
* the 'cooked' copy from it.
* @param slot
* @return
*/
private Value getInternal(int slot) {
Value value = values[slot];
if (value instanceof ObjectValue) {
ObjectReference shadowValue = env.getReferenceStackSlot(slotAddress(slot));
if (!shadowValue.equals(value.getObjectValue())) {
Clock.stop();
Trace.trace(ROOTS, "Updating %s from shadow stack, slot=%s, stack=%s, shadow=%s", method.getSlotName(slot), slotAddress(slot), value, shadowValue);
Clock.start();
value = values[slot] = new ObjectValue(shadowValue);
}
}
return value;
}
use of org.vmmagic.unboxed.ObjectReference in project JikesRVM by JikesRVM.
the class StackFrame method computeRoots.
/**
* GC support: trace this stack frame.
* @param trace The MMTk trace object to receive the roots
* @return The number of roots found
*/
public int computeRoots(TraceLocal trace) {
Clock.stop();
Trace.trace(Item.ROOTS, "--- Computing roots, stack frame %s (%s) ---", method.getName(), base);
Clock.start();
int rootCount = 0;
for (Address root : getRootAddresses()) {
ObjectReference obj = root.loadObjectReference();
if (!obj.isNull()) {
Clock.stop();
Sanity.assertValid(obj);
if (Trace.isEnabled(Item.ROOTS)) {
Trace.trace(Item.ROOTS, "Tracing root %s->%s", root, ObjectModel.getString(obj));
}
Clock.start();
trace.reportDelayedRootEdge(root);
rootCount++;
}
}
Clock.stop();
Trace.trace(Item.REFERENCES, "Discovering references");
Clock.start();
for (ReferenceValue reference : getReferences()) {
ReferenceProcessor.discover(reference);
}
return rootCount;
}
use of org.vmmagic.unboxed.ObjectReference in project JikesRVM by JikesRVM.
the class GcSanity method assertSanity.
/**
* Assert that the heap state is sane (immediately after a collection)
*/
public void assertSanity() {
Trace.trace(Item.SANITY, "Heap size by ID before: %d, after: %d", before.sizeById(), after.sizeById());
Trace.trace(Item.SANITY, "Heap size by Addr before: %d, after: %d", before.sizeByAddress(), after.sizeByAddress());
/*
* Assert that there are no duplicated objects, ie objects with the same
* object ID in more than one place.
*/
if (after.getDuplicates().size() > 0) {
int errors = 0;
for (Set<HeapEntry> aliasSet : after.getDuplicates()) {
HeapEntry first = aliasSet.iterator().next();
boolean firstDup = true;
System.err.printf("### Object %s is duplicated in the heap: ", first.getId());
for (HeapEntry entry : aliasSet) {
if (firstDup) {
firstDup = false;
} else {
System.err.printf(", ");
}
ObjectReference object = entry.getObject();
System.err.printf("%s/%s", object, Space.getSpaceForObject(object).getName());
}
System.err.printf("%n");
if (errors++ > ERROR_LIMIT) {
System.err.printf("[SANITY] Error limit reached...%n");
break;
}
}
throw new AssertionError("Duplicate objects found in heap");
}
/*
* Assert that collection preserved the number of objects in the heap
*/
if (before.sizeById() != after.sizeById()) {
System.err.printf("[SANITY] ERROR: Live object population has changed, before : %d objects, after: %d objects%n", before.sizeById(), after.sizeById());
dumpDifferencesAndDie();
}
assert before.sizeByAddress() == after.sizeByAddress() : "before : " + before.sizeByAddress() + " objects, after: " + after.sizeByAddress() + " objects";
/*
* Assert that the collection preserved the live set
*/
if (!before.getLive().equals(after.getLive())) {
System.err.printf("[SANITY] ERROR: Live object set has changed%n");
dumpDifferencesAndDie();
}
if (Trace.isEnabled(Item.SANITY)) {
printSpaceStats("before", before);
printSpaceStats("after", after);
}
}
use of org.vmmagic.unboxed.ObjectReference in project JikesRVM by JikesRVM.
the class ObjectTable method alloc.
/**
* Register allocation of an object
* @param region The start of the allocated bytes
* @param size The size of the region
*/
public void alloc(Address region, int size) {
// Can't hold a lock while doing anything that might block
// in the deterministic scheduler. Therefore we don't lock,
// and rely on the fact that objects is a concurrent data structure
ObjectReference object = VM.objectModel.getObjectFromStartAddress(region);
objects.put(object, new Entry(object, region, size));
}
Aggregations