/*
* This file is part of the Jikes RVM project (http://jikesrvm.org).
*
* This file is licensed to You under the Common Public License (CPL);
* You may not use this file except in compliance with the License. You
* may obtain a copy of the License at
*
* http://www.opensource.org/licenses/cpl1.0.php
*
* See the COPYRIGHT.txt file distributed with this work for information
* regarding copyright ownership.
*/
package org.mmtk.utility.alloc;
import org.mmtk.policy.LargeObjectSpace;
import org.mmtk.utility.Constants;
import org.vmmagic.unboxed.*;
import org.vmmagic.pragma.*;
/**
* This abstract class implements core functionality for a generic
* large object allocator. The shared VMResource used by each instance
* is the point of global synchronization, and synchronization only
* occurs at the granularity of aquiring (and releasing) chunks of
* memory from the VMResource. Subclasses may require finer grained
* synchronization during a marking phase, for example.<p>
*
* This is a first cut implementation, with plenty of room for
* improvement...
*/
@Uninterruptible public abstract class LargeObjectAllocator extends Allocator implements Constants {
/****************************************************************************
*
* Class variables
*/
protected static final Word PAGE_MASK = Word.fromIntSignExtend(~(BYTES_IN_PAGE - 1));
/****************************************************************************
*
* Instance variables
*/
protected LargeObjectSpace space;
/****************************************************************************
*
* Initialization
*/
/**
* Constructor
*
* @param space The space with which this large object allocator
* will be associated.
*/
public LargeObjectAllocator(LargeObjectSpace space) {
this.space = space;
}
/****************************************************************************
*
* Allocation
*/
/**
* Allocate space for an object
*
* @param bytes The number of bytes allocated
* @param align The requested alignment.
* @param offset The alignment offset.
* @return The address of the first byte of the allocated cell Will
* not return zero.
*/
@NoInline
public final Address alloc(int bytes, int align, int offset) {
Address cell = allocSlow(bytes, align, offset);
postAlloc(cell);
return alignAllocation(cell, align, offset);
}
protected abstract void postAlloc(Address cell);
/**
* Allocate a large object. Large objects are directly allocted and
* freed in page-grained units via the vm resource. This routine
* returned zeroed memory.
*
* @param bytes The required size of this space in bytes.
* @param offset The alignment offset.
* @param align The requested alignment.
* @return The address of the start of the newly allocated region at
* least <code>bytes</code> bytes in size.
*/
protected final Address allocSlowOnce(int bytes, int align, int offset) {
int header = superPageHeaderSize() + cellHeaderSize(); //must be multiple of MIN_ALIGNMENT
int maxbytes = getMaximumAlignedSize(bytes + header, align);
int pages = (maxbytes + BYTES_IN_PAGE - 1) >> LOG_BYTES_IN_PAGE;
Address sp = space.acquire(pages);
if (sp.isZero()) return sp;
Address cell = sp.plus(header);
return cell;
}
/****************************************************************************
*
* Freeing
*/
/**
* Free a cell. If the cell is large (own superpage) then release
* the superpage, if not add to the super page's free list and if
* all cells on the superpage are free, then release the
* superpage.
*
* @param cell The address of the first byte of the cell to be freed
*/
@Inline
public final void free(Address cell) {
space.release(getSuperPage(cell));
}
/****************************************************************************
*
* Superpages
*/
protected abstract int superPageHeaderSize();
protected abstract int cellHeaderSize();
/**
* Return the superpage for a given cell. If the cell is a small
* cell then this is found by masking the cell address to find the
* containing page. Otherwise the first word of the cell contains
* the address of the page.
*
* @param cell The address of the first word of the cell (exclusive
* of any sub-class specific metadata).
* @return The address of the first word of the superpage containing
* <code>cell</code>.
*/
@Inline
public static Address getSuperPage(Address cell) {
return cell.toWord().and(PAGE_MASK).toAddress();
}
/****************************************************************************
*
* Miscellaneous
*/
public void show() {
}
}