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.generational; 014 015import org.mmtk.plan.*; 016import org.mmtk.policy.LargeObjectLocal; 017import org.mmtk.utility.deque.*; 018 019import org.mmtk.vm.VM; 020 021import org.vmmagic.pragma.*; 022 023/** 024 * This abstract class implements <i>per-collector thread</i> 025 * behavior and state for <i>generational copying collectors</i>.<p> 026 * 027 * Specifically, this class defines nursery collection behavior (through 028 * <code>nurseryTrace</code> and the <code>collectionPhase</code> method). 029 * Per-collector thread remset consumers are instantiated here (used by 030 * sub-classes). 031 * 032 * @see Gen 033 * @see GenMutator 034 * @see StopTheWorldCollector 035 * @see CollectorContext 036 */ 037@Uninterruptible public abstract class GenCollector extends StopTheWorldCollector { 038 039 /***************************************************************************** 040 * Instance fields 041 */ 042 043 /** 044 * 045 */ 046 protected final GenNurseryTraceLocal nurseryTrace; 047 048 protected final LargeObjectLocal los; 049 050 // remembered set consumers 051 protected final ObjectReferenceDeque modbuf; 052 protected final AddressDeque remset; 053 protected final AddressPairDeque arrayRemset; 054 055 /**************************************************************************** 056 * 057 * Initialization 058 */ 059 060 /** 061 * Constructor 062 * <p> 063 * Note that the collector is a consumer of remsets, while the 064 * mutator is a producer. The <code>GenMutator</code> class is 065 * responsible for construction of the WriteBuffer (producer). 066 * @see GenMutator 067 */ 068 public GenCollector() { 069 los = new LargeObjectLocal(Plan.loSpace); 070 arrayRemset = new AddressPairDeque(global().arrayRemsetPool); 071 remset = new AddressDeque("remset", global().remsetPool); 072 modbuf = new ObjectReferenceDeque("modbuf", global().modbufPool); 073 nurseryTrace = new GenNurseryTraceLocal(global().nurseryTrace, this); 074 } 075 076 /**************************************************************************** 077 * 078 * Collection 079 */ 080 081 /** 082 * {@inheritDoc} 083 */ 084 @Override 085 @NoInline 086 public void collectionPhase(short phaseId, boolean primary) { 087 088 if (phaseId == Gen.PREPARE) { 089 los.prepare(true); 090 global().arrayRemsetPool.prepareNonBlocking(); 091 global().remsetPool.prepareNonBlocking(); 092 global().modbufPool.prepareNonBlocking(); 093 nurseryTrace.prepare(); 094 return; 095 } 096 if (phaseId == Simple.STACK_ROOTS && !global().gcFullHeap) { 097 VM.scanning.computeNewThreadRoots(getCurrentTrace()); 098 return; 099 } 100 if (phaseId == StopTheWorld.ROOTS) { 101 VM.scanning.computeGlobalRoots(getCurrentTrace()); 102 if (!Gen.USE_NON_HEAP_OBJECT_REFERENCE_WRITE_BARRIER || global().traceFullHeap()) { 103 VM.scanning.computeStaticRoots(getCurrentTrace()); 104 } 105 if (Plan.SCAN_BOOT_IMAGE && global().traceFullHeap()) { 106 VM.scanning.computeBootImageRoots(getCurrentTrace()); 107 } 108 return; 109 } 110 111 if (phaseId == Gen.CLOSURE) { 112 if (!global().gcFullHeap) { 113 nurseryTrace.completeTrace(); 114 } 115 return; 116 } 117 118 if (phaseId == Gen.RELEASE) { 119 los.release(true); 120 if (!global().traceFullHeap()) { 121 nurseryTrace.release(); 122 global().arrayRemsetPool.reset(); 123 global().remsetPool.reset(); 124 global().modbufPool.reset(); 125 } 126 return; 127 } 128 129 super.collectionPhase(phaseId, primary); 130 } 131 132 /**************************************************************************** 133 * 134 * Miscellaneous 135 */ 136 137 /** @return The active global plan as a <code>Gen</code> instance. */ 138 @Inline 139 private static Gen global() { 140 return (Gen) VM.activePlan.global(); 141 } 142 143 @Override 144 public final TraceLocal getCurrentTrace() { 145 if (global().traceFullHeap()) return getFullHeapTrace(); 146 return nurseryTrace; 147 } 148 149 /** @return The trace to use when collecting the mature space */ 150 public abstract TraceLocal getFullHeapTrace(); 151 152}