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