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.copyms;
014    
015    import org.mmtk.plan.*;
016    import org.mmtk.policy.LargeObjectLocal;
017    import org.mmtk.policy.MarkSweepLocal;
018    import org.mmtk.utility.alloc.Allocator;
019    import org.mmtk.vm.VM;
020    
021    import org.vmmagic.pragma.*;
022    import 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
039    public class CopyMSCollector extends StopTheWorldCollector {
040    
041      /****************************************************************************
042       * Instance fields
043       */
044    
045      /**
046       *
047       */
048      private MarkSweepLocal mature;
049      private 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() { return trace; }
148    
149    }