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.semispace; 014 015import org.mmtk.policy.CopySpace; 016import org.mmtk.policy.Space; 017import org.mmtk.plan.*; 018import org.mmtk.utility.heap.VMRequest; 019 020import org.vmmagic.pragma.*; 021import org.vmmagic.unboxed.*; 022 023/** 024 * This class implements a simple semi-space collector. See the Jones 025 * & Lins GC book, section 2.2 for an overview of the basic 026 * algorithm. This implementation also includes a large object space 027 * (LOS), and an uncollected "immortal" space.<p> 028 * 029 * All plans make a clear distinction between <i>global</i> and 030 * <i>thread-local</i> activities. Global activities must be 031 * synchronized, whereas no synchronization is required for 032 * thread-local activities. Instances of Plan map 1:1 to "kernel 033 * threads" (aka CPUs). Thus instance 034 * methods allow fast, unsychronized access to Plan utilities such as 035 * allocation and collection. Each instance rests on static resources 036 * (such as memory and virtual memory resources) which are "global" 037 * and therefore "static" members of Plan. This mapping of threads to 038 * instances is crucial to understanding the correctness and 039 * performance properties of this plan. 040 */ 041@Uninterruptible 042public class SS extends StopTheWorld { 043 044 /**************************************************************************** 045 * 046 * Class variables 047 */ 048 049 /** {@code true} if allocating into the "higher" semispace */ 050 public static boolean hi = false; 051 052 /** One of the two semi spaces that alternate roles at each collection */ 053 public static final CopySpace copySpace0 = new CopySpace("ss0", false, VMRequest.discontiguous()); 054 public static final int SS0 = copySpace0.getDescriptor(); 055 056 /** One of the two semi spaces that alternate roles at each collection */ 057 public static final CopySpace copySpace1 = new CopySpace("ss1", true, VMRequest.discontiguous()); 058 public static final int SS1 = copySpace1.getDescriptor(); 059 060 public final Trace ssTrace; 061 062 /**************************************************************************** 063 * 064 * Initialization 065 */ 066 067 /** 068 * Class variables 069 */ 070 071 /** 072 * 073 */ 074 public static final int ALLOC_SS = Plan.ALLOC_DEFAULT; 075 076 public static final int SCAN_SS = 0; 077 078 /** 079 * Constructor 080 */ 081 public SS() { 082 ssTrace = new Trace(metaDataSpace); 083 } 084 085 /** 086 * @return The to space for the current collection. 087 */ 088 @Inline 089 public static CopySpace toSpace() { 090 return hi ? copySpace1 : copySpace0; 091 } 092 093 /** 094 * @return The from space for the current collection. 095 */ 096 @Inline 097 public static CopySpace fromSpace() { 098 return hi ? copySpace0 : copySpace1; 099 } 100 101 102 /**************************************************************************** 103 * 104 * Collection 105 */ 106 107 /** 108 * {@inheritDoc} 109 */ 110 @Override 111 @Inline 112 public void collectionPhase(short phaseId) { 113 if (phaseId == SS.PREPARE) { 114 hi = !hi; // flip the semi-spaces 115 // prepare each of the collected regions 116 copySpace0.prepare(hi); 117 copySpace1.prepare(!hi); 118 ssTrace.prepare(); 119 super.collectionPhase(phaseId); 120 return; 121 } 122 if (phaseId == CLOSURE) { 123 ssTrace.prepare(); 124 return; 125 } 126 if (phaseId == SS.RELEASE) { 127 // release the collected region 128 fromSpace().release(); 129 130 super.collectionPhase(phaseId); 131 return; 132 } 133 134 super.collectionPhase(phaseId); 135 } 136 137 /**************************************************************************** 138 * 139 * Accounting 140 */ 141 142 /** 143 * Return the number of pages reserved for copying. 144 */ 145 @Override 146 public final int getCollectionReserve() { 147 // we must account for the number of pages required for copying, 148 // which equals the number of semi-space pages reserved 149 return toSpace().reservedPages() + super.getCollectionReserve(); 150 } 151 152 /** 153 * Return the number of pages reserved for use given the pending 154 * allocation. This is <i>exclusive of</i> space reserved for 155 * copying. 156 */ 157 @Override 158 public int getPagesUsed() { 159 return super.getPagesUsed() + toSpace().reservedPages(); 160 } 161 162 /** 163 * Return the number of pages available for allocation, <i>assuming 164 * all future allocation is to the semi-space</i>. 165 * 166 * @return The number of pages available for allocation, <i>assuming 167 * all future allocation is to the semi-space</i>. 168 */ 169 @Override 170 public final int getPagesAvail() { 171 return(super.getPagesAvail()) >> 1; 172 } 173 174 @Override 175 public boolean willNeverMove(ObjectReference object) { 176 if (Space.isInSpace(SS0, object) || Space.isInSpace(SS1, object)) 177 return false; 178 return super.willNeverMove(object); 179 } 180 181 @Override 182 @Interruptible 183 protected void registerSpecializedMethods() { 184 TransitiveClosure.registerSpecializedScan(SCAN_SS, SSTraceLocal.class); 185 super.registerSpecializedMethods(); 186 } 187}