use of org.mmtk.plan.CollectorContext in project JikesRVM by JikesRVM.
the class ObjectModel method copy.
@Override
public ObjectReference copy(ObjectReference from, int allocator) {
int oldBytes = getSize(from);
int newBytes = getCopiedSize(from);
int align = getAlignWhenCopied(from);
CollectorContext c = Scheduler.currentCollector();
allocator = c.copyCheckAllocator(from, newBytes, align, allocator);
Address toRegion = c.allocCopy(from, newBytes, align, getAlignOffsetWhenCopied(from), allocator);
ObjectReference to = toRegion.toObjectReference();
Clock.stop();
if (isWatched(from) || Trace.isEnabled(Item.COLLECT)) {
Trace.printf(Item.COLLECT, "Copying object %s from %s to %s%n", objectIdString(from), getString(from), getString(to));
}
Sanity.assertValid(from);
Sanity.getObjectTable().copy(from, to);
Clock.start();
Address fromRegion = from.toAddress();
for (int i = 0; i < oldBytes; i += MemoryConstants.BYTES_IN_INT) {
toRegion.plus(i).store(fromRegion.plus(i).loadInt());
}
int status = toRegion.loadInt(STATUS_OFFSET);
if ((status & HASHED_AND_MOVED) == HASHED) {
toRegion.store(status | HASHED_AND_MOVED, STATUS_OFFSET);
toRegion.store(getHashCode(from), Offset.fromIntZeroExtend(oldBytes));
}
c.postCopy(to, null, newBytes, allocator);
Clock.stop();
if (isWatched(from)) {
System.err.printf("WATCH: Object %d copied from %s to %s%n", getId(from), addressAndSpaceString(from), addressAndSpaceString(to));
dumpObjectHeader("after copy: ", to);
}
Clock.start();
return to;
}
use of org.mmtk.plan.CollectorContext in project JikesRVM by JikesRVM.
the class ScanBootImage method scanBootImage.
/**
**************************************************************************
*
* GC-time decoding (multi-threaded)
*/
/**
* Scan the boot image for object references. Executed by
* all GC threads in parallel, with each doing a portion of the
* boot image.
*
* @param trace The trace object to which the roots should be added
*/
@Inline
@Uninterruptible
public static void scanBootImage(TraceLocal trace) {
/* establish sentinals in map & image */
Address mapStart = BootRecord.the_boot_record.bootImageRMapStart;
Address mapEnd = BootRecord.the_boot_record.bootImageRMapEnd;
Address imageStart = BootRecord.the_boot_record.bootImageDataStart;
/* figure out striding */
CollectorContext collector = RVMThread.getCurrentThread().getCollectorContext();
int stride = collector.parallelWorkerCount() << LOG_CHUNK_BYTES;
int start = collector.parallelWorkerOrdinal() << LOG_CHUNK_BYTES;
Address cursor = mapStart.plus(start);
/* statistics */
roots = 0;
refs = 0;
/* process chunks in parallel till done */
while (cursor.LT(mapEnd)) {
processChunk(cursor, imageStart, mapStart, mapEnd, trace);
cursor = cursor.plus(stride);
}
/* print some debugging stats */
if (DEBUG) {
Log.write("<boot image");
Log.write(" roots: ", roots);
Log.write(" refs: ", refs);
Log.write(">");
}
}
use of org.mmtk.plan.CollectorContext in project JikesRVM by JikesRVM.
the class ScanStatics method scanStatics.
/**
* Scan static variables (JTOC) for object references. Executed by
* all GC threads in parallel, with each doing a portion of the
* JTOC.
*
* @param trace the trace to use for scanning
*/
@Inline
@Uninterruptible
public static void scanStatics(TraceLocal trace) {
// The address of the statics table
// equivalent to Statics.getSlots()
final Address slots = Magic.getJTOC();
// This thread as a collector
final CollectorContext cc = RVMThread.getCurrentThread().getCollectorContext();
// The number of collector threads
final int numberOfCollectors = cc.parallelWorkerCount();
// The number of static references
final int numberOfReferences = Statics.getNumberOfReferenceSlots();
// The size to give each thread
final int chunkSize = (numberOfReferences / numberOfCollectors) & chunkSizeMask;
// The number of this collector thread (1...n)
final int threadOrdinal = cc.parallelWorkerOrdinal();
// Start and end of statics region to be processed
final int start = (threadOrdinal == 0) ? refSlotSize : threadOrdinal * chunkSize;
final int end = (threadOrdinal + 1 == numberOfCollectors) ? numberOfReferences : (threadOrdinal + 1) * chunkSize;
// Process region
for (int slot = start; slot < end; slot += refSlotSize) {
Offset slotOffset = Offset.fromIntSignExtend(slot << LOG_BYTES_IN_INT);
if (ScanThread.VALIDATE_REFS)
checkReference(slots.plus(slotOffset), slot);
trace.processRootEdge(slots.plus(slotOffset), true);
}
}
use of org.mmtk.plan.CollectorContext in project JikesRVM by JikesRVM.
the class Scanning method computeGlobalRoots.
/**
* Computes global roots. This method establishes all such roots for
* collection and places them in the root locations queue. This method
* should not have side effects (such as copying or forwarding of
* objects). There are a number of important preconditions:
*
* <ul>
* <li> The <code>threadCounter</code> must be reset so that load
* balancing parallel GC can share the work of scanning threads.
* </ul>
*
* @param trace The trace to use for computing roots.
*/
@Override
public void computeGlobalRoots(TraceLocal trace) {
/* scan JNI functions */
CollectorContext cc = RVMThread.getCurrentThread().getCollectorContext();
Address jniFunctions = Magic.objectAsAddress(JNIEnvironment.JNIFunctions);
int threads = cc.parallelWorkerCount();
int size = JNIEnvironment.JNIFunctions.length();
int chunkSize = size / threads;
int start = cc.parallelWorkerOrdinal() * chunkSize;
int end = (cc.parallelWorkerOrdinal() + 1 == threads) ? size : threads * chunkSize;
for (int i = start; i < end; i++) {
Address functionAddressSlot = jniFunctions.plus(i << LOG_BYTES_IN_ADDRESS);
if (JNIGenericHelpers.implementedInJava(i)) {
trace.processRootEdge(functionAddressSlot, true);
} else {
// Function implemented as a C function, must not be
// scanned.
}
}
Address linkageTriplets = Magic.objectAsAddress(JNIEnvironment.linkageTriplets);
if (!linkageTriplets.isZero()) {
for (int i = start; i < end; i++) {
trace.processRootEdge(linkageTriplets.plus(i << LOG_BYTES_IN_ADDRESS), true);
}
}
/* scan jni global refs */
Address jniGlobalRefs = Magic.objectAsAddress(JNIGlobalRefTable.JNIGlobalRefs);
size = JNIGlobalRefTable.JNIGlobalRefs.length();
chunkSize = size / threads;
start = cc.parallelWorkerOrdinal() * chunkSize;
end = (cc.parallelWorkerOrdinal() + 1 == threads) ? size : threads * chunkSize;
for (int i = start; i < end; i++) {
trace.processRootEdge(jniGlobalRefs.plus(i << LOG_BYTES_IN_ADDRESS), true);
}
}
use of org.mmtk.plan.CollectorContext in project JikesRVM by JikesRVM.
the class ObjectReferenceDequeTest method testnHeads.
@Test
public void testnHeads() {
final int NDEQUES = 4;
// Page and a half
final int ENTRIES = 1500;
runTest(new CollectorContext() {
@Override
public void run() {
SharedDeque shared = new SharedDeque("shared", Plan.metaDataSpace, 1);
ObjectReferenceDeque[] deques = new ObjectReferenceDeque[NDEQUES];
shared.prepareNonBlocking();
for (int d = 0; d < NDEQUES; d++) {
deques[d] = new ObjectReferenceDeque("deque+d", shared);
for (int i = 0; i < ENTRIES; i++) {
deques[d].push(o(d * 100000 + i + 1));
}
deques[d].flushLocal();
}
for (int i = 0; i < ENTRIES * NDEQUES; i++) {
Assert.assertFalse(deques[0].pop().isNull());
}
for (int d = 0; d < NDEQUES; d++) {
Assert.assertTrue(deques[d].isEmpty());
}
shared.reset();
}
});
}
Aggregations