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    
045      /**
046       *
047       */
048      private StickyMSNurseryTraceLocal nurseryTrace;
049    
050      /****************************************************************************
051       * Initialization
052       */
053    
054      /**
055       * Constructor
056       */
057      public StickyMSCollector() {
058        ObjectReferenceDeque modBuffer = new ObjectReferenceDeque("mod buffer", global().modPool);
059        fullTrace = new  MSTraceLocal(global().msTrace, modBuffer);
060        nurseryTrace = new StickyMSNurseryTraceLocal(global().msTrace, modBuffer);
061      }
062    
063      /****************************************************************************
064       *
065       * Collection
066       */
067    
068      /**
069       * {@inheritDoc}
070       */
071      @Override
072      @Inline
073      public final void collectionPhase(short phaseId, boolean primary) {
074        boolean collectWholeHeap = global().collectWholeHeap;
075    
076        if (phaseId == StickyMS.PREPARE) {
077          currentTrace = collectWholeHeap ? (TraceLocal) fullTrace : (TraceLocal) nurseryTrace;
078          global().modPool.prepareNonBlocking();  /* always do this */
079        }
080    
081        if (!collectWholeHeap) {
082          if (phaseId == StickyMS.PREPARE) {
083            nurseryTrace.prepare();
084            return;
085          }
086    
087          if (phaseId == StickyMS.ROOTS) {
088            VM.scanning.computeStaticRoots(currentTrace);
089            VM.scanning.computeGlobalRoots(currentTrace);
090            return;
091          }
092    
093          if (phaseId == StickyMS.CLOSURE) {
094            nurseryTrace.completeTrace();
095            return;
096          }
097    
098          if (phaseId == StickyMS.RELEASE) {
099            nurseryTrace.release();
100            global().modPool.reset();
101            return;
102          }
103        }
104    
105        super.collectionPhase(phaseId, primary);
106      }
107    
108      /****************************************************************************
109       *
110       * Miscellaneous
111       */
112    
113      /** @return The active global plan as an <code>MS</code> instance. */
114      @Inline
115      private static StickyMS global() {
116        return (StickyMS) VM.activePlan.global();
117      }
118    }