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 */
013package org.mmtk.plan.stickyimmix;
014
015import org.mmtk.plan.*;
016import org.mmtk.plan.immix.Immix;
017import org.mmtk.plan.immix.ImmixCollector;
018import org.mmtk.plan.immix.ImmixDefragTraceLocal;
019import org.mmtk.plan.immix.ImmixTraceLocal;
020import org.mmtk.policy.immix.CollectorLocal;
021import org.mmtk.utility.alloc.ImmixAllocator;
022import org.mmtk.utility.deque.ObjectReferenceDeque;
023import org.mmtk.vm.VM;
024
025import 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.
037 * @see StickyImmixMutator
038 * @see StopTheWorldCollector
039 * @see CollectorContext
040 * @see Phase
041 */
042@Uninterruptible
043public class StickyImmixCollector extends ImmixCollector {
044
045  /****************************************************************************
046   * Instance fields
047   */
048
049  /**
050   *
051   */
052  private final 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}