/** * Process any remembered set entries. This means enumerating the mod buffer and for each entry, * marking the object as unlogged (we don't enqueue for scanning since we're doing a full heap * GC). */ protected void processRememberedSets() { if (modBuffer != null) { logMessage(5, "clearing modBuffer"); while (!modBuffer.isEmpty()) { ObjectReference src = modBuffer.pop(); Plan.markAsUnlogged(src); } } }
/** * Process GC work until either complete or workLimit units of work are completed. * * @param workLimit The maximum units of work to perform. * @return True if all work was completed within workLimit. */ @Inline public boolean incrementalTrace(int workLimit) { logMessage(4, "Continuing GC in parallel (incremental)"); logMessage(5, "processing gray objects"); int units = 0; do { while (!values.isEmpty() && units < workLimit) { ObjectReference v = values.pop(); scanObject(v); units++; } } while (!values.isEmpty() && units < workLimit); return values.isEmpty(); }
/** Finishing processing all GC work. This method iterates until all work queues are empty. */ @Inline public void completeTrace() { logMessage(4, "Processing GC in parallel"); if (!rootLocations.isEmpty()) { processRoots(); } logMessage(5, "processing gray objects"); assertMutatorRemsetsFlushed(); do { while (!values.isEmpty()) { ObjectReference v = values.pop(); scanObject(v); } processRememberedSets(); } while (!values.isEmpty()); assertMutatorRemsetsFlushed(); }
public void release() { values.reset(); rootLocations.reset(); }
/** Flush the local buffers of all deques. */ public final void flush() { values.flushLocal(); rootLocations.flushLocal(); }
/** * Add a gray object * * @param object The object to be enqueued */ @Inline public final void processNode(ObjectReference object) { values.push(object); }