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