| /* |
| * This file is part of the Jikes RVM project (http://jikesrvm.org). |
| * |
| * This file is licensed to You under the Eclipse Public License (EPL); |
| * You may not use this file except in compliance with the License. You |
| * may obtain a copy of the License at |
| * |
| * http://www.opensource.org/licenses/eclipse-1.0.php |
| * |
| * See the COPYRIGHT.txt file distributed with this work for information |
| * regarding copyright ownership. |
| */ |
| package org.mmtk.plan.generational; |
| |
| import org.mmtk.plan.*; |
| import org.mmtk.policy.LargeObjectLocal; |
| import org.mmtk.utility.deque.*; |
| |
| import org.mmtk.vm.VM; |
| |
| import org.vmmagic.pragma.*; |
| |
| /** |
| * This abstract class implements <i>per-collector thread</i> |
| * behavior and state for <i>generational copying collectors</i>.<p> |
| * |
| * Specifically, this class defines nursery collection behavior (through |
| * <code>nurseryTrace</code> and the <code>collectionPhase</code> method). |
| * Per-collector thread remset consumers are instantiated here (used by |
| * sub-classes). |
| * |
| * @see Gen |
| * @see GenMutator |
| * @see StopTheWorldCollector |
| * @see CollectorContext |
| */ |
| @Uninterruptible public abstract class GenCollector extends StopTheWorldCollector { |
| |
| /***************************************************************************** |
| * Instance fields |
| */ |
| |
| protected final GenNurseryTraceLocal nurseryTrace; |
| |
| protected final LargeObjectLocal los; |
| |
| // remembered set consumers |
| protected final ObjectReferenceDeque modbuf; |
| protected final AddressDeque remset; |
| protected final AddressPairDeque arrayRemset; |
| |
| /**************************************************************************** |
| * |
| * Initialization |
| */ |
| |
| /** |
| * Constructor |
| * |
| * Note that the collector is a consumer of remsets, while the |
| * mutator is a producer. The <code>GenMutator</code> class is |
| * responsible for construction of the WriteBuffer (producer). |
| * @see GenMutator |
| */ |
| public GenCollector() { |
| los = new LargeObjectLocal(Plan.loSpace); |
| arrayRemset = new AddressPairDeque(global().arrayRemsetPool); |
| remset = new AddressDeque("remset", global().remsetPool); |
| modbuf = new ObjectReferenceDeque("modbuf", global().modbufPool); |
| nurseryTrace = new GenNurseryTraceLocal(global().nurseryTrace, this); |
| } |
| |
| /**************************************************************************** |
| * |
| * Collection |
| */ |
| |
| /** |
| * Perform a per-collector collection phase. |
| * |
| * @param phaseId The collection phase to perform |
| * @param primary Use this thread for single-threaded local activities. |
| */ |
| @NoInline |
| public void collectionPhase(short phaseId, boolean primary) { |
| |
| if (phaseId == Gen.PREPARE) { |
| los.prepare(true); |
| global().arrayRemsetPool.prepareNonBlocking(); |
| global().remsetPool.prepareNonBlocking(); |
| global().modbufPool.prepareNonBlocking(); |
| nurseryTrace.prepare(); |
| return; |
| } |
| |
| if (phaseId == StopTheWorld.ROOTS) { |
| VM.scanning.computeGlobalRoots(getCurrentTrace()); |
| if (!Gen.USE_NON_HEAP_OBJECT_REFERENCE_WRITE_BARRIER || global().traceFullHeap()) { |
| VM.scanning.computeStaticRoots(getCurrentTrace()); |
| } |
| if (Plan.SCAN_BOOT_IMAGE && global().traceFullHeap()) { |
| VM.scanning.computeBootImageRoots(getCurrentTrace()); |
| } |
| return; |
| } |
| |
| if (phaseId == Gen.CLOSURE) { |
| if (!global().gcFullHeap) { |
| nurseryTrace.completeTrace(); |
| } |
| return; |
| } |
| |
| if (phaseId == Gen.RELEASE) { |
| los.release(true); |
| if (!global().traceFullHeap()) { |
| nurseryTrace.release(); |
| global().arrayRemsetPool.reset(); |
| global().remsetPool.reset(); |
| global().modbufPool.reset(); |
| } |
| return; |
| } |
| |
| super.collectionPhase(phaseId, primary); |
| } |
| |
| /**************************************************************************** |
| * |
| * Miscellaneous |
| */ |
| |
| /** @return The active global plan as a <code>Gen</code> instance. */ |
| @Inline |
| private static Gen global() { |
| return (Gen) VM.activePlan.global(); |
| } |
| |
| public final TraceLocal getCurrentTrace() { |
| if (global().traceFullHeap()) return getFullHeapTrace(); |
| return nurseryTrace; |
| } |
| |
| /** @return The trace to use when collecting the mature space */ |
| public abstract TraceLocal getFullHeapTrace(); |
| |
| } |