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.generational.immix;
014    
015    import org.mmtk.plan.generational.Gen;
016    import org.mmtk.plan.Trace;
017    import org.mmtk.plan.TransitiveClosure;
018    import org.mmtk.policy.immix.ImmixSpace;
019    import org.mmtk.policy.immix.ObjectHeader;
020    import org.mmtk.policy.Space;
021    import org.mmtk.utility.heap.VMRequest;
022    
023    import org.vmmagic.pragma.*;
024    import org.vmmagic.unboxed.*;
025    
026    /**
027     * This class implements the functionality of a two-generation copying
028     * collector where <b>the higher generation is an immix space</b>.
029     *
030     * Nursery collections occur when either the heap is full or the nursery
031     * is full.  The nursery size is determined by an optional command line
032     * argument. If undefined, the nursery size is "infinite", so nursery
033     * collections only occur when the heap is full (this is known as a
034     * flexible-sized nursery collector).  Thus both fixed and flexible
035     * nursery sizes are supported.  Full heap collections occur when the
036     * nursery size has dropped to a statically defined threshold,
037     * <code>NURSERY_THRESHOLD</code><p>
038     *
039     * See the PLDI'08 paper by Blackburn and McKinley for a description
040     * of the algorithm: http://doi.acm.org/10.1145/1375581.1375586<p>
041     *
042     * See the Jones & Lins GC book, chapter 7 for a detailed discussion
043     * of generational collection and section 7.3 for an overview of the
044     * flexible nursery behavior ("The Standard ML of New Jersey
045     * collector"), or go to Appel's paper "Simple generational garbage
046     * collection and fast allocation." SP&E 19(2):171--183, 1989.<p>
047     *
048     *
049     * For general comments about the global/local distinction among classes refer
050     * to Plan.java and PlanLocal.java.
051     */
052    @Uninterruptible
053    public class GenImmix extends Gen {
054    
055      /*****************************************************************************
056       *
057       * Class fields
058       */
059    
060      /** The mature space, which for GenImmix uses a mark sweep collection policy. */
061      public static final ImmixSpace immixSpace = new ImmixSpace("immix", false, VMRequest.create());
062    
063      public static final int IMMIX = immixSpace.getDescriptor();
064    
065      /** Specialized scanning method identifier */
066      public static final int SCAN_IMMIX = 1;
067    
068      /****************************************************************************
069       *
070       * Instance fields
071       */
072    
073      /** The trace class for a full-heap collection */
074      public final Trace matureTrace = new Trace(metaDataSpace);
075      private boolean lastGCWasDefrag = false;
076    
077      /*****************************************************************************
078       *
079       * Collection
080       */
081    
082      /**
083       * {@inheritDoc}
084       */
085      @Inline
086      @Override
087      public final void collectionPhase(short phaseId) {
088        if (phaseId == SET_COLLECTION_KIND) {
089          super.collectionPhase(phaseId);
090          if (gcFullHeap) {
091            immixSpace.decideWhetherToDefrag(emergencyCollection, true, collectionAttempt, userTriggeredCollection);
092          }
093          return;
094        }
095    
096        if (traceFullHeap()) {
097          if (phaseId == PREPARE) {
098            super.collectionPhase(phaseId);
099            matureTrace.prepare();
100            immixSpace.prepare(true);
101            return;
102          }
103    
104          if (phaseId == CLOSURE) {
105            matureTrace.prepare();
106            return;
107          }
108    
109          if (phaseId == RELEASE) {
110            matureTrace.release();
111            lastGCWasDefrag = immixSpace.release(true);
112            super.collectionPhase(phaseId);
113            return;
114          }
115        } else
116          lastGCWasDefrag = false;
117    
118        super.collectionPhase(phaseId);
119      }
120    
121      @Override
122      public boolean lastCollectionWasExhaustive() {
123        return lastGCWasDefrag;
124      }
125    
126      /*****************************************************************************
127       *
128       * Accounting
129       */
130    
131      /**
132       * Return the number of pages reserved for use given the pending
133       * allocation.
134       */
135      @Inline
136      @Override
137      public int getPagesUsed() {
138        return immixSpace.reservedPages() + super.getPagesUsed();
139      }
140    
141      @Override
142      public int getMaturePhysicalPagesAvail() {
143        return immixSpace.availablePhysicalPages();
144      }
145    
146      @Override
147      public int getCollectionReserve() {
148        return super.getCollectionReserve() + immixSpace.defragHeadroomPages();
149      }
150    
151      /*****************************************************************************
152       *
153       * Miscellaneous
154       */
155    
156      /**
157       * @return The active mature space
158       */
159      @Override
160      @Inline
161      protected final Space activeMatureSpace() {
162        return immixSpace;
163      }
164    
165      @Override
166      public boolean willNeverMove(ObjectReference object) {
167        if (Space.isInSpace(IMMIX, object)) {
168          ObjectHeader.pinObject(object);
169          return true;
170        } else
171          return super.willNeverMove(object);
172      }
173    
174      @Override
175      @Interruptible
176      protected void registerSpecializedMethods() {
177        TransitiveClosure.registerSpecializedScan(SCAN_IMMIX, GenImmixMatureTraceLocal.class);
178    //    TransitiveClosure.registerSpecializedScan(SCAN_DEFRAG, GenImmixMatureDefragTraceLocal.class);
179        super.registerSpecializedMethods();
180      }
181    }