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.copying; 014 015import org.mmtk.policy.CopySpace; 016import org.mmtk.policy.Space; 017import org.mmtk.plan.generational.*; 018import org.mmtk.plan.Trace; 019import org.mmtk.plan.TransitiveClosure; 020import org.mmtk.utility.heap.VMRequest; 021import org.mmtk.vm.VM; 022 023import org.vmmagic.pragma.*; 024 025/** 026 * This class implements the functionality of a standard 027 * two-generation copying collector. Nursery collections occur when 028 * either the heap is full or the nursery is full. The nursery size 029 * is determined by an optional command line argument. If undefined, 030 * the nursery size is "infinite", so nursery collections only occur 031 * when the heap is full (this is known as a flexible-sized nursery 032 * collector). Thus both fixed and flexible nursery sizes are 033 * supported. Full heap collections occur when the nursery size has 034 * dropped to a statically defined threshold, 035 * <code>NURSERY_THRESHOLD</code>.<p> 036 * 037 * See the Jones & Lins GC book, chapter 7 for a detailed discussion 038 * of generational collection and section 7.3 for an overview of the 039 * flexible nursery behavior ("The Standard ML of New Jersey 040 * collector"), or go to Appel's paper "Simple generational garbage 041 * collection and fast allocation." SP&E 19(2):171--183, 1989.<p> 042 * 043 * All plans make a clear distinction between <i>global</i> and 044 * <i>thread-local</i> activities. Global activities must be 045 * synchronized, whereas no synchronization is required for 046 * thread-local activities. Instances of Plan map 1:1 to "kernel 047 * threads" (aka CPUs). Thus instance 048 * methods allow fast, unsychronized access to Plan utilities such as 049 * allocation and collection. Each instance rests on static resources 050 * (such as memory and virtual memory resources) which are "global" 051 * and therefore "static" members of Plan. This mapping of threads to 052 * instances is crucial to understanding the correctness and 053 * performance properties of this plan. 054 */ 055@Uninterruptible public class GenCopy extends Gen { 056 057 /**************************************************************************** 058 * 059 * Class variables 060 */ 061 062 // GC state 063 064 /** 065 * <code>true</code> if copying to "higher" semispace 066 */ 067 static boolean hi = false; 068 069 /** 070 * The low half of the copying mature space. We allocate into this space 071 * when <code>hi</code> is <code>false</code>. 072 */ 073 static CopySpace matureSpace0 = new CopySpace("ss0", false, VMRequest.discontiguous()); 074 static final int MS0 = matureSpace0.getDescriptor(); 075 076 /** 077 * The high half of the copying mature space. We allocate into this space 078 * when <code>hi</code> is <code>true</code>. 079 */ 080 static CopySpace matureSpace1 = new CopySpace("ss1", true, VMRequest.discontiguous()); 081 static final int MS1 = matureSpace1.getDescriptor(); 082 083 084 /**************************************************************************** 085 * 086 * Instance fields 087 */ 088 089 /** 090 * 091 */ 092 final Trace matureTrace; 093 094 /** 095 * Constructor 096 */ 097 public GenCopy() { 098 super(); 099 if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(!IGNORE_REMSETS); // Not supported for GenCopy 100 matureTrace = new Trace(metaDataSpace); 101 } 102 103 @Override 104 protected boolean copyMature() { 105 return true; 106 } 107 108 /** 109 * @return The semispace we are currently allocating into 110 */ 111 static CopySpace toSpace() { 112 return hi ? matureSpace1 : matureSpace0; 113 } 114 115 /** 116 * @return Space descriptor for to-space. 117 */ 118 static int toSpaceDesc() { 119 return hi ? MS1 : MS0; 120 } 121 122 /** 123 * @return The semispace we are currently copying from 124 * (or copied from at last major GC) 125 */ 126 static CopySpace fromSpace() { 127 return hi ? matureSpace0 : matureSpace1; 128 } 129 130 /** 131 * @return Space descriptor for from-space 132 */ 133 static int fromSpaceDesc() { 134 return hi ? MS0 : MS1; 135 } 136 137 /**************************************************************************** 138 * 139 * Collection 140 */ 141 142 /** 143 * {@inheritDoc} 144 */ 145 @Override 146 @Inline 147 public void collectionPhase(short phaseId) { 148 if (traceFullHeap()) { 149 if (phaseId == PREPARE) { 150 super.collectionPhase(phaseId); 151 hi = !hi; // flip the semi-spaces 152 matureSpace0.prepare(hi); 153 matureSpace1.prepare(!hi); 154 matureTrace.prepare(); 155 return; 156 } 157 if (phaseId == CLOSURE) { 158 matureTrace.prepare(); 159 return; 160 } 161 if (phaseId == RELEASE) { 162 matureTrace.release(); 163 fromSpace().release(); 164 super.collectionPhase(phaseId); 165 return; 166 } 167 } 168 super.collectionPhase(phaseId); 169 } 170 171 /***************************************************************************** 172 * 173 * Accounting 174 */ 175 176 /** 177 * Return the number of pages reserved for use given the pending 178 * allocation. 179 */ 180 @Override 181 @Inline 182 public int getPagesUsed() { 183 return toSpace().reservedPages() + super.getPagesUsed(); 184 } 185 186 /** 187 * Return the number of pages reserved for copying. 188 * 189 * @return the number of pages reserved for copying. 190 */ 191 @Override 192 public final int getCollectionReserve() { 193 // we must account for the number of pages required for copying, 194 // which equals the number of semi-space pages reserved 195 return toSpace().reservedPages() + super.getCollectionReserve(); 196 } 197 198 @Override 199 public int getMaturePhysicalPagesAvail() { 200 return toSpace().availablePhysicalPages() >> 1; 201 } 202 203 /************************************************************************** 204 * Miscellaneous methods 205 */ 206 207 /** 208 * @return The mature space we are currently allocating into 209 */ 210 @Override 211 @Inline 212 public Space activeMatureSpace() { 213 return toSpace(); 214 } 215 216 @Override 217 @Interruptible 218 protected void registerSpecializedMethods() { 219 TransitiveClosure.registerSpecializedScan(SCAN_MATURE, GenCopyMatureTraceLocal.class); 220 super.registerSpecializedMethods(); 221 } 222}