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