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.copyms; 014 015import org.mmtk.plan.*; 016import org.mmtk.policy.CopySpace; 017import org.mmtk.policy.MarkSweepSpace; 018import org.mmtk.policy.Space; 019import org.mmtk.utility.heap.VMRequest; 020import org.mmtk.utility.options.Options; 021import org.mmtk.utility.sanitychecker.SanityChecker; 022 023import org.vmmagic.pragma.*; 024import 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 048public 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.highFraction(0.15f)); 062 public static final MarkSweepSpace msSpace = new MarkSweepSpace("ms", VMRequest.discontiguous()); 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}