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    }