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.immix; 014 015import org.mmtk.plan.*; 016import org.mmtk.policy.ImmortalLocal; 017import org.mmtk.policy.immix.CollectorLocal; 018import org.mmtk.utility.alloc.BumpPointer; 019import org.mmtk.utility.alloc.ImmixAllocator; 020import org.mmtk.vm.VM; 021 022import org.vmmagic.pragma.*; 023import org.vmmagic.unboxed.Address; 024import org.vmmagic.unboxed.ObjectReference; 025 026/** 027 * This class implements <i>per-collector thread</i> behavior 028 * and state for the <i>Immix</i> plan, which implements a full-heap 029 * immix collector.<p> 030 * 031 * Specifically, this class defines <i>Immix</i> collection behavior 032 * (through <code>fastTrace</code> and the <code>collectionPhase</code> 033 * method).<p> 034 * 035 * @see Immix for an overview of the immix algorithm.<p> 036 * 037 * FIXME The SegregatedFreeList class (and its decendents such as 038 * MarkSweepLocal) does not properly separate mutator and collector 039 * behaviors, so the immix field below should really not exist in 040 * this class as there is no collection-time allocation in this 041 * collector. 042 * 043 * @see Immix 044 * @see org.mmtk.policy.immix.MutatorLocal 045 * @see StopTheWorldCollector 046 * @see CollectorContext 047 * @see Phase 048 */ 049@Uninterruptible 050public class ImmixCollector extends StopTheWorldCollector { 051 052 /**************************************************************************** 053 * Instance fields 054 */ 055 056 /** 057 * 058 */ 059 protected ImmixTraceLocal fastTrace; 060 protected ImmixDefragTraceLocal defragTrace; 061 protected CollectorLocal immix; 062 protected final ImmixAllocator copy; 063 protected final BumpPointer immortal; 064 protected TraceLocal currentTrace; 065 066 /**************************************************************************** 067 * Initialization 068 */ 069 070 /** 071 * Constructor 072 */ 073 public ImmixCollector() { 074 fastTrace = new ImmixTraceLocal(global().immixTrace, null); 075 defragTrace = new ImmixDefragTraceLocal(global().immixTrace, null); 076 immix = new CollectorLocal(Immix.immixSpace); 077 copy = new ImmixAllocator(Immix.immixSpace, true, true); 078 immortal = new ImmortalLocal(Plan.immortalSpace); 079 } 080 081 /**************************************************************************** 082 * 083 * Collection-time allocation 084 */ 085 086 /** 087 * {@inheritDoc} 088 */ 089 @Override 090 @Inline 091 public Address allocCopy(ObjectReference original, int bytes, 092 int align, int offset, int allocator) { 093 if (VM.VERIFY_ASSERTIONS) { 094 VM.assertions._assert(bytes <= Plan.MAX_NON_LOS_COPY_BYTES); 095 VM.assertions._assert(allocator == Immix.ALLOC_DEFAULT); 096 } 097 return copy.alloc(bytes, align, offset); 098 } 099 100 @Override 101 @Inline 102 public void postCopy(ObjectReference object, ObjectReference typeRef, 103 int bytes, int allocator) { 104 if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(allocator == Immix.ALLOC_DEFAULT); 105 Immix.immixSpace.postCopy(object, bytes, true); 106 107 if (VM.VERIFY_ASSERTIONS) { 108 VM.assertions._assert(getCurrentTrace().isLive(object)); 109 VM.assertions._assert(getCurrentTrace().willNotMoveInCurrentCollection(object)); 110 } 111 } 112 113 /**************************************************************************** 114 * 115 * Collection 116 */ 117 118 /** 119 * {@inheritDoc} 120 */ 121 @Override 122 @Inline 123 public void collectionPhase(short phaseId, boolean primary) { 124 125 if (phaseId == Immix.PREPARE) { 126 super.collectionPhase(phaseId, primary); 127 currentTrace = Immix.immixSpace.inImmixDefragCollection() ? defragTrace : fastTrace; 128 immix.prepare(true); 129 currentTrace.prepare(); 130 copy.reset(); 131 return; 132 } 133 134 if (phaseId == Immix.CLOSURE) { 135 currentTrace.completeTrace(); 136 return; 137 } 138 139 if (phaseId == Immix.RELEASE) { 140 currentTrace.release(); 141 immix.release(true); 142 super.collectionPhase(phaseId, primary); 143 return; 144 } 145 146 super.collectionPhase(phaseId, primary); 147 } 148 149 /**************************************************************************** 150 * 151 * Miscellaneous 152 */ 153 154 /** @return The active global plan as an <code>Immix</code> instance. */ 155 @Inline 156 private static Immix global() { 157 return (Immix) VM.activePlan.global(); 158 } 159 160 /** @return The current fastTrace instance. */ 161 @Override 162 @Inline 163 public final TraceLocal getCurrentTrace() { 164 return currentTrace; 165 } 166}