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}