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     */
013    package org.mmtk.plan.generational.marksweep;
014    
015    import org.mmtk.plan.Plan;
016    import org.mmtk.plan.TraceLocal;
017    import org.mmtk.plan.generational.*;
018    import org.mmtk.policy.MarkSweepLocal;
019    import org.mmtk.policy.Space;
020    import org.mmtk.utility.HeaderByte;
021    import org.mmtk.utility.alloc.Allocator;
022    import org.mmtk.utility.statistics.Stats;
023    
024    import org.mmtk.vm.VM;
025    
026    import org.vmmagic.pragma.*;
027    import 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
048    public 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    }