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; 014 015 import org.mmtk.utility.Log; 016 import org.mmtk.utility.options.Options; 017 import org.mmtk.utility.sanitychecker.SanityCheckerLocal; 018 019 import org.mmtk.vm.VM; 020 021 import 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.<p> 031 * 032 * @see CollectorContext 033 */ 034 @Uninterruptible 035 public 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 VM.softReferences.clear(); 078 else 079 VM.softReferences.scan(getCurrentTrace(),global().isCurrentGCNursery()); 080 } 081 return; 082 } 083 084 if (phaseId == Simple.WEAK_REFS) { 085 if (primary) { 086 if (Options.noReferenceTypes.getValue()) 087 VM.weakReferences.clear(); 088 else 089 VM.weakReferences.scan(getCurrentTrace(),global().isCurrentGCNursery()); 090 } 091 return; 092 } 093 094 if (phaseId == Simple.FINALIZABLE) { 095 if (primary) { 096 if (Options.noFinalizer.getValue()) 097 VM.finalizableProcessor.clear(); 098 else 099 VM.finalizableProcessor.scan(getCurrentTrace(),global().isCurrentGCNursery()); 100 } 101 return; 102 } 103 104 if (phaseId == Simple.PHANTOM_REFS) { 105 if (primary) { 106 if (Options.noReferenceTypes.getValue()) 107 VM.phantomReferences.clear(); 108 else 109 VM.phantomReferences.scan(getCurrentTrace(),global().isCurrentGCNursery()); 110 } 111 return; 112 } 113 114 if (phaseId == Simple.FORWARD_REFS) { 115 if (primary && !Options.noReferenceTypes.getValue() && 116 VM.activePlan.constraints().needsForwardAfterLiveness()) { 117 VM.softReferences.forward(getCurrentTrace(),global().isCurrentGCNursery()); 118 VM.weakReferences.forward(getCurrentTrace(),global().isCurrentGCNursery()); 119 VM.phantomReferences.forward(getCurrentTrace(),global().isCurrentGCNursery()); 120 } 121 return; 122 } 123 124 if (phaseId == Simple.FORWARD_FINALIZABLE) { 125 if (primary && !Options.noFinalizer.getValue() && 126 VM.activePlan.constraints().needsForwardAfterLiveness()) { 127 VM.finalizableProcessor.forward(getCurrentTrace(),global().isCurrentGCNursery()); 128 } 129 return; 130 } 131 132 if (phaseId == Simple.COMPLETE) { 133 // Nothing to do 134 return; 135 } 136 137 if (phaseId == Simple.RELEASE) { 138 // Nothing to do 139 return; 140 } 141 142 if (Options.sanityCheck.getValue() && sanityLocal.collectionPhase(phaseId, primary)) { 143 return; 144 } 145 146 Log.write("Per-collector phase "); Log.write(Phase.getName(phaseId)); 147 Log.writeln(" not handled."); 148 VM.assertions.fail("Per-collector phase not handled!"); 149 } 150 151 /**************************************************************************** 152 * 153 * Miscellaneous. 154 */ 155 156 /** @return The active global plan as a <code>Simple</code> instance. */ 157 @Inline 158 private static Simple global() { 159 return (Simple) VM.activePlan.global(); 160 } 161 }