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