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.copyms;
014
015import org.mmtk.plan.*;
016import org.mmtk.policy.LargeObjectLocal;
017import org.mmtk.policy.MarkSweepLocal;
018import org.mmtk.utility.alloc.Allocator;
019import org.mmtk.vm.VM;
020
021import org.vmmagic.pragma.*;
022import org.vmmagic.unboxed.*;
023
024/**
025 * This class implements <i>per-collector thread</i> behavior
026 * and state for the <i>CopyMS</i> plan.<p>
027 *
028 * Specifically, this class defines <i>CopyMS</i>
029 * collection behavior (through <code>trace</code> and
030 * the <code>collectionPhase</code> method), and
031 * collection-time allocation into the mature space.
032 *
033 * @see CopyMS
034 * @see CopyMSMutator
035 * @see StopTheWorldCollector
036 * @see CollectorContext
037 */
038@Uninterruptible
039public class CopyMSCollector extends StopTheWorldCollector {
040
041  /****************************************************************************
042   * Instance fields
043   */
044
045  /**
046   *
047   */
048  private final MarkSweepLocal mature;
049  private final CopyMSTraceLocal trace;
050
051  protected final LargeObjectLocal los;
052
053  /****************************************************************************
054   *
055   * Initialization
056   */
057
058  /**
059   * Create a new (local) instance.
060   */
061  public CopyMSCollector() {
062    los = new LargeObjectLocal(Plan.loSpace);
063    mature = new MarkSweepLocal(CopyMS.msSpace);
064    trace = new CopyMSTraceLocal(global().trace);
065 }
066
067  /****************************************************************************
068   *
069   * Collection-time allocation
070   */
071
072  /**
073   * {@inheritDoc}
074   */
075  @Override
076  @Inline
077  public final Address allocCopy(ObjectReference original, int bytes,
078      int align, int offset, int allocator) {
079    if (allocator == Plan.ALLOC_LOS) {
080      if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(Allocator.getMaximumAlignedSize(bytes, align) > Plan.MAX_NON_LOS_COPY_BYTES);
081      return los.alloc(bytes, align, offset);
082    } else {
083      if (VM.VERIFY_ASSERTIONS) {
084        VM.assertions._assert(bytes <= Plan.MAX_NON_LOS_COPY_BYTES);
085        VM.assertions._assert(allocator == CopyMS.ALLOC_MS);
086      }
087      return mature.alloc(bytes, align, offset);
088    }
089  }
090
091  @Override
092  @Inline
093  public final void postCopy(ObjectReference object, ObjectReference typeRef,
094      int bytes, int allocator) {
095    if (allocator == Plan.ALLOC_LOS)
096      Plan.loSpace.initializeHeader(object, false);
097    else
098      CopyMS.msSpace.postCopy(object, true);
099  }
100
101  /****************************************************************************
102   *
103   * Collection
104   */
105
106  /**
107   * {@inheritDoc}
108   */
109  @Override
110  @Inline
111  public final void collectionPhase(short phaseId, boolean primary) {
112    if (phaseId == CopyMS.PREPARE) {
113      super.collectionPhase(phaseId, primary);
114      mature.prepare();
115      trace.prepare();
116      return;
117    }
118
119    if (phaseId == CopyMS.CLOSURE) {
120      trace.completeTrace();
121      return;
122    }
123
124    if (phaseId == CopyMS.RELEASE) {
125      mature.release();
126      trace.release();
127      super.collectionPhase(phaseId, primary);
128      return;
129    }
130
131    super.collectionPhase(phaseId, primary);
132  }
133
134  /****************************************************************************
135   *
136   * Miscellaneous
137   */
138
139  /** @return the active global plan as an <code>MS</code> instance. */
140  @Inline
141  private static CopyMS global() {
142    return (CopyMS) VM.activePlan.global();
143  }
144
145  /** @return The current trace instance. */
146  @Override
147  public final TraceLocal getCurrentTrace() {
148    return trace;
149  }
150
151}