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.copyms;
014
015 import org.mmtk.plan.*;
016 import org.mmtk.policy.CopySpace;
017 import org.mmtk.policy.MarkSweepSpace;
018 import org.mmtk.policy.Space;
019 import org.mmtk.utility.heap.VMRequest;
020 import org.mmtk.utility.options.Options;
021 import org.mmtk.utility.sanitychecker.SanityChecker;
022
023 import org.vmmagic.pragma.*;
024 import org.vmmagic.unboxed.ObjectReference;
025
026 /**
027 * This class implements the global state of a full-heap collector
028 * with a copying nursery and mark-sweep mature space. Unlike a full
029 * generational collector, there is no write barrier, no remembered set, and
030 * every collection is full-heap.<p>
031 *
032 * All plans make a clear distinction between <i>global</i> and
033 * <i>thread-local</i> activities, and divides global and local state
034 * into separate class hierarchies. Global activities must be
035 * synchronized, whereas no synchronization is required for
036 * thread-local activities. There is a single instance of Plan (or the
037 * appropriate sub-class), and a 1:1 mapping of PlanLocal to "kernel
038 * threads" (aka CPUs). Thus instance
039 * methods of PlanLocal allow fast, unsychronized access to functions such as
040 * allocation and collection.<p>
041 *
042 * The global instance defines and manages static resources
043 * (such as memory and virtual memory resources). This mapping of threads to
044 * instances is crucial to understanding the correctness and
045 * performance properties of MMTk plans.
046 */
047 @Uninterruptible
048 public class CopyMS extends StopTheWorld {
049
050 /****************************************************************************
051 * Constants
052 */
053
054 /****************************************************************************
055 * Class variables
056 */
057
058 /**
059 *
060 */
061 public static final CopySpace nurserySpace = new CopySpace("nursery", false, VMRequest.create(0.15f, true));
062 public static final MarkSweepSpace msSpace = new MarkSweepSpace("ms", VMRequest.create());
063
064 public static final int NURSERY = nurserySpace.getDescriptor();
065 public static final int MARK_SWEEP = msSpace.getDescriptor();
066
067 public static final int ALLOC_NURSERY = ALLOC_DEFAULT;
068 public static final int ALLOC_MS = StopTheWorld.ALLOCATORS + 1;
069
070 public static final int SCAN_COPYMS = 0;
071
072 /****************************************************************************
073 * Instance variables
074 */
075
076 /**
077 *
078 */
079 public final Trace trace;
080
081 /**
082 * Constructor.
083 */
084 public CopyMS() {
085 trace = new Trace(metaDataSpace);
086 }
087
088
089 /*****************************************************************************
090 * Collection
091 */
092
093 /**
094 * {@inheritDoc}
095 */
096 @Override
097 @Inline
098 public final void collectionPhase(short phaseId) {
099 if (phaseId == PREPARE) {
100 super.collectionPhase(phaseId);
101 trace.prepare();
102 msSpace.prepare(true);
103 nurserySpace.prepare(true);
104 return;
105 }
106 if (phaseId == CLOSURE) {
107 trace.prepare();
108 return;
109 }
110 if (phaseId == RELEASE) {
111 trace.release();
112 msSpace.release();
113 nurserySpace.release();
114 switchNurseryZeroingApproach(nurserySpace);
115 super.collectionPhase(phaseId);
116 return;
117 }
118
119 super.collectionPhase(phaseId);
120 }
121
122 @Override
123 public final boolean collectionRequired(boolean spaceFull, Space space) {
124 boolean nurseryFull = nurserySpace.reservedPages() > Options.nurserySize.getMaxNursery();
125
126 return super.collectionRequired(spaceFull, space) || nurseryFull;
127 }
128
129 /*****************************************************************************
130 *
131 * Accounting
132 */
133
134 /**
135 * {@inheritDoc}
136 */
137 @Override
138 public int getPagesUsed() {
139 return super.getPagesUsed() +
140 msSpace.reservedPages() +
141 nurserySpace.reservedPages();
142 }
143
144 /**
145 * Return the number of pages reserved for collection.
146 * For mark sweep this is a fixed fraction of total pages.
147 */
148 @Override
149 public int getCollectionReserve() {
150 return nurserySpace.reservedPages() + super.getCollectionReserve();
151 }
152
153 /**
154 * @return The number of pages available for allocation, <i>assuming
155 * all future allocation is to the nursery</i>.
156 */
157 @Override
158 public final int getPagesAvail() {
159 return (getTotalPages() - getPagesReserved()) >> 1;
160 }
161
162 @Override
163 public int sanityExpectedRC(ObjectReference object, int sanityRootRC) {
164 Space space = Space.getSpaceForObject(object);
165
166 // Nursery
167 if (space == CopyMS.nurserySpace) {
168 return SanityChecker.DEAD;
169 }
170
171 return space.isReachable(object) ? SanityChecker.ALIVE : SanityChecker.DEAD;
172 }
173
174 @Override
175 @Interruptible
176 protected void registerSpecializedMethods() {
177 TransitiveClosure.registerSpecializedScan(SCAN_COPYMS, CopyMSTraceLocal.class);
178 super.registerSpecializedMethods();
179 }
180
181 @Interruptible
182 @Override
183 public void fullyBooted() {
184 super.fullyBooted();
185 nurserySpace.setZeroingApproach(Options.nurseryZeroing.getNonTemporal(), Options.nurseryZeroing.getConcurrent());
186 }
187 }