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 private final ImmixSpace immixSpace;
044 private final ChunkList chunkMap;
045 private final Defrag defrag;
046
047
048 /****************************************************************************
049 *
050 * Initialization
051 */
052
053 /**
054 * Constructor
055 *
056 * @param space The mark-sweep space to which this allocator
057 * instances is bound.
058 */
059 public CollectorLocal(ImmixSpace space) {
060 immixSpace = space;
061 chunkMap = immixSpace.getChunkMap();
062 defrag = immixSpace.getDefrag();
063 }
064
065 /****************************************************************************
066 *
067 * Collection
068 */
069
070 /**
071 * Prepare for a collection. If paranoid, perform a sanity check.
072 */
073 public void prepare(boolean majorGC) {
074 int ordinal = VM.collection.activeGCThreadOrdinal();
075 if (majorGC) {
076 if (immixSpace.inImmixDefragCollection()) {
077 short threshold = Defrag.defragSpillThreshold;
078 resetLineMarksAndDefragStateTable(ordinal, threshold);
079 }
080 }
081 }
082
083 private void resetLineMarksAndDefragStateTable(int ordinal, final short threshold) {
084 if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(immixSpace.inImmixDefragCollection());
085 int stride = VM.collection.activeGCThreads();
086 Address chunk = chunkMap.firstChunk(ordinal, stride);
087 while (!chunk.isZero()) {
088 Chunk.resetLineMarksAndDefragStateTable(chunk, threshold);
089 chunk = chunkMap.nextChunk(chunk, ordinal, stride);
090 }
091 }
092
093 /**
094 * Finish up after a collection.
095 *
096 * We help sweeping all the blocks in parallel.
097 */
098 public void release(boolean majorGC) {
099 sweepAllBlocks(majorGC);
100 }
101
102 private void sweepAllBlocks(boolean majorGC) {
103 int stride = VM.collection.activeGCThreads();
104 int ordinal = VM.collection.activeGCThreadOrdinal();
105 int[] markSpillHisto = defrag.getAndZeroSpillMarkHistogram(ordinal);
106 Address chunk = chunkMap.firstChunk(ordinal, stride);
107 final byte markValue = immixSpace.lineMarkState;
108 final boolean resetMarks = majorGC && markValue == MAX_LINE_MARK_STATE;
109 while (!chunk.isZero()) {
110 Chunk.sweep(chunk, Chunk.getHighWater(chunk), immixSpace, markSpillHisto, markValue, resetMarks);
111 chunk = chunkMap.nextChunk(chunk, ordinal, stride);
112 }
113 }
114 }