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.MutatorLocal; 018 019import org.mmtk.utility.alloc.Allocator; 020 021import org.vmmagic.pragma.*; 022import org.vmmagic.unboxed.*; 023 024/** 025 * This class implements <i>per-mutator thread</i> behavior 026 * and state for the <i>Immix</i> plan, which implements a full-heap 027 * immix collector.<p> 028 * 029 * Specifically, this class defines <i>Immix</i> mutator-time allocation 030 * and per-mutator thread collection semantics (flushing and restoring 031 * per-mutator allocator state). 032 * 033 * @see Immix 034 * @see org.mmtk.policy.immix.CollectorLocal 035 * @see StopTheWorldMutator 036 * @see MutatorContext 037 */ 038@Uninterruptible 039public class ImmixMutator extends StopTheWorldMutator { 040 041 /**************************************************************************** 042 * Instance fields 043 */ 044 protected final MutatorLocal immix; 045 046 /**************************************************************************** 047 * 048 * Initialization 049 */ 050 051 /** 052 * Constructor 053 */ 054 public ImmixMutator() { 055 immix = new org.mmtk.policy.immix.MutatorLocal(Immix.immixSpace, false); 056 } 057 058 /**************************************************************************** 059 * 060 * MutatorLocal-time allocation 061 */ 062 063 /** 064 * {@inheritDoc}<p> 065 * 066 * This class handles the default allocator from the mark sweep space, 067 * and delegates everything else to the superclass. 068 */ 069 @Override 070 @Inline 071 public Address alloc(int bytes, int align, int offset, int allocator, int site) { 072 if (allocator == Immix.ALLOC_DEFAULT) 073 return immix.alloc(bytes, align, offset); 074 return super.alloc(bytes, align, offset, allocator, site); 075 } 076 077 /** 078 * {@inheritDoc} 079 * 080 * Initialize the object header for objects in the mark-sweep space, 081 * and delegate to the superclass for other objects. 082 */ 083 @Override 084 @Inline 085 public void postAlloc(ObjectReference ref, ObjectReference typeRef, 086 int bytes, int allocator) { 087 if (allocator == Immix.ALLOC_DEFAULT) 088 Immix.immixSpace.postAlloc(ref, bytes); 089 else 090 super.postAlloc(ref, typeRef, bytes, allocator); 091 } 092 093 @Override 094 public Allocator getAllocatorFromSpace(Space space) { 095 if (space == Immix.immixSpace) return immix; // FIXME is it not a problem that we have a 2:1 mapping? 096 return super.getAllocatorFromSpace(space); 097 } 098 099 /**************************************************************************** 100 * 101 * Collection 102 */ 103 104 /** 105 * {@inheritDoc} 106 */ 107 @Override 108 @Inline 109 public void collectionPhase(short phaseId, boolean primary) { 110 111 if (phaseId == Immix.PREPARE) { 112 super.collectionPhase(phaseId, primary); 113 immix.prepare(); 114 return; 115 } 116 117 if (phaseId == Immix.RELEASE) { 118 immix.release(); 119 super.collectionPhase(phaseId, primary); 120 return; 121 } 122 123 super.collectionPhase(phaseId, primary); 124 } 125}