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.utility.alloc;
014
015import static org.mmtk.utility.Constants.*;
016
017import org.mmtk.policy.BaseLargeObjectSpace;
018
019import org.vmmagic.unboxed.*;
020import org.vmmagic.pragma.*;
021
022/**
023 * This abstract class implements core functionality for a generic
024 * large object allocator. The shared VMResource used by each instance
025 * is the point of global synchronization, and synchronization only
026 * occurs at the granularity of acquiring (and releasing) chunks of
027 * memory from the VMResource.  Subclasses may require finer grained
028 * synchronization during a marking phase, for example.<p>
029 *
030 * This is a first cut implementation, with plenty of room for
031 * improvement...
032 */
033@Uninterruptible
034public abstract class LargeObjectAllocator extends Allocator {
035
036  /****************************************************************************
037   *
038   * Instance variables
039   */
040
041  /**
042   *
043   */
044  protected final BaseLargeObjectSpace space;
045
046  /****************************************************************************
047   *
048   * Initialization
049   */
050
051  /**
052   * Constructor
053   *
054   * @param space The space with which this large object allocator
055   * will be associated.
056   */
057  public LargeObjectAllocator(BaseLargeObjectSpace space) {
058    this.space = space;
059  }
060
061  @Override
062  protected final BaseLargeObjectSpace getSpace() {
063    return this.space;
064  }
065
066  /****************************************************************************
067   *
068   * Allocation
069   */
070
071  /**
072   * Allocate space for an object
073   *
074   * @param bytes The number of bytes allocated
075   * @param align The requested alignment.
076   * @param offset The alignment offset.
077   * @return The address of the first byte of the allocated cell Will
078   * not return zero.
079   */
080  @NoInline
081  public final Address alloc(int bytes, int align, int offset) {
082    Address cell = allocSlow(bytes, align, offset);
083    return alignAllocation(cell, align, offset);
084  }
085
086  /**
087   * Allocate a large object.  Large objects are directly allocted and
088   * freed in page-grained units via the vm resource.  This routine
089   * returned zeroed memory.
090   *
091   * @param bytes The required size of this space in bytes.
092   * @param offset The alignment offset.
093   * @param align The requested alignment.
094   * @return The address of the start of the newly allocated region at
095   * least <code>bytes</code> bytes in size.
096   */
097  @Override
098  protected final Address allocSlowOnce(int bytes, int align, int offset) {
099    int header = space.getHeaderSize();
100    int maxbytes = getMaximumAlignedSize(bytes + header, align);
101    int pages = (maxbytes + BYTES_IN_PAGE - 1) >> LOG_BYTES_IN_PAGE;
102    Address sp = space.acquire(pages);
103    if (sp.isZero()) return sp;
104    Address cell = sp.plus(header);
105    return cell;
106  }
107
108  /****************************************************************************
109   *
110   * Miscellaneous
111   */
112  public void show() {
113  }
114}
115