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.semispace;
014
015 import org.mmtk.policy.CopySpace;
016 import org.mmtk.policy.Space;
017 import org.mmtk.plan.*;
018 import org.mmtk.utility.heap.VMRequest;
019
020 import org.vmmagic.pragma.*;
021 import 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
042 public 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.create());
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.create());
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 }