001 /*
002 * This file is part of the Jikes RVM project (http://jikesrvm.org).
003 *
004 * This file is licensed to You under the Eclipse Public License (EPL);
005 * You may not use this file except in compliance with the License. You
006 * may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/eclipse-1.0.php
009 *
010 * See the COPYRIGHT.txt file distributed with this work for information
011 * regarding copyright ownership.
012 */
013 package org.mmtk.plan.generational;
014
015 import org.mmtk.plan.*;
016 import org.mmtk.policy.LargeObjectLocal;
017 import org.mmtk.utility.deque.*;
018
019 import org.mmtk.vm.VM;
020
021 import org.vmmagic.pragma.*;
022
023 /**
024 * This abstract class implements <i>per-collector thread</i>
025 * behavior and state for <i>generational copying collectors</i>.<p>
026 *
027 * Specifically, this class defines nursery collection behavior (through
028 * <code>nurseryTrace</code> and the <code>collectionPhase</code> method).
029 * Per-collector thread remset consumers are instantiated here (used by
030 * sub-classes).
031 *
032 * @see Gen
033 * @see GenMutator
034 * @see StopTheWorldCollector
035 * @see CollectorContext
036 */
037 @Uninterruptible public abstract class GenCollector extends StopTheWorldCollector {
038
039 /*****************************************************************************
040 * Instance fields
041 */
042
043 protected final GenNurseryTraceLocal nurseryTrace;
044
045 protected final LargeObjectLocal los;
046
047 // remembered set consumers
048 protected final ObjectReferenceDeque modbuf;
049 protected final AddressDeque remset;
050 protected final AddressPairDeque arrayRemset;
051
052 /****************************************************************************
053 *
054 * Initialization
055 */
056
057 /**
058 * Constructor
059 *
060 * Note that the collector is a consumer of remsets, while the
061 * mutator is a producer. The <code>GenMutator</code> class is
062 * responsible for construction of the WriteBuffer (producer).
063 * @see GenMutator
064 */
065 public GenCollector() {
066 los = new LargeObjectLocal(Plan.loSpace);
067 arrayRemset = new AddressPairDeque(global().arrayRemsetPool);
068 remset = new AddressDeque("remset", global().remsetPool);
069 modbuf = new ObjectReferenceDeque("modbuf", global().modbufPool);
070 nurseryTrace = new GenNurseryTraceLocal(global().nurseryTrace, this);
071 }
072
073 /****************************************************************************
074 *
075 * Collection
076 */
077
078 /**
079 * Perform a per-collector collection phase.
080 *
081 * @param phaseId The collection phase to perform
082 * @param primary Use this thread for single-threaded local activities.
083 */
084 @NoInline
085 public void collectionPhase(short phaseId, boolean primary) {
086
087 if (phaseId == Gen.PREPARE) {
088 los.prepare(true);
089 global().arrayRemsetPool.prepareNonBlocking();
090 global().remsetPool.prepareNonBlocking();
091 global().modbufPool.prepareNonBlocking();
092 nurseryTrace.prepare();
093 return;
094 }
095
096 if (phaseId == StopTheWorld.ROOTS) {
097 VM.scanning.computeGlobalRoots(getCurrentTrace());
098 if (!Gen.USE_NON_HEAP_OBJECT_REFERENCE_WRITE_BARRIER || global().traceFullHeap()) {
099 VM.scanning.computeStaticRoots(getCurrentTrace());
100 }
101 if (Plan.SCAN_BOOT_IMAGE && global().traceFullHeap()) {
102 VM.scanning.computeBootImageRoots(getCurrentTrace());
103 }
104 return;
105 }
106
107 if (phaseId == Gen.CLOSURE) {
108 if (!global().gcFullHeap) {
109 nurseryTrace.completeTrace();
110 }
111 return;
112 }
113
114 if (phaseId == Gen.RELEASE) {
115 los.release(true);
116 if (!global().traceFullHeap()) {
117 nurseryTrace.release();
118 global().arrayRemsetPool.reset();
119 global().remsetPool.reset();
120 global().modbufPool.reset();
121 }
122 return;
123 }
124
125 super.collectionPhase(phaseId, primary);
126 }
127
128 /****************************************************************************
129 *
130 * Miscellaneous
131 */
132
133 /** @return The active global plan as a <code>Gen</code> instance. */
134 @Inline
135 private static Gen global() {
136 return (Gen) VM.activePlan.global();
137 }
138
139 public final TraceLocal getCurrentTrace() {
140 if (global().traceFullHeap()) return getFullHeapTrace();
141 return nurseryTrace;
142 }
143
144 /** @return The trace to use when collecting the mature space */
145 public abstract TraceLocal getFullHeapTrace();
146
147 }