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
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", DEFAULT_POLL_FREQUENCY, VMRequest.create());
062    
063      public static final int IMMIX = immixSpace.getDescriptor();
064    
065      public static final int SCAN_IMMIX = 1;
066      public static final int SCAN_DEFRAG = 2;
067    
068      /****************************************************************************
069       *
070       * Instance fields
071       */
072      /* The trace class for a full-heap collection */
073      public final Trace matureTrace = new Trace(metaDataSpace);
074      private boolean lastGCWasDefrag = false;
075    
076      /*****************************************************************************
077       *
078       * Collection
079       */
080    
081      /**
082       * Perform a (global) collection phase.
083       */
084      @Inline
085      @Override
086      public final void collectionPhase(short phaseId) {
087        if (phaseId == SET_COLLECTION_KIND) {
088          super.collectionPhase(phaseId);
089          if (gcFullHeap)
090            immixSpace.decideWhetherToDefrag(emergencyCollection, true, collectionAttempt, collectionTrigger);
091          return;
092        }
093    
094        if (traceFullHeap()) {
095          if (phaseId == PREPARE) {
096            super.collectionPhase(phaseId);
097            matureTrace.prepare();
098            immixSpace.prepare(true);
099            return;
100          }
101    
102          if (phaseId == CLOSURE) {
103            matureTrace.prepare();
104            return;
105          }
106    
107          if (phaseId == RELEASE) {
108            matureTrace.release();
109            lastGCWasDefrag = immixSpace.release(true);
110            super.collectionPhase(phaseId);
111            return;
112          }
113        } else
114          lastGCWasDefrag = false;
115    
116        super.collectionPhase(phaseId);
117      }
118    
119      /**
120       * @return Whether last GC was an exhaustive attempt to collect the heap.  For many collectors this is the same as asking whether the last GC was a full heap collection.
121       */
122      @Override
123      public boolean lastCollectionWasExhaustive() {
124        return lastGCWasDefrag;
125      }
126    
127      /*****************************************************************************
128       *
129       * Accounting
130       */
131    
132      /**
133       * Return the number of pages reserved for use given the pending
134       * allocation.
135       *
136       * @return The number of pages reserved given the pending
137       * allocation, excluding space reserved for copying.
138       */
139      @Inline
140      @Override
141      public int getPagesUsed() {
142        return immixSpace.reservedPages() + super.getPagesUsed();
143      }
144    
145      /**
146       * Return the number of pages available for allocation into the mature
147       * space.
148       *
149       * @return The number of pages available for allocation into the mature
150       * space.
151       */
152      public int getMaturePhysicalPagesAvail() {
153        return immixSpace.availablePhysicalPages();
154      }
155    
156      /*****************************************************************************
157       *
158       * Miscellaneous
159       */
160    
161      /**
162       * Accessor method to allow the generic generational code in Gen.java
163       * to access the mature space.
164       *
165       * @return The active mature space
166       */
167      @Inline
168      protected final Space activeMatureSpace() {
169        return immixSpace;
170      }
171    
172      /**
173       * @see org.mmtk.plan.Plan#willNeverMove
174       *
175       * @param object Object in question
176       * @return true if the object will never move
177       */
178      @Override
179      public boolean willNeverMove(ObjectReference object) {
180        if (Space.isInSpace(IMMIX, object)) {
181          ObjectHeader.pinObject(object);
182          return true;
183        } else
184          return super.willNeverMove(object);
185      }
186    
187      /**
188       * Register specialized methods.
189       */
190      @Interruptible
191      protected void registerSpecializedMethods() {
192        TransitiveClosure.registerSpecializedScan(SCAN_IMMIX, GenImmixMatureTraceLocal.class);
193        TransitiveClosure.registerSpecializedScan(SCAN_DEFRAG, GenImmixMatureDefragTraceLocal.class);
194        super.registerSpecializedMethods();
195      }
196    }