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.policy.immix;
014
015 import static org.mmtk.policy.immix.ImmixConstants.*;
016
017 import org.mmtk.utility.Constants;
018 import org.mmtk.vm.VM;
019
020 import org.vmmagic.pragma.*;
021 import org.vmmagic.unboxed.Address;
022
023 /**
024 * This class implements unsynchronized (local) elements of an
025 * immix collector. Marking is done using both a bit in
026 * each header's object word, and a mark byte. Sweeping is
027 * performed lazily.<p>
028 *
029 */
030 @Uninterruptible
031 public final class CollectorLocal implements Constants {
032
033 /****************************************************************************
034 *
035 * Class variables
036 */
037
038
039 /****************************************************************************
040 *
041 * Instance variables
042 */
043
044 /**
045 *
046 */
047 private final ImmixSpace immixSpace;
048 private final ChunkList chunkMap;
049 private final Defrag defrag;
050
051
052 /****************************************************************************
053 *
054 * Initialization
055 */
056
057 /**
058 * Constructor
059 *
060 * @param space The mark-sweep space to which this allocator
061 * instances is bound.
062 */
063 public CollectorLocal(ImmixSpace space) {
064 immixSpace = space;
065 chunkMap = immixSpace.getChunkMap();
066 defrag = immixSpace.getDefrag();
067 }
068
069 /****************************************************************************
070 *
071 * Collection
072 */
073
074 /**
075 * Prepare for a collection. If paranoid, perform a sanity check.
076 */
077 public void prepare(boolean majorGC) {
078 int ordinal = VM.activePlan.collector().parallelWorkerOrdinal();
079 if (majorGC) {
080 if (immixSpace.inImmixDefragCollection()) {
081 short threshold = Defrag.defragSpillThreshold;
082 resetLineMarksAndDefragStateTable(ordinal, threshold);
083 }
084 }
085 }
086
087 private void resetLineMarksAndDefragStateTable(int ordinal, final short threshold) {
088 if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(immixSpace.inImmixDefragCollection());
089 int stride = VM.activePlan.collector().parallelWorkerCount();
090 Address chunk = chunkMap.firstChunk(ordinal, stride);
091 while (!chunk.isZero()) {
092 Chunk.resetLineMarksAndDefragStateTable(chunk, threshold);
093 chunk = chunkMap.nextChunk(chunk, ordinal, stride);
094 }
095 }
096
097 /**
098 * Finish up after a collection.
099 *
100 * We help sweeping all the blocks in parallel.
101 */
102 public void release(boolean majorGC) {
103 sweepAllBlocks(majorGC);
104 }
105
106 private void sweepAllBlocks(boolean majorGC) {
107 int stride = VM.activePlan.collector().parallelWorkerCount();
108 int ordinal = VM.activePlan.collector().parallelWorkerOrdinal();
109 int[] markSpillHisto = defrag.getAndZeroSpillMarkHistogram(ordinal);
110 Address chunk = chunkMap.firstChunk(ordinal, stride);
111 final byte markValue = immixSpace.lineMarkState;
112 final boolean resetMarks = majorGC && markValue == MAX_LINE_MARK_STATE;
113 while (!chunk.isZero()) {
114 Chunk.sweep(chunk, Chunk.getHighWater(chunk), immixSpace, markSpillHisto, markValue, resetMarks);
115 chunk = chunkMap.nextChunk(chunk, ordinal, stride);
116 }
117 }
118 }