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.stickyms;
014
015import org.mmtk.plan.*;
016import org.mmtk.plan.marksweep.MSCollector;
017import org.mmtk.plan.marksweep.MSTraceLocal;
018import org.mmtk.utility.deque.ObjectReferenceDeque;
019import org.mmtk.vm.VM;
020
021import 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.
033 * @see StickyMSMutator
034 * @see StopTheWorldCollector
035 * @see CollectorContext
036 * @see Phase
037 */
038@Uninterruptible
039public class StickyMSCollector extends MSCollector {
040
041  /****************************************************************************
042   * Instance fields
043   */
044
045  /**
046   *
047   */
048  private final 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}