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 }