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.CopySpace;
017    import org.mmtk.policy.MarkSweepSpace;
018    import org.mmtk.policy.Space;
019    import org.mmtk.utility.heap.VMRequest;
020    import org.mmtk.utility.options.Options;
021    import org.mmtk.utility.sanitychecker.SanityChecker;
022    
023    import org.vmmagic.pragma.*;
024    import org.vmmagic.unboxed.ObjectReference;
025    
026    /**
027     * This class implements the global state of a full-heap collector
028     * with a copying nursery and mark-sweep mature space.  Unlike a full
029     * generational collector, there is no write barrier, no remembered set, and
030     * every collection is full-heap.<p>
031     *
032     * All plans make a clear distinction between <i>global</i> and
033     * <i>thread-local</i> activities, and divides global and local state
034     * into separate class hierarchies.  Global activities must be
035     * synchronized, whereas no synchronization is required for
036     * thread-local activities.  There is a single instance of Plan (or the
037     * appropriate sub-class), and a 1:1 mapping of PlanLocal to "kernel
038     * threads" (aka CPUs).  Thus instance
039     * methods of PlanLocal allow fast, unsychronized access to functions such as
040     * allocation and collection.<p>
041     *
042     * The global instance defines and manages static resources
043     * (such as memory and virtual memory resources).  This mapping of threads to
044     * instances is crucial to understanding the correctness and
045     * performance properties of MMTk plans.
046     */
047    @Uninterruptible
048    public class CopyMS extends StopTheWorld {
049    
050      /****************************************************************************
051       * Constants
052       */
053    
054      /****************************************************************************
055       * Class variables
056       */
057    
058      /**
059       *
060       */
061      public static final CopySpace nurserySpace = new CopySpace("nursery", false, VMRequest.create(0.15f, true));
062      public static final MarkSweepSpace msSpace = new MarkSweepSpace("ms", VMRequest.create());
063    
064      public static final int NURSERY = nurserySpace.getDescriptor();
065      public static final int MARK_SWEEP = msSpace.getDescriptor();
066    
067      public static final int ALLOC_NURSERY = ALLOC_DEFAULT;
068      public static final int ALLOC_MS = StopTheWorld.ALLOCATORS + 1;
069    
070      public static final int SCAN_COPYMS = 0;
071    
072      /****************************************************************************
073       * Instance variables
074       */
075    
076      /**
077       *
078       */
079      public final Trace trace;
080    
081      /**
082       * Constructor.
083     */
084      public CopyMS() {
085        trace = new Trace(metaDataSpace);
086      }
087    
088    
089      /*****************************************************************************
090       * Collection
091       */
092    
093      /**
094       * {@inheritDoc}
095       */
096      @Override
097      @Inline
098      public final void collectionPhase(short phaseId) {
099        if (phaseId == PREPARE) {
100          super.collectionPhase(phaseId);
101          trace.prepare();
102          msSpace.prepare(true);
103          nurserySpace.prepare(true);
104          return;
105        }
106        if (phaseId == CLOSURE) {
107          trace.prepare();
108          return;
109        }
110        if (phaseId == RELEASE) {
111          trace.release();
112          msSpace.release();
113          nurserySpace.release();
114          switchNurseryZeroingApproach(nurserySpace);
115          super.collectionPhase(phaseId);
116          return;
117        }
118    
119        super.collectionPhase(phaseId);
120      }
121    
122      @Override
123      public final boolean collectionRequired(boolean spaceFull, Space space) {
124        boolean nurseryFull = nurserySpace.reservedPages() > Options.nurserySize.getMaxNursery();
125    
126        return super.collectionRequired(spaceFull, space) || nurseryFull;
127      }
128    
129      /*****************************************************************************
130       *
131       * Accounting
132       */
133    
134      /**
135       * {@inheritDoc}
136       */
137      @Override
138      public int getPagesUsed() {
139        return super.getPagesUsed() +
140          msSpace.reservedPages() +
141          nurserySpace.reservedPages();
142      }
143    
144      /**
145       * Return the number of pages reserved for collection.
146       * For mark sweep this is a fixed fraction of total pages.
147       */
148      @Override
149      public int getCollectionReserve() {
150        return nurserySpace.reservedPages() + super.getCollectionReserve();
151      }
152    
153      /**
154       * @return The number of pages available for allocation, <i>assuming
155       * all future allocation is to the nursery</i>.
156       */
157      @Override
158      public final int getPagesAvail() {
159        return (getTotalPages() - getPagesReserved()) >> 1;
160      }
161    
162      @Override
163      public int sanityExpectedRC(ObjectReference object, int sanityRootRC) {
164        Space space = Space.getSpaceForObject(object);
165    
166        // Nursery
167        if (space == CopyMS.nurserySpace) {
168          return SanityChecker.DEAD;
169        }
170    
171        return space.isReachable(object) ? SanityChecker.ALIVE : SanityChecker.DEAD;
172      }
173    
174      @Override
175      @Interruptible
176      protected void registerSpecializedMethods() {
177        TransitiveClosure.registerSpecializedScan(SCAN_COPYMS, CopyMSTraceLocal.class);
178        super.registerSpecializedMethods();
179      }
180    
181      @Interruptible
182      @Override
183      public void fullyBooted() {
184        super.fullyBooted();
185        nurserySpace.setZeroingApproach(Options.nurseryZeroing.getNonTemporal(), Options.nurseryZeroing.getConcurrent());
186      }
187    }