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.policy.CopySpace;
016    import org.mmtk.policy.Space;
017    import org.mmtk.plan.*;
018    import org.mmtk.utility.heap.VMRequest;
019    
020    import org.vmmagic.pragma.*;
021    import org.vmmagic.unboxed.*;
022    
023    /**
024     * This class implements a simple semi-space collector. See the Jones
025     * & Lins GC book, section 2.2 for an overview of the basic
026     * algorithm. This implementation also includes a large object space
027     * (LOS), and an uncollected "immortal" space.<p>
028     *
029     * All plans make a clear distinction between <i>global</i> and
030     * <i>thread-local</i> activities.  Global activities must be
031     * synchronized, whereas no synchronization is required for
032     * thread-local activities.  Instances of Plan map 1:1 to "kernel
033     * threads" (aka CPUs).  Thus instance
034     * methods allow fast, unsychronized access to Plan utilities such as
035     * allocation and collection.  Each instance rests on static resources
036     * (such as memory and virtual memory resources) which are "global"
037     * and therefore "static" members of Plan.  This mapping of threads to
038     * instances is crucial to understanding the correctness and
039     * performance properties of this plan.
040     */
041    @Uninterruptible
042    public class SS extends StopTheWorld {
043    
044      /****************************************************************************
045       *
046       * Class variables
047       */
048    
049      /** {@code true} if allocating into the "higher" semispace */
050      public static boolean hi = false;
051    
052      /** One of the two semi spaces that alternate roles at each collection */
053      public static final CopySpace copySpace0 = new CopySpace("ss0", false, VMRequest.create());
054      public static final int SS0 = copySpace0.getDescriptor();
055    
056      /** One of the two semi spaces that alternate roles at each collection */
057      public static final CopySpace copySpace1 = new CopySpace("ss1", true, VMRequest.create());
058      public static final int SS1 = copySpace1.getDescriptor();
059    
060      public final Trace ssTrace;
061    
062      /****************************************************************************
063       *
064       * Initialization
065       */
066    
067      /**
068       * Class variables
069       */
070    
071      /**
072       *
073       */
074      public static final int ALLOC_SS = Plan.ALLOC_DEFAULT;
075    
076      public static final int SCAN_SS = 0;
077    
078      /**
079       * Constructor
080       */
081      public SS() {
082        ssTrace = new Trace(metaDataSpace);
083      }
084    
085      /**
086       * @return The to space for the current collection.
087       */
088      @Inline
089      public static CopySpace toSpace() {
090        return hi ? copySpace1 : copySpace0;
091      }
092    
093      /**
094       * @return The from space for the current collection.
095       */
096      @Inline
097      public static CopySpace fromSpace() {
098        return hi ? copySpace0 : copySpace1;
099      }
100    
101    
102      /****************************************************************************
103       *
104       * Collection
105       */
106    
107      /**
108       * {@inheritDoc}
109       */
110      @Override
111      @Inline
112      public void collectionPhase(short phaseId) {
113        if (phaseId == SS.PREPARE) {
114          hi = !hi; // flip the semi-spaces
115          // prepare each of the collected regions
116          copySpace0.prepare(hi);
117          copySpace1.prepare(!hi);
118          ssTrace.prepare();
119          super.collectionPhase(phaseId);
120          return;
121        }
122        if (phaseId == CLOSURE) {
123          ssTrace.prepare();
124          return;
125        }
126        if (phaseId == SS.RELEASE) {
127          // release the collected region
128          fromSpace().release();
129    
130          super.collectionPhase(phaseId);
131          return;
132        }
133    
134        super.collectionPhase(phaseId);
135      }
136    
137      /****************************************************************************
138       *
139       * Accounting
140       */
141    
142      /**
143       * Return the number of pages reserved for copying.
144       */
145      @Override
146      public final int getCollectionReserve() {
147        // we must account for the number of pages required for copying,
148        // which equals the number of semi-space pages reserved
149        return toSpace().reservedPages() + super.getCollectionReserve();
150      }
151    
152      /**
153       * Return the number of pages reserved for use given the pending
154       * allocation.  This is <i>exclusive of</i> space reserved for
155       * copying.
156       */
157      @Override
158      public int getPagesUsed() {
159        return super.getPagesUsed() + toSpace().reservedPages();
160      }
161    
162      /**
163       * Return the number of pages available for allocation, <i>assuming
164       * all future allocation is to the semi-space</i>.
165       *
166       * @return The number of pages available for allocation, <i>assuming
167       * all future allocation is to the semi-space</i>.
168       */
169      @Override
170      public final int getPagesAvail() {
171        return(super.getPagesAvail()) >> 1;
172      }
173    
174      @Override
175      public boolean willNeverMove(ObjectReference object) {
176        if (Space.isInSpace(SS0, object) || Space.isInSpace(SS1, object))
177          return false;
178        return super.willNeverMove(object);
179      }
180    
181      @Override
182      @Interruptible
183      protected void registerSpecializedMethods() {
184        TransitiveClosure.registerSpecializedScan(SCAN_SS, SSTraceLocal.class);
185        super.registerSpecializedMethods();
186      }
187    }