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.stickyms;
014
015 import org.mmtk.plan.*;
016 import org.mmtk.plan.marksweep.MSCollector;
017 import org.mmtk.plan.marksweep.MSTraceLocal;
018 import org.mmtk.utility.deque.ObjectReferenceDeque;
019 import org.mmtk.vm.VM;
020
021 import org.vmmagic.pragma.*;
022
023 /**
024 * This class implements <i>per-collector thread</i> behavior
025 * and state for the <i>StickMS</i> plan, which implements a generational
026 * sticky mark bits mark-sweep collector.<p>
027 *
028 * Specifically, this class defines <i>StickyMS</i> collection behavior
029 * (through <code>trace</code> and the <code>collectionPhase</code>
030 * method).<p>
031 *
032 * @see StickyMS for an overview of the algorithm.<p>
033 * @see StickyMSMutator
034 * @see StopTheWorldCollector
035 * @see CollectorContext
036 * @see Phase
037 */
038 @Uninterruptible
039 public class StickyMSCollector extends MSCollector {
040
041 /****************************************************************************
042 * Instance fields
043 */
044
045 /**
046 *
047 */
048 private StickyMSNurseryTraceLocal nurseryTrace;
049
050 /****************************************************************************
051 * Initialization
052 */
053
054 /**
055 * Constructor
056 */
057 public StickyMSCollector() {
058 ObjectReferenceDeque modBuffer = new ObjectReferenceDeque("mod buffer", global().modPool);
059 fullTrace = new MSTraceLocal(global().msTrace, modBuffer);
060 nurseryTrace = new StickyMSNurseryTraceLocal(global().msTrace, modBuffer);
061 }
062
063 /****************************************************************************
064 *
065 * Collection
066 */
067
068 /**
069 * {@inheritDoc}
070 */
071 @Override
072 @Inline
073 public final void collectionPhase(short phaseId, boolean primary) {
074 boolean collectWholeHeap = global().collectWholeHeap;
075
076 if (phaseId == StickyMS.PREPARE) {
077 currentTrace = collectWholeHeap ? (TraceLocal) fullTrace : (TraceLocal) nurseryTrace;
078 global().modPool.prepareNonBlocking(); /* always do this */
079 }
080
081 if (!collectWholeHeap) {
082 if (phaseId == StickyMS.PREPARE) {
083 nurseryTrace.prepare();
084 return;
085 }
086
087 if (phaseId == StickyMS.ROOTS) {
088 VM.scanning.computeStaticRoots(currentTrace);
089 VM.scanning.computeGlobalRoots(currentTrace);
090 return;
091 }
092
093 if (phaseId == StickyMS.CLOSURE) {
094 nurseryTrace.completeTrace();
095 return;
096 }
097
098 if (phaseId == StickyMS.RELEASE) {
099 nurseryTrace.release();
100 global().modPool.reset();
101 return;
102 }
103 }
104
105 super.collectionPhase(phaseId, primary);
106 }
107
108 /****************************************************************************
109 *
110 * Miscellaneous
111 */
112
113 /** @return The active global plan as an <code>MS</code> instance. */
114 @Inline
115 private static StickyMS global() {
116 return (StickyMS) VM.activePlan.global();
117 }
118 }