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