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