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.marksweep;
014
015import org.mmtk.plan.Plan;
016import org.mmtk.plan.TraceLocal;
017import org.mmtk.plan.generational.*;
018import org.mmtk.policy.MarkSweepLocal;
019import org.mmtk.policy.Space;
020import org.mmtk.utility.HeaderByte;
021import org.mmtk.utility.alloc.Allocator;
022import org.mmtk.utility.statistics.Stats;
023
024import org.mmtk.vm.VM;
025
026import org.vmmagic.pragma.*;
027import org.vmmagic.unboxed.*;
028
029/**
030 * This class implements <i>per-collector thread</i> behavior and state for
031 * the <code>GenMS</code> two-generational copying collector.<p>
032 *
033 * Specifically, this class defines semantics specific to the collection of
034 * the mature generation (<code>GenCollector</code> defines nursery semantics).
035 * In particular the mature space allocator is defined (for collection-time
036 * allocation into the mature space), and the mature space per-collector thread
037 * collection time semantics are defined.<p>
038 *
039 * @see GenMS for a description of the <code>GenMS</code> algorithm.
040 *
041 * @see GenMS
042 * @see GenMSMutator
043 * @see GenCollector
044 * @see org.mmtk.plan.StopTheWorldCollector
045 * @see org.mmtk.plan.CollectorContext
046 */
047@Uninterruptible
048public class GenMSCollector extends GenCollector {
049
050  /*****************************************************************************
051   *
052   * Instance fields
053   */
054
055  /** The allocator for the mature space */
056  private final MarkSweepLocal mature;
057  private final GenMSMatureTraceLocal matureTrace;
058
059  /**
060   * Constructor
061   */
062  public GenMSCollector() {
063    mature = new MarkSweepLocal(GenMS.msSpace);
064    matureTrace = new GenMSMatureTraceLocal(global().matureTrace, this);
065  }
066
067  /****************************************************************************
068   * Collection-time allocation
069   */
070
071  /**
072   * {@inheritDoc}
073   */
074  @Inline
075  @Override
076  public final Address allocCopy(ObjectReference original, int bytes,
077                                 int align, int offset, int allocator) {
078    if (Stats.GATHER_MARK_CONS_STATS) {
079      if (Space.isInSpace(GenMS.NURSERY, original)) GenMS.nurseryMark.inc(bytes);
080    }
081
082    if (allocator == Plan.ALLOC_LOS) {
083      if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(Allocator.getMaximumAlignedSize(bytes, align) > Plan.MAX_NON_LOS_COPY_BYTES);
084      return los.alloc(bytes, align, offset);
085    } else {
086      if (VM.VERIFY_ASSERTIONS) {
087        VM.assertions._assert(bytes <= Plan.MAX_NON_LOS_COPY_BYTES);
088        VM.assertions._assert(allocator == GenMS.ALLOC_MATURE_MINORGC ||
089            allocator == GenMS.ALLOC_MATURE_MAJORGC);
090      }
091      return mature.alloc(bytes, align, offset);
092    }
093  }
094
095  @Inline
096  @Override
097  public final void postCopy(ObjectReference object, ObjectReference typeRef,
098                             int bytes, int allocator) {
099    if (allocator == Plan.ALLOC_LOS)
100      Plan.loSpace.initializeHeader(object, false);
101    else
102      GenMS.msSpace.postCopy(object, allocator == GenMS.ALLOC_MATURE_MAJORGC);
103    if (Gen.USE_OBJECT_BARRIER)
104      HeaderByte.markAsUnlogged(object);
105  }
106
107  /*****************************************************************************
108   *
109   * Collection
110   */
111
112  /**
113   * {@inheritDoc}
114   */
115  @Override
116  @NoInline
117  public void collectionPhase(short phaseId, boolean primary) {
118    if (global().traceFullHeap()) {
119      if (phaseId == GenMS.PREPARE) {
120        super.collectionPhase(phaseId, primary);
121        matureTrace.prepare();
122        if (global().gcFullHeap) mature.prepare();
123        return;
124      }
125
126      if (phaseId == GenMS.CLOSURE) {
127        matureTrace.completeTrace();
128        return;
129      }
130
131      if (phaseId == GenMS.RELEASE) {
132        matureTrace.release();
133        if (global().gcFullHeap) {
134          mature.release();
135        }
136        super.collectionPhase(phaseId, primary);
137        return;
138      }
139    }
140
141    super.collectionPhase(phaseId, primary);
142  }
143
144  @Override
145  @Inline
146  public final TraceLocal getFullHeapTrace() {
147    return matureTrace;
148  }
149
150  /****************************************************************************
151   *
152   * Miscellaneous
153   */
154
155  /** @return The active global plan as a <code>GenMS</code> instance. */
156  @Inline
157  private static GenMS global() {
158    return (GenMS) VM.activePlan.global();
159  }
160}