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.copying; 014 015 import org.mmtk.policy.CopySpace; 016 import org.mmtk.policy.Space; 017 import org.mmtk.plan.generational.*; 018 import org.mmtk.plan.Trace; 019 import org.mmtk.plan.TransitiveClosure; 020 import org.mmtk.utility.heap.VMRequest; 021 import org.mmtk.vm.VM; 022 023 import 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.create()); 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.create()); 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() { return hi ? MS1 : MS0; } 119 120 /** 121 * @return The semispace we are currently copying from 122 * (or copied from at last major GC) 123 */ 124 static CopySpace fromSpace() { 125 return hi ? matureSpace0 : matureSpace1; 126 } 127 128 /** 129 * @return Space descriptor for from-space 130 */ 131 static int fromSpaceDesc() { return hi ? MS0 : MS1; } 132 133 /**************************************************************************** 134 * 135 * Collection 136 */ 137 138 /** 139 * {@inheritDoc} 140 */ 141 @Override 142 @Inline 143 public void collectionPhase(short phaseId) { 144 if (traceFullHeap()) { 145 if (phaseId == PREPARE) { 146 super.collectionPhase(phaseId); 147 hi = !hi; // flip the semi-spaces 148 matureSpace0.prepare(hi); 149 matureSpace1.prepare(!hi); 150 matureTrace.prepare(); 151 return; 152 } 153 if (phaseId == CLOSURE) { 154 matureTrace.prepare(); 155 return; 156 } 157 if (phaseId == RELEASE) { 158 matureTrace.release(); 159 fromSpace().release(); 160 super.collectionPhase(phaseId); 161 return; 162 } 163 } 164 super.collectionPhase(phaseId); 165 } 166 167 /***************************************************************************** 168 * 169 * Accounting 170 */ 171 172 /** 173 * Return the number of pages reserved for use given the pending 174 * allocation. 175 */ 176 @Override 177 @Inline 178 public int getPagesUsed() { 179 return toSpace().reservedPages() + super.getPagesUsed(); 180 } 181 182 /** 183 * Return the number of pages reserved for copying. 184 * 185 * @return the number of pages reserved for copying. 186 */ 187 @Override 188 public final int getCollectionReserve() { 189 // we must account for the number of pages required for copying, 190 // which equals the number of semi-space pages reserved 191 return toSpace().reservedPages() + super.getCollectionReserve(); 192 } 193 194 @Override 195 public int getMaturePhysicalPagesAvail() { 196 return toSpace().availablePhysicalPages() >> 1; 197 } 198 199 /************************************************************************** 200 * Miscellaneous methods 201 */ 202 203 /** 204 * @return The mature space we are currently allocating into 205 */ 206 @Override 207 @Inline 208 public Space activeMatureSpace() { 209 return toSpace(); 210 } 211 212 @Override 213 @Interruptible 214 protected void registerSpecializedMethods() { 215 TransitiveClosure.registerSpecializedScan(SCAN_MATURE, GenCopyMatureTraceLocal.class); 216 super.registerSpecializedMethods(); 217 } 218 }