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      /**
049       *
050       */
051      protected final SSTraceLocal trace;
052      protected final CopyLocal ss;
053      protected final LargeObjectLocal los;
054    
055      /****************************************************************************
056       *
057       * Initialization
058       */
059    
060      /**
061       * Constructor
062       */
063      public SSCollector() {
064        this(new SSTraceLocal(global().ssTrace));
065      }
066    
067      /**
068       * Constructor
069       * @param tr The trace to use
070       */
071      protected SSCollector(SSTraceLocal tr) {
072        ss = new CopyLocal();
073        los = new LargeObjectLocal(Plan.loSpace);
074        trace = tr;
075      }
076    
077      /****************************************************************************
078       *
079       * Collection-time allocation
080       */
081    
082      /**
083       * {@inheritDoc}
084       */
085      @Override
086      @Inline
087      public Address allocCopy(ObjectReference original, int bytes,
088          int align, int offset, int allocator) {
089        if (allocator == Plan.ALLOC_LOS) {
090          if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(bytes > Plan.MAX_NON_LOS_COPY_BYTES);
091          return los.alloc(bytes, align, offset);
092        } else {
093          if (VM.VERIFY_ASSERTIONS) {
094            VM.assertions._assert(bytes <= Plan.MAX_NON_LOS_COPY_BYTES);
095            VM.assertions._assert(allocator == SS.ALLOC_SS);
096          }
097          return ss.alloc(bytes, align, offset);
098        }
099      }
100    
101      @Override
102      @Inline
103      public void postCopy(ObjectReference object, ObjectReference typeRef,
104          int bytes, int allocator) {
105        ForwardingWord.clearForwardingBits(object);
106        if (allocator == Plan.ALLOC_LOS)
107          Plan.loSpace.initializeHeader(object, false);
108      }
109    
110      /****************************************************************************
111       *
112       * Collection
113       */
114    
115      /**
116       * {@inheritDoc}
117       */
118      @Override
119      @Inline
120      public void collectionPhase(short phaseId, boolean primary) {
121        if (phaseId == SS.PREPARE) {
122          // rebind the copy bump pointer to the appropriate semispace.
123          ss.rebind(SS.toSpace());
124          los.prepare(true);
125          super.collectionPhase(phaseId, primary);
126          return;
127        }
128    
129        if (phaseId == SS.CLOSURE) {
130          trace.completeTrace();
131          return;
132        }
133    
134        if (phaseId == SS.RELEASE) {
135          trace.release();
136          los.release(true);
137          super.collectionPhase(phaseId, primary);
138          return;
139        }
140    
141        super.collectionPhase(phaseId, primary);
142      }
143    
144    
145      /****************************************************************************
146       *
147       * Object processing and tracing
148       */
149    
150      /**
151       * Return {@code true} if the given reference is to an object that is within
152       * one of the semi-spaces.
153       *
154       * @param object The object in question
155       * @return {@code true} if the given reference is to an object that is within
156       * one of the semi-spaces.
157       */
158      public static boolean isSemiSpaceObject(ObjectReference object) {
159        return Space.isInSpace(SS.SS0, object) || Space.isInSpace(SS.SS1, object);
160      }
161    
162      /****************************************************************************
163       *
164       * Miscellaneous
165       */
166    
167      /** @return The active global plan as an <code>SS</code> instance. */
168      @Inline
169      private static SS global() {
170        return (SS) VM.activePlan.global();
171      }
172    
173      @Override
174      public TraceLocal getCurrentTrace() {
175        return trace;
176      }
177    }