/* * This file is part of the Jikes RVM project (http://jikesrvm.org). * * This file is licensed to You under the Eclipse Public License (EPL); * 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/eclipse-1.0.php * * See the COPYRIGHT.txt file distributed with this work for information * regarding copyright ownership. */ package org.mmtk.policy; import static org.mmtk.utility.Constants.*; import org.mmtk.utility.heap.FreeListPageResource; import org.mmtk.utility.heap.VMRequest; import org.vmmagic.pragma.*; import org.vmmagic.unboxed.*; /** * Each instance of this class corresponds to one treadmill <b>space</b>.<p> * * Each of the instance methods of this class may be called by any * thread (i.e. synchronization must be explicit in any instance or * class method).<p> * * This stands in contrast to TreadmillLocal, which is instantiated * and called on a per-thread basis, where each instance of * TreadmillLocal corresponds to one thread operating over one space. */ @Uninterruptible public abstract class BaseLargeObjectSpace extends Space { /**************************************************************************** * * Class variables */ /** * */ protected static final Word PAGE_MASK = Word.fromIntSignExtend(~(BYTES_IN_PAGE - 1)); /**************************************************************************** * * Initialization */ /** * The caller specifies the region of virtual memory to be used for * this space. If this region conflicts with an existing space, * then the constructor will fail. * * @param name The name of this space (used when printing error messages etc) * @param zeroed if true, allocations return zeroed memory. * @param vmRequest An object describing the virtual memory requested. */ public BaseLargeObjectSpace(String name, boolean zeroed, VMRequest vmRequest) { super(name, false, false, zeroed, vmRequest); if (vmRequest.isDiscontiguous()) { pr = new FreeListPageResource(this, 0); } else { pr = new FreeListPageResource(this, start, extent); } } /** * Calculates the header size required for the large object. * * Must be multiple of MIN_ALIGNMENT. * * @return the calculated header size */ public final int getHeaderSize() { return superPageHeaderSize() + cellHeaderSize(); } /**************************************************************************** * * 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) { release(getSuperPage(cell)); } /**************************************************************************** * * Superpages */ /** * Return the size of the per-superpage header required by this * system. In this case it is just the underlying superpage header * size. * * @return The size of the per-superpage header required by this * system. */ protected abstract int superPageHeaderSize(); /** * Return the size of the per-cell header for cells of a given class * size. * * @return The size of the per-cell header for cells of a given class * size. */ 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(); } /** * Return the size of the super page * * @param first the Address of the first word in the superpage * @return the size in bytes */ public Extent getSize(Address first) { return ((FreeListPageResource) pr).getSize(first); } }