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 private StickyMSNurseryTraceLocal nurseryTrace;
045
046 /****************************************************************************
047 * Initialization
048 */
049
050 /**
051 * Constructor
052 */
053 public StickyMSCollector() {
054 ObjectReferenceDeque modBuffer = new ObjectReferenceDeque("mod buffer", global().modPool);
055 fullTrace = new MSTraceLocal(global().msTrace, modBuffer);
056 nurseryTrace = new StickyMSNurseryTraceLocal(global().msTrace, modBuffer);
057 }
058
059 /****************************************************************************
060 *
061 * Collection
062 */
063
064 /**
065 * Perform a per-collector collection phase.
066 *
067 * @param phaseId The collection phase to perform
068 * @param primary Perform any single-threaded activities using this thread.
069 */
070 @Inline
071 public final void collectionPhase(short phaseId, boolean primary) {
072 boolean collectWholeHeap = global().collectWholeHeap;
073
074 if (phaseId == StickyMS.PREPARE) {
075 currentTrace = collectWholeHeap ? (TraceLocal) fullTrace : (TraceLocal) nurseryTrace;
076 global().modPool.prepareNonBlocking(); /* always do this */
077 }
078
079 if (!collectWholeHeap) {
080 if (phaseId == StickyMS.PREPARE) {
081 nurseryTrace.prepare();
082 return;
083 }
084
085 if (phaseId == StickyMS.ROOTS) {
086 VM.scanning.computeStaticRoots(currentTrace);
087 VM.scanning.computeGlobalRoots(currentTrace);
088 return;
089 }
090
091 if (phaseId == StickyMS.CLOSURE) {
092 nurseryTrace.completeTrace();
093 return;
094 }
095
096 if (phaseId == StickyMS.RELEASE) {
097 nurseryTrace.release();
098 global().modPool.reset();
099 return;
100 }
101 }
102
103 super.collectionPhase(phaseId, primary);
104 }
105
106 /****************************************************************************
107 *
108 * Miscellaneous
109 */
110
111 /** @return The active global plan as an <code>MS</code> instance. */
112 @Inline
113 private static StickyMS global() {
114 return (StickyMS) VM.activePlan.global();
115 }
116 }