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.stickyimmix; 014 015import org.mmtk.plan.*; 016import org.mmtk.plan.immix.Immix; 017import org.mmtk.plan.immix.ImmixCollector; 018import org.mmtk.plan.immix.ImmixDefragTraceLocal; 019import org.mmtk.plan.immix.ImmixTraceLocal; 020import org.mmtk.policy.immix.CollectorLocal; 021import org.mmtk.utility.alloc.ImmixAllocator; 022import org.mmtk.utility.deque.ObjectReferenceDeque; 023import org.mmtk.vm.VM; 024 025import org.vmmagic.pragma.*; 026 027/** 028 * This class implements <i>per-collector thread</i> behavior 029 * and state for the <i>StickMS</i> plan, which implements a generational 030 * sticky mark bits immix collector.<p> 031 * 032 * Specifically, this class defines <i>StickyMS</i> collection behavior 033 * (through <code>trace</code> and the <code>collectionPhase</code> 034 * method).<p> 035 * 036 * @see StickyImmix for an overview of the algorithm. 037 * @see StickyImmixMutator 038 * @see StopTheWorldCollector 039 * @see CollectorContext 040 * @see Phase 041 */ 042@Uninterruptible 043public class StickyImmixCollector extends ImmixCollector { 044 045 /**************************************************************************** 046 * Instance fields 047 */ 048 049 /** 050 * 051 */ 052 private final StickyImmixNurseryTraceLocal nurseryTrace; 053 private final ImmixAllocator nurseryCopy; 054 055 /**************************************************************************** 056 * Initialization 057 */ 058 059 /** 060 * Constructor 061 */ 062 public StickyImmixCollector() { 063 ObjectReferenceDeque modBuffer = new ObjectReferenceDeque("mod buffer", global().modPool); 064 fastTrace = new ImmixTraceLocal(global().immixTrace, modBuffer); 065 defragTrace = new ImmixDefragTraceLocal(global().immixTrace, modBuffer); 066 nurseryTrace = new StickyImmixNurseryTraceLocal(global().immixTrace, modBuffer); 067 immix = new CollectorLocal(StickyImmix.immixSpace); 068 nurseryCopy = new ImmixAllocator(Immix.immixSpace, true, true); 069 } 070 071 /**************************************************************************** 072 * 073 * Collection 074 */ 075 076 /** 077 * {@inheritDoc} 078 */ 079 @Override 080 @Inline 081 public final void collectionPhase(short phaseId, boolean primary) { 082 boolean collectWholeHeap = global().collectWholeHeap; 083 084 if (phaseId == StickyImmix.PREPARE) { 085 global().modPool.prepareNonBlocking(); /* always do this */ 086 } 087 088 if (!collectWholeHeap) { 089 if (phaseId == StickyImmix.PREPARE) { 090 currentTrace = nurseryTrace; 091 immix.prepare(false); 092 nurseryTrace.prepare(); 093 nurseryCopy.reset(); 094 copy.reset(); 095 return; 096 } 097 098 if (phaseId == StickyImmix.ROOTS) { 099 VM.scanning.computeStaticRoots(currentTrace); 100 VM.scanning.computeGlobalRoots(currentTrace); 101 return; 102 } 103 104 if (phaseId == StickyImmix.CLOSURE) { 105 nurseryTrace.completeTrace(); 106 return; 107 } 108 109 if (phaseId == StickyImmix.RELEASE) { 110 nurseryTrace.release(); 111 immix.release(false); 112 global().modPool.reset(); 113 return; 114 } 115 } 116 117 super.collectionPhase(phaseId, primary); 118 } 119 120 /**************************************************************************** 121 * 122 * Miscellaneous 123 */ 124 125 /** @return The active global plan as an <code>StickyImmix</code> instance. */ 126 private static StickyImmix global() { 127 return (StickyImmix) VM.activePlan.global(); 128 } 129}