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; 014 015import org.mmtk.utility.Log; 016import org.mmtk.utility.options.Options; 017import org.mmtk.utility.sanitychecker.SanityCheckerLocal; 018 019import org.mmtk.vm.VM; 020 021import org.vmmagic.pragma.*; 022 023/** 024 * This class (and its sub-classes) implement <i>per-collector thread</i> 025 * behavior and state.<p> 026 * 027 * MMTk assumes that the VM instantiates instances of CollectorContext 028 * in thread local storage (TLS) for each thread participating in 029 * collection. Accesses to this state are therefore assumed to be 030 * low-cost during mutator time. 031 * 032 * @see CollectorContext 033 */ 034@Uninterruptible 035public abstract class SimpleCollector extends ParallelCollector { 036 037 /**************************************************************************** 038 * Instance fields 039 */ 040 041 /** Used for sanity checking. */ 042 protected final SanityCheckerLocal sanityLocal = new SanityCheckerLocal(); 043 044 /**************************************************************************** 045 * 046 * Collection 047 */ 048 049 /** 050 * {@inheritDoc} 051 */ 052 @Override 053 @Inline 054 public void collectionPhase(short phaseId, boolean primary) { 055 if (phaseId == Simple.PREPARE) { 056 // Nothing to do 057 return; 058 } 059 060 if (phaseId == Simple.STACK_ROOTS) { 061 VM.scanning.computeThreadRoots(getCurrentTrace()); 062 return; 063 } 064 065 if (phaseId == Simple.ROOTS) { 066 VM.scanning.computeGlobalRoots(getCurrentTrace()); 067 VM.scanning.computeStaticRoots(getCurrentTrace()); 068 if (Plan.SCAN_BOOT_IMAGE) { 069 VM.scanning.computeBootImageRoots(getCurrentTrace()); 070 } 071 return; 072 } 073 074 if (phaseId == Simple.SOFT_REFS) { 075 if (primary) { 076 if (!Options.noReferenceTypes.getValue()) { 077 if (!Plan.isEmergencyCollection()) { 078 VM.softReferences.scan(getCurrentTrace(),global().isCurrentGCNursery(),true); 079 } 080 } 081 } 082 return; 083 } 084 085 if (phaseId == Simple.WEAK_REFS) { 086 if (primary) { 087 if (Options.noReferenceTypes.getValue()) { 088 VM.softReferences.clear(); 089 VM.weakReferences.clear(); 090 } else { 091 VM.softReferences.scan(getCurrentTrace(),global().isCurrentGCNursery(), false); 092 VM.weakReferences.scan(getCurrentTrace(),global().isCurrentGCNursery(), false); 093 } 094 } 095 return; 096 } 097 098 if (phaseId == Simple.FINALIZABLE) { 099 if (primary) { 100 if (Options.noFinalizer.getValue()) 101 VM.finalizableProcessor.clear(); 102 else 103 VM.finalizableProcessor.scan(getCurrentTrace(),global().isCurrentGCNursery()); 104 } 105 return; 106 } 107 108 if (phaseId == Simple.PHANTOM_REFS) { 109 if (primary) { 110 if (Options.noReferenceTypes.getValue()) 111 VM.phantomReferences.clear(); 112 else 113 VM.phantomReferences.scan(getCurrentTrace(),global().isCurrentGCNursery(),false); 114 } 115 return; 116 } 117 118 if (phaseId == Simple.FORWARD_REFS) { 119 if (primary && !Options.noReferenceTypes.getValue() && 120 VM.activePlan.constraints().needsForwardAfterLiveness()) { 121 VM.softReferences.forward(getCurrentTrace(),global().isCurrentGCNursery()); 122 VM.weakReferences.forward(getCurrentTrace(),global().isCurrentGCNursery()); 123 VM.phantomReferences.forward(getCurrentTrace(),global().isCurrentGCNursery()); 124 } 125 return; 126 } 127 128 if (phaseId == Simple.FORWARD_FINALIZABLE) { 129 if (primary && !Options.noFinalizer.getValue() && 130 VM.activePlan.constraints().needsForwardAfterLiveness()) { 131 VM.finalizableProcessor.forward(getCurrentTrace(),global().isCurrentGCNursery()); 132 } 133 return; 134 } 135 136 if (phaseId == Simple.COMPLETE) { 137 // Nothing to do 138 return; 139 } 140 141 if (phaseId == Simple.RELEASE) { 142 // Nothing to do 143 return; 144 } 145 146 if (Options.sanityCheck.getValue() && sanityLocal.collectionPhase(phaseId, primary)) { 147 return; 148 } 149 150 Log.write("Per-collector phase "); Log.write(Phase.getName(phaseId)); 151 Log.writeln(" not handled."); 152 VM.assertions.fail("Per-collector phase not handled!"); 153 } 154 155 /**************************************************************************** 156 * 157 * Miscellaneous. 158 */ 159 160 /** @return The active global plan as a <code>Simple</code> instance. */ 161 @Inline 162 private static Simple global() { 163 return (Simple) VM.activePlan.global(); 164 } 165}