/* * This file is part of the Jikes RVM project (http://jikesrvm.org). * * This file is licensed to You under the Eclipse Public License (EPL); * You may not use this file except in compliance with the License. You * may obtain a copy of the License at * * http://www.opensource.org/licenses/eclipse-1.0.php * * See the COPYRIGHT.txt file distributed with this work for information * regarding copyright ownership. */ package org.mmtk.policy.immix; import static org.mmtk.policy.immix.ImmixConstants.*; import org.mmtk.vm.VM; import org.vmmagic.pragma.*; import org.vmmagic.unboxed.Address; /** * This class implements unsynchronized (local) elements of an * immix collector. Marking is done using both a bit in * each header's object word, and a mark byte. Sweeping is * performed lazily. * */ @Uninterruptible public final class CollectorLocal { /**************************************************************************** * * Class variables */ /**************************************************************************** * * Instance variables */ /** * */ private final ImmixSpace immixSpace; private final ChunkList chunkMap; private final Defrag defrag; /**************************************************************************** * * Initialization */ /** * Constructor * * @param space The mark-sweep space to which this allocator * instances is bound. */ public CollectorLocal(ImmixSpace space) { immixSpace = space; chunkMap = immixSpace.getChunkMap(); defrag = immixSpace.getDefrag(); } /**************************************************************************** * * Collection */ /** * Prepare for a collection. If paranoid, perform a sanity check. * * @param majorGC whether the collection will be a full heap collection */ public void prepare(boolean majorGC) { int ordinal = VM.activePlan.collector().parallelWorkerOrdinal(); if (majorGC) { if (immixSpace.inImmixDefragCollection()) { short threshold = Defrag.defragSpillThreshold; resetLineMarksAndDefragStateTable(ordinal, threshold); } } } private void resetLineMarksAndDefragStateTable(int ordinal, final short threshold) { if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(immixSpace.inImmixDefragCollection()); int stride = VM.activePlan.collector().parallelWorkerCount(); Address chunk = chunkMap.firstChunk(ordinal, stride); while (!chunk.isZero()) { Chunk.resetLineMarksAndDefragStateTable(chunk, threshold); chunk = chunkMap.nextChunk(chunk, ordinal, stride); } } /** * Finish up after a collection. * * We help sweeping all the blocks in parallel. * * @param majorGC whether the collection was a full heap collection */ public void release(boolean majorGC) { sweepAllBlocks(majorGC); } private void sweepAllBlocks(boolean majorGC) { int stride = VM.activePlan.collector().parallelWorkerCount(); int ordinal = VM.activePlan.collector().parallelWorkerOrdinal(); int[] markSpillHisto = defrag.getAndZeroSpillMarkHistogram(ordinal); Address chunk = chunkMap.firstChunk(ordinal, stride); final byte markValue = immixSpace.lineMarkState; final boolean resetMarks = majorGC && markValue == MAX_LINE_MARK_STATE; while (!chunk.isZero()) { Chunk.sweep(chunk, Chunk.getHighWater(chunk), immixSpace, markSpillHisto, markValue, resetMarks); chunk = chunkMap.nextChunk(chunk, ordinal, stride); } } }