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 /**
054 * Return the space this allocator is currently bound to.
055 *
056 * @return The Space.
057 */
058 protected final S getSpace() {
059 return this.space;
060 }
061
062 /****************************************************************************
063 *
064 * Allocation
065 */
066
067 /**
068 * Allocate <code>bytes</code> contiguous bytes of zeroed memory.<p>
069 *
070 * This code implements the fast path, and on failure delegates to the slow path.
071 *
072 * @param bytes The size of the object to occupy this space, in bytes.
073 * @param align The requested alignment.
074 * @param offset The alignment offset.
075 * @return The address of the first word or zero on failure
076 */
077 @Inline
078 public final Address alloc(int bytes, int align, int offset) {
079 int alignedBytes = getMaximumAlignedSize(bytes, align);
080 int sizeClass = getSizeClass(alignedBytes);
081 Address cell = freeList.get(sizeClass);
082 if (!cell.isZero()) {
083 freeList.set(sizeClass, cell.loadAddress());
084 /* Clear the free list link */
085 cell.store(Address.zero());
086 if (alignedBytes != bytes) {
087 /* Ensure aligned as requested. */
088 cell = alignAllocation(cell, align, offset);
089 }
090 return cell;
091 }
092 return allocSlow(bytes, align, offset);
093 }
094
095 /**
096 * The number of distinct size classes.
097 *
098 * NOTE: For optimal performance this call must be implemented in a way
099 * it can be inlined and optimized within the allocation sequence.
100 */
101 @Inline
102 private int sizeClassCount() {
103 return SegregatedFreeListSpace.sizeClassCount();
104 }
105
106 /**
107 * Get the size class for a given number of bytes.
108 *
109 * NOTE: For optimal performance this call must be implemented in a way
110 * it can be inlined and optimized within the allocation sequence.
111 *
112 * @param bytes The number of bytes required to accommodate the object
113 * @return The size class capable of accommodating the allocation request.
114 */
115 @Inline
116 private int getSizeClass(int bytes) {
117 return space.getSizeClass(bytes);
118 }
119 }