From: <dfr...@us...> - 2008-06-16 08:24:52
|
Revision: 14500 http://jikesrvm.svn.sourceforge.net/jikesrvm/?rev=14500&view=rev Author: dframpton-oss Date: 2008-06-16 01:24:48 -0700 (Mon, 16 Jun 2008) Log Message: ----------- Add simple alignment checking test Modified Paths: -------------- rvmroot/trunk/MMTk/ext/vm/harness/org/mmtk/harness/vm/Memory.java rvmroot/trunk/MMTk/ext/vm/harness/org/mmtk/harness/vm/ObjectModel.java rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/Mutator.java rvmroot/trunk/MMTk/harness/src/org/mmtk/test/HashCode.java Added Paths: ----------- rvmroot/trunk/MMTk/harness/src/org/mmtk/test/Alignment.java Modified: rvmroot/trunk/MMTk/ext/vm/harness/org/mmtk/harness/vm/Memory.java =================================================================== --- rvmroot/trunk/MMTk/ext/vm/harness/org/mmtk/harness/vm/Memory.java 2008-06-16 06:27:27 UTC (rev 14499) +++ rvmroot/trunk/MMTk/ext/vm/harness/org/mmtk/harness/vm/Memory.java 2008-06-16 08:24:48 UTC (rev 14500) @@ -200,9 +200,9 @@ /** @return The log base two of the minimum allocation alignment */ protected byte getLogMinAlignmentConstant() { return SimulatedMemory.LOG_BYTES_IN_WORD; } /** @return The log base two of (MAX_ALIGNMENT/MIN_ALIGNMENT) */ - protected byte getMaxAlignmentShiftConstant() { return 0; } + protected byte getMaxAlignmentShiftConstant() { return 1; } /** @return The maximum number of bytes of padding to prepend to an object */ - protected int getMaxBytesPaddingConstant() { return 0; } + protected int getMaxBytesPaddingConstant() { return SimulatedMemory.BYTES_IN_WORD; } /** @return The value to store in alignment holes */ - protected int getAlignmentValueConstant() { return 0; } + protected int getAlignmentValueConstant() { return ObjectModel.ALIGNMENT_VALUE; } } Modified: rvmroot/trunk/MMTk/ext/vm/harness/org/mmtk/harness/vm/ObjectModel.java =================================================================== --- rvmroot/trunk/MMTk/ext/vm/harness/org/mmtk/harness/vm/ObjectModel.java 2008-06-16 06:27:27 UTC (rev 14499) +++ rvmroot/trunk/MMTk/ext/vm/harness/org/mmtk/harness/vm/ObjectModel.java 2008-06-16 08:24:48 UTC (rev 14500) @@ -32,7 +32,7 @@ * References * Data * - * We assume BITS_IN_WORD >= 32 + * Only tested using 32 bit and assumes at least 32 bits. */ /** The total header size (including any requested GC words) */ @@ -59,7 +59,12 @@ private static final int HASHED = 0x1 << (3 * SimulatedMemory.BITS_IN_BYTE); /** Has this object been moved since it was hashed? */ private static final int HASHED_AND_MOVED = 0x3 << (3 * SimulatedMemory.BITS_IN_BYTE); + /** Is this object 8 byte aligned */ + private static final int DOUBLE_ALIGN = 0x1 << (2 * SimulatedMemory.BITS_IN_BYTE); + /** The value placed in alignment holes */ + public static final int ALIGNMENT_VALUE = 1; + /** The next object id that will be allocated */ private static int nextObjectId = 1; @@ -69,22 +74,25 @@ } /** - * Allocate an object and return the initialized ObjectReference. + * Allocate an object and return the ObjectReference. * * @param context The MMTk MutatorContext to use. * @param refCount The number of reference fields. * @param dataCount The number of data fields. + * @param doubleAlign Align the object at an 8 byte boundary? * @return The new ObjectReference. */ - public static ObjectReference allocateObject(MutatorContext context, int refCount, int dataCount) { + public static ObjectReference allocateObject(MutatorContext context, int refCount, int dataCount, boolean doubleAlign) { int bytes = (HEADER_WORDS + refCount + dataCount) << SimulatedMemory.LOG_BYTES_IN_WORD; + int align = (doubleAlign ? 2 : 1) * SimulatedMemory.BYTES_IN_WORD; int allocator = context.checkAllocator(bytes, SimulatedMemory.LOG_BYTES_IN_WORD, Plan.ALLOC_DEFAULT); // Allocate the raw memory - Address region = context.alloc(bytes, SimulatedMemory.BYTES_IN_WORD, 0, allocator, 0); + Address region = context.alloc(bytes, align, 0, allocator, 0); // Create an object reference. ObjectReference ref = region.toObjectReference(); + if (doubleAlign) region.store(DOUBLE_ALIGN, STATUS_OFFSET); setId(ref, allocateObjectId()); setRefCount(ref, refCount); setDataCount(ref, dataCount); @@ -197,7 +205,7 @@ * Return the hash code for this object. * * @param ref The object. - * @return The hashcode + * @return The hash code */ public static int getHashCode(ObjectReference ref) { Address addr = ref.toAddress(); @@ -312,7 +320,8 @@ * @return The alignment required for a copy of <code>obj</code> */ public int getAlignWhenCopied(ObjectReference object) { - return SimulatedMemory.BYTES_IN_WORD; + boolean doubleAlign = (object.toAddress().loadInt(STATUS_OFFSET) & DOUBLE_ALIGN) == DOUBLE_ALIGN; + return (doubleAlign ? 2 : 1) * SimulatedMemory.BYTES_IN_WORD; } /** @@ -340,6 +349,9 @@ */ public ObjectReference getNextObject(ObjectReference object) { Address nextAddress = object.toAddress().plus(getSize(object)); + if (nextAddress.loadInt() == ALIGNMENT_VALUE) { + nextAddress = nextAddress.plus(SimulatedMemory.BYTES_IN_WORD); + } if (nextAddress.loadWord().isZero()) { return ObjectReference.nullReference(); } @@ -350,13 +362,16 @@ * Return an object reference from knowledge of the low order word */ public ObjectReference getObjectFromStartAddress(Address start) { + if (start.loadInt() == ALIGNMENT_VALUE) { + start = start.plus(SimulatedMemory.BYTES_IN_WORD); + } return start.toObjectReference(); } /** * Gets a pointer to the address just past the end of the object. * - * @param object The objecty. + * @param object The object. */ public Address getObjectEndAddress(ObjectReference object) { return object.toAddress().plus(getSize(object)); Modified: rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/Mutator.java =================================================================== --- rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/Mutator.java 2008-06-16 06:27:27 UTC (rev 14499) +++ rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/Mutator.java 2008-06-16 08:24:48 UTC (rev 14500) @@ -371,16 +371,14 @@ } /** - * Return the address of an object as a string for output + * Return the current address of an object (for use in assertions/debug output). + * This method will never yield to a collection. * * @param var The variable storing the object reference. - * @return The hash code + * @return The address of the object. */ - public String muToString(String var) { - ObjectReference ref = getVar(var); - String result = ref.toString(); - gcSafePoint(); - return result; + public Address muAddress(String var) { + return getVar(var).toAddress(); } /** @@ -389,26 +387,58 @@ * @param bytes the size of the object in bytes. */ public void muAlloc(int bytes) { - muAlloc(null, bytes); + muAlloc(null, bytes, false); } /** + * Allocate an object of the specified size. + * + * @param bytes the size of the object in bytes. + * @param doubleAlign Align the object on an 8 byte boundary + */ + public void muAlloc(int bytes, boolean doubleAlign) { + muAlloc(null, bytes, doubleAlign); + } + + /** * Allocate an object with the specified number of reference and data fields. * * @param refCount The number of reference fields. * @param dataCount The number of data fields. */ public void muAlloc(int refCount, int dataCount) { - muAlloc(null, refCount, dataCount); + muAlloc(null, refCount, dataCount, false); } /** + * Allocate an object with the specified number of reference and data fields. + * + * @param refCount The number of reference fields. + * @param dataCount The number of data fields. + * @param doubleAlign Align the object on an 8 byte boundary + */ + public void muAlloc(int refCount, int dataCount, boolean doubleAlign) { + muAlloc(null, refCount, dataCount, doubleAlign); + } + + /** * Allocate an object of the specified size and store a reference to it in the given variable. * * @param toVar The variable to store the object into. * @param bytes the size of the object in bytes. */ public void muAlloc(String toVar, int bytes) { + muAlloc(toVar, 0, false); + } + + /** + * Allocate an object of the specified size and store a reference to it in the given variable. + * + * @param toVar The variable to store the object into. + * @param bytes the size of the object in bytes. + * @param doubleAlign Align the object on an 8 byte boundary + */ + public void muAlloc(String toVar, int bytes, boolean doubleAlign) { int words = (bytes >>> SimulatedMemory.LOG_BYTES_IN_WORD); assert words >= ObjectModel.HEADER_WORDS: "Allocation request smaller than minimum object size"; muAlloc(toVar, 0, words - ObjectModel.HEADER_WORDS); @@ -423,7 +453,20 @@ * @param dataCount The number of data fields. */ public void muAlloc(String toVar, int refCount, int dataCount) { - ObjectReference ref = ObjectModel.allocateObject(context, refCount, dataCount); + muAlloc(toVar, refCount, dataCount, false); + } + + /** + * Allocate an object with the specified number of reference and data fields and store a + * reference to it in the given variable. + * + * @param toVar The variable to store the object into. + * @param refCount The number of reference fields. + * @param dataCount The number of data fields. + * @param doubleAlign Align the object on an 8 byte boundary + */ + public void muAlloc(String toVar, int refCount, int dataCount, boolean doubleAlign) { + ObjectReference ref = ObjectModel.allocateObject(context, refCount, dataCount, doubleAlign); setVar(toVar, ref); gcSafePoint(); } Added: rvmroot/trunk/MMTk/harness/src/org/mmtk/test/Alignment.java =================================================================== --- rvmroot/trunk/MMTk/harness/src/org/mmtk/test/Alignment.java (rev 0) +++ rvmroot/trunk/MMTk/harness/src/org/mmtk/test/Alignment.java 2008-06-16 08:24:48 UTC (rev 14500) @@ -0,0 +1,78 @@ +/* + * This file is part of the Jikes RVM project (http://jikesrvm.org). + * + * This file is licensed to You under the Common Public License (CPL); + * You may not use this file except in compliance with the License. You + * may obtain a copy of the License at + * + * http://www.opensource.org/licenses/cpl1.0.php + * + * See the COPYRIGHT.txt file distributed with this work for information + * regarding copyright ownership. + */ +package org.mmtk.test; + +import org.mmtk.harness.Mutator; + +/** + * This is a simple test that allocates aligned and unaligned objects. + */ +public class Alignment extends Test { + /** Size of linked list to create */ + private static final int LIST_SIZE = 200; + + /** The frequency at which objects are 8 byte aligned */ + private static final int ALIGN_EVERY = 3; + + /** + * Create a linked list, then verify it. + */ + protected void main(Mutator m) { + buildList(m); + verifyList(m); + System.err.println("Triggering GC..."); + m.muGC(); + verifyList(m); + m.muEnd(); + } + + /** + * Verify the linked list. + */ + private void verifyList(Mutator m) { + System.err.println("Checking list..."); + int found = 0; + m.muCopy("current", "head"); + while (!m.muIsNull("current")) { + boolean doubleAlign = (found++ % ALIGN_EVERY) == 0; + int mask = doubleAlign ? 0x7 : 0x3; + if ((m.muAddress("current").toInt() & mask) != 0) { + System.err.println("ERROR: Misaligned object " + m.muAddress("current") + (doubleAlign ? " [8B]" : " [4B]")); + } + + // Follow the linked list + m.muLoad("next", "current", 0); + m.muCopy("current", "next"); + } + if (found != LIST_SIZE) { + System.err.println("ERROR: expected " + LIST_SIZE + " objects but found only " + found); + } + } + + /** + * Build a linked list + */ + private void buildList(Mutator m) { + System.err.println("Building list..."); + // Build the linked list + m.muAlloc("head", 1, 1); + m.muStoreData("head", 0, m.muHashCode("head")); + m.muCopy("last", "head"); + for(int j=1; j < LIST_SIZE; j++) { + boolean doubleAlign = (j % ALIGN_EVERY) == 0; + m.muAlloc("current", 1, 1, doubleAlign); + m.muStore("last", 0, "current"); + m.muCopy("last", "current"); + } + } +} Property changes on: rvmroot/trunk/MMTk/harness/src/org/mmtk/test/Alignment.java ___________________________________________________________________ Name: svn:eol-style + native Modified: rvmroot/trunk/MMTk/harness/src/org/mmtk/test/HashCode.java =================================================================== --- rvmroot/trunk/MMTk/harness/src/org/mmtk/test/HashCode.java 2008-06-16 06:27:27 UTC (rev 14499) +++ rvmroot/trunk/MMTk/harness/src/org/mmtk/test/HashCode.java 2008-06-16 08:24:48 UTC (rev 14500) @@ -62,7 +62,7 @@ m.muCopy("current", "next"); } if (found != (LIST_SIZE / HASH_EVERY)) { - System.err.println("WARNING: expected " + (LIST_SIZE / HASH_EVERY) + "hashed objects but found only " + found); + System.err.println("ERROR: expected " + (LIST_SIZE / HASH_EVERY) + " hashed objects but found only " + found); } } @@ -80,7 +80,7 @@ if ((i % HASH_EVERY) == 0) { int hashValue = m.muHashCode("current"); if (hashValue == 0) { - System.err.println("WARNING: hashCode of 0 found"); + System.err.println("ERROR: hashCode of 0 returned"); } m.muStoreData("current", 0, hashValue); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |