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