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