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.generational;
014
015import org.mmtk.plan.*;
016import org.mmtk.policy.LargeObjectLocal;
017import org.mmtk.utility.deque.*;
018
019import org.mmtk.vm.VM;
020
021import org.vmmagic.pragma.*;
022
023/**
024 * This abstract class implements <i>per-collector thread</i>
025 * behavior and state for <i>generational copying collectors</i>.<p>
026 *
027 * Specifically, this class defines nursery collection behavior (through
028 * <code>nurseryTrace</code> and the <code>collectionPhase</code> method).
029 * Per-collector thread remset consumers are instantiated here (used by
030 * sub-classes).
031 *
032 * @see Gen
033 * @see GenMutator
034 * @see StopTheWorldCollector
035 * @see CollectorContext
036 */
037@Uninterruptible public abstract class GenCollector extends StopTheWorldCollector {
038
039  /*****************************************************************************
040   * Instance fields
041   */
042
043  /**
044   *
045   */
046  protected final GenNurseryTraceLocal nurseryTrace;
047
048  protected final LargeObjectLocal los;
049
050  // remembered set consumers
051  protected final ObjectReferenceDeque modbuf;
052  protected final AddressDeque remset;
053  protected final AddressPairDeque arrayRemset;
054
055  /****************************************************************************
056   *
057   * Initialization
058   */
059
060  /**
061   * Constructor
062   * <p>
063   * Note that the collector is a consumer of remsets, while the
064   * mutator is a producer.  The <code>GenMutator</code> class is
065   * responsible for construction of the WriteBuffer (producer).
066   * @see GenMutator
067   */
068  public GenCollector() {
069    los = new LargeObjectLocal(Plan.loSpace);
070    arrayRemset = new AddressPairDeque(global().arrayRemsetPool);
071    remset = new AddressDeque("remset", global().remsetPool);
072    modbuf = new ObjectReferenceDeque("modbuf", global().modbufPool);
073    nurseryTrace = new GenNurseryTraceLocal(global().nurseryTrace, this);
074  }
075
076  /****************************************************************************
077   *
078   * Collection
079   */
080
081  /**
082   * {@inheritDoc}
083   */
084  @Override
085  @NoInline
086  public void collectionPhase(short phaseId, boolean primary) {
087
088    if (phaseId == Gen.PREPARE) {
089      los.prepare(true);
090      global().arrayRemsetPool.prepareNonBlocking();
091      global().remsetPool.prepareNonBlocking();
092      global().modbufPool.prepareNonBlocking();
093      nurseryTrace.prepare();
094      return;
095    }
096    if (phaseId == Simple.STACK_ROOTS && !global().gcFullHeap) {
097      VM.scanning.computeNewThreadRoots(getCurrentTrace());
098      return;
099    }
100    if (phaseId == StopTheWorld.ROOTS) {
101      VM.scanning.computeGlobalRoots(getCurrentTrace());
102      if (!Gen.USE_NON_HEAP_OBJECT_REFERENCE_WRITE_BARRIER || global().traceFullHeap()) {
103        VM.scanning.computeStaticRoots(getCurrentTrace());
104      }
105      if (Plan.SCAN_BOOT_IMAGE && global().traceFullHeap()) {
106        VM.scanning.computeBootImageRoots(getCurrentTrace());
107      }
108      return;
109    }
110
111    if (phaseId == Gen.CLOSURE) {
112      if (!global().gcFullHeap) {
113        nurseryTrace.completeTrace();
114      }
115      return;
116    }
117
118    if (phaseId == Gen.RELEASE) {
119      los.release(true);
120      if (!global().traceFullHeap()) {
121        nurseryTrace.release();
122        global().arrayRemsetPool.reset();
123        global().remsetPool.reset();
124        global().modbufPool.reset();
125      }
126      return;
127    }
128
129    super.collectionPhase(phaseId, primary);
130  }
131
132  /****************************************************************************
133   *
134   * Miscellaneous
135   */
136
137  /** @return The active global plan as a <code>Gen</code> instance. */
138  @Inline
139  private static Gen global() {
140    return (Gen) VM.activePlan.global();
141  }
142
143  @Override
144  public final TraceLocal getCurrentTrace() {
145    if (global().traceFullHeap()) return getFullHeapTrace();
146    return nurseryTrace;
147  }
148
149  /** @return The trace to use when collecting the mature space */
150  public abstract TraceLocal getFullHeapTrace();
151
152}