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 /**
044 *
045 */
046 protected final GenNurseryTraceLocal nurseryTrace;
047
048 protected final LargeObjectLocal los;
049
050 // remembered set consumers
051 protected final ObjectReferenceDeque modbuf;
052 protected final AddressDeque remset;
053 protected final AddressPairDeque arrayRemset;
054
055 /****************************************************************************
056 *
057 * Initialization
058 */
059
060 /**
061 * Constructor
062 * <p>
063 * Note that the collector is a consumer of remsets, while the
064 * mutator is a producer. The <code>GenMutator</code> class is
065 * responsible for construction of the WriteBuffer (producer).
066 * @see GenMutator
067 */
068 public GenCollector() {
069 los = new LargeObjectLocal(Plan.loSpace);
070 arrayRemset = new AddressPairDeque(global().arrayRemsetPool);
071 remset = new AddressDeque("remset", global().remsetPool);
072 modbuf = new ObjectReferenceDeque("modbuf", global().modbufPool);
073 nurseryTrace = new GenNurseryTraceLocal(global().nurseryTrace, this);
074 }
075
076 /****************************************************************************
077 *
078 * Collection
079 */
080
081 /**
082 * {@inheritDoc}
083 */
084 @Override
085 @NoInline
086 public void collectionPhase(short phaseId, boolean primary) {
087
088 if (phaseId == Gen.PREPARE) {
089 los.prepare(true);
090 global().arrayRemsetPool.prepareNonBlocking();
091 global().remsetPool.prepareNonBlocking();
092 global().modbufPool.prepareNonBlocking();
093 nurseryTrace.prepare();
094 return;
095 }
096
097 if (phaseId == StopTheWorld.ROOTS) {
098 VM.scanning.computeGlobalRoots(getCurrentTrace());
099 if (!Gen.USE_NON_HEAP_OBJECT_REFERENCE_WRITE_BARRIER || global().traceFullHeap()) {
100 VM.scanning.computeStaticRoots(getCurrentTrace());
101 }
102 if (Plan.SCAN_BOOT_IMAGE && global().traceFullHeap()) {
103 VM.scanning.computeBootImageRoots(getCurrentTrace());
104 }
105 return;
106 }
107
108 if (phaseId == Gen.CLOSURE) {
109 if (!global().gcFullHeap) {
110 nurseryTrace.completeTrace();
111 }
112 return;
113 }
114
115 if (phaseId == Gen.RELEASE) {
116 los.release(true);
117 if (!global().traceFullHeap()) {
118 nurseryTrace.release();
119 global().arrayRemsetPool.reset();
120 global().remsetPool.reset();
121 global().modbufPool.reset();
122 }
123 return;
124 }
125
126 super.collectionPhase(phaseId, primary);
127 }
128
129 /****************************************************************************
130 *
131 * Miscellaneous
132 */
133
134 /** @return The active global plan as a <code>Gen</code> instance. */
135 @Inline
136 private static Gen global() {
137 return (Gen) VM.activePlan.global();
138 }
139
140 @Override
141 public final TraceLocal getCurrentTrace() {
142 if (global().traceFullHeap()) return getFullHeapTrace();
143 return nurseryTrace;
144 }
145
146 /** @return The trace to use when collecting the mature space */
147 public abstract TraceLocal getFullHeapTrace();
148
149 }