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
049 /**
050 *
051 */
052 private StickyImmixNurseryTraceLocal nurseryTrace;
053 private final ImmixAllocator nurseryCopy;
054
055 /****************************************************************************
056 * Initialization
057 */
058
059 /**
060 * Constructor
061 */
062 public StickyImmixCollector() {
063 ObjectReferenceDeque modBuffer = new ObjectReferenceDeque("mod buffer", global().modPool);
064 fastTrace = new ImmixTraceLocal(global().immixTrace, modBuffer);
065 defragTrace = new ImmixDefragTraceLocal(global().immixTrace, modBuffer);
066 nurseryTrace = new StickyImmixNurseryTraceLocal(global().immixTrace, modBuffer);
067 immix = new CollectorLocal(StickyImmix.immixSpace);
068 nurseryCopy = new ImmixAllocator(Immix.immixSpace, true, true);
069 }
070
071 /****************************************************************************
072 *
073 * Collection
074 */
075
076 /**
077 * {@inheritDoc}
078 */
079 @Override
080 @Inline
081 public final void collectionPhase(short phaseId, boolean primary) {
082 boolean collectWholeHeap = global().collectWholeHeap;
083
084 if (phaseId == StickyImmix.PREPARE) {
085 global().modPool.prepareNonBlocking(); /* always do this */
086 }
087
088 if (!collectWholeHeap) {
089 if (phaseId == StickyImmix.PREPARE) {
090 currentTrace = nurseryTrace;
091 immix.prepare(false);
092 nurseryTrace.prepare();
093 nurseryCopy.reset();
094 copy.reset();
095 return;
096 }
097
098 if (phaseId == StickyImmix.ROOTS) {
099 VM.scanning.computeStaticRoots(currentTrace);
100 VM.scanning.computeGlobalRoots(currentTrace);
101 return;
102 }
103
104 if (phaseId == StickyImmix.CLOSURE) {
105 nurseryTrace.completeTrace();
106 return;
107 }
108
109 if (phaseId == StickyImmix.RELEASE) {
110 nurseryTrace.release();
111 immix.release(false);
112 global().modPool.reset();
113 return;
114 }
115 }
116
117 super.collectionPhase(phaseId, primary);
118 }
119
120 /****************************************************************************
121 *
122 * Miscellaneous
123 */
124
125 /** @return The active global plan as an <code>StickyImmix</code> instance. */
126 private static StickyImmix global() {
127 return (StickyImmix) VM.activePlan.global();
128 }
129 }