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.semispace;
014    
015    import org.mmtk.plan.*;
016    import org.mmtk.policy.CopyLocal;
017    import org.mmtk.policy.LargeObjectLocal;
018    import org.mmtk.policy.Space;
019    import org.mmtk.utility.ForwardingWord;
020    import org.mmtk.vm.VM;
021    
022    import org.vmmagic.unboxed.*;
023    import org.vmmagic.pragma.*;
024    
025    /**
026     * This class implements <i>per-collector thread</i> behavior
027     * and state for the <i>SS</i> plan, which implements a full-heap
028     * semi-space collector.<p>
029     *
030     * Specifically, this class defines <i>SS</i> collection behavior
031     * (through <code>trace</code> and the <code>collectionPhase</code>
032     * method), and collection-time allocation (copying of objects).<p>
033     *
034     * See {@link SS} for an overview of the semi-space algorithm.<p>
035     *
036     * @see SS
037     * @see SSMutator
038     * @see StopTheWorldCollector
039     * @see CollectorContext
040     */
041    @Uninterruptible
042    public class SSCollector extends StopTheWorldCollector {
043    
044      /****************************************************************************
045       * Instance fields
046       */
047    
048      protected final SSTraceLocal trace;
049      protected final CopyLocal ss;
050      protected final LargeObjectLocal los;
051    
052      /****************************************************************************
053       *
054       * Initialization
055       */
056    
057      /**
058       * Constructor
059       */
060      public SSCollector() {
061        this(new SSTraceLocal(global().ssTrace));
062      }
063    
064      /**
065       * Constructor
066       * @param tr The trace to use
067       */
068      protected SSCollector(SSTraceLocal tr) {
069        ss = new CopyLocal();
070        los = new LargeObjectLocal(Plan.loSpace);
071        trace = tr;
072      }
073    
074      /****************************************************************************
075       *
076       * Collection-time allocation
077       */
078    
079      /**
080       * Allocate space for copying an object (this method <i>does not</i>
081       * copy the object, it only allocates space)
082       *
083       * @param original A reference to the original object
084       * @param bytes The size of the space to be allocated (in bytes)
085       * @param align The requested alignment.
086       * @param offset The alignment offset.
087       * @return The address of the first byte of the allocated region
088       */
089      @Inline
090      public Address allocCopy(ObjectReference original, int bytes,
091          int align, int offset, int allocator) {
092        if (allocator == Plan.ALLOC_LOS) {
093          if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(bytes > Plan.MAX_NON_LOS_COPY_BYTES);
094          return los.alloc(bytes, align, offset);
095        } else {
096          if (VM.VERIFY_ASSERTIONS) {
097            VM.assertions._assert(bytes <= Plan.MAX_NON_LOS_COPY_BYTES);
098            VM.assertions._assert(allocator == SS.ALLOC_SS);
099          }
100          return ss.alloc(bytes, align, offset);
101        }
102      }
103    
104      /**
105       * Perform any post-copy actions.
106       *
107       * @param object The newly allocated object
108       * @param typeRef the type reference for the instance being created
109       * @param bytes The size of the space to be allocated (in bytes)
110       */
111      @Inline
112      public void postCopy(ObjectReference object, ObjectReference typeRef,
113          int bytes, int allocator) {
114        ForwardingWord.clearForwardingBits(object);
115        if (allocator == Plan.ALLOC_LOS)
116          Plan.loSpace.initializeHeader(object, false);
117      }
118    
119      /****************************************************************************
120       *
121       * Collection
122       */
123    
124      /**
125       * Perform a per-collector collection phase.
126       *
127       * @param phaseId The collection phase to perform
128       * @param primary Perform any single-threaded activities using this thread.
129       */
130      @Inline
131      public void collectionPhase(short phaseId, boolean primary) {
132        if (phaseId == SS.PREPARE) {
133          // rebind the copy bump pointer to the appropriate semispace.
134          ss.rebind(SS.toSpace());
135          los.prepare(true);
136          super.collectionPhase(phaseId, primary);
137          return;
138        }
139    
140        if (phaseId == SS.CLOSURE) {
141          trace.completeTrace();
142          return;
143        }
144    
145        if (phaseId == SS.RELEASE) {
146          trace.release();
147          los.release(true);
148          super.collectionPhase(phaseId, primary);
149          return;
150        }
151    
152        super.collectionPhase(phaseId, primary);
153      }
154    
155    
156      /****************************************************************************
157       *
158       * Object processing and tracing
159       */
160    
161      /**
162       * Return true if the given reference is to an object that is within
163       * one of the semi-spaces.
164       *
165       * @param object The object in question
166       * @return True if the given reference is to an object that is within
167       * one of the semi-spaces.
168       */
169      public static boolean isSemiSpaceObject(ObjectReference object) {
170        return Space.isInSpace(SS.SS0, object) || Space.isInSpace(SS.SS1, object);
171      }
172    
173      /****************************************************************************
174       *
175       * Miscellaneous
176       */
177    
178      /** @return The active global plan as an <code>SS</code> instance. */
179      @Inline
180      private static SS global() {
181        return (SS) VM.activePlan.global();
182      }
183    
184      /** @return the current trace object. */
185      public TraceLocal getCurrentTrace() {
186        return trace;
187      }
188    }