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.policy;
014
015import static org.mmtk.utility.Constants.*;
016
017import org.mmtk.utility.heap.FreeListPageResource;
018import org.mmtk.utility.heap.VMRequest;
019
020import org.vmmagic.pragma.*;
021import org.vmmagic.unboxed.*;
022
023/**
024 * Each instance of this class corresponds to one treadmill <b>space</b>.<p>
025 *
026 * Each of the instance methods of this class may be called by any
027 * thread (i.e. synchronization must be explicit in any instance or
028 * class method).<p>
029 *
030 * This stands in contrast to TreadmillLocal, which is instantiated
031 * and called on a per-thread basis, where each instance of
032 * TreadmillLocal corresponds to one thread operating over one space.
033 */
034@Uninterruptible
035public abstract class BaseLargeObjectSpace extends Space {
036
037  /****************************************************************************
038   *
039   * Class variables
040   */
041
042  /**
043   *
044   */
045  protected static final Word PAGE_MASK = Word.fromIntSignExtend(~(BYTES_IN_PAGE - 1));
046
047  /****************************************************************************
048   *
049   * Initialization
050   */
051
052  /**
053   * The caller specifies the region of virtual memory to be used for
054   * this space.  If this region conflicts with an existing space,
055   * then the constructor will fail.
056   *
057   * @param name The name of this space (used when printing error messages etc)
058   * @param zeroed if true, allocations return zeroed memory.
059   * @param vmRequest An object describing the virtual memory requested.
060   */
061  public BaseLargeObjectSpace(String name, boolean zeroed, VMRequest vmRequest) {
062    super(name, false, false, zeroed, vmRequest);
063    if (vmRequest.isDiscontiguous()) {
064      pr = new FreeListPageResource(this, 0);
065    } else {
066      pr = new FreeListPageResource(this, start, extent);
067    }
068  }
069
070  /**
071   * Calculates the header size required for the large object.
072   *
073   * Must be multiple of MIN_ALIGNMENT.
074   *
075   * @return the calculated header size
076   */
077  public final int getHeaderSize() {
078    return superPageHeaderSize() + cellHeaderSize();
079  }
080
081  /****************************************************************************
082   *
083   * Freeing
084   */
085
086  /**
087   * Free a cell.  If the cell is large (own superpage) then release
088   * the superpage, if not add to the super page's free list and if
089   * all cells on the superpage are free, then release the
090   * superpage.
091   *
092   * @param cell The address of the first byte of the cell to be freed
093   */
094  @Inline
095  public final void free(Address cell) {
096    release(getSuperPage(cell));
097  }
098
099  /****************************************************************************
100   *
101   * Superpages
102   */
103
104  /**
105   * Return the size of the per-superpage header required by this
106   * system.  In this case it is just the underlying superpage header
107   * size.
108   *
109   * @return The size of the per-superpage header required by this
110   * system.
111   */
112  protected abstract int superPageHeaderSize();
113
114  /**
115   * Return the size of the per-cell header for cells of a given class
116   * size.
117   *
118   * @return The size of the per-cell header for cells of a given class
119   * size.
120   */
121  protected abstract int cellHeaderSize();
122
123  /**
124   * Return the superpage for a given cell.  If the cell is a small
125   * cell then this is found by masking the cell address to find the
126   * containing page.  Otherwise the first word of the cell contains
127   * the address of the page.
128   *
129   * @param cell The address of the first word of the cell (exclusive
130   * of any sub-class specific metadata).
131   * @return The address of the first word of the superpage containing
132   *         <code>cell</code>.
133   */
134  @Inline
135  public static Address getSuperPage(Address cell) {
136    return cell.toWord().and(PAGE_MASK).toAddress();
137  }
138
139  /**
140   * Return the size of the super page
141   *
142   * @param first the Address of the first word in the superpage
143   * @return the size in bytes
144   */
145  public Extent getSize(Address first) {
146    return ((FreeListPageResource) pr).getSize(first);
147  }
148}