Index: MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/Barriers.java =================================================================== --- MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/Barriers.java (revision 13397) +++ MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/Barriers.java (working copy) @@ -88,6 +88,26 @@ } /** + * Sets an element of a object array without invoking any write + * barrier. + * + * @param dst the destination array + * @param index the index of the element to set + * @param value the new value for the element + */ + @Override + public final void setArrayNoBarrier(Object [] dst, int index, Object value) { + setArrayNoBarrierStatic(dst, index, value); + } + @UninterruptibleNoWarn + public static void setArrayNoBarrierStatic(Object [] dst, int index, Object value) { + if (VM.runningVM) + VM_Magic.setObjectAtOffset(dst, Offset.fromIntZeroExtend(index << LOG_BYTES_IN_ADDRESS), value); + else + dst[index] = value; + } + + /** * Sets an element of a char array without invoking any write * barrier. This method is called by the Log method, as it will be * used during garbage collection and needs to manipulate character Index: MMTk/src/org/mmtk/policy/ImmortalSpace.java =================================================================== --- MMTk/src/org/mmtk/policy/ImmortalSpace.java (revision 13397) +++ MMTk/src/org/mmtk/policy/ImmortalSpace.java (working copy) @@ -49,6 +49,21 @@ * * 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 pageBudget The number of pages this space may consume + * before consulting the plan + * @param start The start address of the space in virtual memory + * @param bytes The size of the space in virtual memory, in bytes + */ + public ImmortalSpace(String name, int pageBudget) { + super(name, false, true); + pr = new MonotonePageResource(pageBudget, this, META_DATA_PAGES_PER_REGION); + } /** * The caller specifies the region of virtual memory to be used for Index: MMTk/src/org/mmtk/policy/RawPageSpace.java =================================================================== --- MMTk/src/org/mmtk/policy/RawPageSpace.java (revision 13397) +++ MMTk/src/org/mmtk/policy/RawPageSpace.java (working copy) @@ -41,6 +41,22 @@ * @param start The start address of the space in virtual memory * @param bytes The size of the space in virtual memory, in bytes */ + public RawPageSpace(String name, int pageBudget) { + super(name, false, false); + pr = new FreeListPageResource(pageBudget, this, 0); + } + + /** + * 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 pageBudget The number of pages this space may consume + * before consulting the plan + * @param start The start address of the space in virtual memory + * @param bytes The size of the space in virtual memory, in bytes + */ public RawPageSpace(String name, int pageBudget, Address start, Extent bytes) { super(name, false, false, start, bytes); Index: MMTk/src/org/mmtk/policy/MarkSweepSpace.java =================================================================== --- MMTk/src/org/mmtk/policy/MarkSweepSpace.java (revision 13397) +++ MMTk/src/org/mmtk/policy/MarkSweepSpace.java (working copy) @@ -86,6 +86,22 @@ * @param start The start address of the space in virtual memory * @param bytes The size of the space in virtual memory, in bytes */ + public MarkSweepSpace(String name, int pageBudget) { + super(name, false, false); + pr = new FreeListPageResource(pageBudget, this, MarkSweepLocal.META_DATA_PAGES_PER_REGION); + } + + /** + * 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 pageBudget The number of pages this space may consume + * before consulting the plan + * @param start The start address of the space in virtual memory + * @param bytes The size of the space in virtual memory, in bytes + */ public MarkSweepSpace(String name, int pageBudget, Address start, Extent bytes) { super(name, false, false, start, bytes); Index: MMTk/src/org/mmtk/policy/CopySpace.java =================================================================== --- MMTk/src/org/mmtk/policy/CopySpace.java (revision 13397) +++ MMTk/src/org/mmtk/policy/CopySpace.java (working copy) @@ -80,6 +80,26 @@ * @param fromSpace The does this instance start life as from-space * (or to-space)? */ + public CopySpace(String name, int pageBudget, boolean fromSpace) { + super(name, true, false); + this.fromSpace = fromSpace; + pr = new MonotonePageResource(pageBudget, this, META_DATA_PAGES_PER_REGION); + } + + + /** + * 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 pageBudget The number of pages this space may consume + * before consulting the plan + * @param start The start address of the space in virtual memory + * @param bytes The size of the space in virtual memory, in bytes + * @param fromSpace The does this instance start life as from-space + * (or to-space)? + */ public CopySpace(String name, int pageBudget, Address start, Extent bytes, boolean fromSpace) { super(name, true, false, start, bytes); @@ -204,7 +224,13 @@ * Release this copy space after a collection. This means releasing * all pages associated with this (now empty) space. */ - public void release() { ((MonotonePageResource) pr).reset(); } + public void release() { + if (!contiguous) { + start = Address.zero(); + extent = Extent.zero(); + } + ((MonotonePageResource) pr).reset(); + } /** * Release an allocated page or pages. In this case we do nothing Index: MMTk/src/org/mmtk/policy/Space.java =================================================================== --- MMTk/src/org/mmtk/policy/Space.java (revision 13397) +++ MMTk/src/org/mmtk/policy/Space.java (working copy) @@ -41,9 +41,9 @@ * policy, spaces also manage memory consumption (used virtual * memory).
* - * Discontiguous spaces are currently unsupported. */ -@Uninterruptible public abstract class Space implements Constants { +@Uninterruptible +public abstract class Space implements Constants { /**************************************************************************** * @@ -53,19 +53,23 @@ private static boolean DEBUG = false; // the following is somewhat arbitrary for the 64 bit system at this stage - private static final int LOG_ADDRESS_SPACE = (BYTES_IN_ADDRESS == 4) ? 32 : 40; - private static Address HEAP_START = chunkAlign(VM.HEAP_START, true); - private static Address AVAILABLE_START = chunkAlign(VM.AVAILABLE_START, false); - private static Address AVAILABLE_END = chunkAlign(VM.AVAILABLE_END, true); - private static Extent AVAILABLE_BYTES = AVAILABLE_END.toWord().minus(AVAILABLE_START.toWord()).toExtent(); - public static final Address HEAP_END = chunkAlign(VM.HEAP_END, false); - + private static final int LOG_ADDRESS_SPACE = (BYTES_IN_ADDRESS == 4) ? 32 : 38; public static final int LOG_BYTES_IN_CHUNK = 22; public static final int BYTES_IN_CHUNK = 1 << LOG_BYTES_IN_CHUNK; + public static final int PAGES_IN_CHUNK = 1 << (LOG_BYTES_IN_CHUNK - LOG_BYTES_IN_PAGE); private static final int LOG_MAX_CHUNKS = LOG_ADDRESS_SPACE - LOG_BYTES_IN_CHUNK; public static final int MAX_CHUNKS = 1 << LOG_MAX_CHUNKS; public static final int MAX_SPACES = 20; // quite arbitrary + public static final Address HEAP_START = chunkAlign(VM.HEAP_START, true); + public static final Address AVAILABLE_START = chunkAlign(VM.AVAILABLE_START, false); + private static final Address AVAILABLE_END = chunkAlign(VM.AVAILABLE_END, true); + private static final Extent AVAILABLE_BYTES = AVAILABLE_END.toWord().minus(AVAILABLE_START.toWord()).toExtent(); + public static final int AVAILABLE_PAGES = AVAILABLE_BYTES.toWord().rshl(LOG_BYTES_IN_PAGE).toInt(); + public static final Address HEAP_END = chunkAlign(VM.HEAP_END, false); + + private static final boolean FORCE_SLOW_MAP_LOOKUP = true; + private static final int PAGES = 0; private static final int MB = 1; private static final int PAGES_MB = 2; @@ -80,13 +84,15 @@ * * Instance variables */ - private int descriptor; - private int index; - private String name; + private final String name; + private final int descriptor; + private final int index; + protected final boolean immortal; + protected final boolean movable; + protected final boolean contiguous; + protected Address start; protected Extent extent; - protected boolean immortal; - protected boolean movable; private boolean allocationFailed; protected PageResource pr; @@ -97,6 +103,41 @@ */ /** + * This is the base constructor for all spaces.
+ * + * @param name The name of this space (used when printing error messages etc) + * @param movable Are objects in this space movable? + * @param immortal Are objects in this space immortal (uncollected)? + * @param contiguous Is this space contiguous? + * @param descriptor The descriptor for this space. + */ + Space(String name, boolean movable, boolean immortal, boolean contiguous, int descriptor) { + this.name = name; + this.movable = movable; + this.immortal = immortal; + this.contiguous = contiguous; + this.descriptor = descriptor; + this.index = spaceCount++; + spaces[index] = this; + } + + /** + * This is the base constructor for discontiguous spaces + * (i.e. those that may occupy multiple disjoint regions of virtual + * memory).
+ * + * @param name The name of this space (used when printing error messages etc) + * @param movable Are objects in this space movable? + * @param immortal Are objects in this space immortal (uncollected)? + */ + Space(String name, boolean movable, boolean immortal) { + this(name, movable, immortal, false, SpaceDescriptor.createDescriptor()); + this.start = Address.zero(); + this.extent = Extent.zero(); + VM.memory.setHeapRange(index, HEAP_START, HEAP_END); // this should really be refined! Once we have a code space, we can be a lot more specific about what is a valid code heap area + } + + /** * This is the base constructor for contiguous spaces * (i.e. those that occupy a single contiguous range of virtual * memory which is identified at construction time).
@@ -113,12 +154,9 @@
*/
Space(String name, boolean movable, boolean immortal, Address start,
Extent bytes) {
- this.name = name;
- this.movable = movable;
- this.immortal = immortal;
+ this(name, movable, immortal, true, SpaceDescriptor.createDescriptor(start, start.plus(bytes)));
this.start = start;
- index = spaceCount++;
- spaces[index] = this;
+ this.extent = bytes;
/* ensure requests are chunk aligned */
if (bytes.NE(chunkAlign(bytes, false))) {
@@ -130,10 +168,7 @@
Log.write(bytes.toLong()); Log.writeln(" bytes");
Log.writeln("(requests should be Space.BYTES_IN_CHUNK aligned)");
}
- this.extent = bytes;
-
VM.memory.setHeapRange(index, start, start.plus(bytes));
- createDescriptor(false);
Map.insert(start, extent, descriptor, this);
if (DEBUG) {
@@ -276,7 +311,6 @@
}
}
-
/****************************************************************************
*
* Accessor methods
@@ -406,7 +440,7 @@
@Inline
public static boolean isInSpace(int descriptor, Address address) {
if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(!address.isZero());
- if (!SpaceDescriptor.isContiguous(descriptor)) {
+ if (FORCE_SLOW_MAP_LOOKUP || !SpaceDescriptor.isContiguous(descriptor)) {
return getDescriptorForAddress(address) == descriptor;
} else {
Address start = SpaceDescriptor.getStart(descriptor);
@@ -503,6 +537,20 @@
return rtn;
}
+ public Address growDiscontiguousSpace(Extent bytes) {
+ Extent extent = chunkAlign(bytes, false);
+ int chunks = extent.toWord().rshl(LOG_BYTES_IN_CHUNK).toInt();
+ start = Map.allocateContiguousChunks(descriptor, this, chunks, start);
+ this.extent = (start.isZero()) ? Extent.zero() : extent;
+ return start;
+ }
+
+ public void releaseDiscontiguousChunk(Address chunk) {
+ if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(chunk.EQ(chunkAlign(chunk, true)));
+ // FIXME need to properly deal with start and extent --- see use in VM_Scheduler :-/
+ Map.freeContiguousChunks(chunk);
+ }
+
/**
* Release a unit of allocation (a page or pages)
*
@@ -665,7 +713,7 @@
* @param down If true the address will be rounded down, otherwise
* it will rounded up.
*/
- private static Address chunkAlign(Address addr, boolean down) {
+ public static Address chunkAlign(Address addr, boolean down) {
if (!down) addr = addr.plus(BYTES_IN_CHUNK - 1);
return addr.toWord().rshl(LOG_BYTES_IN_CHUNK).lsh(LOG_BYTES_IN_CHUNK).toAddress();
}
@@ -677,24 +725,12 @@
* @param down If true the address will be rounded down, otherwise
* it will rounded up.
*/
- private static Extent chunkAlign(Extent bytes, boolean down) {
+ public static Extent chunkAlign(Extent bytes, boolean down) {
if (!down) bytes = bytes.plus(BYTES_IN_CHUNK - 1);
return bytes.toWord().rshl(LOG_BYTES_IN_CHUNK).lsh(LOG_BYTES_IN_CHUNK).toExtent();
}
/**
- * Initialize/create the descriptor for this space
- *
- * @param shared True if this is a shared (discontiguous) space
- */
- private void createDescriptor(boolean shared) {
- if (shared)
- descriptor = SpaceDescriptor.createDescriptor();
- else
- descriptor = SpaceDescriptor.createDescriptor(start, start.plus(extent));
- }
-
- /**
* Convert a fraction into a number of bytes according to the
* fraction of available bytes.
*
Index: MMTk/src/org/mmtk/policy/LargeObjectSpace.java
===================================================================
--- MMTk/src/org/mmtk/policy/LargeObjectSpace.java (revision 13397)
+++ MMTk/src/org/mmtk/policy/LargeObjectSpace.java (working copy)
@@ -73,6 +73,22 @@
* @param start The start address of the space in virtual memory
* @param bytes The size of the space in virtual memory, in bytes
*/
+ public LargeObjectSpace(String name, int pageBudget) {
+ super(name, false, false);
+ init(pageBudget);
+ }
+
+ /**
+ * 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 pageBudget The number of pages this space may consume
+ * before consulting the plan
+ * @param start The start address of the space in virtual memory
+ * @param bytes The size of the space in virtual memory, in bytes
+ */
public LargeObjectSpace(String name, int pageBudget, Address start,
Extent bytes) {
super(name, false, false, start, bytes);
@@ -165,7 +181,10 @@
@Interruptible
private void init(int pageBudget) {
- pr = new FreeListPageResource(pageBudget, this, start, extent);
+ if (start.isZero())
+ pr = new FreeListPageResource(pageBudget, this, 0);
+ else
+ pr = new FreeListPageResource(pageBudget, this, start, extent);
cells = new DoublyLinkedList(LOG_BYTES_IN_PAGE, true);
treadmill = new Treadmill(LOG_BYTES_IN_PAGE, true);
}
Index: MMTk/src/org/mmtk/vm/Barriers.java
===================================================================
--- MMTk/src/org/mmtk/vm/Barriers.java (revision 13397)
+++ MMTk/src/org/mmtk/vm/Barriers.java (working copy)
@@ -29,6 +29,16 @@
public abstract void setArrayNoBarrier(char [] dst, int index, char value);
/**
+ * Sets an element of an object array without invoking any write
+ * barrier.
+ *
+ * @param dst the destination array
+ * @param index the index of the element to set
+ * @param value the new value for the element
+ */
+ public abstract void setArrayNoBarrier(Object [] dst, int index, Object value);
+
+ /**
* Perform the actual write of the write barrier.
*
* @param ref The object that has the reference field
Index: MMTk/src/org/mmtk/utility/BaseGenericFreeList.java
===================================================================
--- MMTk/src/org/mmtk/utility/BaseGenericFreeList.java (revision 13397)
+++ MMTk/src/org/mmtk/utility/BaseGenericFreeList.java (working copy)
@@ -165,17 +165,19 @@
* Free a previously allocated contiguous lump of units.
*
* @param unit The index of the first unit.
+ * @param returnCoalescedSize TODO
* @return The number of units freed.
*/
- public final int free(int unit) {
+ public final int free(int unit, boolean returnCoalescedSize) {
int freed = getSize(unit);
int start = getFree(getLeft(unit)) ? getLeft(unit) : unit;
int end = getFree(getRight(unit)) ? getRight(unit) : unit;
if (start != end)
coalesce(start, end);
+ if (returnCoalescedSize)
+ freed = getSize(start);
addToFree(start);
if (DEBUG) dbgPrintFree();
-
return freed;
}
@@ -243,6 +245,7 @@
setSize(unit, size);
setSize(unit + size, basesize - size);
addToFree(unit + size);
+ if (DEBUG) dbgPrintFree();
}
/**
@@ -284,6 +287,7 @@
int prev = getPrev(unit);
setNext(prev, next);
setPrev(next, prev);
+ if (DEBUG) dbgPrintFree();
}
/**
@@ -313,9 +317,9 @@
Log.write(i);
if (!f)
Log.write("<-");
- Log.write("[");
+ Log.write("(");
Log.write(s);
- Log.write("]");
+ Log.write(")");
Log.write(" ");
Log.flush();
}
Index: MMTk/src/org/mmtk/utility/sanitychecker/SanityChecker.java
===================================================================
--- MMTk/src/org/mmtk/utility/sanitychecker/SanityChecker.java (revision 13397)
+++ MMTk/src/org/mmtk/utility/sanitychecker/SanityChecker.java (working copy)
@@ -12,9 +12,9 @@
*/
package org.mmtk.utility.sanitychecker;
+import org.mmtk.plan.Plan;
import org.mmtk.plan.Trace;
import org.mmtk.plan.StopTheWorld;
-import org.mmtk.policy.RawPageSpace;
import org.mmtk.policy.Space;
import org.mmtk.utility.Constants;
import org.mmtk.utility.Log;
@@ -42,20 +42,17 @@
public static final int SANITY_DATA_MB = 32;
public static final int LOG_SANITY_DATA_SIZE = 21;
- public static final RawPageSpace sanitySpace = new RawPageSpace("sanity", Integer.MAX_VALUE, SANITY_DATA_MB);
- public static final int SANITY = sanitySpace.getDescriptor();
-
/* Trace */
public Trace trace;
- private SanityDataTable sanityTable;
+ private final SanityDataTable sanityTable;
private boolean preGCSanity;
/****************************************************************************
* Constants
*/
public SanityChecker() {
- sanityTable = new SanityDataTable(sanitySpace, LOG_SANITY_DATA_SIZE);
- trace = new Trace(sanitySpace);
+ sanityTable = new SanityDataTable(Plan.sanitySpace, LOG_SANITY_DATA_SIZE);
+ trace = new Trace(Plan.sanitySpace);
preGCSanity = true;
}
Index: MMTk/src/org/mmtk/utility/heap/FreeListPageResource.java
===================================================================
--- MMTk/src/org/mmtk/utility/heap/FreeListPageResource.java (revision 13397)
+++ MMTk/src/org/mmtk/utility/heap/FreeListPageResource.java (working copy)
@@ -13,6 +13,7 @@
package org.mmtk.utility.heap;
import org.mmtk.policy.Space;
+import static org.mmtk.policy.Space.PAGES_IN_CHUNK;
import org.mmtk.utility.alloc.EmbeddedMetaData;
import org.mmtk.utility.Conversions;
import org.mmtk.utility.GenericFreeList;
@@ -31,9 +32,9 @@
@Uninterruptible public final class FreeListPageResource extends PageResource
implements Constants {
- private GenericFreeList freeList;
+ private final GenericFreeList freeList;
private int highWaterMark = 0;
- private int metaDataPagesPerRegion = 0;
+ private final int metaDataPagesPerRegion;
/**
* Constructor
@@ -51,6 +52,7 @@
Extent bytes) {
super(pageBudget, space, start);
freeList = new GenericFreeList(Conversions.bytesToPages(bytes));
+ this.metaDataPagesPerRegion = 0;
}
/**
@@ -82,16 +84,21 @@
* pre-defined at initializtion time and is dynamically defined to
* be some set of pages, according to demand and availability.
*
- * CURRENTLY UNIMPLEMENTED
- *
* @param pageBudget The budget of pages available to this memory
* manager before it must poll the collector.
* @param space The space to which this resource is attached
*/
- public FreeListPageResource(int pageBudget, Space space) {
+ public FreeListPageResource(int pageBudget, Space space, int metaDataPagesPerRegion) {
super(pageBudget, space);
- /* unimplemented */
- if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(false);
+ this.metaDataPagesPerRegion = metaDataPagesPerRegion;
+ this.start = Space.AVAILABLE_START;
+ freeList = new GenericFreeList(Space.AVAILABLE_PAGES, EmbeddedMetaData.PAGES_IN_REGION);
+ for (int p = 0; p < Space.AVAILABLE_PAGES; p++) {
+
+ int tmp = freeList.alloc(1); // pin down entire space
+// Log.write("fpr["); Log.write(p); Log.write(" "); Log.write(tmp); Log.writeln("]");
+ if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(tmp == p);
+ }
}
/**
@@ -107,9 +114,11 @@
*/
@Inline
protected Address allocPages(int pages) {
- if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(contiguous);
+ if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(metaDataPagesPerRegion == 0 || pages <= PAGES_IN_CHUNK - metaDataPagesPerRegion);
lock();
int pageOffset = freeList.alloc(pages);
+ if (pageOffset == -1 && !contiguous)
+ pageOffset = allocateDiscontiguousChunks(pages);
if (pageOffset == -1) {
unlock();
return Address.zero();
@@ -159,10 +168,50 @@
lock();
reserved -= pages;
committed -= pages;
- freeList.free(pageOffset);
+ int freed = freeList.free(pageOffset, true);
+ // FIXME Can't yet deal with multi-chunk regions :-/
+ if (!contiguous && metaDataPagesPerRegion > 0 && freed == PAGES_IN_CHUNK - metaDataPagesPerRegion)
+ freeDiscontiguousChunk(Space.chunkAlign(first, true));
unlock();
}
+ private int allocateDiscontiguousChunks(int pages) {
+ if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(metaDataPagesPerRegion == 0 || pages <= PAGES_IN_CHUNK - metaDataPagesPerRegion);
+ int rtn = -1;
+ Extent required = Space.chunkAlign(Extent.fromIntZeroExtend(pages<
*/
-@Uninterruptible public final class MonotonePageResource extends PageResource
+@Uninterruptible
+public final class MonotonePageResource extends PageResource
implements Constants {
/****************************************************************************
@@ -38,13 +39,13 @@
*/
private Address cursor;
private Address sentinel;
- private int metaDataPagesPerRegion;
+ private final int metaDataPagesPerRegion;
/**
* Constructor
*
* Contiguous monotone resource. The address range is pre-defined at
- * initializtion time and is immutable.
+ * initialization time and is immutable.
*
* @param pageBudget The budget of pages available to this memory
* manager before it must poll the collector.
@@ -66,7 +67,7 @@
* Constructor
*
* Discontiguous monotone resource. The address range is not
- * pre-defined at initializtion time and is dynamically defined to
+ * pre-defined at initialization time and is dynamically defined to
* be some set of pages, according to demand and availability.
*
* CURRENTLY UNIMPLEMENTED
@@ -80,8 +81,6 @@
public MonotonePageResource(int pageBudget, Space space, int metaDataPagesPerRegion) {
super(pageBudget, space);
/* unimplemented */
- if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(false);
- this.contiguous = false;
this.start = Address.zero();
this.cursor = Address.zero();
this.sentinel = Address.zero();
@@ -94,7 +93,7 @@
*
* If the request can be satisfied, then ensure the pages are
* mmpapped and zeroed before returning the address of the start of
- * the region. If the request cannot be satisified, return zero.
+ * the region. If the request cannot be satisfied, return zero.
*
* @param requestPages The number of pages to be allocated.
* @return The start of the first page if successful, zero on
@@ -102,8 +101,6 @@
*/
@Inline
protected Address allocPages(int requestPages) {
- if (VM.VERIFY_ASSERTIONS)
- VM.assertions._assert(contiguous);
int pages = requestPages;
lock();
Address rtn = cursor;
@@ -119,6 +116,15 @@
}
Extent bytes = Conversions.pagesToBytes(pages);
Address tmp = cursor.plus(bytes);
+
+ if (!contiguous && tmp.GT(sentinel)) {
+ space.growDiscontiguousSpace(bytes);
+ start = space.getStart();
+ cursor = start;
+ sentinel = cursor.plus(space.getExtent());
+ rtn = cursor;
+ tmp = cursor.plus(bytes);
+ }
if (VM.VERIFY_ASSERTIONS)
VM.assertions._assert(rtn.GE(cursor) && rtn.LT(cursor.plus(bytes)));
if (tmp.GT(sentinel)) {
@@ -210,19 +216,34 @@
unlock();
}
-
/**
* Release all pages associated with this page resource, optionally
* zeroing on release and optionally memory protecting on release.
*/
@Inline
private void releasePages() {
- if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(contiguous);
+ Address first = start;
+ do {
Extent bytes = cursor.diff(start).toWord().toExtent();
releasePages(start, bytes);
cursor = start;
+ } while (!contiguous && moveToNextChunk());
+ if (!contiguous) {
+ sentinel = Address.zero();
+ Map.freeAllChunks(first);
+ }
}
+ private boolean moveToNextChunk() {
+ start = Map.getNextContiguousRegion(start);
+ if (start.isZero())
+ return false;
+ else {
+ cursor = start.plus(Map.getContiguousRegionSize(start));
+ return true;
+ }
+ }
+
/**
* Release a range of pages associated with this page resource, optionally
* zeroing on release and optionally memory protecting on release.
Index: MMTk/src/org/mmtk/utility/heap/PageResource.java
===================================================================
--- MMTk/src/org/mmtk/utility/heap/PageResource.java (revision 13397)
+++ MMTk/src/org/mmtk/utility/heap/PageResource.java (working copy)
@@ -31,7 +31,7 @@
* be satisfied (for either reason) a GC may be triggered.
*
* This class is abstract, and is subclassed with monotone and
- * freelist variants, which reflect monotonic and ad hoc space useage
+ * freelist variants, which reflect monotonic and ad hoc space usage
* respectively. Monotonic use is easier to manage, but is obviously
* more restrictive (useful for copying collectors which allocate
* monotonically before freeing the entire space and starting over).
@@ -45,7 +45,7 @@
*/
protected static final boolean ZERO_ON_RELEASE = false; // debugging
- private static Lock classLock;
+ private static final Lock classLock;
private static long cumulativeCommitted = 0;
@@ -58,14 +58,15 @@
protected int reserved;
protected int committed;
protected int required;
- private int pageBudget;
+ private final int pageBudget;
- protected boolean contiguous = false;
+ protected final boolean contiguous;
+ protected final Space space;
protected Address start; // only for contiguous
// locking
- private Lock gcLock; // used during GC
- private Lock mutatorLock; // used by mutators
+ private final Lock gcLock; // used during GC
+ private final Lock mutatorLock; // used by mutators
/****************************************************************************
*
@@ -83,23 +84,35 @@
* manager before it must poll the collector.
* @param space The space to which this resource is attached
*/
- PageResource(int pageBudget, Space space) {
+ private PageResource(int pageBudget, Space space, boolean contiguous) {
this.pageBudget = pageBudget;
+ this.contiguous = contiguous;
+ this.space = space;
gcLock = VM.newLock(space.getName() + ".gcLock");
mutatorLock = VM.newLock(space.getName() + ".mutatorLock");
}
/**
- * Constructor
+ * Constructor for discontiguous spaces
*
* @param pageBudget The budget of pages available to this memory
* manager before it must poll the collector.
* @param space The space to which this resource is attached
*/
+ PageResource(int pageBudget, Space space) {
+ this(pageBudget, space, false);
+ }
+
+ /**
+ * Constructor for contiguous spaces
+ *
+ * @param pageBudget The budget of pages available to this memory
+ * manager before it must poll the collector.
+ * @param space The space to which this resource is attached
+ */
PageResource(int pageBudget, Space space, Address start) {
- this(pageBudget, space);
+ this(pageBudget, space, true);
this.start = start;
- this.contiguous = true;
}
/**
Index: MMTk/src/org/mmtk/utility/heap/SpaceDescriptor.java
===================================================================
--- MMTk/src/org/mmtk/utility/heap/SpaceDescriptor.java (revision 13397)
+++ MMTk/src/org/mmtk/utility/heap/SpaceDescriptor.java (working copy)
@@ -57,6 +57,9 @@
private static final int VM_MANTISSA_BITS = 14;
private static final int VM_BASE_EXPONENT = BITS_IN_INT - VM_MANTISSA_BITS;
+ private static int discontiguousSpaceIndex = 0;
+ private static int DISCONTIG_INDEX_INCREMENT = 1<false
.
*/
- static CopySpace matureSpace0 = new CopySpace("ss0", DEFAULT_POLL_FREQUENCY, (float) 0.25, false);
+ static CopySpace matureSpace0 = new CopySpace("ss0", DEFAULT_POLL_FREQUENCY, false);
static final int MS0 = matureSpace0.getDescriptor();
/**
* The high half of the copying mature space. We allocate into this space
* when hi
is true
.
*/
- static CopySpace matureSpace1 = new CopySpace("ss1", DEFAULT_POLL_FREQUENCY, (float) 0.25, true);
+ static CopySpace matureSpace1 = new CopySpace("ss1", DEFAULT_POLL_FREQUENCY, true);
static final int MS1 = matureSpace1.getDescriptor();
Index: MMTk/src/org/mmtk/plan/generational/Gen.java
===================================================================
--- MMTk/src/org/mmtk/plan/generational/Gen.java (revision 13397)
+++ MMTk/src/org/mmtk/plan/generational/Gen.java (working copy)
@@ -72,7 +72,7 @@
public static SizeCounter nurseryCons;
/** The nursery space is where all new objects are allocated by default */
- public static final CopySpace nurserySpace = new CopySpace("nursery", DEFAULT_POLL_FREQUENCY, (float) 0.15, true, false);
+ public static final CopySpace nurserySpace = new CopySpace("nursery", DEFAULT_POLL_FREQUENCY, 0.15f, true, false);
public static final int NURSERY = nurserySpace.getDescriptor();
public static final Address NURSERY_START = nurserySpace.getStart();
Index: MMTk/src/org/mmtk/plan/generational/marksweep/GenMS.java
===================================================================
--- MMTk/src/org/mmtk/plan/generational/marksweep/GenMS.java (revision 13397)
+++ MMTk/src/org/mmtk/plan/generational/marksweep/GenMS.java (working copy)
@@ -51,7 +51,7 @@
*/
/** The mature space, which for GenMS uses a mark sweep collection policy. */
- public static final MarkSweepSpace msSpace = new MarkSweepSpace("ms", DEFAULT_POLL_FREQUENCY, MATURE_FRACTION);
+ public static final MarkSweepSpace msSpace = new MarkSweepSpace("ms", DEFAULT_POLL_FREQUENCY);
public static final int MS = msSpace.getDescriptor();
Index: MMTk/src/org/mmtk/plan/semispace/SS.java
===================================================================
--- MMTk/src/org/mmtk/plan/semispace/SS.java (revision 13397)
+++ MMTk/src/org/mmtk/plan/semispace/SS.java (working copy)
@@ -51,11 +51,11 @@
public static boolean hi = false; // True if allocing to "higher" semispace
/** One of the two semi spaces that alternate roles at each collection */
- public static final CopySpace copySpace0 = new CopySpace("ss0", DEFAULT_POLL_FREQUENCY, SEMISPACE_VIRT_MEM_FRAC, false);
+ public static final CopySpace copySpace0 = new CopySpace("ss0", DEFAULT_POLL_FREQUENCY, false);
public static final int SS0 = copySpace0.getDescriptor();
/** One of the two semi spaces that alternate roles at each collection */
- public static final CopySpace copySpace1 = new CopySpace("ss1", DEFAULT_POLL_FREQUENCY, SEMISPACE_VIRT_MEM_FRAC, true);
+ public static final CopySpace copySpace1 = new CopySpace("ss1", DEFAULT_POLL_FREQUENCY, true);
public static final int SS1 = copySpace1.getDescriptor();
public final Trace ssTrace;
Index: MMTk/src/org/mmtk/plan/Plan.java
===================================================================
--- MMTk/src/org/mmtk/plan/Plan.java (revision 13397)
+++ MMTk/src/org/mmtk/plan/Plan.java (working copy)
@@ -21,6 +21,7 @@
import org.mmtk.utility.Constants;
import org.mmtk.utility.Conversions;
import org.mmtk.utility.heap.HeapGrowthManager;
+import org.mmtk.utility.heap.Map;
import org.mmtk.utility.Log;
import org.mmtk.utility.options.*;
import org.mmtk.utility.sanitychecker.SanityChecker;
@@ -46,13 +47,13 @@
* thread-local activities. There is a single instance of Plan (or the
* appropriate sub-class), and a 1:1 mapping of PlanLocal to "kernel
* threads" (aka CPUs or in Jikes RVM, VM_Processors). Thus instance
- * methods of PlanLocal allow fast, unsychronized access to functions such as
+ * methods of PlanLocal allow fast, unsynchronized access to functions such as
* allocation and collection.
*
* The global instance defines and manages static resources
* (such as memory and virtual memory resources). This mapping of threads to
* instances is crucial to understanding the correctness and
- * performance proprties of MMTk plans.
+ * performance properties of MMTk plans.
*/
@Uninterruptible
public abstract class Plan implements Constants {
@@ -111,24 +112,27 @@
public static final Space vmSpace = VM.memory.getVMSpace();
/** Any immortal objects allocated after booting are allocated here. */
- public static final ImmortalSpace immortalSpace = new ImmortalSpace("immortal", DEFAULT_POLL_FREQUENCY, IMMORTAL_MB);
+ public static final ImmortalSpace immortalSpace = new ImmortalSpace("immortal", DEFAULT_POLL_FREQUENCY);
/** All meta data that is used by MMTk is allocated (and accounted for) in the meta data space. */
- public static final RawPageSpace metaDataSpace = new RawPageSpace("meta", DEFAULT_POLL_FREQUENCY, META_DATA_MB);
+ public static final RawPageSpace metaDataSpace = new RawPageSpace("meta", DEFAULT_POLL_FREQUENCY);
/** Large objects are allocated into a special large object space. */
- public static final LargeObjectSpace loSpace = new LargeObjectSpace("los", DEFAULT_POLL_FREQUENCY, LOS_FRAC);
+ public static final LargeObjectSpace loSpace = new LargeObjectSpace("los", DEFAULT_POLL_FREQUENCY);
/** Primitive (non-ref) large objects are allocated into a special primitive
large object space. */
public static final LargeObjectSpace ploSpace = new LargeObjectSpace("plos", DEFAULT_POLL_FREQUENCY, PLOS_FRAC, true);
+ public static final RawPageSpace sanitySpace = new RawPageSpace("sanity", Integer.MAX_VALUE);
+
/* Space descriptors */
public static final int IMMORTAL = immortalSpace.getDescriptor();
public static final int VM_SPACE = vmSpace.getDescriptor();
public static final int META = metaDataSpace.getDescriptor();
public static final int LOS = loSpace.getDescriptor();
public static final int PLOS = ploSpace.getDescriptor();
+ public static final int SANITY = sanitySpace.getDescriptor();
/** Timer that counts total time */
public static final Timer totalTime = new Timer("time");
@@ -158,6 +162,7 @@
Options.eagerMmapSpaces = new EagerMmapSpaces();
Options.sanityCheck = new SanityCheck();
Options.debugAddress = new DebugAddress();
+ Map.finalizeStaticSpaceMap();
}
/****************************************************************************