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.semispace.gctrace;
014
015 import org.mmtk.plan.*;
016 import org.mmtk.plan.semispace.*;
017 import org.mmtk.vm.VM;
018
019 import org.vmmagic.pragma.*;
020
021
022 /**
023 * This class implements <i>per-collector thread</i> behavior and state for the
024 * <i>GCTrace</i> plan, which implements a GC tracing algorithm.<p>
025 *
026 * Specifically, this class defines <i>SS</i> collection behavior
027 * (through <code>inducedTrace</code> and the <code>collectionPhase</code>
028 * method), and collection-time allocation (copying of objects).<p>
029 *
030 * See {@link GCTrace} for an overview of the GC trace algorithm.<p>
031 *
032 * @see SSCollector
033 * @see GCTrace
034 * @see GCTraceMutator
035 * @see org.mmtk.plan.StopTheWorldCollector
036 * @see org.mmtk.plan.CollectorContext
037 */
038 @Uninterruptible public class GCTraceCollector extends SSCollector {
039 /****************************************************************************
040 * Instance fields
041 */
042 protected final GCTraceTraceLocal inducedTrace;
043
044 /****************************************************************************
045 *
046 * Initialization
047 */
048
049 /**
050 * Constructor
051 */
052 public GCTraceCollector() {
053 inducedTrace = new GCTraceTraceLocal(global().ssTrace);
054 }
055
056 /****************************************************************************
057 *
058 * Collection
059 */
060
061 /**
062 * {@inheritDoc}
063 */
064 @Override
065 public void collectionPhase(short phaseId, boolean primary) {
066 if (phaseId == GCTrace.CLOSURE) {
067 inducedTrace.completeTrace();
068 return;
069 }
070
071 if (phaseId == GCTrace.RELEASE) {
072 inducedTrace.release();
073 if (!GCTrace.traceInducedGC) {
074 super.collectionPhase(phaseId, primary);
075 }
076 return;
077 }
078
079 /* fall through case */
080 if (!GCTrace.traceInducedGC ||
081 ((phaseId != StopTheWorld.SOFT_REFS) &&
082 (phaseId != StopTheWorld.WEAK_REFS) &&
083 (phaseId != StopTheWorld.PHANTOM_REFS) &&
084 (phaseId != StopTheWorld.FINALIZABLE) &&
085 (phaseId != SS.PREPARE))) {
086 // Delegate up.
087 super.collectionPhase(phaseId, primary);
088 }
089 }
090
091 /****************************************************************************
092 *
093 * Miscellaneous
094 */
095
096 /** @return The active global plan as a <code>GCTrace</code> instance. */
097 @Inline
098 private static GCTrace global() {
099 return (GCTrace) VM.activePlan.global();
100 }
101
102 @Override
103 public TraceLocal getCurrentTrace() {
104 return inducedTrace;
105 }
106 }