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.plan.*; 016import org.mmtk.policy.CopyLocal; 017import org.mmtk.policy.LargeObjectLocal; 018import org.mmtk.policy.Space; 019import org.mmtk.utility.ForwardingWord; 020import org.mmtk.vm.VM; 021 022import org.vmmagic.unboxed.*; 023import org.vmmagic.pragma.*; 024 025/** 026 * This class implements <i>per-collector thread</i> behavior 027 * and state for the <i>SS</i> plan, which implements a full-heap 028 * semi-space collector.<p> 029 * 030 * Specifically, this class defines <i>SS</i> collection behavior 031 * (through <code>trace</code> and the <code>collectionPhase</code> 032 * method), and collection-time allocation (copying of objects).<p> 033 * 034 * See {@link SS} for an overview of the semi-space algorithm. 035 * 036 * @see SS 037 * @see SSMutator 038 * @see StopTheWorldCollector 039 * @see CollectorContext 040 */ 041@Uninterruptible 042public class SSCollector extends StopTheWorldCollector { 043 044 /**************************************************************************** 045 * Instance fields 046 */ 047 048 /** 049 * 050 */ 051 protected final SSTraceLocal trace; 052 protected final CopyLocal ss; 053 protected final LargeObjectLocal los; 054 055 /**************************************************************************** 056 * 057 * Initialization 058 */ 059 060 /** 061 * Constructor 062 */ 063 public SSCollector() { 064 this(new SSTraceLocal(global().ssTrace)); 065 } 066 067 /** 068 * Constructor 069 * @param tr The trace to use 070 */ 071 protected SSCollector(SSTraceLocal tr) { 072 ss = new CopyLocal(); 073 los = new LargeObjectLocal(Plan.loSpace); 074 trace = tr; 075 } 076 077 /**************************************************************************** 078 * 079 * Collection-time allocation 080 */ 081 082 /** 083 * {@inheritDoc} 084 */ 085 @Override 086 @Inline 087 public Address allocCopy(ObjectReference original, int bytes, 088 int align, int offset, int allocator) { 089 if (allocator == Plan.ALLOC_LOS) { 090 if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(bytes > Plan.MAX_NON_LOS_COPY_BYTES); 091 return los.alloc(bytes, align, offset); 092 } else { 093 if (VM.VERIFY_ASSERTIONS) { 094 VM.assertions._assert(bytes <= Plan.MAX_NON_LOS_COPY_BYTES); 095 VM.assertions._assert(allocator == SS.ALLOC_SS); 096 } 097 return ss.alloc(bytes, align, offset); 098 } 099 } 100 101 @Override 102 @Inline 103 public void postCopy(ObjectReference object, ObjectReference typeRef, 104 int bytes, int allocator) { 105 ForwardingWord.clearForwardingBits(object); 106 if (allocator == Plan.ALLOC_LOS) 107 Plan.loSpace.initializeHeader(object, false); 108 } 109 110 /**************************************************************************** 111 * 112 * Collection 113 */ 114 115 /** 116 * {@inheritDoc} 117 */ 118 @Override 119 @Inline 120 public void collectionPhase(short phaseId, boolean primary) { 121 if (phaseId == SS.PREPARE) { 122 // rebind the copy bump pointer to the appropriate semispace. 123 ss.rebind(SS.toSpace()); 124 los.prepare(true); 125 super.collectionPhase(phaseId, primary); 126 return; 127 } 128 129 if (phaseId == SS.CLOSURE) { 130 trace.completeTrace(); 131 return; 132 } 133 134 if (phaseId == SS.RELEASE) { 135 trace.release(); 136 los.release(true); 137 super.collectionPhase(phaseId, primary); 138 return; 139 } 140 141 super.collectionPhase(phaseId, primary); 142 } 143 144 145 /**************************************************************************** 146 * 147 * Object processing and tracing 148 */ 149 150 /** 151 * Return {@code true} if the given reference is to an object that is within 152 * one of the semi-spaces. 153 * 154 * @param object The object in question 155 * @return {@code true} if the given reference is to an object that is within 156 * one of the semi-spaces. 157 */ 158 public static boolean isSemiSpaceObject(ObjectReference object) { 159 return Space.isInSpace(SS.SS0, object) || Space.isInSpace(SS.SS1, object); 160 } 161 162 /**************************************************************************** 163 * 164 * Miscellaneous 165 */ 166 167 /** @return The active global plan as an <code>SS</code> instance. */ 168 @Inline 169 private static SS global() { 170 return (SS) VM.activePlan.global(); 171 } 172 173 @Override 174 public TraceLocal getCurrentTrace() { 175 return trace; 176 } 177}