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    
049      /**
050       *
051       */
052      private StickyImmixNurseryTraceLocal nurseryTrace;
053      private final ImmixAllocator nurseryCopy;
054    
055      /****************************************************************************
056       * Initialization
057       */
058    
059      /**
060       * Constructor
061       */
062      public StickyImmixCollector() {
063        ObjectReferenceDeque modBuffer = new ObjectReferenceDeque("mod buffer", global().modPool);
064        fastTrace = new ImmixTraceLocal(global().immixTrace, modBuffer);
065        defragTrace = new ImmixDefragTraceLocal(global().immixTrace, modBuffer);
066        nurseryTrace = new StickyImmixNurseryTraceLocal(global().immixTrace, modBuffer);
067        immix = new CollectorLocal(StickyImmix.immixSpace);
068        nurseryCopy = new ImmixAllocator(Immix.immixSpace, true, true);
069      }
070    
071      /****************************************************************************
072       *
073       * Collection
074       */
075    
076      /**
077       * {@inheritDoc}
078       */
079      @Override
080      @Inline
081      public final void collectionPhase(short phaseId, boolean primary) {
082        boolean collectWholeHeap = global().collectWholeHeap;
083    
084        if (phaseId == StickyImmix.PREPARE) {
085          global().modPool.prepareNonBlocking();  /* always do this */
086        }
087    
088        if (!collectWholeHeap) {
089          if (phaseId == StickyImmix.PREPARE) {
090            currentTrace = nurseryTrace;
091            immix.prepare(false);
092            nurseryTrace.prepare();
093            nurseryCopy.reset();
094            copy.reset();
095            return;
096          }
097    
098          if (phaseId == StickyImmix.ROOTS) {
099            VM.scanning.computeStaticRoots(currentTrace);
100            VM.scanning.computeGlobalRoots(currentTrace);
101            return;
102          }
103    
104          if (phaseId == StickyImmix.CLOSURE) {
105            nurseryTrace.completeTrace();
106            return;
107          }
108    
109          if (phaseId == StickyImmix.RELEASE) {
110            nurseryTrace.release();
111            immix.release(false);
112            global().modPool.reset();
113            return;
114          }
115        }
116    
117        super.collectionPhase(phaseId, primary);
118      }
119    
120      /****************************************************************************
121       *
122       * Miscellaneous
123       */
124    
125      /** @return The active global plan as an <code>StickyImmix</code> instance. */
126      private static StickyImmix global() {
127        return (StickyImmix) VM.activePlan.global();
128      }
129    }