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;
014
015 import org.mmtk.utility.Log;
016 import org.mmtk.utility.options.Options;
017 import org.mmtk.utility.sanitychecker.SanityCheckerLocal;
018
019 import org.mmtk.vm.VM;
020
021 import org.vmmagic.pragma.*;
022
023 /**
024 * This class (and its sub-classes) implement <i>per-collector thread</i>
025 * behavior and state.<p>
026 *
027 * MMTk assumes that the VM instantiates instances of CollectorContext
028 * in thread local storage (TLS) for each thread participating in
029 * collection. Accesses to this state are therefore assumed to be
030 * low-cost during mutator time.<p>
031 *
032 * @see CollectorContext
033 */
034 @Uninterruptible
035 public abstract class SimpleCollector extends ParallelCollector {
036
037 /****************************************************************************
038 * Instance fields
039 */
040
041 /** Used for sanity checking. */
042 protected final SanityCheckerLocal sanityLocal = new SanityCheckerLocal();
043
044 /****************************************************************************
045 *
046 * Collection
047 */
048
049 /**
050 * {@inheritDoc}
051 */
052 @Override
053 @Inline
054 public void collectionPhase(short phaseId, boolean primary) {
055 if (phaseId == Simple.PREPARE) {
056 // Nothing to do
057 return;
058 }
059
060 if (phaseId == Simple.STACK_ROOTS) {
061 VM.scanning.computeThreadRoots(getCurrentTrace());
062 return;
063 }
064
065 if (phaseId == Simple.ROOTS) {
066 VM.scanning.computeGlobalRoots(getCurrentTrace());
067 VM.scanning.computeStaticRoots(getCurrentTrace());
068 if (Plan.SCAN_BOOT_IMAGE) {
069 VM.scanning.computeBootImageRoots(getCurrentTrace());
070 }
071 return;
072 }
073
074 if (phaseId == Simple.SOFT_REFS) {
075 if (primary) {
076 if (Options.noReferenceTypes.getValue())
077 VM.softReferences.clear();
078 else
079 VM.softReferences.scan(getCurrentTrace(),global().isCurrentGCNursery());
080 }
081 return;
082 }
083
084 if (phaseId == Simple.WEAK_REFS) {
085 if (primary) {
086 if (Options.noReferenceTypes.getValue())
087 VM.weakReferences.clear();
088 else
089 VM.weakReferences.scan(getCurrentTrace(),global().isCurrentGCNursery());
090 }
091 return;
092 }
093
094 if (phaseId == Simple.FINALIZABLE) {
095 if (primary) {
096 if (Options.noFinalizer.getValue())
097 VM.finalizableProcessor.clear();
098 else
099 VM.finalizableProcessor.scan(getCurrentTrace(),global().isCurrentGCNursery());
100 }
101 return;
102 }
103
104 if (phaseId == Simple.PHANTOM_REFS) {
105 if (primary) {
106 if (Options.noReferenceTypes.getValue())
107 VM.phantomReferences.clear();
108 else
109 VM.phantomReferences.scan(getCurrentTrace(),global().isCurrentGCNursery());
110 }
111 return;
112 }
113
114 if (phaseId == Simple.FORWARD_REFS) {
115 if (primary && !Options.noReferenceTypes.getValue() &&
116 VM.activePlan.constraints().needsForwardAfterLiveness()) {
117 VM.softReferences.forward(getCurrentTrace(),global().isCurrentGCNursery());
118 VM.weakReferences.forward(getCurrentTrace(),global().isCurrentGCNursery());
119 VM.phantomReferences.forward(getCurrentTrace(),global().isCurrentGCNursery());
120 }
121 return;
122 }
123
124 if (phaseId == Simple.FORWARD_FINALIZABLE) {
125 if (primary && !Options.noFinalizer.getValue() &&
126 VM.activePlan.constraints().needsForwardAfterLiveness()) {
127 VM.finalizableProcessor.forward(getCurrentTrace(),global().isCurrentGCNursery());
128 }
129 return;
130 }
131
132 if (phaseId == Simple.COMPLETE) {
133 // Nothing to do
134 return;
135 }
136
137 if (phaseId == Simple.RELEASE) {
138 // Nothing to do
139 return;
140 }
141
142 if (Options.sanityCheck.getValue() && sanityLocal.collectionPhase(phaseId, primary)) {
143 return;
144 }
145
146 Log.write("Per-collector phase "); Log.write(Phase.getName(phaseId));
147 Log.writeln(" not handled.");
148 VM.assertions.fail("Per-collector phase not handled!");
149 }
150
151 /****************************************************************************
152 *
153 * Miscellaneous.
154 */
155
156 /** @return The active global plan as a <code>Simple</code> instance. */
157 @Inline
158 private static Simple global() {
159 return (Simple) VM.activePlan.global();
160 }
161 }