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.stickyms;
014    
015    import org.mmtk.plan.*;
016    import org.mmtk.plan.marksweep.MSCollector;
017    import org.mmtk.plan.marksweep.MSTraceLocal;
018    import org.mmtk.utility.deque.ObjectReferenceDeque;
019    import org.mmtk.vm.VM;
020    
021    import org.vmmagic.pragma.*;
022    
023    /**
024     * This class implements <i>per-collector thread</i> behavior
025     * and state for the <i>StickMS</i> plan, which implements a generational
026     * sticky mark bits mark-sweep collector.<p>
027     *
028     * Specifically, this class defines <i>StickyMS</i> collection behavior
029     * (through <code>trace</code> and the <code>collectionPhase</code>
030     * method).<p>
031     *
032     * @see StickyMS for an overview of the algorithm.<p>
033     * @see StickyMSMutator
034     * @see StopTheWorldCollector
035     * @see CollectorContext
036     * @see Phase
037     */
038    @Uninterruptible
039    public class StickyMSCollector extends MSCollector {
040    
041      /****************************************************************************
042       * Instance fields
043       */
044      private StickyMSNurseryTraceLocal nurseryTrace;
045    
046      /****************************************************************************
047       * Initialization
048       */
049    
050      /**
051       * Constructor
052       */
053      public StickyMSCollector() {
054        ObjectReferenceDeque modBuffer = new ObjectReferenceDeque("mod buffer", global().modPool);
055        fullTrace = new  MSTraceLocal(global().msTrace, modBuffer);
056        nurseryTrace = new StickyMSNurseryTraceLocal(global().msTrace, modBuffer);
057      }
058    
059      /****************************************************************************
060       *
061       * Collection
062       */
063    
064      /**
065       * Perform a per-collector collection phase.
066       *
067       * @param phaseId The collection phase to perform
068       * @param primary Perform any single-threaded activities using this thread.
069       */
070      @Inline
071      public final void collectionPhase(short phaseId, boolean primary) {
072        boolean collectWholeHeap = global().collectWholeHeap;
073    
074        if (phaseId == StickyMS.PREPARE) {
075          currentTrace = collectWholeHeap ? (TraceLocal) fullTrace : (TraceLocal) nurseryTrace;
076          global().modPool.prepareNonBlocking();  /* always do this */
077        }
078    
079        if (!collectWholeHeap) {
080          if (phaseId == StickyMS.PREPARE) {
081            nurseryTrace.prepare();
082            return;
083          }
084    
085          if (phaseId == StickyMS.ROOTS) {
086            VM.scanning.computeStaticRoots(currentTrace);
087            VM.scanning.computeGlobalRoots(currentTrace);
088            return;
089          }
090    
091          if (phaseId == StickyMS.CLOSURE) {
092            nurseryTrace.completeTrace();
093            return;
094          }
095    
096          if (phaseId == StickyMS.RELEASE) {
097            nurseryTrace.release();
098            global().modPool.reset();
099            return;
100          }
101        }
102    
103        super.collectionPhase(phaseId, primary);
104      }
105    
106      /****************************************************************************
107       *
108       * Miscellaneous
109       */
110    
111      /** @return The active global plan as an <code>MS</code> instance. */
112      @Inline
113      private static StickyMS global() {
114        return (StickyMS) VM.activePlan.global();
115      }
116    }