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.generational; 014 015 import org.mmtk.plan.*; 016 import org.mmtk.policy.LargeObjectLocal; 017 import org.mmtk.utility.deque.*; 018 019 import org.mmtk.vm.VM; 020 021 import 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 097 if (phaseId == StopTheWorld.ROOTS) { 098 VM.scanning.computeGlobalRoots(getCurrentTrace()); 099 if (!Gen.USE_NON_HEAP_OBJECT_REFERENCE_WRITE_BARRIER || global().traceFullHeap()) { 100 VM.scanning.computeStaticRoots(getCurrentTrace()); 101 } 102 if (Plan.SCAN_BOOT_IMAGE && global().traceFullHeap()) { 103 VM.scanning.computeBootImageRoots(getCurrentTrace()); 104 } 105 return; 106 } 107 108 if (phaseId == Gen.CLOSURE) { 109 if (!global().gcFullHeap) { 110 nurseryTrace.completeTrace(); 111 } 112 return; 113 } 114 115 if (phaseId == Gen.RELEASE) { 116 los.release(true); 117 if (!global().traceFullHeap()) { 118 nurseryTrace.release(); 119 global().arrayRemsetPool.reset(); 120 global().remsetPool.reset(); 121 global().modbufPool.reset(); 122 } 123 return; 124 } 125 126 super.collectionPhase(phaseId, primary); 127 } 128 129 /**************************************************************************** 130 * 131 * Miscellaneous 132 */ 133 134 /** @return The active global plan as a <code>Gen</code> instance. */ 135 @Inline 136 private static Gen global() { 137 return (Gen) VM.activePlan.global(); 138 } 139 140 @Override 141 public final TraceLocal getCurrentTrace() { 142 if (global().traceFullHeap()) return getFullHeapTrace(); 143 return nurseryTrace; 144 } 145 146 /** @return The trace to use when collecting the mature space */ 147 public abstract TraceLocal getFullHeapTrace(); 148 149 }