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 }