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.utility.alloc; 014 015 import org.mmtk.policy.SegregatedFreeListSpace; 016 import org.mmtk.utility.*; 017 018 import org.vmmagic.pragma.*; 019 import org.vmmagic.unboxed.*; 020 021 /** 022 * This abstract class implements the fast past for a segregated free list. 023 */ 024 @Uninterruptible 025 public abstract class SegregatedFreeList<S extends SegregatedFreeListSpace> extends Allocator implements Constants { 026 027 /**************************************************************************** 028 * 029 * Instance variables 030 */ 031 032 /** The space */ 033 protected final S space; 034 035 /** The current free lists for the size classes */ 036 protected final AddressArray freeList; 037 038 /**************************************************************************** 039 * 040 * Initialization 041 */ 042 043 /** 044 * Constructor 045 * 046 * @param space The space with which this allocator will be associated 047 */ 048 public SegregatedFreeList(S space) { 049 this.space = space; 050 this.freeList = AddressArray.create(sizeClassCount()); 051 } 052 053 @Override 054 protected final S getSpace() { 055 return this.space; 056 } 057 058 /**************************************************************************** 059 * 060 * Allocation 061 */ 062 063 /** 064 * Allocate <code>bytes</code> contiguous bytes of zeroed memory.<p> 065 * 066 * This code implements the fast path, and on failure delegates to the slow path. 067 * 068 * @param bytes The size of the object to occupy this space, in bytes. 069 * @param align The requested alignment. 070 * @param offset The alignment offset. 071 * @return The address of the first word or zero on failure 072 */ 073 @Inline 074 public final Address alloc(int bytes, int align, int offset) { 075 int alignedBytes = getMaximumAlignedSize(bytes, align); 076 int sizeClass = getSizeClass(alignedBytes); 077 Address cell = freeList.get(sizeClass); 078 if (!cell.isZero()) { 079 freeList.set(sizeClass, cell.loadAddress()); 080 /* Clear the free list link */ 081 cell.store(Address.zero()); 082 if (alignedBytes != bytes) { 083 /* Ensure aligned as requested. */ 084 cell = alignAllocation(cell, align, offset); 085 } 086 return cell; 087 } 088 return allocSlow(bytes, align, offset); 089 } 090 091 /** 092 * The number of distinct size classes.<p> 093 * 094 * NOTE: For optimal performance this call must be implemented in a way 095 * it can be inlined and optimized within the allocation sequence. 096 */ 097 @Inline 098 private int sizeClassCount() { 099 return SegregatedFreeListSpace.sizeClassCount(); 100 } 101 102 /** 103 * Get the size class for a given number of bytes.<p> 104 * 105 * NOTE: For optimal performance this call must be implemented in a way 106 * it can be inlined and optimized within the allocation sequence. 107 * 108 * @param bytes The number of bytes required to accommodate the object 109 * @return The size class capable of accommodating the allocation request. 110 */ 111 @Inline 112 private int getSizeClass(int bytes) { 113 return space.getSizeClass(bytes); 114 } 115 }