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.plan.immix; 014 015import org.mmtk.plan.*; 016import org.mmtk.policy.Space; 017import org.mmtk.policy.immix.ImmixSpace; 018import org.mmtk.policy.immix.ObjectHeader; 019import org.mmtk.utility.heap.VMRequest; 020 021import org.vmmagic.pragma.*; 022import org.vmmagic.unboxed.*; 023 024/** 025 * This class implements the global state of an immix collector.<p> 026 * 027 * See the PLDI'08 paper by Blackburn and McKinley for a description 028 * of the algorithm: http://doi.acm.org/10.1145/1375581.1375586<p> 029 * 030 * All plans make a clear distinction between <i>global</i> and 031 * <i>thread-local</i> activities, and divides global and local state 032 * into separate class hierarchies. Global activities must be 033 * synchronized, whereas no synchronization is required for 034 * thread-local activities. There is a single instance of Plan (or the 035 * appropriate sub-class), and a 1:1 mapping of PlanLocal to "kernel 036 * threads" (aka CPUs or in Jikes RVM, Processors). Thus instance 037 * methods of PlanLocal allow fast, unsychronized access to functions such as 038 * allocation and collection.<p> 039 * 040 * The global instance defines and manages static resources 041 * (such as memory and virtual memory resources). This mapping of threads to 042 * instances is crucial to understanding the correctness and 043 * performance properties of MMTk plans. 044 */ 045@Uninterruptible 046public class Immix extends StopTheWorld { 047 048 /**************************************************************************** 049 * Constants 050 */ 051 052 /**************************************************************************** 053 * Class variables 054 */ 055 056 /** 057 * 058 */ 059 public static final ImmixSpace immixSpace = new ImmixSpace("immix", VMRequest.discontiguous()); 060 public static final int IMMIX = immixSpace.getDescriptor(); 061 062 public static final int SCAN_IMMIX = 0; 063 public static final int SCAN_DEFRAG = 1; 064 065 /**************************************************************************** 066 * Instance variables 067 */ 068 069 /** 070 * 071 */ 072 public final Trace immixTrace = new Trace(metaDataSpace); 073 /** will the next collection collect the whole heap? */ 074 public boolean nextGCWholeHeap = true; 075 /** will this collection collect the whole heap */ 076 public boolean collectWholeHeap = nextGCWholeHeap; 077 protected boolean lastGCWasDefrag = false; 078 079 /** 080 * Constructor. 081 * 082 */ 083 public Immix() { 084 } 085 086 /***************************************************************************** 087 * 088 * Collection 089 */ 090 091 /** 092 * {@inheritDoc} 093 */ 094 @Override 095 @Inline 096 public void collectionPhase(short phaseId) { 097 if (phaseId == SET_COLLECTION_KIND) { 098 super.collectionPhase(phaseId); 099 immixSpace.decideWhetherToDefrag(emergencyCollection, collectWholeHeap, collectionAttempt, userTriggeredCollection); 100 return; 101 } 102 103 if (phaseId == PREPARE) { 104 super.collectionPhase(phaseId); 105 immixTrace.prepare(); 106 immixSpace.prepare(true); 107 return; 108 } 109 110 if (phaseId == CLOSURE) { 111 immixTrace.prepare(); 112 return; 113 } 114 115 if (phaseId == RELEASE) { 116 immixTrace.release(); 117 lastGCWasDefrag = immixSpace.release(true); 118 super.collectionPhase(phaseId); 119 return; 120 } 121 122 super.collectionPhase(phaseId); 123 } 124 125 @Override 126 public boolean lastCollectionWasExhaustive() { 127 return lastGCWasDefrag; 128 } 129 130 /***************************************************************************** 131 * 132 * Accounting 133 */ 134 135 /** 136 * Return the number of pages reserved for use given the pending 137 * allocation. The superclass accounts for its spaces, we just 138 * augment this with the mark-sweep space's contribution. 139 */ 140 @Override 141 public int getPagesUsed() { 142 return immixSpace.reservedPages() + super.getPagesUsed(); 143 } 144 145 /** 146 * Return the number of pages reserved for collection. 147 */ 148 @Override 149 public int getCollectionReserve() { 150 return super.getCollectionReserve() + immixSpace.defragHeadroomPages(); 151 } 152 153 @Override 154 public boolean willNeverMove(ObjectReference object) { 155 if (Space.isInSpace(IMMIX, object)) { 156 ObjectHeader.pinObject(object); 157 return true; 158 } else 159 return super.willNeverMove(object); 160 } 161 162 @Override 163 @Interruptible 164 protected void registerSpecializedMethods() { 165 TransitiveClosure.registerSpecializedScan(SCAN_IMMIX, ImmixTraceLocal.class); 166 TransitiveClosure.registerSpecializedScan(SCAN_DEFRAG, ImmixDefragTraceLocal.class); 167 super.registerSpecializedMethods(); 168 } 169 170 @Override 171 @Interruptible 172 public void preCollectorSpawn() { 173 immixSpace.initializeDefrag(); 174 } 175}