diff -r 743a2cc2ed20 -r 058fdc3780ba MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/Barriers.java --- a/MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/Barriers.java Tue Aug 04 11:04:15 2009 +1000 +++ b/MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/Barriers.java Mon Nov 16 09:21:21 2009 +1100 @@ -12,9 +12,17 @@ */ package org.jikesrvm.mm.mmtk; +import static org.jikesrvm.mm.mminterface.MemoryManagerConstants.BOOT_IMAGE_IS_ARRAYLETIZED; +import static org.jikesrvm.mm.mminterface.MemoryManagerConstants.DO_FIRSTN_OPT; +import static org.jikesrvm.mm.mminterface.MemoryManagerConstants.FIRSTN_INT_ELEMS; + +import org.jikesrvm.HeapLayoutConstants; import org.jikesrvm.SizeConstants; import org.jikesrvm.runtime.Magic; import org.mmtk.vm.VM; +import org.mmtk.utility.Constants; +import org.jikesrvm.mm.mminterface.MemoryManager; +import org.jikesrvm.mm.mminterface.MemoryManagerConstants; import org.vmmagic.unboxed.*; import org.vmmagic.pragma.*; @@ -38,7 +46,10 @@ Object obj = ref.toObject(); Offset offset = metaDataA.toOffset(); int location = metaDataB.toInt(); - Magic.setObjectAtOffset(obj, offset, target.toObject(), location); + if (mode == Constants.AASTORE_WRITE_BARRIER) + metaDataB.toAddress().store(target, offset); + else + Magic.setObjectAtOffset(obj, offset, target.toObject(), location); } /** @@ -214,11 +225,15 @@ * @param value the new value for the element */ @UninterruptibleNoWarn - public final void setArrayNoBarrier(Object [] dst, int index, Object value) { + public final void setArrayNoGCBarrier(Object [] dst, int index, Object value) { if (org.jikesrvm.VM.runningVM) { - Address base = ObjectReference.fromObject(dst).toAddress(); - Address slot = base.plus(Offset.fromIntZeroExtend(index << LOG_BYTES_IN_ADDRESS)); - VM.activePlan.global().storeObjectReference(slot, ObjectReference.fromObject(value)); + if (MemoryManagerConstants.USE_REFERENCE_ARRAYLETS && ((BOOT_IMAGE_IS_ARRAYLETIZED || (Magic.objectAsAddress(dst)).GE(HeapLayoutConstants.BOOT_IMAGE_DATA_END)) && (!DO_FIRSTN_OPT || (index >= FIRSTN_INT_ELEMS)))) { + MemoryManager.arrayletizedArrayStore(ObjectReference.fromObject(dst), index, ObjectReference.fromObject(value), false); + } else { + Address base = ObjectReference.fromObject(dst).toAddress(); + Address slot = base.plus(Offset.fromIntZeroExtend(index << LOG_BYTES_IN_ADDRESS)); + VM.activePlan.global().storeObjectReference(slot, ObjectReference.fromObject(value)); + } } else { dst[index] = value; } diff -r 743a2cc2ed20 -r 058fdc3780ba MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/FinalizableProcessor.java --- a/MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/FinalizableProcessor.java Tue Aug 04 11:04:15 2009 +1000 +++ b/MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/FinalizableProcessor.java Mon Nov 16 09:21:21 2009 +1100 @@ -18,6 +18,7 @@ import org.jikesrvm.SizeConstants; import org.jikesrvm.VM; import org.jikesrvm.mm.mminterface.Selected; +import org.jikesrvm.mm.mminterface.MemoryManager; import org.jikesrvm.runtime.Magic; import org.jikesrvm.Services; import org.jikesrvm.scheduler.Scheduler; @@ -105,11 +106,11 @@ Object[] newReadyForFinalize = new Object[readyLength]; int j = 0; for(int i=nextReadyIndex; i < lastReadyIndex && i < readyForFinalize.length; i++) { - newReadyForFinalize[j++] = readyForFinalize[i]; + MemoryManager.arrayStoreWriteBarrier(newReadyForFinalize, j++, MemoryManager.arrayLoadReadBarrier(readyForFinalize, i)); } if (lastReadyIndex < nextReadyIndex) { for(int i=0; i < lastReadyIndex; i++) { - newReadyForFinalize[j++] = readyForFinalize[i]; + MemoryManager.arrayStoreWriteBarrier(newReadyForFinalize, j++, MemoryManager.arrayLoadReadBarrier(readyForFinalize, i)); } } lastReadyIndex = j; @@ -216,8 +217,7 @@ ref = trace.retainForFinalize(ref); /* Add to object table */ - Offset offset = Word.fromIntZeroExtend(lastReadyIndex).lsh(LOG_BYTES_IN_ADDRESS).toOffset(); - Selected.Plan.get().storeObjectReference(Magic.objectAsAddress(readyForFinalize).plus(offset), ref); + MemoryManager.arrayStoreWriteBarrier(readyForFinalize, lastReadyIndex, ref.toObject()); lastReadyIndex = (lastReadyIndex + 1) % readyForFinalize.length; } nurseryIndex = maxIndex = toIndex; @@ -239,8 +239,8 @@ } Object result = null; if (nextReadyIndex != lastReadyIndex) { - result = readyForFinalize[nextReadyIndex]; - Services.setArrayUninterruptible(readyForFinalize, nextReadyIndex, null); + result = MemoryManager.arrayLoadReadBarrier(readyForFinalize, nextReadyIndex); + MemoryManager.arrayStoreWriteBarrier(readyForFinalize, nextReadyIndex, ObjectReference.nullReference().toObject()); nextReadyIndex = (nextReadyIndex + 1) % readyForFinalize.length; } lock.release(); diff -r 743a2cc2ed20 -r 058fdc3780ba MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/Memory.java --- a/MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/Memory.java Tue Aug 04 11:04:15 2009 +1000 +++ b/MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/Memory.java Mon Nov 16 09:21:21 2009 +1100 @@ -12,6 +12,7 @@ */ package org.jikesrvm.mm.mmtk; +import static org.jikesrvm.mm.mminterface.MemoryManagerConstants.LOG_ELEMENTS_IN_INT_ARRAYLET; import org.mmtk.plan.Plan; import org.mmtk.policy.ImmortalSpace; import org.mmtk.utility.Constants; @@ -50,6 +51,8 @@ // private static int BOOT_SEGMENT_MB = 4+(BOOT_IMAGE_SIZE.toInt()>>LOG_BYTES_IN_MBYTE); private static int BOOT_SEGMENT_MB = (0x10000000>>LOG_BYTES_IN_MBYTE); + protected final int getLogArrayletElements() { return LOG_ELEMENTS_IN_INT_ARRAYLET; } + /** * Return the space associated with/reserved for the VM. In the * case of Jikes RVM this is the boot image space.
diff -r 743a2cc2ed20 -r 058fdc3780ba MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/ObjectModel.java
--- a/MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/ObjectModel.java Tue Aug 04 11:04:15 2009 +1000
+++ b/MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/ObjectModel.java Mon Nov 16 09:21:21 2009 +1100
@@ -12,15 +12,20 @@
*/
package org.jikesrvm.mm.mmtk;
+//import org.mmtk.plan.Plan;
+//import org.mmtk.policy.Space;
import org.mmtk.utility.alloc.Allocator;
+import org.mmtk.utility.Log; //jbs added
import org.jikesrvm.runtime.Magic;
import org.jikesrvm.objectmodel.JavaHeaderConstants;
+//import org.jikesrvm.objectmodel.ObjectModel;
import org.jikesrvm.objectmodel.TIB;
import org.jikesrvm.classloader.Atom;
import org.jikesrvm.classloader.RVMArray;
import org.jikesrvm.classloader.RVMClass;
import org.jikesrvm.classloader.RVMType;
+import org.jikesrvm.mm.mminterface.MemoryManagerConstants;
import org.jikesrvm.mm.mminterface.Selected;
import org.jikesrvm.mm.mminterface.DebugUtil;
import org.jikesrvm.mm.mminterface.MemoryManager;
@@ -31,8 +36,133 @@
@Uninterruptible public final class ObjectModel extends org.mmtk.vm.ObjectModel implements org.mmtk.utility.Constants,
org.jikesrvm.Constants {
+ public boolean getCollectArrayletStats() { return MemoryManagerConstants.DO_COLLECT_SPACE_SAVING_STATS; }
+ public boolean getCollectAccessStats() { return MemoryManagerConstants.DO_COLLECT_ARRAY_ACCESS_STATS; }
+ public boolean getDoAnyTypesCow() { return MemoryManagerConstants.DO_ANY_COPY_ON_WRITE_ARRAYS; }
+
protected Offset getArrayBaseOffset() { return JavaHeaderConstants.ARRAY_BASE_OFFSET; }
+ //jbs added
+ //done at the end of GC
+ public void printAndResetStats() {
+ if (MemoryManagerConstants.DO_COLLECT_SPACE_SAVING_STATS) {
+ Log.write(" JBS STATS, GC time. Printing in bytes spine, arraylet, zero arraylet, num set zero arraylet: ");
+ Log.write(MemoryManagerConstants.NUM_GC_SPINE_BYTES); Log.write(" ");
+ Log.write(MemoryManagerConstants.NUM_GC_ARRAYLET_BYTES); Log.write(" ");
+ Log.write(MemoryManagerConstants.NUM_GC_ZERO_ARRAYLET_BYTES); Log.write(" ");
+ Log.write(MemoryManagerConstants.ZERO_ARRAYLET_AT_GC); Log.write(" ");
+ Log.write(MemoryManagerConstants.NUM_GC_REF_SPINE_BYTES); Log.write(" ");
+ Log.write(MemoryManagerConstants.NUM_GC_REF_ARRAYLET_BYTES); Log.write(" ");
+ Log.write(MemoryManagerConstants.NUM_GC_REF_ZERO_ARRAYLET_BYTES); Log.write(" ");
+ Log.write(MemoryManagerConstants.REF_ZERO_ARRAYLET_AT_GC); Log.write(" ");
+ Log.write(MemoryManagerConstants.NUM_PRIMARRCONTIG_BYTES_GC); Log.write(" ");
+ Log.write(MemoryManagerConstants.NUM_REFARRCONTIG_BYTES_GC); Log.write(" ");
+ Log.write(MemoryManagerConstants.NUM_GC_ARRAYLETIZED_BYTES); Log.write(" ");
+ Log.write(MemoryManagerConstants.NUM_GC_REF_ARRAYLETIZED_BYTES); Log.write(" ");
+ Log.write((MemoryManagerConstants.NUM_GC_TAINTED_ARRAYLET_PTRS * MemoryManagerConstants.ARRAYLET_BYTES / 2)); Log.write(" ");
+ Log.writeln();
+ Log.write(" Counting zero bytes in live arraylets at gc time: ");
+ Log.write(MemoryManagerConstants.NUM_GC_ARRAYLET_ZERO_BYTES); Log.write(" ");
+ Log.write(MemoryManagerConstants.NUM_GC_REF_ARRAYLET_ZERO_BYTES); Log.write(" ");
+ Log.write(" as percentage ");
+ double stat = (MemoryManagerConstants.NUM_GC_ARRAYLET_ZERO_BYTES + MemoryManagerConstants.NUM_GC_REF_ARRAYLET_ZERO_BYTES) / ((double) (MemoryManagerConstants.NUM_GC_ARRAYLET_BYTES + MemoryManagerConstants.NUM_GC_REF_ARRAYLET_BYTES));
+ Log.write(stat);
+ Log.writeln();
+
+ MemoryManagerConstants.NUM_GC_SPINE_BYTES = 0;
+ MemoryManagerConstants.NUM_GC_ARRAYLET_BYTES = 0;
+ MemoryManagerConstants.NUM_GC_ARRAYLETIZED_BYTES = 0;
+ MemoryManagerConstants.NUM_GC_ZERO_ARRAYLET_BYTES = 0;
+ MemoryManagerConstants.ZERO_ARRAYLET_AT_GC = 0;
+ MemoryManagerConstants.NUM_GC_REF_SPINE_BYTES = 0;
+ MemoryManagerConstants.NUM_GC_REF_ARRAYLET_BYTES = 0;
+ MemoryManagerConstants.NUM_GC_REF_ARRAYLETIZED_BYTES = 0;
+ MemoryManagerConstants.NUM_GC_REF_ZERO_ARRAYLET_BYTES = 0;
+ MemoryManagerConstants.REF_ZERO_ARRAYLET_AT_GC = 0;
+ MemoryManagerConstants.NUM_REFARRCONTIG_BYTES_GC = 0;
+ MemoryManagerConstants.NUM_PRIMARRCONTIG_BYTES_GC = 0;
+ MemoryManagerConstants.NUM_GC_TAINTED_ARRAYLET_PTRS = 0;
+ MemoryManagerConstants.NUM_GC_ARRAYLET_ZERO_BYTES = 0;
+ MemoryManagerConstants.NUM_GC_REF_ARRAYLET_ZERO_BYTES = 0;
+ }
+ }
+
+ public void resetHarnessStats() {
+ if (MemoryManagerConstants.DO_COLLECT_SPACE_SAVING_STATS) {
+ MemoryManagerConstants.ARRAYLET_BYTES_REQUESTED = 0;
+ MemoryManagerConstants.ARRAYLET_BYTES_ALLOCATED = 0;
+ MemoryManagerConstants.NUM_PRIM_BYTES_ARRAYCOPY = 0;
+ MemoryManagerConstants.NUM_REF_BYTES_ARRAYCOPY = 0;
+
+ MemoryManagerConstants.NUM_ALLOC_ARRAYS = 0;
+ MemoryManagerConstants.NUM_ALLOC_ARRAYLETIZABLE = 0;
+ MemoryManagerConstants.NUM_ALLOC_ZRAYS = 0;
+ MemoryManagerConstants.NUM_ALLOC_REF_ARRAYS = 0;
+ MemoryManagerConstants.NUM_ALLOC_REF_ARRAYLETIZABLE = 0;
+ MemoryManagerConstants.NUM_ALLOC_REF_ZRAYS = 0;
+
+ MemoryManagerConstants.NUM_ALLOC_BYTES_ARRAYS = 0;
+ MemoryManagerConstants.NUM_ALLOC_BYTES_ARRAYLETIZABLE = 0;
+ MemoryManagerConstants.NUM_ALLOC_BYTES_ZRAYS = 0;
+ MemoryManagerConstants.NUM_ALLOC_REF_BYTES_ARRAYS = 0;
+ MemoryManagerConstants.NUM_ALLOC_REF_BYTES_ARRAYLETIZABLE = 0;
+ MemoryManagerConstants.NUM_ALLOC_REF_BYTES_ZRAYS = 0;
+
+
+ MemoryManagerConstants.NUM_ZERO_ARRAYLET_ARRAYCOPY_OPT = 0;
+ MemoryManagerConstants.NUM_REF_ZERO_ARRAYLET_ARRAYCOPY_OPT = 0;
+ MemoryManagerConstants.NUM_ALLOC_BYTES_SCALAR = 0;
+ MemoryManagerConstants.CUM_GC_ZERO_ARRAYLET = 0;
+ MemoryManagerConstants.CUM_GC_REF_ZERO_ARRAYLET = 0;
+
+ MemoryManagerConstants.NUM_PRIM_BYTES_ARRAYCOPY_ARRAYLET = 0;
+ MemoryManagerConstants.NUM_REF_BYTES_ARRAYCOPY_ARRAYLET = 0;
+
+ MemoryManagerConstants.NUM_BYTE_ARRAYLETS_SHARED = 0;
+ MemoryManagerConstants.NUM_BYTE_ARRAYLETS_COPY_ON_WRITE = 0;
+ MemoryManagerConstants.NUM_BYTE_ARRAYS_BYTES_COPIED = 0;
+ MemoryManagerConstants.NUM_CHAR_ARRAYLETS_SHARED = 0;
+ MemoryManagerConstants.NUM_CHAR_ARRAYLETS_COPY_ON_WRITE = 0;
+ MemoryManagerConstants.NUM_CHAR_ARRAYS_BYTES_COPIED = 0;
+ MemoryManagerConstants.NUM_SHORT_ARRAYLETS_SHARED = 0;
+ MemoryManagerConstants.NUM_SHORT_ARRAYLETS_COPY_ON_WRITE = 0;
+ MemoryManagerConstants.NUM_SHORT_ARRAYS_BYTES_COPIED = 0;
+ MemoryManagerConstants.NUM_INT_ARRAYLETS_SHARED = 0;
+ MemoryManagerConstants.NUM_INT_ARRAYLETS_COPY_ON_WRITE = 0;
+ MemoryManagerConstants.NUM_INT_ARRAYS_BYTES_COPIED = 0;
+ MemoryManagerConstants.NUM_REF_ARRAYLETS_SHARED = 0;
+ MemoryManagerConstants.NUM_REF_ARRAYLETS_COPY_ON_WRITE = 0;
+ MemoryManagerConstants.NUM_REF_BYTES_ARRAYCOPY = 0;
+ MemoryManagerConstants.NUM_DOUBLE_ARRAYLETS_SHARED = 0;
+ MemoryManagerConstants.NUM_DOUBLE_ARRAYLETS_COPY_ON_WRITE = 0;
+ MemoryManagerConstants.NUM_DOUBLE_ARRAYS_BYTES_COPIED = 0;
+
+ MemoryManagerConstants.NUM_FLOAT_ARRAYLETS_SHARED = 0;
+ MemoryManagerConstants.NUM_FLOAT_ARRAYLETS_COPY_ON_WRITE = 0;
+ MemoryManagerConstants.NUM_FLOAT_ARRAYS_BYTES_COPIED = 0;
+
+ MemoryManagerConstants.NUM_BOOLEAN_ARRAYLETS_SHARED = 0;
+ MemoryManagerConstants.NUM_BOOLEAN_ARRAYLETS_COPY_ON_WRITE = 0;
+ MemoryManagerConstants.NUM_BOOLEAN_ARRAYS_BYTES_COPIED = 0;
+
+ MemoryManagerConstants.NUM_LONG_ARRAYLETS_SHARED = 0;
+ MemoryManagerConstants.NUM_LONG_ARRAYLETS_COPY_ON_WRITE = 0;
+ MemoryManagerConstants.NUM_LONG_ARRAYS_BYTES_COPIED = 0;
+
+
+ }
+ if (MemoryManagerConstants.DO_COLLECT_ARRAY_ACCESS_STATS) {
+ MemoryManagerConstants.primWbFast = 0;
+ MemoryManagerConstants.primWbSlow = 0;
+ MemoryManagerConstants.primRbFast = 0;
+ MemoryManagerConstants.primRbSlow = 0;
+ MemoryManagerConstants.refWbFast = 0;
+ MemoryManagerConstants.refWbSlow = 0;
+ MemoryManagerConstants.refRbFast = 0;
+ MemoryManagerConstants.refRbSlow = 0;
+ }
+ }
+
/**
* Copy an object using a plan's allocCopy to get space and install
* the forwarding pointer. On entry,
@@ -44,6 +56,9 @@
@NonMoving
public final class RVMArray extends RVMType implements Constants, ClassLoaderConstants {
+
+ //jbs added for debugging
+ //private static int arrayCopyCounter = 0;
/*
* We hold on to a number of commonly used arrays for easy access.
*/
@@ -55,6 +70,7 @@
public static final RVMArray LongArray;
public static final RVMArray FloatArray;
public static final RVMArray DoubleArray;
+ public static final RVMArray WordArray;
public static final RVMArray JavaLangObjectArray;
static {
@@ -66,6 +82,7 @@
ShortArray = (RVMArray) TypeReference.ShortArray.resolve();
IntArray = (RVMArray) TypeReference.IntArray.resolve();
LongArray = (RVMArray) TypeReference.LongArray.resolve();
+ WordArray = (RVMArray) TypeReference.WordArray.resolve();
JavaLangObjectArray = (RVMArray) TypeReference.JavaLangObjectArray.resolve();
}
@@ -99,6 +116,14 @@
private final int alignment;
/**
+ * Are instances of this type arrayletized?
+ */
+ private final boolean arrayletized;
+
+ @Uninterruptible
+ public boolean isArrayletizable() { return arrayletized; }
+
+ /**
* Reference Count GC: is this type acyclic?
*/
private final boolean acyclic;
@@ -181,6 +206,46 @@
}
/**
+ * The number of elements that are inlined into the spine.
+ */
+ @Uninterruptible
+ public int getFirstNElements() {
+ if (VM.VerifyAssertions) {
+ VM._assert(arrayletized);
+ }
+ if (elementType == RVMType.BooleanType) {
+ return MemoryManagerConstants.FIRSTN_BOOLEAN_ELEMS;
+ } else if (elementType == RVMType.ByteType) {
+ return MemoryManagerConstants.FIRSTN_BYTE_ELEMS;
+ } else if (elementType == RVMType.CharType) {
+ return MemoryManagerConstants.FIRSTN_CHAR_ELEMS;
+ } else if (elementType == RVMType.ShortType) {
+ return MemoryManagerConstants.FIRSTN_SHORT_ELEMS;
+ } else if (elementType == RVMType.IntType) {
+ return MemoryManagerConstants.FIRSTN_INT_ELEMS;
+ } else if (elementType == RVMType.LongType) {
+ return MemoryManagerConstants.FIRSTN_LONG_ELEMS;
+ } else if (elementType == RVMType.FloatType) {
+ return MemoryManagerConstants.FIRSTN_FLOAT_ELEMS;
+ } else if (elementType == RVMType.DoubleType) {
+ return MemoryManagerConstants.FIRSTN_DOUBLE_ELEMS;
+ } else {
+ return MemoryManagerConstants.FIRSTN_REF_ELEMS;
+ }
+ }
+
+ /**
+ * The number of elements in each arraylet.
+ */
+ @Uninterruptible
+ public int getLogArrayletElements() {
+ if (VM.VerifyAssertions) {
+ VM._assert(arrayletized);
+ }
+ return MemoryManagerConstants.LOG_ARRAYLET_BYTES - getLogElementSize();
+ }
+
+ /**
* Calculate the size, in bytes, of an array element, log base 2.
* @return log base 2 of array element size
*/
@@ -223,9 +288,56 @@
@Pure
@Uninterruptible
public int getInstanceSize(int numelts) {
+ final int headerBytes = ObjectModel.computeArrayHeaderSize(this);
+ if (arrayletized) {
+ int firstN = getFirstNElements();
+ int logArrayletElements = getLogArrayletElements();
+ int arrayletizedElements = numelts - firstN;
+ if (arrayletizedElements > 0) {
+ int arrayletCount = 1 + (arrayletizedElements >> logArrayletElements);
+ int spineBytes = arrayletCount<
@@ -44,12 +46,14 @@
* member or whether the member needs linking.
*/
@Entrypoint
- private static int[] memberOffsets;
+ private static WordArray memberOffsets;
static {
- memberOffsets = MemoryManager.newContiguousIntArray(32000);
+ memberOffsets = MemoryManager.createNativeIntBuffer(32000);
if (NEEDS_DYNAMIC_LINK != 0) {
- java.util.Arrays.fill(memberOffsets, NEEDS_DYNAMIC_LINK);
+ for(int i=0; i < MemoryManager.nativeIntBufferLength(memberOffsets); i++) {
+ memberOffsets.setInt(i, NEEDS_DYNAMIC_LINK);
+ }
}
}
@@ -76,7 +80,7 @@
RuntimeEntrypoints.initializeClassForDynamicLink(declaringClass);
int offset = resolvedMember.getOffset().toInt();
if (VM.VerifyAssertions) VM._assert(offset != NEEDS_DYNAMIC_LINK);
- memberOffsets[ref.getId()] = offset;
+ memberOffsets.setInt(ref.getId(), offset);
return offset;
}
@@ -86,12 +90,20 @@
* the given member reference.
*/
static synchronized void ensureCapacity(int id) {
- if (id >= memberOffsets.length) {
- int oldLen = memberOffsets.length;
- int[] tmp1 = MemoryManager.newContiguousIntArray((oldLen * 3) / 2);
- System.arraycopy(memberOffsets, 0, tmp1, 0, oldLen);
+ int oldLen = MemoryManager.nativeIntBufferLength(memberOffsets);
+ if (id >= oldLen) {
+ WordArray tmp1 = MemoryManager.createNativeIntBuffer((oldLen * 3) / 2);
+ if (VM.runningVM) {
+ Memory.memcopy(Magic.objectAsAddress(tmp1), Magic.objectAsAddress(memberOffsets), oldLen << LOG_BYTES_IN_INT);
+ } else {
+ for(int i=0; i < oldLen; i++) {
+ tmp1.setInt(i, memberOffsets.getInt(i));
+ }
+ }
if (NEEDS_DYNAMIC_LINK != 0) {
- java.util.Arrays.fill(tmp1, oldLen, tmp1.length, NEEDS_DYNAMIC_LINK);
+ for(int i=oldLen; i < MemoryManager.nativeIntBufferLength(tmp1); i++) {
+ tmp1.setInt(i, NEEDS_DYNAMIC_LINK);
+ }
}
Magic.sync(); // be sure array initialization is visible before we publish the reference!
memberOffsets = tmp1;
diff -r 743a2cc2ed20 -r 058fdc3780ba rvm/src/org/jikesrvm/compilers/baseline/BaselineCompiledMethod.java
--- a/rvm/src/org/jikesrvm/compilers/baseline/BaselineCompiledMethod.java Tue Aug 04 11:04:15 2009 +1000
+++ b/rvm/src/org/jikesrvm/compilers/baseline/BaselineCompiledMethod.java Mon Nov 16 09:21:21 2009 +1100
@@ -12,6 +12,7 @@
*/
package org.jikesrvm.compilers.baseline;
+import org.jikesrvm.HeapLayoutConstants;
import org.jikesrvm.VM;
import org.jikesrvm.PrintLN;
import org.jikesrvm.ArchitectureSpecific.BaselineConstants;
@@ -27,6 +28,7 @@
import org.jikesrvm.compilers.common.ExceptionTable;
import org.jikesrvm.runtime.DynamicLink;
import org.jikesrvm.runtime.ExceptionDeliverer;
+import org.jikesrvm.runtime.Magic;
import org.jikesrvm.runtime.StackBrowser;
import org.vmmagic.pragma.SynchronizedObject;
import org.vmmagic.pragma.Uninterruptible;
@@ -376,8 +378,21 @@
public int size() {
int size = TYPE.peekType().asClass().getInstanceSize();
- if (bytecodeMap != null) size += RVMArray.ByteArray.getInstanceSize(bytecodeMap.length);
- if (eTable != null) size += RVMArray.IntArray.getInstanceSize(eTable.length);
+ //jbs changed
+ if (bytecodeMap != null) {
+ if (Magic.objectAsAddress(bytecodeMap).LT(HeapLayoutConstants.BOOT_IMAGE_DATA_END)) {
+ size += RVMArray.ByteArray.getBootImageContiguousInstanceSize(bytecodeMap.length);
+ } else {
+ size += RVMArray.ByteArray.getInstanceSize(bytecodeMap.length);
+ }
+ }
+ if (eTable != null) {
+ if (Magic.objectAsAddress(eTable).LT(HeapLayoutConstants.BOOT_IMAGE_DATA_END)) {
+ size += RVMArray.IntArray.getBootImageContiguousInstanceSize(eTable.length);
+ } else {
+ size += RVMArray.IntArray.getInstanceSize(eTable.length);
+ }
+ }
if (referenceMaps != null) size += referenceMaps.size();
return size;
}
diff -r 743a2cc2ed20 -r 058fdc3780ba rvm/src/org/jikesrvm/compilers/baseline/BaselineCompiler.java
--- a/rvm/src/org/jikesrvm/compilers/baseline/BaselineCompiler.java Tue Aug 04 11:04:15 2009 +1000
+++ b/rvm/src/org/jikesrvm/compilers/baseline/BaselineCompiler.java Mon Nov 16 09:21:21 2009 +1100
@@ -244,6 +244,7 @@
// determine if we are going to insert edge counters for this method
if (options
.EDGE_COUNTERS &&
+ method.getName() != org.jikesrvm.classloader.RVMClassLoader.HackArrayMethodName &&
!method.getDeclaringClass().hasBridgeFromNativeAnnotation() &&
(method.hasCondBranch() || method.hasSwitch())) {
((BaselineCompiledMethod) compiledMethod).setHasCounterArray(); // yes, we will inject counters for this method.
diff -r 743a2cc2ed20 -r 058fdc3780ba rvm/src/org/jikesrvm/compilers/baseline/BranchProfiles.java
--- a/rvm/src/org/jikesrvm/compilers/baseline/BranchProfiles.java Tue Aug 04 11:04:15 2009 +1000
+++ b/rvm/src/org/jikesrvm/compilers/baseline/BranchProfiles.java Mon Nov 16 09:21:21 2009 +1100
@@ -16,6 +16,8 @@
import org.jikesrvm.classloader.BytecodeConstants;
import org.jikesrvm.classloader.BytecodeStream;
import org.jikesrvm.classloader.NormalMethod;
+import org.jikesrvm.mm.mminterface.MemoryManager;
+import org.vmmagic.unboxed.WordArray;
/**
* Profile data for all conditional branches (including switches)
@@ -60,9 +62,9 @@
}
}
- BranchProfiles(NormalMethod m, int[] cs) {
+ BranchProfiles(NormalMethod m, WordArray cs) {
method = m;
- numCounters = cs.length;
+ numCounters = MemoryManager.nativeIntBufferLength(cs);
// Originally we only allocate half of the number of edges for branch
// profiles, like data = new BranchProfile[cs.length/2]
@@ -70,7 +72,7 @@
// least two edges, supposingly. Then we found that the lookupswitch
// bytecode could have only one edge, so the number of branch profiles
// is not necessarily less than half of the number of edges.
- BranchProfile[] data = new BranchProfile[cs.length];
+ BranchProfile[] data = new BranchProfile[MemoryManager.nativeIntBufferLength(cs)];
BytecodeStream bcodes = m.getBytecodes();
int dataIdx = 0;
int countIdx = 0;
@@ -99,8 +101,8 @@
case JBC_if_acmpne:
case JBC_ifnull:
case JBC_ifnonnull: {
- int yea = cs[countIdx + EdgeCounts.TAKEN];
- int nea = cs[countIdx + EdgeCounts.NOT_TAKEN];
+ int yea = cs.getInt(countIdx + EdgeCounts.TAKEN);
+ int nea = cs.getInt(countIdx + EdgeCounts.NOT_TAKEN);
int offset = bcodes.getBranchOffset();
boolean backwards = offset < 0;
countIdx += 2;
@@ -137,7 +139,7 @@
}
// Make sure we are in sync
- if (VM.VerifyAssertions) VM._assert(countIdx == cs.length);
+ if (VM.VerifyAssertions) VM._assert(countIdx == MemoryManager.nativeIntBufferLength(cs));
if (dataIdx != data.length) {
// We had a switch statment; shrink the array.
diff -r 743a2cc2ed20 -r 058fdc3780ba rvm/src/org/jikesrvm/compilers/baseline/EdgeCounts.java
--- a/rvm/src/org/jikesrvm/compilers/baseline/EdgeCounts.java Tue Aug 04 11:04:15 2009 +1000
+++ b/rvm/src/org/jikesrvm/compilers/baseline/EdgeCounts.java Mon Nov 16 09:21:21 2009 +1100
@@ -22,8 +22,10 @@
import org.jikesrvm.Callbacks;
import org.jikesrvm.classloader.MemberReference;
import org.jikesrvm.classloader.NormalMethod;
+import org.jikesrvm.mm.mminterface.MemoryManager;
import org.jikesrvm.runtime.Magic;
import org.vmmagic.pragma.Entrypoint;
+import org.vmmagic.unboxed.WordArray;
/**
* A repository of edge counters for bytecode-level edge conditional branches.
@@ -50,8 +52,8 @@
* number of times a particular branch event occurs.
*/
@Entrypoint
- private static int[][] data;
-
+ private static WordArray[] data;
+
public void notifyExit(int value) { dumpCounts(); }
public static void boot(String inputFileName) {
@@ -74,17 +76,17 @@
private static synchronized void allocateCounters(int id, int numEntries) {
if (data == null) {
- data = new int[id + 500][];
+ data = new WordArray[id + 500];
}
if (id >= data.length) {
int newSize = data.length * 2;
if (newSize <= id) newSize = id + 500;
- int[][] tmp = new int[newSize][];
+ WordArray[] tmp = new WordArray[newSize];
System.arraycopy(data, 0, tmp, 0, data.length);
Magic.sync();
data = tmp;
}
- data[id] = new int[numEntries];
+ data[id] = MemoryManager.createNativeIntBuffer(numEntries);
}
public static BranchProfiles getBranchProfiles(NormalMethod m) {
@@ -132,7 +134,7 @@
VM.sysFail("Unable to open input edge counter file " + fn);
}
try {
- int[] cur = null;
+ WordArray cur = null;
int curIdx = 0;
for (String s = in.readLine(); s != null; s = in.readLine()) {
StringTokenizer parser = new StringTokenizer(s, " \t\n\r\f,{}");
@@ -149,12 +151,12 @@
if (type.equals("switch")) {
parser.nextToken(); // discard '<'
for (String nt = parser.nextToken(); !nt.equals(">"); nt = parser.nextToken()) {
- cur[curIdx++] = Integer.parseInt(nt);
+ cur.setInt(curIdx++, Integer.parseInt(nt));
}
} else if (type.equals("forwbranch") || type.equals("backbranch")) {
parser.nextToken(); // discard '<'
- cur[curIdx + TAKEN] = Integer.parseInt(parser.nextToken());
- cur[curIdx + NOT_TAKEN] = Integer.parseInt(parser.nextToken());
+ cur.setInt(curIdx + TAKEN, Integer.parseInt(parser.nextToken()));
+ cur.setInt(curIdx + NOT_TAKEN, Integer.parseInt(parser.nextToken()));
curIdx += 2;
} else {
VM.sysFail("Format error in edge counter input file");
diff -r 743a2cc2ed20 -r 058fdc3780ba rvm/src/org/jikesrvm/compilers/baseline/ReferenceMaps.java
--- a/rvm/src/org/jikesrvm/compilers/baseline/ReferenceMaps.java Tue Aug 04 11:04:15 2009 +1000
+++ b/rvm/src/org/jikesrvm/compilers/baseline/ReferenceMaps.java Mon Nov 16 09:21:21 2009 +1100
@@ -13,11 +13,14 @@
package org.jikesrvm.compilers.baseline;
import org.jikesrvm.ArchitectureSpecific.BaselineConstants;
+import org.jikesrvm.HeapLayoutConstants;
import org.jikesrvm.VM;
import org.jikesrvm.classloader.RVMArray;
import org.jikesrvm.classloader.RVMMethod;
import org.jikesrvm.classloader.NormalMethod;
import org.jikesrvm.classloader.TypeReference;
+import org.jikesrvm.mm.mminterface.MemoryManagerConstants;
+import org.jikesrvm.runtime.Magic;
import org.jikesrvm.scheduler.ProcessorLock;
import org.vmmagic.pragma.Interruptible;
import org.vmmagic.pragma.Uninterruptible;
@@ -378,11 +381,28 @@
@Interruptible
public int size() {
int size = TypeReference.ReferenceMaps.peekType().asClass().getInstanceSize();
- if (MCSites != null) size += RVMArray.IntArray.getInstanceSize(MCSites.length);
- if (referenceMaps != null) size += RVMArray.ByteArray.getInstanceSize(referenceMaps.length);
+ if (MCSites != null) {
+ if (Magic.objectAsAddress(MCSites).LT(HeapLayoutConstants.BOOT_IMAGE_DATA_END)) {
+ size += RVMArray.IntArray.getBootImageContiguousInstanceSize(MCSites.length);
+ } else {
+ size += RVMArray.IntArray.getInstanceSize(MCSites.length);
+ }
+ }
+ if (referenceMaps != null) {
+ if (Magic.objectAsAddress(referenceMaps).LT(HeapLayoutConstants.BOOT_IMAGE_DATA_END)) {
+ size += RVMArray.ByteArray.getBootImageContiguousInstanceSize(referenceMaps.length);
+ } else {
+ size += RVMArray.ByteArray.getInstanceSize(referenceMaps.length);
+ }
+ }
if (jsrInfo != null && jsrInfo.unusualReferenceMaps != null) {
+ //jbs added arraylet
+ if (Magic.objectAsAddress(jsrInfo.unusualReferenceMaps).LT(HeapLayoutConstants.BOOT_IMAGE_DATA_END)) {
+ size += RVMArray.JavaLangObjectArray.getBootImageContiguousInstanceSize(jsrInfo.unusualReferenceMaps.length);
+ } else {
size += RVMArray.JavaLangObjectArray.getInstanceSize(jsrInfo.unusualReferenceMaps.length);
}
+ }
return size;
}
diff -r 743a2cc2ed20 -r 058fdc3780ba rvm/src/org/jikesrvm/compilers/baseline/SwitchBranchProfile.java
--- a/rvm/src/org/jikesrvm/compilers/baseline/SwitchBranchProfile.java Tue Aug 04 11:04:15 2009 +1000
+++ b/rvm/src/org/jikesrvm/compilers/baseline/SwitchBranchProfile.java Mon Nov 16 09:21:21 2009 +1100
@@ -12,6 +12,8 @@
*/
package org.jikesrvm.compilers.baseline;
+import org.vmmagic.unboxed.WordArray;
+
/**
* Profile data for a branch instruction.
*/
@@ -29,11 +31,11 @@
* @param start idx of first entry in cs
* @param numEntries number of entries in cs for this switch
*/
- SwitchBranchProfile(int _bci, int[] cs, int start, int numEntries) {
+ SwitchBranchProfile(int _bci, WordArray cs, int start, int numEntries) {
super(_bci, sumCounts(cs, start, numEntries));
counts = new float[numEntries];
for (int i = 0; i < numEntries; i++) {
- counts[i] = (float) cs[start + i];
+ counts[i] = (float) cs.getInt(start + i);
}
}
@@ -61,10 +63,10 @@
return res + " >";
}
- private static float sumCounts(int[] counts, int start, int numEntries) {
+ private static float sumCounts(WordArray counts, int start, int numEntries) {
float sum = 0.0f;
for (int i = start; i < start + numEntries; i++) {
- sum += (float) counts[i];
+ sum += (float) counts.getInt(i);
}
return sum;
}
diff -r 743a2cc2ed20 -r 058fdc3780ba rvm/src/org/jikesrvm/compilers/baseline/ia32/Barriers.java
--- a/rvm/src/org/jikesrvm/compilers/baseline/ia32/Barriers.java Tue Aug 04 11:04:15 2009 +1000
+++ b/rvm/src/org/jikesrvm/compilers/baseline/ia32/Barriers.java Mon Nov 16 09:21:21 2009 +1100
@@ -27,12 +27,56 @@
*/
class Barriers implements BaselineConstants {
+
+
static void compileArrayStoreBarrier(Assembler asm) {
// on entry java stack contains ...|target_array_ref|array_index|ref_to_store|
BaselineCompilerImpl.genParameterRegisterLoad(asm, 3);
asm.emitCALL_Abs(Magic.getTocPointer().plus(Entrypoints.arrayStoreWriteBarrierMethod.getOffset()));
}
+ static void compileArrayStorePrimitiveShortBarrier(Assembler asm) {
+ // on entry java stack contains ...|target_array_ref|array_index|ref_to_store|
+ BaselineCompilerImpl.genParameterRegisterLoad(asm, 3);
+ asm.emitCALL_Abs(Magic.getTocPointer().plus(Entrypoints.arrayStorePrimitiveShortWriteBarrierMethod.getOffset()));
+ }
+
+ static void compileArrayStorePrimitiveCharBarrier(Assembler asm) {
+ // on entry java stack contains ...|target_array_ref|array_index|ref_to_store|
+ BaselineCompilerImpl.genParameterRegisterLoad(asm, 3);
+ asm.emitCALL_Abs(Magic.getTocPointer().plus(Entrypoints.arrayStorePrimitiveCharWriteBarrierMethod.getOffset()));
+ }
+
+ static void compileArrayStorePrimitiveByteBarrier(Assembler asm) {
+ // on entry java stack contains ...|target_array_ref|array_index|ref_to_store|
+ BaselineCompilerImpl.genParameterRegisterLoad(asm, 3);
+ asm.emitCALL_Abs(Magic.getTocPointer().plus(Entrypoints.arrayStorePrimitiveByteWriteBarrierMethod.getOffset()));
+ }
+
+ static void compileArrayStorePrimitiveFloatBarrier(Assembler asm) {
+ // on entry java stack contains ...|target_array_ref|array_index|ref_to_store|
+ BaselineCompilerImpl.genParameterRegisterLoad(asm, 3);
+ asm.emitCALL_Abs(Magic.getTocPointer().plus(Entrypoints.arrayStorePrimitiveFloatWriteBarrierMethod.getOffset()));
+ }
+
+ static void compileArrayStorePrimitiveIntBarrier(Assembler asm) {
+ // on entry java stack contains ...|target_array_ref|array_index|ref_to_store|
+ BaselineCompilerImpl.genParameterRegisterLoad(asm, 3);
+ asm.emitCALL_Abs(Magic.getTocPointer().plus(Entrypoints.arrayStorePrimitiveIntWriteBarrierMethod.getOffset()));
+ }
+
+ static void compileArrayStorePrimitiveLongBarrier(Assembler asm) {
+ // on entry java stack contains ...|target_array_ref|array_index|ref_to_store|
+ BaselineCompilerImpl.genParameterRegisterLoad(asm, 4);
+ asm.emitCALL_Abs(Magic.getTocPointer().plus(Entrypoints.arrayStorePrimitiveLongWriteBarrierMethod.getOffset()));
+ }
+
+ static void compileArrayStorePrimitiveDoubleBarrier(Assembler asm) {
+ // on entry java stack contains ...|target_array_ref|array_index|ref_to_store|
+ BaselineCompilerImpl.genParameterRegisterLoad(asm, 4);
+ asm.emitCALL_Abs(Magic.getTocPointer().plus(Entrypoints.arrayStorePrimitiveDoubleWriteBarrierMethod.getOffset()));
+ }
+
static void compilePutfieldBarrier(Assembler asm, GPR reg, int locationMetadata) {
// on entry java stack contains ...|target_ref|ref_to_store|
// SP[0] -> ref_to_store, SP[1] -> target_ref
@@ -83,6 +127,14 @@
asm.emitCALL_Abs(Magic.getTocPointer().plus(Entrypoints.putstaticWriteBarrierMethod.getOffset()));
}
+ static void compileHackArrayLoadBarrier(Assembler asm, boolean pushResult) {
+ // on entry java stack contains ...|target_array_ref|array_index|
+ // SP -> index, SP+4 -> target_ref
+ BaselineCompilerImpl.genParameterRegisterLoad(asm, 2);
+ asm.emitCALL_Abs(Magic.getTocPointer().plus(Entrypoints.hackArrayLoadReadBarrierMethod.getOffset()));
+ if (pushResult) asm.emitPUSH_Reg(T0);
+ }
+
static void compileArrayLoadBarrier(Assembler asm, boolean pushResult) {
// on entry java stack contains ...|target_array_ref|array_index|
// SP -> index, SP+4 -> target_ref
@@ -91,6 +143,75 @@
if (pushResult) asm.emitPUSH_Reg(T0);
}
+ static void compileArrayLoadPrimitiveShortBarrier(Assembler asm, boolean pushResult) {
+ // on entry java stack contains ...|target_array_ref|array_index|
+ // SP -> index, SP+4 -> target_ref
+ BaselineCompilerImpl.genParameterRegisterLoad(asm, 2);
+ asm.emitCALL_Abs(Magic.getTocPointer().plus(Entrypoints.arrayLoadPrimitiveShortReadBarrierMethod.getOffset()));
+ if (pushResult) asm.emitPUSH_Reg(T0);
+ }
+
+ static void compileArrayLoadPrimitiveCharBarrier(Assembler asm, boolean pushResult) {
+ // on entry java stack contains ...|target_array_ref|array_index|
+ // SP -> index, SP+4 -> target_ref
+ BaselineCompilerImpl.genParameterRegisterLoad(asm, 2);
+ asm.emitCALL_Abs(Magic.getTocPointer().plus(Entrypoints.arrayLoadPrimitiveCharReadBarrierMethod.getOffset()));
+ if (pushResult) asm.emitPUSH_Reg(T0);
+ }
+
+ static void compileArrayLoadPrimitiveByteBarrier(Assembler asm, boolean pushResult) {
+ // on entry java stack contains ...|target_array_ref|array_index|
+ // SP -> index, SP+4 -> target_ref
+ BaselineCompilerImpl.genParameterRegisterLoad(asm, 2);
+ asm.emitCALL_Abs(Magic.getTocPointer().plus(Entrypoints.arrayLoadPrimitiveByteReadBarrierMethod.getOffset()));
+ if (pushResult) asm.emitPUSH_Reg(T0);
+ }
+
+ static void compileArrayLoadPrimitiveFloatBarrier(Assembler asm, boolean pushResult) {
+ // on entry java stack contains ...|target_array_ref|array_index|
+ // SP -> index, SP+4 -> target_ref
+ BaselineCompilerImpl.genParameterRegisterLoad(asm, 2);
+ asm.emitCALL_Abs(Magic.getTocPointer().plus(Entrypoints.arrayLoadPrimitiveFloatReadBarrierMethod.getOffset()));
+ if (pushResult) asm.emitPUSH_Reg(T0); //shouldn't be true
+ }
+
+ static void compileArrayLoadPrimitiveIntBarrier(Assembler asm, boolean pushResult) {
+ // on entry java stack contains ...|target_array_ref|array_index|
+ // SP -> index, SP+4 -> target_ref
+ BaselineCompilerImpl.genParameterRegisterLoad(asm, 2);
+ asm.emitCALL_Abs(Magic.getTocPointer().plus(Entrypoints.arrayLoadPrimitiveIntReadBarrierMethod.getOffset()));
+ if (pushResult) asm.emitPUSH_Reg(T0);
+ }
+
+ static void compileArrayLoadPrimitiveLongBarrier(Assembler asm, boolean pushResult) {
+ // on entry java stack contains ...|target_array_ref|array_index|
+ // SP -> index, SP+4 -> target_ref
+ BaselineCompilerImpl.genParameterRegisterLoad(asm, 2);
+ asm.emitCALL_Abs(Magic.getTocPointer().plus(Entrypoints.arrayLoadPrimitiveLongReadBarrierMethod.getOffset()));
+ if (pushResult) {
+ asm.emitPUSH_Reg(T0);
+ asm.emitPUSH_Reg(T1);
+ }
+ }
+
+ static void compileArrayLoadPrimitiveDoubleBarrier(Assembler asm, boolean pushResult) {
+ // on entry java stack contains ...|target_array_ref|array_index|
+ // SP -> index, SP+4 -> target_ref
+ BaselineCompilerImpl.genParameterRegisterLoad(asm, 2);
+ asm.emitCALL_Abs(Magic.getTocPointer().plus(Entrypoints.arrayLoadPrimitiveDoubleReadBarrierMethod.getOffset()));
+ if (pushResult) { //jbs should NOT be true
+ //adjustStack(-2*WORDSIZE, true);
+ if (SSE2_FULL) {
+ asm.emitMOVLPD_RegInd_Reg(SP, XMM0);
+ } else {
+ asm.emitFSTP_RegInd_Reg_Quad(SP, FP0);
+ }
+ // asm.emitPUSH_Reg(T1);
+ // asm.emitPUSH_Reg(T0); //jbs switched for debugging...
+ }
+ }
+
+
static void compileGetfieldBarrier(Assembler asm, GPR reg, int locationMetadata) {
// on entry java stack contains ...|target_ref|
// SP -> target_ref
diff -r 743a2cc2ed20 -r 058fdc3780ba rvm/src/org/jikesrvm/compilers/baseline/ia32/BaselineCompilerImpl.java
--- a/rvm/src/org/jikesrvm/compilers/baseline/ia32/BaselineCompilerImpl.java Tue Aug 04 11:04:15 2009 +1000
+++ b/rvm/src/org/jikesrvm/compilers/baseline/ia32/BaselineCompilerImpl.java Mon Nov 16 09:21:21 2009 +1100
@@ -12,6 +12,7 @@
*/
package org.jikesrvm.compilers.baseline.ia32;
+import org.jikesrvm.HeapLayoutConstants;
import org.jikesrvm.SizeConstants;
import org.jikesrvm.VM;
import org.jikesrvm.adaptive.AosEntrypoints;
@@ -58,7 +59,6 @@
* BaselineCompilerImpl is the baseline compiler implementation for the IA32 architecture.
*/
public abstract class BaselineCompilerImpl extends BaselineCompiler implements BaselineConstants, SizeConstants {
-
static {
// Force resolution of BaselineMagic before using in genMagic
Object x = BaselineMagic.generateMagic(null, null, null, Offset.zero());
@@ -519,8 +519,65 @@
asm.emitPOP_Reg(T0); // T0 is array index
asm.emitPOP_Reg(S0); // S0 is array ref
genBoundsCheck(asm, T0, S0); // T0 is index, S0 is address of array
- // push [S0+T0<<2]
- asm.emitPUSH_RegIdx(S0, T0, Assembler.WORD, NO_SLOT);
+ if (MemoryManagerConstants.USE_PRIMITIVE_INT_ARRAYLETS) {
+ if (MemoryManagerConstants.INLINE_BASELINE_INT_READ_BARRIER) {
+ ForwardReference fr, fr2 = null;
+ //jbs S0 holds array, T0 holds index
+
+ //if (MemoryManagerConstants.DO_FIRSTN_OPT) { //we can actually get rid of this - if not true, firstn_value = 0
+ asm.emitCMP_Reg_Imm(T0, MemoryManagerConstants.FIRSTN_INT_ELEMS);
+ // Jmp around trap if index is OK
+ asm.emitBranchLikelyNextInstruction();
+ fr = asm.forwardJcc(Assembler.LLT);
+ //}
+ //check if in boot image, jump to fr
+ //FIXME - not 64-bit safe right now
+ if (!MemoryManagerConstants.BOOT_IMAGE_IS_ARRAYLETIZED) {
+ asm.emitCMP_Reg_Imm(S0, org.jikesrvm.HeapLayoutConstants.BOOT_IMAGE_DATA_END.toInt());
+
+ //inline barrier - slow path index >= SPINE_FIRSTN_ELEMENTS
+ fr2 = asm.forwardJcc(Assembler.LLT);
+ }
+ //T0 = T0 - SPINE_FIRSTN_ELEMENTS;
+ //T0 = index - SPINE_FIRSTN
+ asm.emitSUB_Reg_Imm(T0, MemoryManagerConstants.FIRSTN_INT_ELEMS);
+ //need another register to store result
+ //T1 = T0
+ asm.emitMOV_Reg_Reg(T1, T0);
+ //T1 = T1 >> LOG_ELEMENTS_IN_ARRAYLET;
+ //T1 is the index into arraylet indirection pointers
+ asm.emitSAR_Reg_Imm(T1, MemoryManagerConstants.LOG_ELEMENTS_IN_INT_ARRAYLET);
+ //T1 is arrayletIndirIndex in MemoryManager
+ //T1 = T1 + SPINE_FIRSTN_ELEMENTS
+ //"index" into the spine array with arraylet indirection
+ asm.emitADD_Reg_Imm(T1, MemoryManagerConstants.FIRSTN_INT_ELEMS);
+ //need to get arraylet indirection - load address, follow that
+ //T1 = S0[T1 << 2];
+ //T1 is arraylet address
+ asm.emitMOV_Reg_RegIdx(S0, S0, T1, (short)LG_WORDSIZE, NO_SLOT);
+ //now S0 is base - check for zeroArraylet?
+ //jbs - note - need to check if firstN_value == arraylet_elements?
+ //T0 = T0 AND ARRAYLET_ELEMENT_MASK
+ asm.emitAND_Reg_Imm(T0, MemoryManagerConstants.INT_ARRAYLET_MASK);
+ fr.resolve(asm);
+ if (fr2 != null) {
+ fr2.resolve(asm);
+ }
+ //push [T1+T0<<2];
+
+ //asm.emitMOV_Reg_RegIdx(value, S0, T0, (short)LG_WORDSIZE, NO_SLOT);
+ asm.emitPUSH_RegIdx(S0, T0, (short)LG_WORDSIZE, NO_SLOT);
+ //asm.emitPOP_Reg(value); // pop result
+ //done
+ } else {
+ asm.emitPUSH_Reg(S0);
+ asm.emitPUSH_Reg(T0);
+ Barriers.compileArrayLoadPrimitiveIntBarrier(asm, true);
+ }
+ } else {
+ // push [S0+T0<<2]
+ asm.emitPUSH_RegIdx(S0, T0, Assembler.WORD, NO_SLOT);
+ }
}
/**
@@ -528,8 +585,22 @@
*/
@Override
protected final void emit_faload() {
- // identical to iaload
- emit_iaload();
+ asm.emitPOP_Reg(T0); // T0 is array index
+ asm.emitPOP_Reg(S0); // S0 is array ref
+ genBoundsCheck(asm, T0, S0); // T0 is index, S0 is address of array
+ if (MemoryManagerConstants.USE_PRIMITIVE_FLOAT_ARRAYLETS) {
+ asm.emitPUSH_Reg(S0);
+ asm.emitPUSH_Reg(T0);
+ Barriers.compileArrayLoadPrimitiveFloatBarrier(asm, false); //true);
+ adjustStack(-WORDSIZE, true);
+ if (SSE2_FULL) {
+ asm.emitMOVSS_RegInd_Reg(SP, XMM0);
+ } else {
+ asm.emitFSTP_RegInd_Reg(SP, FP0);
+ }
+ } else {
+ asm.emitPUSH_RegIdx(S0, T0, Assembler.WORD, NO_SLOT);
+ }
}
/**
@@ -540,11 +611,56 @@
asm.emitPOP_Reg(T0); // T0 is array index
asm.emitPOP_Reg(T1); // T1 is array ref
genBoundsCheck(asm, T0, T1); // T0 is index, T1 is address of array
- if (MemoryManagerConstants.NEEDS_READ_BARRIER) {
- // rewind 2 args on stack
- asm.emitPUSH_Reg(T1); // T1 is array ref
- asm.emitPUSH_Reg(T0); // T0 is array index
- Barriers.compileArrayLoadBarrier(asm, true);
+ if (MemoryManagerConstants.NEEDS_READ_BARRIER || MemoryManagerConstants.USE_REFERENCE_ARRAYLETS || MemoryManagerConstants.USE_OBJECT_ARRAY_ACCESS_BARRIER) {
+ if (MemoryManagerConstants.INLINE_BASELINE_REFERENCE_READ_BARRIER) {
+ ForwardReference fr, fr2 = null;
+ //if (MemoryManagerConstants.DO_FIRSTN_OPT) { //we can actually get rid of this - if not true, firstn_value = 0
+ asm.emitCMP_Reg_Imm(T0, MemoryManagerConstants.FIRSTN_REF_ELEMS);
+ // Jmp around trap if index is OK
+ asm.emitBranchLikelyNextInstruction();
+ fr = asm.forwardJcc(Assembler.LLT);
+ //}
+ //check if in boot image, jump to fr
+ //FIXME - not 64-bit safe right now
+ if (!MemoryManagerConstants.BOOT_IMAGE_IS_ARRAYLETIZED) {
+ asm.emitCMP_Reg_Imm(T1, org.jikesrvm.HeapLayoutConstants.BOOT_IMAGE_DATA_END.toInt());
+ //inline barrier - slow path index >= SPINE_FIRSTN_ELEMENTS
+ fr2 = asm.forwardJcc(Assembler.LLT);
+ }
+ //T0 = T0 - SPINE_FIRSTN_ELEMENTS;
+ //T0 = index - SPINE_FIRSTN
+ asm.emitSUB_Reg_Imm(T0, MemoryManagerConstants.FIRSTN_REF_ELEMS);
+ //need another register to store result
+ //T1 = T0
+ asm.emitMOV_Reg_Reg(S0, T0);
+ //T1 = T1 >> LOG_ELEMENTS_IN_ARRAYLET;
+ //T1 is the index into arraylet indirection pointers
+ asm.emitSAR_Reg_Imm(S0, MemoryManagerConstants.LOG_ELEMENTS_IN_REF_ARRAYLET);
+ //T1 is arrayletIndirIndex in MemoryManager
+ //T1 = T1 + SPINE_FIRSTN_ELEMENTS
+ //"index" into the spine array with arraylet indirection
+ asm.emitADD_Reg_Imm(S0, MemoryManagerConstants.FIRSTN_REF_ELEMS);
+ //need to get arraylet indirection - load address, follow that
+ //T1 = S0[T1 << 2];
+ //T1 is arraylet address
+ asm.emitMOV_Reg_RegIdx(T1, T1, S0, (short)LG_WORDSIZE, NO_SLOT);
+ //now S0 is base - check for zeroArraylet?
+ //jbs - note - need to check if firstN_value == arraylet_elements?
+ //T0 = T0 AND ARRAYLET_ELEMENT_MASK
+ asm.emitAND_Reg_Imm(T0, MemoryManagerConstants.REF_ARRAYLET_MASK);
+ fr.resolve(asm);
+ if (fr2 != null) {
+ fr2.resolve(asm);
+ }
+ //push [T1+T0<<2];
+ asm.emitPUSH_RegIdx(T1, T0, (short)LG_WORDSIZE, NO_SLOT);
+ //done
+ } else {
+ // rewind 2 args on stack
+ asm.emitPUSH_Reg(T1); // T1 is array ref
+ asm.emitPUSH_Reg(T0); // T0 is array index
+ Barriers.compileArrayLoadBarrier(asm, true);
+ }
} else {
asm.emitPUSH_RegIdx(T1, T0, (short)LG_WORDSIZE, NO_SLOT); // push [S0+T0*WORDSIZE]
}
@@ -559,12 +675,87 @@
asm.emitPOP_Reg(S0); // S0 is array ref
genBoundsCheck(asm, T0, S0); // T0 is index, S0 is address of array
// T1 = (int)[S0+T0<<1]
- if (VM.BuildFor32Addr) {
- asm.emitMOVZX_Reg_RegIdx_Word(T1, S0, T0, Assembler.SHORT, NO_SLOT);
- } else {
- asm.emitMOVZXQ_Reg_RegIdx_Word(T1, S0, T0, Assembler.SHORT, NO_SLOT);
- }
- asm.emitPUSH_Reg(T1); // push short onto stack
+ if (MemoryManagerConstants.USE_PRIMITIVE_CHAR_ARRAYLETS) {
+ if (MemoryManagerConstants.INLINE_BASELINE_CHAR_READ_BARRIER) {
+ ForwardReference fr, fr2 = null;
+ //jbs S0 holds array, T0 holds index
+
+ //if (MemoryManagerConstants.DO_FIRSTN_OPT) { //we can actually get rid of this - if not true, firstn_value = 0
+ asm.emitCMP_Reg_Imm(T0, MemoryManagerConstants.FIRSTN_SHORT_ELEMS);
+ // Jmp around trap if index is OK
+ asm.emitBranchLikelyNextInstruction();
+ fr = asm.forwardJcc(Assembler.LLT);
+ //}
+ //check if in boot image, jump to fr
+ //FIXME - not 64-bit safe right now
+ if (!MemoryManagerConstants.BOOT_IMAGE_IS_ARRAYLETIZED) {
+ asm.emitCMP_Reg_Imm(S0, org.jikesrvm.HeapLayoutConstants.BOOT_IMAGE_DATA_END.toInt());
+
+ //inline barrier - slow path index >= SPINE_FIRSTN_ELEMENTS
+ fr2 = asm.forwardJcc(Assembler.LLT);
+ }
+ //T0 = T0 - SPINE_FIRSTN_ELEMENTS;
+ //T0 = index - SPINE_FIRSTN
+ asm.emitSUB_Reg_Imm(T0, MemoryManagerConstants.FIRSTN_SHORT_ELEMS);
+ //need another register to store result
+ //T1 = T0
+ asm.emitMOV_Reg_Reg(T1, T0);
+ //T1 = T1 >> LOG_ELEMENTS_IN_ARRAYLET;
+ //T1 is the index into arraylet indirection pointers
+ asm.emitSAR_Reg_Imm(T1, MemoryManagerConstants.LOG_ELEMENTS_IN_SHORT_ARRAYLET);
+ //T1 is arrayletIndirIndex in MemoryManager
+ asm.emitSAL_Reg_Imm(T1, LG_WORDSIZE);
+ //T1 = T1 + SPINE_FIRSTN_ELEMENTS
+ //"index" into the spine array with arraylet indirection
+ asm.emitADD_Reg_Imm(T1, MemoryManagerConstants.FIRSTN_SHORT_BYTES);// MemoryManagerConstants.FIRSTN_SHORT_VALUE);
+ //need to get arraylet indirection - load address, follow that
+ //T1 = S0[T1 << 2];
+ //T1 is arraylet address
+ //asm.emitMOV_Reg_RegIdx(S0, S0, T1, Assembler.SHORT, NO_SLOT);
+ /*if (VM.BuildFor32Addr) {
+ asm.emitMOVZX_Reg_RegIdx_Word(S0, S0, T1, Assembler.SHORT, NO_SLOT);
+ } else {
+ asm.emitMOVZXQ_Reg_RegIdx_Word(S0, S0, T1, Assembler.SHORT, NO_SLOT);
+ }*/
+ //jbs now T1 is offset off of S0 we need to load.
+ asm.emitADD_Reg_Reg(S0, T1);
+ asm.emitMOV_Reg_RegInd(S0, S0);
+ //asm.emitMOV_Reg_RegDisp(S0, S0, T1);
+
+ //now S0 is base - check for zeroArraylet?
+ //jbs - note - need to check if firstN_value == arraylet_elements?
+ //T0 = T0 AND ARRAYLET_ELEMENT_MASK
+ asm.emitAND_Reg_Imm(T0, MemoryManagerConstants.SHORT_ARRAYLET_MASK);
+ fr.resolve(asm);
+ if (fr2 != null) {
+ fr2.resolve(asm);
+ }
+ //push [T1+T0<<2];
+
+ //asm.emitMOV_Reg_RegIdx(value, S0, T0, (short)LG_WORDSIZE, NO_SLOT);
+ //asm.emitPUSH_RegIdx(S0, T0, Assembler.SHORT, NO_SLOT);
+ //asm.emitPOP_Reg(value); // pop result
+ if (VM.BuildFor32Addr) {
+ asm.emitMOVZX_Reg_RegIdx_Word(T1, S0, T0, Assembler.SHORT, NO_SLOT);
+ } else {
+ asm.emitMOVZXQ_Reg_RegIdx_Word(T1, S0, T0, Assembler.SHORT, NO_SLOT);
+ }
+ asm.emitPUSH_Reg(T1); // push short onto stack
+ //done
+ } else {
+ //asm.emitADD_Reg_Imm(SP, WORDSIZE * -2); // rewind 2 args on stack
+ asm.emitPUSH_Reg(S0);
+ asm.emitPUSH_Reg(T0);
+ Barriers.compileArrayLoadPrimitiveCharBarrier(asm, true);
+ }
+ } else {
+ if (VM.BuildFor32Addr) {
+ asm.emitMOVZX_Reg_RegIdx_Word(T1, S0, T0, Assembler.SHORT, NO_SLOT);
+ } else {
+ asm.emitMOVZXQ_Reg_RegIdx_Word(T1, S0, T0, Assembler.SHORT, NO_SLOT);
+ }
+ asm.emitPUSH_Reg(T1); // push short onto stack
+ }
}
/**
@@ -576,12 +767,88 @@
asm.emitPOP_Reg(S0); // S0 is array ref
genBoundsCheck(asm, T0, S0); // T0 is index, S0 is address of array
// T1 = (int)[S0+T0<<1]
- if (VM.BuildFor32Addr) {
- asm.emitMOVSX_Reg_RegIdx_Word(T1, S0, T0, Assembler.SHORT, NO_SLOT);
- } else {
- asm.emitMOVSXQ_Reg_RegIdx_Word(T1, S0, T0, Assembler.SHORT, NO_SLOT);
- }
- asm.emitPUSH_Reg(T1); // push short onto stack
+ //jbs changed arraylets
+ if (MemoryManagerConstants.USE_PRIMITIVE_SHORT_ARRAYLETS) {
+ //asm.emitADD_Reg_Imm(SP, WORDSIZE * -2); // rewind 2 args on stack
+ if (MemoryManagerConstants.INLINE_BASELINE_CHAR_READ_BARRIER) {
+ ForwardReference fr, fr2 = null;
+ //jbs S0 holds array, T0 holds index
+
+ //if (MemoryManagerConstants.DO_FIRSTN_OPT) { //we can actually get rid of this - if not true, firstn_value = 0
+ asm.emitCMP_Reg_Imm(T0, MemoryManagerConstants.FIRSTN_SHORT_ELEMS);
+ // Jmp around trap if index is OK
+ asm.emitBranchLikelyNextInstruction();
+ fr = asm.forwardJcc(Assembler.LLT);
+ //}
+ //check if in boot image, jump to fr
+ //FIXME - not 64-bit safe right now
+ if (!MemoryManagerConstants.BOOT_IMAGE_IS_ARRAYLETIZED) {
+ asm.emitCMP_Reg_Imm(S0, org.jikesrvm.HeapLayoutConstants.BOOT_IMAGE_DATA_END.toInt());
+
+ //inline barrier - slow path index >= SPINE_FIRSTN_ELEMENTS
+ fr2 = asm.forwardJcc(Assembler.LLT);
+ }
+ //T0 = T0 - SPINE_FIRSTN_ELEMENTS;
+ //T0 = index - SPINE_FIRSTN
+ asm.emitSUB_Reg_Imm(T0, MemoryManagerConstants.FIRSTN_SHORT_ELEMS);
+ //need another register to store result
+ //T1 = T0
+ asm.emitMOV_Reg_Reg(T1, T0);
+ //T1 = T1 >> LOG_ELEMENTS_IN_ARRAYLET;
+ //T1 is the index into arraylet indirection pointers
+ asm.emitSAR_Reg_Imm(T1, MemoryManagerConstants.LOG_ELEMENTS_IN_SHORT_ARRAYLET);
+ //T1 is arrayletIndirIndex in MemoryManager
+ asm.emitSAL_Reg_Imm(T1, LG_WORDSIZE);
+ //T1 = T1 + SPINE_FIRSTN_ELEMENTS
+ //"index" into the spine array with arraylet indirection
+ asm.emitADD_Reg_Imm(T1, MemoryManagerConstants.FIRSTN_SHORT_BYTES);// MemoryManagerConstants.FIRSTN_SHORT_VALUE);
+ //need to get arraylet indirection - load address, follow that
+ //T1 = S0[T1 << 2];
+ //T1 is arraylet address
+ //asm.emitMOV_Reg_RegIdx(S0, S0, T1, Assembler.SHORT, NO_SLOT);
+ /*if (VM.BuildFor32Addr) {
+ asm.emitMOVZX_Reg_RegIdx_Word(S0, S0, T1, Assembler.SHORT, NO_SLOT);
+ } else {
+ asm.emitMOVZXQ_Reg_RegIdx_Word(S0, S0, T1, Assembler.SHORT, NO_SLOT);
+ }*/
+ //jbs now T1 is offset off of S0 we need to load.
+ asm.emitADD_Reg_Reg(S0, T1);
+ asm.emitMOV_Reg_RegInd(S0, S0);
+ //asm.emitMOV_Reg_RegDisp(S0, S0, T1);
+
+ //now S0 is base - check for zeroArraylet?
+ //jbs - note - need to check if firstN_value == arraylet_elements?
+ //T0 = T0 AND ARRAYLET_ELEMENT_MASK
+ asm.emitAND_Reg_Imm(T0, MemoryManagerConstants.SHORT_ARRAYLET_MASK);
+ fr.resolve(asm);
+ if (fr2 != null) {
+ fr2.resolve(asm);
+ }
+ //push [T1+T0<<2];
+
+ //asm.emitMOV_Reg_RegIdx(value, S0, T0, (short)LG_WORDSIZE, NO_SLOT);
+ //asm.emitPUSH_RegIdx(S0, T0, Assembler.SHORT, NO_SLOT);
+ //asm.emitPOP_Reg(value); // pop result
+ if (VM.BuildFor32Addr) {
+ asm.emitMOVSX_Reg_RegIdx_Word(T1, S0, T0, Assembler.SHORT, NO_SLOT);
+ } else {
+ asm.emitMOVSXQ_Reg_RegIdx_Word(T1, S0, T0, Assembler.SHORT, NO_SLOT);
+ }
+ asm.emitPUSH_Reg(T1); // push short onto stack
+ //done
+ } else {
+ asm.emitPUSH_Reg(S0);
+ asm.emitPUSH_Reg(T0);
+ Barriers.compileArrayLoadPrimitiveShortBarrier(asm, true);
+ }
+ } else {
+ if (VM.BuildFor32Addr) {
+ asm.emitMOVSX_Reg_RegIdx_Word(T1, S0, T0, Assembler.SHORT, NO_SLOT);
+ } else {
+ asm.emitMOVSXQ_Reg_RegIdx_Word(T1, S0, T0, Assembler.SHORT, NO_SLOT);
+ }
+ asm.emitPUSH_Reg(T1); // push short onto stack
+ }
}
/**
@@ -592,13 +859,89 @@
asm.emitPOP_Reg(T0); // T0 is array index
asm.emitPOP_Reg(S0); // S0 is array ref
genBoundsCheck(asm, T0, S0); // T0 is index, S0 is address of array
+ boolean arrayletize = true;
// T1 = (int)[S0+T0<<1]
- if (VM.BuildFor32Addr) {
- asm.emitMOVSX_Reg_RegIdx_Byte(T1, S0, T0, Assembler.BYTE, NO_SLOT);
- } else {
- asm.emitMOVSXQ_Reg_RegIdx_Byte(T1, S0, T0, Assembler.BYTE, NO_SLOT);
- }
- asm.emitPUSH_Reg(T1); // push byte onto stack
+ if (arrayletize && MemoryManagerConstants.USE_PRIMITIVE_BOOLEAN_ARRAYLETS || MemoryManagerConstants.USE_PRIMITIVE_BYTE_ARRAYLETS) {
+ //asm.emitADD_Reg_Imm(SP, WORDSIZE * -2); // rewind 2 args on stack
+ if (MemoryManagerConstants.INLINE_BASELINE_BOOL_READ_BARRIER) {
+ ForwardReference fr, fr2 = null;
+ //jbs S0 holds array, T0 holds index
+
+ //if (MemoryManagerConstants.DO_FIRSTN_OPT) { //we can actually get rid of this - if not true, firstn_value = 0
+ asm.emitCMP_Reg_Imm(T0, MemoryManagerConstants.FIRSTN_BYTE_ELEMS);
+ // Jmp around trap if index is OK
+ asm.emitBranchLikelyNextInstruction();
+ fr = asm.forwardJcc(Assembler.LLT);
+ //}
+ //check if in boot image, jump to fr
+ //FIXME - not 64-bit safe right now
+ if (!MemoryManagerConstants.BOOT_IMAGE_IS_ARRAYLETIZED) {
+ asm.emitCMP_Reg_Imm(S0, org.jikesrvm.HeapLayoutConstants.BOOT_IMAGE_DATA_END.toInt());
+
+ //inline barrier - slow path index >= SPINE_FIRSTN_ELEMENTS
+ fr2 = asm.forwardJcc(Assembler.LLT);
+ }
+ //T0 = T0 - SPINE_FIRSTN_ELEMENTS;
+ //T0 = index - SPINE_FIRSTN
+ asm.emitSUB_Reg_Imm(T0, MemoryManagerConstants.FIRSTN_BYTE_ELEMS);
+ //need another register to store result
+ //T1 = T0
+ asm.emitMOV_Reg_Reg(T1, T0);
+ //T1 = T1 >> LOG_ELEMENTS_IN_ARRAYLET;
+ //T1 is the index into arraylet indirection pointers
+ asm.emitSAR_Reg_Imm(T1, MemoryManagerConstants.LOG_ELEMENTS_IN_BYTE_ARRAYLET);
+ //T1 is arrayletIndirIndex in MemoryManager
+ asm.emitSAL_Reg_Imm(T1, LG_WORDSIZE);
+ //T1 = T1 + SPINE_FIRSTN_ELEMENTS
+ //"index" into the spine array with arraylet indirection
+ asm.emitADD_Reg_Imm(T1, MemoryManagerConstants.FIRSTN_BYTE_BYTES);// MemoryManagerConstants.FIRSTN_SHORT_VALUE);
+ //need to get arraylet indirection - load address, follow that
+ //T1 = S0[T1 << 2];
+ //T1 is arraylet address
+ //asm.emitMOV_Reg_RegIdx(S0, S0, T1, Assembler.SHORT, NO_SLOT);
+ /*if (VM.BuildFor32Addr) {
+ asm.emitMOVZX_Reg_RegIdx_Word(S0, S0, T1, Assembler.SHORT, NO_SLOT);
+ } else {
+ asm.emitMOVZXQ_Reg_RegIdx_Word(S0, S0, T1, Assembler.SHORT, NO_SLOT);
+ }*/
+ //jbs now T1 is offset off of S0 we need to load.
+ asm.emitADD_Reg_Reg(S0, T1);
+ asm.emitMOV_Reg_RegInd(S0, S0);
+ //asm.emitMOV_Reg_RegDisp(S0, S0, T1);
+
+ //now S0 is base - check for zeroArraylet?
+ //jbs - note - need to check if firstN_value == arraylet_elements?
+ //T0 = T0 AND ARRAYLET_ELEMENT_MASK
+ asm.emitAND_Reg_Imm(T0, MemoryManagerConstants.BYTE_ARRAYLET_MASK);
+ fr.resolve(asm);
+ if (fr2 != null) {
+ fr2.resolve(asm);
+ }
+ //push [T1+T0<<2];
+
+ //asm.emitMOV_Reg_RegIdx(value, S0, T0, (short)LG_WORDSIZE, NO_SLOT);
+ //asm.emitPUSH_RegIdx(S0, T0, Assembler.SHORT, NO_SLOT);
+ //asm.emitPOP_Reg(value); // pop result
+ if (VM.BuildFor32Addr) {
+ asm.emitMOVSX_Reg_RegIdx_Byte(T1, S0, T0, Assembler.BYTE, NO_SLOT);
+ } else {
+ asm.emitMOVSXQ_Reg_RegIdx_Byte(T1, S0, T0, Assembler.BYTE, NO_SLOT);
+ }
+ asm.emitPUSH_Reg(T1); // push short onto stack
+ //done
+ } else {
+ asm.emitPUSH_Reg(S0);
+ asm.emitPUSH_Reg(T0);
+ Barriers.compileArrayLoadPrimitiveByteBarrier(asm, true);
+ }
+ } else {
+ if (VM.BuildFor32Addr) {
+ asm.emitMOVSX_Reg_RegIdx_Byte(T1, S0, T0, Assembler.BYTE, NO_SLOT);
+ } else {
+ asm.emitMOVSXQ_Reg_RegIdx_Byte(T1, S0, T0, Assembler.BYTE, NO_SLOT);
+ }
+ asm.emitPUSH_Reg(T1); // push byte onto stack
+ }
}
/**
@@ -608,21 +951,49 @@
protected final void emit_laload() {
asm.emitPOP_Reg(T0); // T0 is array index
asm.emitPOP_Reg(T1); // T1 is array ref
- if (VM.BuildFor32Addr && SSE2_BASE) {
- adjustStack(WORDSIZE*-2, true); // create space for result
- }
genBoundsCheck(asm, T0, T1); // T0 is index, T1 is address of array
- if (VM.BuildFor32Addr) {
- if (SSE2_BASE) {
- asm.emitMOVQ_Reg_RegIdx(XMM0, T1, T0, Assembler.LONG, NO_SLOT);
- asm.emitMOVQ_RegInd_Reg(SP, XMM0);
- } else {
- asm.emitPUSH_RegIdx(T1, T0, Assembler.LONG, ONE_SLOT); // load high part of desired long array element
- asm.emitPUSH_RegIdx(T1, T0, Assembler.LONG, NO_SLOT); // load low part of desired long array element
- }
- } else {
- adjustStack(-WORDSIZE, true);
- asm.emitPUSH_RegIdx(T1, T0, Assembler.LONG, NO_SLOT); // load desired long array element
+ ForwardReference fr = null;
+ ForwardReference fr2 = null;
+ if (MemoryManagerConstants.USE_PRIMITIVE_LONG_ARRAYLETS) {
+ asm.emitCMP_Reg_Imm(T0, MemoryManagerConstants.FIRSTN_LONG_ELEMS);
+ // Jmp around trap if index is OK
+ asm.emitBranchLikelyNextInstruction();
+ fr = asm.forwardJcc(Assembler.LLT);
+ //check if in boot image, jump to fr
+ //FIXME - not 64-bit safe right now
+ if (!MemoryManagerConstants.BOOT_IMAGE_IS_ARRAYLETIZED) {
+ asm.emitCMP_Reg_Imm(T1, org.jikesrvm.HeapLayoutConstants.BOOT_IMAGE_DATA_END.toInt());
+ //inline barrier - slow path index >= SPINE_FIRSTN_ELEMENTS
+ fr2 = asm.forwardJcc(Assembler.LLT);
+ }
+ //VM.sysWrite(" In primitiveLoadLongBarrier, got into barrier part "); VM.sysWriteln(MemoryManagerConstants.FIRSTN_LONG_ELEMS);
+ //}
+ //asm.emitADD_Reg_Imm(SP, WORDSIZE * -2); // rewind 2 args on stack
+ asm.emitPUSH_Reg(T1);
+ asm.emitPUSH_Reg(T0);
+ Barriers.compileArrayLoadPrimitiveLongBarrier(asm, true);
+ } else {
+ if (fr != null) {
+ fr.resolve(asm);
+ }
+ if (fr2 != null) {
+ fr2.resolve(asm);
+ }
+ if (VM.BuildFor32Addr) {
+ if (SSE2_BASE) {
+ //jbs added line back here
+ adjustStack(WORDSIZE*-2, true); // create space for result
+
+ asm.emitMOVQ_Reg_RegIdx(XMM0, T1, T0, Assembler.LONG, NO_SLOT);
+ asm.emitMOVQ_RegInd_Reg(SP, XMM0);
+ } else {
+ asm.emitPUSH_RegIdx(T1, T0, Assembler.LONG, ONE_SLOT); // load high part of desired long array element
+ asm.emitPUSH_RegIdx(T1, T0, Assembler.LONG, NO_SLOT); // load low part of desired long array element
+ }
+ } else {
+ adjustStack(-WORDSIZE, true);
+ asm.emitPUSH_RegIdx(T1, T0, Assembler.LONG, NO_SLOT); // load desired long array element
+ }
}
}
@@ -631,8 +1002,57 @@
*/
@Override
protected final void emit_daload() {
- // identical to laload
- emit_laload();
+ asm.emitPOP_Reg(T0); // T0 is array index
+ asm.emitPOP_Reg(T1); // T1 is array ref
+ genBoundsCheck(asm, T0, T1); // T0 is index, T1 is address of array
+ //jbs changed arraylets
+ ForwardReference fr = null;
+ ForwardReference fr2 = null;
+ if (MemoryManagerConstants.USE_PRIMITIVE_DOUBLE_ARRAYLETS) {
+ asm.emitCMP_Reg_Imm(T0, MemoryManagerConstants.FIRSTN_DOUBLE_ELEMS);
+ // Jmp around trap if index is OK
+ asm.emitBranchLikelyNextInstruction();
+ fr = asm.forwardJcc(Assembler.LLT);
+ //}
+ //check if in boot image, jump to fr
+ //FIXME - not 64-bit safe right now
+ if (!MemoryManagerConstants.BOOT_IMAGE_IS_ARRAYLETIZED) {
+ asm.emitCMP_Reg_Imm(T1, org.jikesrvm.HeapLayoutConstants.BOOT_IMAGE_DATA_END.toInt());
+ //inline barrier - slow path index >= SPINE_FIRSTN_ELEMENTS
+ fr2 = asm.forwardJcc(Assembler.LLT);
+ }
+ asm.emitPUSH_Reg(T1);
+ asm.emitPUSH_Reg(T0);
+ Barriers.compileArrayLoadPrimitiveDoubleBarrier(asm, false);
+ adjustStack(-2*WORDSIZE, true);
+ if (SSE2_FULL) {
+ asm.emitMOVLPD_RegInd_Reg(SP, XMM0);
+ } else {
+ asm.emitFSTP_RegInd_Reg_Quad(SP, FP0);
+ }
+ } else {
+ if (fr != null) {
+ fr.resolve(asm);
+ }
+ if (fr2 != null) {
+ fr2.resolve(asm);
+ }
+ if (VM.BuildFor32Addr) {
+ if (SSE2_BASE) {
+ //jbs added line back here
+ adjustStack(WORDSIZE*-2, true); // create space for result
+
+ asm.emitMOVQ_Reg_RegIdx(XMM0, T1, T0, Assembler.LONG, NO_SLOT);
+ asm.emitMOVQ_RegInd_Reg(SP, XMM0);
+ } else {
+ asm.emitPUSH_RegIdx(T1, T0, Assembler.LONG, ONE_SLOT); // load high part of desired long array element
+ asm.emitPUSH_RegIdx(T1, T0, Assembler.LONG, NO_SLOT); // load low part of desired long array element
+ }
+ } else {
+ adjustStack(-WORDSIZE, true);
+ asm.emitPUSH_RegIdx(T1, T0, Assembler.LONG, NO_SLOT); // load desired long array element
+ }
+ }
}
/*
@@ -649,7 +1069,36 @@
asm.emitPOP_Reg(T0); // T0 is array index
asm.emitPOP_Reg(S0); // S0 is array ref
genBoundsCheck(asm, T0, S0); // T0 is index, S0 is address of array
- asm.emitMOV_RegIdx_Reg(S0, T0, Assembler.WORD, NO_SLOT, T1); // [S0 + T0<<2] <- T1
+ //jbs changed arraylets
+ ForwardReference fr = null;
+ ForwardReference fr2 = null;
+ if (MemoryManagerConstants.USE_PRIMITIVE_INT_ARRAYLETS) {
+ asm.emitCMP_Reg_Imm(T0, MemoryManagerConstants.FIRSTN_INT_ELEMS);
+ // Jmp around trap if index is OK
+ asm.emitBranchLikelyNextInstruction();
+ fr = asm.forwardJcc(Assembler.LLT);
+ //}
+ //check if in boot image, jump to fr
+ //FIXME - not 64-bit safe right now
+ if (!MemoryManagerConstants.BOOT_IMAGE_IS_ARRAYLETIZED) {
+ asm.emitCMP_Reg_Imm(S0, org.jikesrvm.HeapLayoutConstants.BOOT_IMAGE_DATA_END.toInt());
+
+ //inline barrier - slow path index >= SPINE_FIRSTN_ELEMENTS
+ fr2 = asm.forwardJcc(Assembler.LLT);
+ }
+ asm.emitPUSH_Reg(S0);
+ asm.emitPUSH_Reg(T0);
+ asm.emitPUSH_Reg(T1);
+ Barriers.compileArrayStorePrimitiveIntBarrier(asm);
+ } else {
+ if (fr != null) {
+ fr.resolve(asm);
+ }
+ if (fr2 != null) {
+ fr2.resolve(asm);
+ }
+ asm.emitMOV_RegIdx_Reg(S0, T0, Assembler.WORD, NO_SLOT, T1); // [S0 + T0<<2] <- T1
+ }
}
/**
@@ -657,8 +1106,27 @@
*/
@Override
protected final void emit_fastore() {
- // identical to iastore
- emit_iastore();
+ Barriers.compileModifyCheck(asm, 8);
+ asm.emitPOP_Reg(T1); // T1 is the value
+ asm.emitPOP_Reg(T0); // T0 is array index
+ asm.emitPOP_Reg(S0); // S0 is array ref
+ genBoundsCheck(asm, T0, S0);
+ if (MemoryManagerConstants.USE_PRIMITIVE_FLOAT_ARRAYLETS) {
+ asm.emitPUSH_Reg(S0);
+ asm.emitPUSH_Reg(T0);
+ asm.emitPUSH_Reg(T1);
+ if (NUM_PARAMETER_FPRS > 0) {
+ if (SSE2_FULL) {
+ asm.emitMOVSS_Reg_RegDisp(XMM0, SP, NO_SLOT);
+ } else {
+ asm.emitFLD_Reg_RegDisp(FP0, SP, NO_SLOT);
+ }
+ }
+ Barriers.compileArrayStorePrimitiveFloatBarrier(asm);
+ } else {
+ // T0 is index, S0 is address of array
+ asm.emitMOV_RegIdx_Reg(S0, T0, Assembler.WORD, NO_SLOT, T1); // [S0 + T0<<2] <- T1
+ }
}
@@ -673,7 +1141,8 @@
genParameterRegisterLoad(asm, 2); // pass 2 parameter
// call checkstore(array ref, value)
asm.emitCALL_Abs(Magic.getTocPointer().plus(Entrypoints.checkstoreMethod.getOffset()));
- if (MemoryManagerConstants.NEEDS_WRITE_BARRIER) {
+ //jbs added arraylet
+ if (MemoryManagerConstants.NEEDS_WRITE_BARRIER || MemoryManagerConstants.USE_REFERENCE_ARRAYLETS || MemoryManagerConstants.USE_OBJECT_ARRAY_ACCESS_BARRIER) {
if (VM.BuildFor32Addr) {
asm.emitMOV_Reg_RegDisp(T0, SP, ONE_SLOT); // T0 is array index
asm.emitMOV_Reg_RegDisp(S0, SP, TWO_SLOTS); // S0 is array ref
@@ -706,8 +1175,37 @@
asm.emitPOP_Reg(T0); // T0 is array index
asm.emitPOP_Reg(S0); // S0 is array ref
genBoundsCheck(asm, T0, S0); // T0 is index, S0 is address of array
- // store halfword element into array i.e. [S0 +T0] <- T1 (halfword)
- asm.emitMOV_RegIdx_Reg_Word(S0, T0, Assembler.SHORT, NO_SLOT, T1);
+ //jbs changed arraylets
+ ForwardReference fr = null;
+ ForwardReference fr2 = null;
+ if (MemoryManagerConstants.USE_PRIMITIVE_CHAR_ARRAYLETS) {
+ asm.emitCMP_Reg_Imm(T0, MemoryManagerConstants.FIRSTN_SHORT_ELEMS);
+ // Jmp around trap if index is OK
+ asm.emitBranchLikelyNextInstruction();
+ fr = asm.forwardJcc(Assembler.LLT);
+ //}
+ //check if in boot image, jump to fr
+ //FIXME - not 64-bit safe right now
+ if (!MemoryManagerConstants.BOOT_IMAGE_IS_ARRAYLETIZED) {
+ asm.emitCMP_Reg_Imm(S0, org.jikesrvm.HeapLayoutConstants.BOOT_IMAGE_DATA_END.toInt());
+
+ //inline barrier - slow path index >= SPINE_FIRSTN_ELEMENTS
+ fr2 = asm.forwardJcc(Assembler.LLT);
+ }
+ asm.emitPUSH_Reg(S0);
+ asm.emitPUSH_Reg(T0);
+ asm.emitPUSH_Reg(T1);
+ Barriers.compileArrayStorePrimitiveCharBarrier(asm);
+ } else {
+ if (fr != null) {
+ fr.resolve(asm);
+ }
+ if (fr2 != null) {
+ fr2.resolve(asm);
+ }
+ // store halfword element into array i.e. [S0 +T0] <- T1 (halfword)
+ asm.emitMOV_RegIdx_Reg_Word(S0, T0, Assembler.SHORT, NO_SLOT, T1);
+ }
}
/**
@@ -715,8 +1213,42 @@
*/
@Override
protected final void emit_sastore() {
- // identical to castore
- emit_castore();
+ Barriers.compileModifyCheck(asm, 8);
+ asm.emitPOP_Reg(T1); // T1 is the value
+ asm.emitPOP_Reg(T0); // T0 is array index
+ asm.emitPOP_Reg(S0); // S0 is array ref
+ genBoundsCheck(asm, T0, S0); // T0 is index, S0 is address of array
+ //jbs changed arraylet
+ ForwardReference fr = null;
+ ForwardReference fr2 = null;
+ if (MemoryManagerConstants.USE_PRIMITIVE_SHORT_ARRAYLETS) {
+ asm.emitCMP_Reg_Imm(T0, MemoryManagerConstants.FIRSTN_SHORT_ELEMS);
+ // Jmp around trap if index is OK
+ asm.emitBranchLikelyNextInstruction();
+ fr = asm.forwardJcc(Assembler.LLT);
+ //}
+ //check if in boot image, jump to fr
+ //FIXME - not 64-bit safe right now
+ if (!MemoryManagerConstants.BOOT_IMAGE_IS_ARRAYLETIZED) {
+ asm.emitCMP_Reg_Imm(S0, org.jikesrvm.HeapLayoutConstants.BOOT_IMAGE_DATA_END.toInt());
+
+ //inline barrier - slow path index >= SPINE_FIRSTN_ELEMENTS
+ fr2 = asm.forwardJcc(Assembler.LLT);
+ }
+ asm.emitPUSH_Reg(S0);
+ asm.emitPUSH_Reg(T0);
+ asm.emitPUSH_Reg(T1);
+ Barriers.compileArrayStorePrimitiveShortBarrier(asm);
+ } else {
+ if (fr != null) {
+ fr.resolve(asm);
+ }
+ if (fr2 != null) {
+ fr2.resolve(asm);
+ }
+ // store halfword element into array i.e. [S0 +T0] <- T1 (halfword)
+ asm.emitMOV_RegIdx_Reg_Word(S0, T0, Assembler.SHORT, NO_SLOT, T1);
+ }
}
/**
@@ -729,7 +1261,37 @@
asm.emitPOP_Reg(T0); // T0 is array index
asm.emitPOP_Reg(S0); // S0 is array ref
genBoundsCheck(asm, T0, S0); // T0 is index, S0 is address of array
- asm.emitMOV_RegIdx_Reg_Byte(S0, T0, Assembler.BYTE, NO_SLOT, T1); // [S0 + T0<<2] <- T1
+ // boolean arrayletize = true;
+ //jbs changed arraylet
+ ForwardReference fr = null;
+ ForwardReference fr2 = null;
+ if (/*arrayletize && */MemoryManagerConstants.USE_PRIMITIVE_BYTE_ARRAYLETS || MemoryManagerConstants.USE_PRIMITIVE_BOOLEAN_ARRAYLETS) {
+ asm.emitCMP_Reg_Imm(T0, MemoryManagerConstants.FIRSTN_BYTE_ELEMS);
+ // Jmp around trap if index is OK
+ asm.emitBranchLikelyNextInstruction();
+ fr = asm.forwardJcc(Assembler.LLT);
+ //}
+ //check if in boot image, jump to fr
+ //FIXME - not 64-bit safe right now
+ if (!MemoryManagerConstants.BOOT_IMAGE_IS_ARRAYLETIZED) {
+ asm.emitCMP_Reg_Imm(S0, org.jikesrvm.HeapLayoutConstants.BOOT_IMAGE_DATA_END.toInt());
+
+ //inline barrier - slow path index >= SPINE_FIRSTN_ELEMENTS
+ fr2 = asm.forwardJcc(Assembler.LLT);
+ }
+ asm.emitPUSH_Reg(S0);
+ asm.emitPUSH_Reg(T0);
+ asm.emitPUSH_Reg(T1);
+ Barriers.compileArrayStorePrimitiveByteBarrier(asm);
+ } else {
+ if (fr != null) {
+ fr.resolve(asm);
+ }
+ if (fr2 != null) {
+ fr2.resolve(asm);
+ }
+ asm.emitMOV_RegIdx_Reg_Byte(S0, T0, Assembler.BYTE, NO_SLOT, T1); // [S0 + T0<<2] <- T1
+ }
}
/**
@@ -756,19 +1318,53 @@
asm.emitPOP_Reg(S0); // S0 is array ref
}
genBoundsCheck(asm, T0, S0); // T0 is index, S0 is address of array
- if (VM.BuildFor32Addr) {
- if (SSE2_BASE) {
- asm.emitMOVQ_RegIdx_Reg(S0, T0, Assembler.LONG, NO_SLOT, XMM0); // [S0+T0<<<3] <- XMM0
- } else {
- // [S0 + T0<<3 + 0] <- T1 store low part into array
- asm.emitMOV_RegIdx_Reg(S0, T0, Assembler.LONG, NO_SLOT, T1);
- asm.emitMOV_Reg_RegDisp(T1, SP, ONE_SLOT); // high part of long value
- // [S0 + T0<<3 + 4] <- T1 store high part into array
- adjustStack(WORDSIZE*4, false); // remove index and ref from the stack
- asm.emitMOV_RegIdx_Reg(S0, T0, Assembler.LONG, ONE_SLOT, T1);
- }
- } else {
- asm.emitMOV_RegIdx_Reg_Quad(S0, T0, Assembler.LONG, NO_SLOT, T1); // [S0+T0<<<3] <- T1
+ //jbs changed arraylet
+ ForwardReference fr = null;
+ ForwardReference fr2 = null;
+ if (MemoryManagerConstants.USE_PRIMITIVE_LONG_ARRAYLETS) {
+ asm.emitCMP_Reg_Imm(T0, MemoryManagerConstants.FIRSTN_LONG_ELEMS);
+ // Jmp around trap if index is OK
+ asm.emitBranchLikelyNextInstruction();
+ fr = asm.forwardJcc(Assembler.LLT);
+ //check if in boot image, jump to fr
+ //FIXME - not 64-bit safe right now
+ if (!MemoryManagerConstants.BOOT_IMAGE_IS_ARRAYLETIZED) {
+ asm.emitCMP_Reg_Imm(S0, org.jikesrvm.HeapLayoutConstants.BOOT_IMAGE_DATA_END.toInt());
+ //inline barrier - slow path index >= SPINE_FIRSTN_ELEMENTS
+ fr2 = asm.forwardJcc(Assembler.LLT);
+ }
+ asm.emitPUSH_Reg(S0);
+ asm.emitPUSH_Reg(T0);
+ if (! (VM.BuildFor32Addr && SSE2_BASE)) {
+ asm.emitPUSH_Reg(T1);
+ } else {
+ //jbs - need to do adjustStack??
+ adjustStack(WORDSIZE*-2, true); // create space for store value
+
+ asm.emitMOVQ_RegInd_Reg(SP, XMM0); //jbs unsure? .emitPUSH_Reg(XMM0);
+ }
+ Barriers.compileArrayStorePrimitiveLongBarrier(asm);
+ } else {
+ if (fr != null) {
+ fr.resolve(asm);
+ }
+ if (fr2 != null) {
+ fr2.resolve(asm);
+ }
+ if (VM.BuildFor32Addr) {
+ if (SSE2_BASE) {
+ asm.emitMOVQ_RegIdx_Reg(S0, T0, Assembler.LONG, NO_SLOT, XMM0); // [S0+T0<<<3] <- XMM0
+ } else {
+ // [S0 + T0<<3 + 0] <- T1 store low part into array
+ asm.emitMOV_RegIdx_Reg(S0, T0, Assembler.LONG, NO_SLOT, T1);
+ asm.emitMOV_Reg_RegDisp(T1, SP, ONE_SLOT); // high part of long value
+ // [S0 + T0<<3 + 4] <- T1 store high part into array
+ adjustStack(WORDSIZE*4, false); // remove index and ref from the stack
+ asm.emitMOV_RegIdx_Reg(S0, T0, Assembler.LONG, ONE_SLOT, T1);
+ }
+ } else {
+ asm.emitMOV_RegIdx_Reg_Quad(S0, T0, Assembler.LONG, NO_SLOT, T1); // [S0+T0<<<3] <- T1
+ }
}
}
@@ -777,8 +1373,73 @@
*/
@Override
protected final void emit_dastore() {
- // identical to lastore
- emit_lastore();
+ Barriers.compileModifyCheck(asm, 3*WORDSIZE);
+ if (VM.BuildFor32Addr) {
+ if (SSE2_BASE) {
+ asm.emitMOVQ_Reg_RegInd(XMM0,SP); // XMM0 is the value
+ adjustStack(WORDSIZE*2, true); // remove value from the stack
+ asm.emitPOP_Reg(T0); // T0 is array index
+ asm.emitPOP_Reg(S0); // S0 is array ref
+ } else {
+ asm.emitMOV_Reg_RegDisp(T0, SP, TWO_SLOTS); // T0 is the array index
+ asm.emitMOV_Reg_RegDisp(S0, SP, THREE_SLOTS); // S0 is the array ref
+ asm.emitMOV_Reg_RegInd(T1, SP); // low part of long value
+ }
+ } else {
+ asm.emitPOP_Reg(T1); // T1 is the value
+ adjustStack(WORDSIZE, true); // throw away slot
+ asm.emitPOP_Reg(T0); // T0 is array index
+ asm.emitPOP_Reg(S0); // S0 is array ref
+ }
+ genBoundsCheck(asm, T0, S0); // T0 is index, S0 is address of array
+ //jbs changed arraylet
+ ForwardReference fr = null;
+ ForwardReference fr2 = null;
+ if (MemoryManagerConstants.USE_PRIMITIVE_DOUBLE_ARRAYLETS) {
+ asm.emitCMP_Reg_Imm(T0, MemoryManagerConstants.FIRSTN_DOUBLE_ELEMS);
+ // Jmp around trap if index is OK
+ asm.emitBranchLikelyNextInstruction();
+ fr = asm.forwardJcc(Assembler.LLT);
+ //}
+ //check if in boot image, jump to fr
+ //FIXME - not 64-bit safe right now
+ if (!MemoryManagerConstants.BOOT_IMAGE_IS_ARRAYLETIZED) {
+ asm.emitCMP_Reg_Imm(S0, org.jikesrvm.HeapLayoutConstants.BOOT_IMAGE_DATA_END.toInt());
+ //inline barrier - slow path index >= SPINE_FIRSTN_ELEMENTS
+ fr2 = asm.forwardJcc(Assembler.LLT);
+ }
+ asm.emitPUSH_Reg(S0);
+ asm.emitPUSH_Reg(T0);
+ //if (!(VM.BuildFor32Addr && SSE2_BASE)) {
+ // asm.emitPUSH_Reg(T1);
+ //} else {
+ //jbs - need to do adjustStack??
+ adjustStack(WORDSIZE*-2, true); // create space for store value
+ //asm.emitMOVQ_RegInd_Reg(SP, XMM0); //jbs unsure? .emitPUSH_Reg(XMM0);
+ //}
+ Barriers.compileArrayStorePrimitiveDoubleBarrier(asm);
+ } else {
+ if (fr != null) {
+ fr.resolve(asm);
+ }
+ if (fr2 != null) {
+ fr2.resolve(asm);
+ }
+ if (VM.BuildFor32Addr) {
+ if (SSE2_BASE) {
+ asm.emitMOVQ_RegIdx_Reg(S0, T0, Assembler.LONG, NO_SLOT, XMM0); // [S0+T0<<<3] <- XMM0
+ } else {
+ // [S0 + T0<<3 + 0] <- T1 store low part into array
+ asm.emitMOV_RegIdx_Reg(S0, T0, Assembler.LONG, NO_SLOT, T1);
+ asm.emitMOV_Reg_RegDisp(T1, SP, ONE_SLOT); // high part of long value
+ // [S0 + T0<<3 + 4] <- T1 store high part into array
+ adjustStack(WORDSIZE*4, false); // remove index and ref from the stack
+ asm.emitMOV_RegIdx_Reg(S0, T0, Assembler.LONG, ONE_SLOT, T1);
+ }
+ } else {
+ asm.emitMOV_RegIdx_Reg_Quad(S0, T0, Assembler.LONG, NO_SLOT, T1); // [S0+T0<<<3] <- T1
+ }
+ }
}
/*
@@ -2426,6 +3087,7 @@
fr.resolve(asm);
// Increment counter for the appropriate case
+
incEdgeCounter(S0, T1, firstCounter);
} else {
asm.emitJCC_Cond_ImmOrLabel(Assembler.LGE, mTarget, bTarget); // if not, goto default case
@@ -3161,6 +3823,7 @@
}
if (DynamicTypeCheck.MIN_DOES_IMPLEMENT_SIZE <= interfaceIndex) {
+ if (VM.VerifyAssertions) VM._assert(BYTES_IN_WORD == BYTES_IN_INT);
// must do arraybounds check of implements bit vector
if (JavaHeaderConstants.ARRAY_LENGTH_BYTES == 4) {
asm.emitCMP_RegDisp_Imm(S0, ObjectModel.getArrayLengthOffset(), interfaceIndex);
@@ -3174,11 +3837,13 @@
}
// Test the appropriate bit and if set, branch around another trap imm
+ //jbs added arraylets
if (interfaceIndex == 0) {
asm.emitTEST_RegInd_Imm(S0, interfaceMask);
} else {
asm.emitTEST_RegDisp_Imm(S0, Offset.fromIntZeroExtend(interfaceIndex << LOG_BYTES_IN_INT), interfaceMask);
}
+
asm.emitBranchLikelyNextInstruction();
ForwardReference fr = asm.forwardJcc(Assembler.NE);
asm.emitINT_Imm(RuntimeEntrypoints.TRAP_MUST_IMPLEMENT + RVM_TRAP_BASE);
@@ -3471,7 +4136,9 @@
}
// Test the appropriate bit and if set, branch around another trap imm
+ //jbs added arraylets
asm.emitTEST_RegDisp_Imm(S0, Offset.fromIntZeroExtend(interfaceIndex << LOG_BYTES_IN_INT), interfaceMask);
+
asm.emitBranchLikelyNextInstruction();
ForwardReference fr = asm.forwardJcc(Assembler.NE);
asm.emitINT_Imm(RuntimeEntrypoints.TRAP_CHECKCAST + RVM_TRAP_BASE);
@@ -3507,9 +4174,9 @@
if (DynamicTypeCheck.MIN_SUPERCLASS_IDS_SIZE <= LHSDepth) {
// must do arraybounds check of superclass display
if (JavaHeaderConstants.ARRAY_LENGTH_BYTES == 4) {
- asm.emitCMP_RegDisp_Imm(S0, ObjectModel.getArrayLengthOffset(), LHSDepth);
- } else {
- asm.emitCMP_RegDisp_Imm_Quad(S0, ObjectModel.getArrayLengthOffset(), LHSDepth);
+ asm.emitCMP_RegDisp_Imm(S0, ObjectModel.getArrayLengthOffset(), LHSDepth >> (LOG_BYTES_IN_WORD - LOG_BYTES_IN_CHAR));
+ } else {
+ asm.emitCMP_RegDisp_Imm_Quad(S0, ObjectModel.getArrayLengthOffset(), LHSDepth >> (LOG_BYTES_IN_WORD - LOG_BYTES_IN_CHAR));
}
asm.emitBranchLikelyNextInstruction();
ForwardReference fr = asm.forwardJcc(Assembler.LGT);
@@ -3518,6 +4185,7 @@
}
// Load id from display at required depth and compare against target id.
+ //jbs added arraylets
asm.emitMOVZX_Reg_RegDisp_Word(S0, S0, Offset.fromIntZeroExtend(LHSDepth << LOG_BYTES_IN_SHORT));
asm.emitCMP_Reg_Imm(S0, LHSId);
asm.emitBranchLikelyNextInstruction();
@@ -3603,7 +4271,9 @@
}
// Test the implements bit and push true if it is set
+ //jbs added arraylets
asm.emitTEST_RegDisp_Imm(S0, Offset.fromIntZeroExtend(interfaceIndex << LOG_BYTES_IN_INT), interfaceMask);
+
ForwardReference notMatched = asm.forwardJcc(Assembler.EQ);
asm.emitPUSH_Imm(1);
ForwardReference done = asm.forwardJMP();
@@ -3645,9 +4315,9 @@
if (DynamicTypeCheck.MIN_SUPERCLASS_IDS_SIZE <= LHSDepth) {
// must do arraybounds check of superclass display
if (JavaHeaderConstants.ARRAY_LENGTH_BYTES == 4) {
- asm.emitCMP_RegDisp_Imm(S0, ObjectModel.getArrayLengthOffset(), LHSDepth);
- } else {
- asm.emitCMP_RegDisp_Imm_Quad(S0, ObjectModel.getArrayLengthOffset(), LHSDepth);
+ asm.emitCMP_RegDisp_Imm(S0, ObjectModel.getArrayLengthOffset(), LHSDepth >> (LOG_BYTES_IN_WORD - LOG_BYTES_IN_CHAR));
+ } else {
+ asm.emitCMP_RegDisp_Imm_Quad(S0, ObjectModel.getArrayLengthOffset(), LHSDepth >> (LOG_BYTES_IN_WORD - LOG_BYTES_IN_CHAR));
}
outOfBounds = asm.forwardJcc(Assembler.LLE);
}
@@ -3840,10 +4510,14 @@
if (!VM.runningTool && ((BaselineCompiledMethod) compiledMethod).hasCounterArray()) {
// use (nonvolatile) EBX to hold base of this method's counter array
- if (MemoryManagerConstants.NEEDS_READ_BARRIER) {
+ //jbs added arraylet
+ if (MemoryManagerConstants.NEEDS_READ_BARRIER || MemoryManagerConstants.USE_REFERENCE_ARRAYLETS || MemoryManagerConstants.USE_OBJECT_ARRAY_ACCESS_BARRIER_ON_EDGE_COUNTS) {
asm.emitPUSH_Abs(Magic.getTocPointer().plus(Entrypoints.edgeCountersField.getOffset()));
asm.emitPUSH_Imm(getEdgeCounterIndex());
- Barriers.compileArrayLoadBarrier(asm, false);
+ if (VM.BuildWithBaseBootImageCompiler && VM.BuildForAdaptiveSystem && MemoryManagerConstants.USE_REFERENCE_ARRAYLETS)
+ Barriers.compileHackArrayLoadBarrier(asm, false);
+ else
+ Barriers.compileArrayLoadBarrier(asm, false);
if (VM.BuildFor32Addr) {
asm.emitMOV_Reg_Reg(EBX, T0);
} else {
@@ -4032,6 +4706,20 @@
}
}
+ private void emitSaveRegisters() {
+ asm.emitPUSH_Reg(S0);
+ asm.emitPUSH_Reg(S1);
+ asm.emitPUSH_Reg(T0);
+ asm.emitPUSH_Reg(T1);
+ }
+
+ private void emitRestoreRegisters() {
+ asm.emitPOP_Reg(T1);
+ asm.emitPOP_Reg(T0);
+ asm.emitPOP_Reg(S1);
+ asm.emitPOP_Reg(S0);
+ }
+
/**
* Generate code to increment edge counter
* @param scratch register to use as scratch
@@ -4041,20 +4729,22 @@
@Inline(value=Inline.When.ArgumentsAreConstant, arguments={1,2})
private void incEdgeCounter(GPR scratch, GPR idx, int counterIdx) {
if (VM.VerifyAssertions) VM._assert(((BaselineCompiledMethod) compiledMethod).hasCounterArray());
- if (idx == null) {
+
+ if (idx == null)
asm.emitMOV_Reg_RegDisp(scratch, EBX, Offset.fromIntZeroExtend(counterIdx << LOG_BYTES_IN_INT));
- } else {
+ else
asm.emitMOV_Reg_RegIdx(scratch, EBX, idx, Assembler.WORD, Offset.fromIntZeroExtend(counterIdx << LOG_BYTES_IN_INT));
- }
+
asm.emitADD_Reg_Imm(scratch, 1);
// Don't write back result if it would make the counter negative (ie
// saturate at 0x7FFFFFFF)
ForwardReference fr1 = asm.forwardJcc(Assembler.S);
- if (idx == null) {
+
+ if (idx == null)
asm.emitMOV_RegDisp_Reg(EBX, Offset.fromIntSignExtend(counterIdx << LOG_BYTES_IN_INT), scratch);
- } else {
+ else
asm.emitMOV_RegIdx_Reg(EBX, idx, Assembler.WORD, Offset.fromIntSignExtend(counterIdx << LOG_BYTES_IN_INT), scratch);
- }
+
fr1.resolve(asm);
}
@@ -4398,7 +5088,22 @@
int id = compiledMethod.getId();
InvocationCounts.allocateCounter(id);
asm.emitMOV_Reg_Abs(ECX, Magic.getTocPointer().plus(AosEntrypoints.invocationCountsField.getOffset()));
- asm.emitSUB_RegDisp_Imm(ECX, Offset.fromIntZeroExtend(compiledMethod.getId() << 2), 1);
+ //jbs added
+ if (MemoryManagerConstants.USE_PRIMITIVE_INT_ARRAYLETS) {
+
+ asm.emitPUSH_Reg(ECX);
+ asm.emitPUSH_Imm(compiledMethod.getId());
+ Barriers.compileArrayLoadPrimitiveIntBarrier(asm, false);
+ //result is in T0 because passed false (dont' push result) above
+ //asm.emitPOP_Reg(T0); // T0 is results of load of array at compiledMethod.getId()
+ asm.emitSUB_Reg_Imm(T0, 1);
+ asm.emitPUSH_Reg(ECX);
+ asm.emitPUSH_Imm(compiledMethod.getId());
+ asm.emitPUSH_Reg(T0); //value to store
+ Barriers.compileArrayStorePrimitiveIntBarrier(asm);
+ } else {
+ asm.emitSUB_RegDisp_Imm(ECX, Offset.fromIntZeroExtend(compiledMethod.getId() << 2), 1);
+ }
ForwardReference notTaken = asm.forwardJcc(Assembler.GT);
asm.emitPUSH_Imm(id);
genParameterRegisterLoad(asm, 1);
diff -r 743a2cc2ed20 -r 058fdc3780ba rvm/src/org/jikesrvm/compilers/baseline/ia32/BaselineMagic.java
--- a/rvm/src/org/jikesrvm/compilers/baseline/ia32/BaselineMagic.java Tue Aug 04 11:04:15 2009 +1000
+++ b/rvm/src/org/jikesrvm/compilers/baseline/ia32/BaselineMagic.java Mon Nov 16 09:21:21 2009 +1100
@@ -754,13 +754,17 @@
// Store at offset
if (VM.BuildFor32Addr) {
asm.emitPOP_Reg(T0); // T0 = offset
- asm.emitADD_Reg_RegDisp(T0, SP, THREE_SLOTS); // T0 = base+offset
+ asm.emitADD_Reg_RegDisp(T0, SP, TWO_SLOTS); // T0 = base+offset
+ //jbs bug fix - added above line and took out below (dframpton)
+ //asm.emitADD_Reg_RegDisp(T0, SP, THREE_SLOTS); // T0 = base+offset
asm.emitPOP_RegInd(T0); // [T0] <- value low
asm.emitPOP_RegDisp(T0, ONE_SLOT); // [T0+4] <- value high
asm.emitPOP_Reg(T0); // throw away slot
} else {
asm.emitPOP_Reg(T0); // offset
- asm.emitADD_Reg_RegDisp_Quad(T0, SP, THREE_SLOTS); // T0 = base+offset
+ asm.emitADD_Reg_RegDisp_Quad(T0, SP, TWO_SLOTS); // T0 = base+offset
+ //jbs bug fix - added above line and took out below (dframpton)
+ //asm.emitADD_Reg_RegDisp_Quad(T0, SP, THREE_SLOTS); // T0 = base+offset
asm.emitPOP_RegInd(T0); // T0 <- value
asm.emitPOP_Reg(T0); // throw away slot
asm.emitPOP_Reg(T0); // throw away slot
@@ -1024,6 +1028,7 @@
generators.put(getMethodReference(Magic.class, MagicNames.objectAsType, Object.class, RVMType.class), g);
generators.put(getMethodReference(Magic.class, MagicNames.objectAsShortArray, Object.class, short[].class), g);
generators.put(getMethodReference(Magic.class, MagicNames.objectAsIntArray, Object.class, int[].class), g);
+ generators.put(getMethodReference(Magic.class, MagicNames.objectAsWordArray, Object.class, WordArray.class), g);
generators.put(getMethodReference(Magic.class, MagicNames.objectAsProcessor, Object.class, Processor.class), g);
generators.put(getMethodReference(Magic.class, MagicNames.processorAsGreenProcessor, Processor.class, GreenProcessor.class), g);
generators.put(getMethodReference(Magic.class, MagicNames.objectAsThread, Object.class, RVMThread.class), g);
@@ -1544,7 +1549,7 @@
if (VALIDATE_OBJECT_REFERENCES) {
g = new LateReferenceCheckDecorator(NO_SLOT, g);
}
- generators.put(getMethodReference(Magic.class, MagicNames.invokeMethodReturningObject, CodeArray.class, WordArray.class, double[].class, byte[].class, WordArray.class, Object.class), g);
+ generators.put(getMethodReference(Magic.class, MagicNames.invokeMethodReturningObject, CodeArray.class, WordArray.class, WordArray.class, WordArray.class, WordArray.class, Object.class), g);
}
/**
@@ -1560,7 +1565,7 @@
}
static {
MagicGenerator g = new InvokeMethodReturningVoid();
- generators.put(getMethodReference(Magic.class, MagicNames.invokeMethodReturningVoid, CodeArray.class, WordArray.class, double[].class, byte[].class, WordArray.class, void.class), g);
+ generators.put(getMethodReference(Magic.class, MagicNames.invokeMethodReturningVoid, CodeArray.class, WordArray.class, WordArray.class, WordArray.class, WordArray.class, void.class), g);
}
/**
@@ -1577,7 +1582,7 @@
}
static {
MagicGenerator g = new InvokeMethodReturningInt();
- generators.put(getMethodReference(Magic.class, MagicNames.invokeMethodReturningInt, CodeArray.class, WordArray.class, double[].class, byte[].class, WordArray.class, int.class), g);
+ generators.put(getMethodReference(Magic.class, MagicNames.invokeMethodReturningInt, CodeArray.class, WordArray.class, WordArray.class, WordArray.class, WordArray.class, int.class), g);
}
/**
@@ -1595,7 +1600,7 @@
}
static {
MagicGenerator g = new InvokeMethodReturningLong();
- generators.put(getMethodReference(Magic.class, MagicNames.invokeMethodReturningLong, CodeArray.class, WordArray.class, double[].class, byte[].class, WordArray.class, long.class), g);
+ generators.put(getMethodReference(Magic.class, MagicNames.invokeMethodReturningLong, CodeArray.class, WordArray.class, WordArray.class, WordArray.class, WordArray.class, long.class), g);
}
/**
@@ -1617,7 +1622,7 @@
}
static {
MagicGenerator g = new InvokeMethodReturningFloat();
- generators.put(getMethodReference(Magic.class, MagicNames.invokeMethodReturningFloat, CodeArray.class, WordArray.class, double[].class, byte[].class, WordArray.class, float.class), g);
+ generators.put(getMethodReference(Magic.class, MagicNames.invokeMethodReturningFloat, CodeArray.class, WordArray.class, WordArray.class, WordArray.class, WordArray.class, float.class), g);
}
/**
@@ -1639,7 +1644,7 @@
}
static {
MagicGenerator g = new InvokeMethodReturningDouble();
- generators.put(getMethodReference(Magic.class, MagicNames.invokeMethodReturningDouble, CodeArray.class, WordArray.class, double[].class, byte[].class, WordArray.class, double.class), g);
+ generators.put(getMethodReference(Magic.class, MagicNames.invokeMethodReturningDouble, CodeArray.class, WordArray.class, WordArray.class, WordArray.class, WordArray.class, double.class), g);
}
/**
@@ -1856,6 +1861,25 @@
}
/**
+ * Get a 16bit element from a runtime table
+ * @see org.jikesrvm.objectmodel.RuntimeTable#get(int)
+ */
+ private static final class Load16_Array extends MagicGenerator {
+ @Override
+ void generateMagic(Assembler asm, MethodReference m, RVMMethod cm, Offset sd) {
+ asm.emitPOP_Reg(T0); // T0 is array index
+ asm.emitPOP_Reg(S0); // S0 is array ref
+ // push [S0+T0<<2]
+ asm.emitMOVZX_Reg_RegIdx_Word(T1, S0, T0, Assembler.SHORT, NO_SLOT);
+ asm.emitPUSH_Reg(T1);
+ }
+ }
+ static {
+ MagicGenerator g = new Load16_Array();
+ generators.put(getMethodReference(WordArray.class, MagicNames.addressArrayGetChar, int.class, char.class), g);
+ }
+
+ /**
* Get a 32bit element from a runtime table
* @see org.jikesrvm.objectmodel.RuntimeTable#get(int)
*/
@@ -1864,11 +1888,15 @@
void generateMagic(Assembler asm, MethodReference m, RVMMethod cm, Offset sd) {
asm.emitPOP_Reg(T0); // T0 is array index
asm.emitPOP_Reg(S0); // S0 is array ref
- BaselineCompilerImpl.genBoundsCheck(asm, T0, S0); // T0 is index, S0 is address of array
// push [S0+T0<<2]
asm.emitPUSH_RegIdx(S0, T0, Assembler.WORD, NO_SLOT);
}
}
+ static {
+ MagicGenerator g = new Load32_Array();
+ generators.put(getMethodReference(WordArray.class, MagicNames.addressArrayGetInt, int.class, int.class), g);
+ }
+
/**
* Get a 64bit element from a runtime table
* @see org.jikesrvm.objectmodel.RuntimeTable#get(int)
@@ -1878,12 +1906,15 @@
void generateMagic(Assembler asm, MethodReference m, RVMMethod cm, Offset sd) {
asm.emitPOP_Reg(T0); // T0 is array index
asm.emitPOP_Reg(S0); // S0 is array ref
- BaselineCompilerImpl.genBoundsCheck(asm, T0, S0); // T0 is index, S0 is address of array
// push [S0+T0<<3]
asm.emitPUSH_RegIdx(S0, T0, Assembler.LONG, NO_SLOT);
}
}
static {
+ MagicGenerator g = new Load64_Array();
+ generators.put(getMethodReference(WordArray.class, MagicNames.addressArrayGetLong, int.class, long.class), g);
+ }
+ static {
MagicGenerator g = VM.BuildFor32Addr ? new Load32_Array() : new Load64_Array();
Class>[] unboxedTypes = new Class>[] { AddressArray.class,
ExtentArray.class, FunctionTable.class, IMT.class,
@@ -1907,15 +1938,34 @@
void generateMagic(Assembler asm, MethodReference m, RVMMethod cm, Offset sd) {
asm.emitPOP_Reg(T0); // T0 is array index
asm.emitPOP_Reg(S0); // S0 is array ref
- BaselineCompilerImpl.genBoundsCheck(asm, T0, S0); // T0 is index, S0 is address of array
// T1 = (int)[S0+T0<<1]
- asm.emitMOVSX_Reg_RegIdx_Byte(T1, S0, T0, Assembler.BYTE, NO_SLOT);
+ asm.emitMOVZX_Reg_RegIdx_Byte(T1, S0, T0, Assembler.BYTE, NO_SLOT);
asm.emitPUSH_Reg(T1); // push byte onto stack
}
}
static {
MagicGenerator g = new LoadByte_Array();
generators.put(getMethodReference(CodeArray.class, MagicNames.addressArrayGet, int.class, byte.class), g);
+ generators.put(getMethodReference(WordArray.class, MagicNames.addressArrayGetByte, int.class, byte.class), g);
+ }
+
+ /**
+ * Store a 16bit element to a runtime table
+ * @see org.jikesrvm.objectmodel.RuntimeTable#set(int, Object)
+ */
+ private static final class Store16_Array extends MagicGenerator {
+ @Override
+ void generateMagic(Assembler asm, MethodReference m, RVMMethod cm, Offset sd) {
+ Barriers.compileModifyCheck(asm, 8);
+ asm.emitPOP_Reg(T1); // T1 is the value
+ asm.emitPOP_Reg(T0); // T0 is array index
+ asm.emitPOP_Reg(S0); // S0 is array ref
+ asm.emitMOV_RegIdx_Reg_Word(S0, T0, Assembler.SHORT, NO_SLOT, T1); // [S0 + T0<<2] <- T1
+ }
+ }
+ static {
+ MagicGenerator g = new Store16_Array();
+ generators.put(getMethodReference(WordArray.class, MagicNames.addressArraySetChar, int.class, char.class, void.class), g);
}
/**
@@ -1929,10 +1979,14 @@
asm.emitPOP_Reg(T1); // T1 is the value
asm.emitPOP_Reg(T0); // T0 is array index
asm.emitPOP_Reg(S0); // S0 is array ref
- BaselineCompilerImpl.genBoundsCheck(asm, T0, S0); // T0 is index, S0 is address of array
asm.emitMOV_RegIdx_Reg(S0, T0, Assembler.WORD, NO_SLOT, T1); // [S0 + T0<<2] <- T1
}
}
+ static {
+ MagicGenerator g = new Store32_Array();
+ generators.put(getMethodReference(WordArray.class, MagicNames.addressArraySetInt, int.class, int.class, void.class), g);
+ }
+
/**
* Store a 64bit element to a runtime table
* @see org.jikesrvm.objectmodel.RuntimeTable#set(int, Object)
@@ -1941,14 +1995,31 @@
@Override
void generateMagic(Assembler asm, MethodReference m, RVMMethod cm, Offset sd) {
Barriers.compileModifyCheck(asm, 8);
- asm.emitPOP_Reg(T1); // T1 is the value
- asm.emitPOP_Reg(T0); // T0 is array index
- asm.emitPOP_Reg(S0); // S0 is array ref
- BaselineCompilerImpl.genBoundsCheck(asm, T0, S0); // T0 is index, S0 is address of array
- asm.emitMOV_RegIdx_Reg_Quad(S0, T0, Assembler.LONG, NO_SLOT, T1); // [S0 + T0<<2] <- T1
+ if (SSE2_BASE) {
+ asm.emitMOVQ_Reg_RegInd(XMM0,SP); // XMM0 is the value
+ asm.emitPOP_Reg(S0); // discard
+ asm.emitPOP_Reg(S0); // discard
+ asm.emitPOP_Reg(T0); // T0 is array index
+ asm.emitPOP_Reg(S0); // S0 is array ref
+ asm.emitMOVQ_RegIdx_Reg(S0, T0, Assembler.LONG, NO_SLOT, XMM0); // [S0+T0<<<3] <- XMM0
+ } else {
+ asm.emitMOV_Reg_RegDisp(T0, SP, TWO_SLOTS); // T0 is the array index
+ asm.emitMOV_Reg_RegDisp(S0, SP, THREE_SLOTS); // S0 is the array ref
+ asm.emitMOV_Reg_RegInd(T1, SP); // low part of long value
+ // [S0 + T0<<3 + 0] <- T1 store low part into array
+ asm.emitMOV_RegIdx_Reg(S0, T0, Assembler.LONG, NO_SLOT, T1);
+ asm.emitMOV_Reg_RegDisp(T1, SP, ONE_SLOT); // high part of long value
+ // [S0 + T0<<3 + 4] <- T1 store high part into array
+ asm.emitADD_Reg_Imm(SP, WORDSIZE*4); // remove index and ref from the stack
+ asm.emitMOV_RegIdx_Reg(S0, T0, Assembler.LONG, ONE_SLOT, T1);
+ }
}
}
static {
+ MagicGenerator g = new Store64_Array();
+ generators.put(getMethodReference(WordArray.class, MagicNames.addressArraySetLong, int.class, long.class, void.class), g);
+ }
+ static {
MagicGenerator g = VM.BuildFor32Addr ? new Store32_Array() : new Store64_Array();
Class>[] unboxedTypes = new Class>[] { AddressArray.class,
ExtentArray.class, FunctionTable.class, IMT.class,
@@ -1974,13 +2045,13 @@
asm.emitPOP_Reg(T1); // T1 is the value
asm.emitPOP_Reg(T0); // T0 is array index
asm.emitPOP_Reg(S0); // S0 is array ref
- BaselineCompilerImpl.genBoundsCheck(asm, T0, S0); // T0 is index, S0 is address of array
asm.emitMOV_RegIdx_Reg_Byte(S0, T0, Assembler.BYTE, NO_SLOT, T1); // [S0 + T0<<2] <- T1
}
}
static {
MagicGenerator g = new StoreByte_Array();
generators.put(getMethodReference(CodeArray.class, MagicNames.addressArraySet, int.class, byte.class, void.class), g);
+ generators.put(getMethodReference(WordArray.class, MagicNames.addressArraySetByte, int.class, byte.class, void.class), g);
}
/**
diff -r 743a2cc2ed20 -r 058fdc3780ba rvm/src/org/jikesrvm/compilers/baseline/ppc/Barriers.java
--- a/rvm/src/org/jikesrvm/compilers/baseline/ppc/Barriers.java Tue Aug 04 11:04:15 2009 +1000
+++ b/rvm/src/org/jikesrvm/compilers/baseline/ppc/Barriers.java Mon Nov 16 09:21:21 2009 +1100
@@ -12,9 +12,11 @@
*/
package org.jikesrvm.compilers.baseline.ppc;
+//import org.jikesrvm.compilers.baseline.ia32.BaselineCompilerImpl;
import org.jikesrvm.compilers.common.assembler.ppc.Assembler;
import org.jikesrvm.ppc.BaselineConstants;
import org.jikesrvm.runtime.Entrypoints;
+import org.jikesrvm.runtime.Magic;
import org.vmmagic.unboxed.Offset;
/**
@@ -31,7 +33,70 @@
asm.emitMTCTR(S0);
asm.emitBCCTRL(); // MemoryManager.arrayStoreWriteBarrier(Object ref, int index, Object value)
}
-
+
+ //jbs added
+ //on entry T0, T1, and T2 already contain the appropriate values
+ static void compileArrayStorePrimitiveIntBarrier(BaselineCompilerImpl comp) {
+ Assembler asm = comp.asm;
+ asm.emitLAddrToc(S0, Entrypoints.arrayStorePrimitiveIntWriteBarrierMethod.getOffset());
+ asm.emitMTCTR(S0);
+ asm.emitBCCTRL(); // MemoryManager.arrayStoreWriteBarrier(Object ref, int index, Object value)
+ }
+
+ //jbs added
+ //on entry T0, T1, and T2 already contain the appropriate values
+ static void compileArrayStorePrimitiveFloatBarrier(BaselineCompilerImpl comp) {
+ Assembler asm = comp.asm;
+ asm.emitLAddrToc(S0, Entrypoints.arrayStorePrimitiveFloatWriteBarrierMethod.getOffset());
+ asm.emitMTCTR(S0);
+ asm.emitBCCTRL(); // MemoryManager.arrayStoreWriteBarrier(Object ref, int index, Object value)
+ }
+
+ //jbs added
+ //on entry T0, T1, and T2 already contain the appropriate values
+ static void compileArrayStorePrimitiveByteBarrier(BaselineCompilerImpl comp) {
+ Assembler asm = comp.asm;
+ asm.emitLAddrToc(S0, Entrypoints.arrayStorePrimitiveByteWriteBarrierMethod.getOffset());
+ asm.emitMTCTR(S0);
+ asm.emitBCCTRL(); // MemoryManager.arrayStoreWriteBarrier(Object ref, int index, Object value)
+ }
+
+ //jbs added
+ //on entry T0, T1, and T2 already contain the appropriate values
+ static void compileArrayStorePrimitiveCharBarrier(BaselineCompilerImpl comp) {
+ Assembler asm = comp.asm;
+ asm.emitLAddrToc(S0, Entrypoints.arrayStorePrimitiveCharWriteBarrierMethod.getOffset());
+ asm.emitMTCTR(S0);
+ asm.emitBCCTRL(); // MemoryManager.arrayStoreWriteBarrier(Object ref, int index, Object value)
+ }
+
+ //jbs added
+ //on entry T0, T1, and T2 already contain the appropriate values
+ static void compileArrayStorePrimitiveShortBarrier(BaselineCompilerImpl comp) {
+ Assembler asm = comp.asm;
+ asm.emitLAddrToc(S0, Entrypoints.arrayStorePrimitiveShortWriteBarrierMethod.getOffset());
+ asm.emitMTCTR(S0);
+ asm.emitBCCTRL(); // MemoryManager.arrayStoreWriteBarrier(Object ref, int index, Object value)
+ }
+
+ //jbs added
+ //on entry T0, T1, T2, T3 already contain the appropriate values
+ static void compileArrayStorePrimitiveLongBarrier(BaselineCompilerImpl comp) {
+ Assembler asm = comp.asm;
+ asm.emitLAddrToc(S0, Entrypoints.arrayStorePrimitiveLongWriteBarrierMethod.getOffset());
+ asm.emitMTCTR(S0);
+ asm.emitBCCTRL(); // MemoryManager.arrayStoreWriteBarrier(Object ref, int index, Object value)
+ }
+
+ //jbs added
+ //on entry T0, T1, and F0 already contain the appropriate values
+ static void compileArrayStorePrimitiveDoubleBarrier(BaselineCompilerImpl comp) {
+ Assembler asm = comp.asm;
+ asm.emitLAddrToc(S0, Entrypoints.arrayStorePrimitiveDoubleWriteBarrierMethod.getOffset());
+ asm.emitMTCTR(S0);
+ asm.emitBCCTRL(); // MemoryManager.arrayStoreWriteBarrier(Object ref, int index, Object value)
+ }
+
// on entry java stack contains ...|target_ref|ref_to_store|
// T1 already contains the offset of the field on entry
static void compilePutfieldBarrier(BaselineCompilerImpl comp, int locationMetadata) {
@@ -79,6 +144,15 @@
asm.emitLVAL(T2, locationMetadata);
asm.emitBCCTRL(); // MemoryManager.putstaticWriteBarrier(T0,T1)
}
+
+ //jbs added arraylet
+ //on entry T0, T1 already contain the appropriate values
+ static void compileHackArrayLoadBarrier(BaselineCompilerImpl comp) {
+ Assembler asm = comp.asm;
+ asm.emitLAddrToc(S0, Entrypoints.hackArrayLoadReadBarrierMethod.getOffset());
+ asm.emitMTCTR(S0);
+ asm.emitBCCTRL(); // MemoryManager.hackArrayLoadReadBarrier(T0,T1)
+ }
// on entry T0, T1 already contain the appropriate values
static void compileArrayLoadBarrier(BaselineCompilerImpl comp) {
@@ -87,6 +161,69 @@
asm.emitMTCTR(S0);
asm.emitBCCTRL(); // MemoryManager.arrayLoadReadBarrier(T0,T1)
}
+
+ //jbs added arraylet
+ //on entry T0, T1 already contain the appropriate values
+ static void compileArrayLoadPrimitiveIntBarrier(BaselineCompilerImpl comp) {
+ Assembler asm = comp.asm;
+ asm.emitLAddrToc(S0, Entrypoints.arrayLoadPrimitiveIntReadBarrierMethod.getOffset());
+ asm.emitMTCTR(S0);
+ asm.emitBCCTRL(); // MemoryManager.arrayLoadReadBarrier(T0,T1)
+ }
+
+ //jbs added arraylet
+ //on entry T0, T1 already contain the appropriate values
+ static void compileArrayLoadPrimitiveFloatBarrier(BaselineCompilerImpl comp) {
+ Assembler asm = comp.asm;
+ asm.emitLAddrToc(S0, Entrypoints.arrayLoadPrimitiveFloatReadBarrierMethod.getOffset());
+ asm.emitMTCTR(S0);
+ asm.emitBCCTRL(); // MemoryManager.arrayLoadReadBarrier(T0,T1)
+ }
+
+ //jbs added arraylet
+ //on entry T0, T1 already contain the appropriate values
+ static void compileArrayLoadPrimitiveByteBarrier(BaselineCompilerImpl comp) {
+ Assembler asm = comp.asm;
+ asm.emitLAddrToc(S0, Entrypoints.arrayLoadPrimitiveByteReadBarrierMethod.getOffset());
+ asm.emitMTCTR(S0);
+ asm.emitBCCTRL(); // MemoryManager.arrayLoadReadBarrier(T0,T1)
+ }
+
+ //jbs added arraylet
+ //on entry T0, T1 already contain the appropriate values
+ static void compileArrayLoadPrimitiveCharBarrier(BaselineCompilerImpl comp) {
+ Assembler asm = comp.asm;
+ asm.emitLAddrToc(S0, Entrypoints.arrayLoadPrimitiveCharReadBarrierMethod.getOffset());
+ asm.emitMTCTR(S0);
+ asm.emitBCCTRL(); // MemoryManager.arrayLoadReadBarrier(T0,T1)
+ }
+
+ //jbs added arraylet
+ //on entry T0, T1 already contain the appropriate values
+ static void compileArrayLoadPrimitiveShortBarrier(BaselineCompilerImpl comp) {
+ Assembler asm = comp.asm;
+ asm.emitLAddrToc(S0, Entrypoints.arrayLoadPrimitiveShortReadBarrierMethod.getOffset());
+ asm.emitMTCTR(S0);
+ asm.emitBCCTRL(); // MemoryManager.arrayLoadReadBarrier(T0,T1)
+ }
+
+ //jbs added arraylet
+ //on entry T0, T1 already contain the appropriate values
+ static void compileArrayLoadPrimitiveLongBarrier(BaselineCompilerImpl comp) {
+ Assembler asm = comp.asm;
+ asm.emitLAddrToc(S0, Entrypoints.arrayLoadPrimitiveLongReadBarrierMethod.getOffset());
+ asm.emitMTCTR(S0);
+ asm.emitBCCTRL(); // MemoryManager.arrayLoadReadBarrier(T0,T1)
+ }
+
+ //jbs added arraylet
+ //on entry T0, T1 already contain the appropriate values
+ static void compileArrayLoadPrimitiveDoubleBarrier(BaselineCompilerImpl comp) {
+ Assembler asm = comp.asm;
+ asm.emitLAddrToc(S0, Entrypoints.arrayLoadPrimitiveDoubleReadBarrierMethod.getOffset());
+ asm.emitMTCTR(S0);
+ asm.emitBCCTRL(); // MemoryManager.arrayLoadReadBarrier(T0,T1)
+ }
// on entry java stack contains ...|source_ref|
// T1 already contains the offset of the field on entry
diff -r 743a2cc2ed20 -r 058fdc3780ba rvm/src/org/jikesrvm/compilers/baseline/ppc/BaselineCompilerImpl.java
--- a/rvm/src/org/jikesrvm/compilers/baseline/ppc/BaselineCompilerImpl.java Tue Aug 04 11:04:15 2009 +1000
+++ b/rvm/src/org/jikesrvm/compilers/baseline/ppc/BaselineCompilerImpl.java Mon Nov 16 09:21:21 2009 +1100
@@ -885,9 +885,14 @@
@Override
protected final void emit_iaload() {
genBoundsCheck();
- asm.emitSLWI(T1, T1, LOG_BYTES_IN_INT); // convert index to offset
- asm.emitLIntX(T2, T0, T1); // load desired int array element
- pushInt(T2);
+ if (MemoryManagerConstants.USE_PRIMITIVE_INT_ARRAYLETS) {
+ Barriers.compileArrayLoadPrimitiveIntBarrier(this);
+ pushInt(T0);
+ } else {
+ asm.emitSLWI(T1, T1, LOG_BYTES_IN_INT); // convert index to offset
+ asm.emitLIntX(T2, T0, T1); // load desired int array element
+ pushInt(T2);
+ }
}
/**
@@ -896,9 +901,14 @@
@Override
protected final void emit_laload() {
genBoundsCheck();
- asm.emitSLWI(T1, T1, LOG_BYTES_IN_LONG); // convert index to offset
- asm.emitLFDX(F0, T0, T1); // load desired (long) array element
- pushLongAsDouble(F0);
+ if (MemoryManagerConstants.USE_PRIMITIVE_LONG_ARRAYLETS) {
+ Barriers.compileArrayLoadPrimitiveLongBarrier(this);
+ pushLong(T0, VM.BuildFor64Addr ? T0 : (T0 + 1));
+ } else {
+ asm.emitSLWI(T1, T1, LOG_BYTES_IN_LONG); // convert index to offset
+ asm.emitLFDX(F0, T0, T1); // load desired (long) array element
+ pushLongAsDouble(F0);
+ }
}
/**
@@ -907,11 +917,14 @@
@Override
protected final void emit_faload() {
genBoundsCheck();
- asm.emitSLWI(T1, T1, LOG_BYTES_IN_FLOAT); // convert index to offset
- asm.emitLWZX(T2, T0, T1); // load desired (float) array element
- pushInt(T2); //LFSX not implemented yet
-// asm.emitLFSX (F0, T0, T1); // load desired (float) array element
-// pushFloat(F0);
+ if (MemoryManagerConstants.USE_PRIMITIVE_FLOAT_ARRAYLETS) {
+ Barriers.compileArrayLoadPrimitiveFloatBarrier(this);
+ pushFloat(F0);
+ } else {
+ asm.emitSLWI(T1, T1, LOG_BYTES_IN_FLOAT); // convert index to offset
+ asm.emitLWZX(T2, T0, T1); // load desired (float) array element
+ pushInt(T2);
+ }
}
/**
@@ -920,9 +933,14 @@
@Override
protected final void emit_daload() {
genBoundsCheck();
- asm.emitSLWI(T1, T1, LOG_BYTES_IN_DOUBLE); // convert index to offset
- asm.emitLFDX(F0, T0, T1); // load desired (double) array element
- pushDouble(F0);
+ if (MemoryManagerConstants.USE_PRIMITIVE_DOUBLE_ARRAYLETS) {
+ Barriers.compileArrayLoadPrimitiveDoubleBarrier(this);
+ pushDouble(F0);
+ } else {
+ asm.emitSLWI(T1, T1, LOG_BYTES_IN_DOUBLE); // convert index to offset
+ asm.emitLFDX(F0, T0, T1); // load desired (double) array element
+ pushDouble(F0);
+ }
}
/**
@@ -931,13 +949,62 @@
@Override
protected final void emit_aaload() {
genBoundsCheck();
- if (MemoryManagerConstants.NEEDS_READ_BARRIER) {
- Barriers.compileArrayLoadBarrier(this);
- pushAddr(T0);
- } else {
- asm.emitSLWI(T1, T1, LOG_BYTES_IN_ADDRESS); // convert index to offset
- asm.emitLAddrX(T2, T0, T1); // load desired (ref) array element
- pushAddr(T2);
+ if (MemoryManagerConstants.NEEDS_READ_BARRIER ||
+ MemoryManagerConstants.USE_OBJECT_ARRAY_ACCESS_BARRIER) {
+ if (MemoryManagerConstants.DO_BASELINE_READ_BARRIER_OPT) {
+ // TODO: Assuming boot image arraylets for now!
+ ForwardReference fr = null, fr2 = null;
+ int AB = T0;
+ if (MemoryManagerConstants.DO_FIRSTN_OPT) {
+ // Are we inside first N?
+ asm.emitCMPI(T1, MemoryManagerConstants.FIRSTN_REF_ELEMS);
+ // Yes: jump to fast path: base T0, index T1
+ fr = asm.emitForwardBC(LT);
+ }
+ if (!MemoryManagerConstants.BOOT_IMAGE_IS_ARRAYLETIZED) {
+ // Are we not arrayletizing the boot image.
+ asm.emitLVALAddr(T2,
+ org.jikesrvm.HeapLayoutConstants.BOOT_IMAGE_DATA_END);
+ // Are we in the boot image
+ asm.emitCMP(T0, T2);
+ fr2 = asm.emitForwardBC(LT);
+ }
+ if (MemoryManagerConstants.DO_FIRSTN_OPT) {
+ // No: subtract N
+ asm.emitADDI(T1, -MemoryManagerConstants.FIRSTN_REF_ELEMS, T1);
+ // No: T2: pointer to first arraylet.
+ asm.emitADDI(T2, MemoryManagerConstants.FIRSTN_REF_ELEMS <<
+ LOG_BYTES_IN_ADDRESS, T0);
+ AB = T2;
+ }
+ // calculate arraylet pointer index
+ asm.emitSRAWI(T3, T1, MemoryManagerConstants.LOG_ELEMENTS_IN_REF_ARRAYLET);
+ // convert from index to offset
+ asm.emitSLWI(T3, T3, LOG_BYTES_IN_ADDRESS);
+ // load indirect arraylet pointer
+ asm.emitLAddrX(T0, AB, T3);
+ // T0 is now arraylet (base)
+
+ // mask out the arraylet index
+ asm.emitANDI(T1, T1, MemoryManagerConstants.REF_ARRAYLET_MASK);
+
+ if (fr != null) {
+ // T0 is base, T1 is index
+ fr.resolve(asm);
+ }
+ if (fr2 != null) fr2.resolve(asm);
+
+ asm.emitSLWI(T1, T1, LOG_BYTES_IN_ADDRESS); // convert index to offset
+ asm.emitLAddrX(T2, T0, T1); // load desired (ref) array element
+ pushAddr(T2);
+ } else {
+ Barriers.compileArrayLoadBarrier(this);
+ pushAddr(T0);
+ }
+ } else {
+ asm.emitSLWI(T1, T1, LOG_BYTES_IN_ADDRESS); // convert index to offset
+ asm.emitLAddrX(T2, T0, T1); // load desired (ref) array element
+ pushAddr(T2);
}
}
@@ -947,9 +1014,14 @@
@Override
protected final void emit_baload() {
genBoundsCheck();
- asm.emitLBZX(T2, T0, T1); // no load byte algebraic ...
- asm.emitEXTSB(T2, T2);
- pushInt(T2);
+ if (MemoryManagerConstants.USE_PRIMITIVE_BYTE_ARRAYLETS) {
+ Barriers.compileArrayLoadPrimitiveByteBarrier(this);
+ pushInt(T0);
+ } else {
+ asm.emitLBZX(T2, T0, T1); // no load byte algebraic ...
+ asm.emitEXTSB(T2, T2);
+ pushInt(T2);
+ }
}
/**
@@ -958,9 +1030,14 @@
@Override
protected final void emit_caload() {
genBoundsCheck();
- asm.emitSLWI(T1, T1, LOG_BYTES_IN_CHAR); // convert index to offset
- asm.emitLHZX(T2, T0, T1); // load desired (char) array element
- pushInt(T2);
+ if (MemoryManagerConstants.USE_PRIMITIVE_CHAR_ARRAYLETS) {
+ Barriers.compileArrayLoadPrimitiveCharBarrier(this);
+ pushInt(T0);
+ } else {
+ asm.emitSLWI(T1, T1, LOG_BYTES_IN_CHAR); // convert index to offset
+ asm.emitLHZX(T2, T0, T1); // load desired (char) array element
+ pushInt(T2);
+ }
}
/**
@@ -969,9 +1046,14 @@
@Override
protected final void emit_saload() {
genBoundsCheck();
- asm.emitSLWI(T1, T1, LOG_BYTES_IN_SHORT); // convert index to offset
- asm.emitLHAX(T2, T0, T1); // load desired (short) array element
- pushInt(T2);
+ if (MemoryManagerConstants.USE_PRIMITIVE_SHORT_ARRAYLETS) {
+ Barriers.compileArrayLoadPrimitiveShortBarrier(this);
+ pushInt(T0);
+ } else {
+ asm.emitSLWI(T1, T1, LOG_BYTES_IN_SHORT); // convert index to offset
+ asm.emitLHAX(T2, T0, T1); // load desired (short) array element
+ pushInt(T2);
+ }
}
/*
@@ -985,8 +1067,12 @@
protected final void emit_iastore() {
popInt(T2); // T2 is value to store
genBoundsCheck();
- asm.emitSLWI(T1, T1, LOG_BYTES_IN_INT); // convert index to offset
- asm.emitSTWX(T2, T0, T1); // store int value in array
+ if (MemoryManagerConstants.USE_PRIMITIVE_INT_ARRAYLETS) {
+ Barriers.compileArrayStorePrimitiveIntBarrier(this);
+ } else {
+ asm.emitSLWI(T1, T1, LOG_BYTES_IN_INT); // convert index to offset
+ asm.emitSTWX(T2, T0, T1); // store int value in array
+ }
}
/**
@@ -994,10 +1080,16 @@
*/
@Override
protected final void emit_lastore() {
- popLongAsDouble(F0); // F0 is value to store
- genBoundsCheck();
- asm.emitSLWI(T1, T1, LOG_BYTES_IN_LONG); // convert index to offset
- asm.emitSTFDX(F0, T0, T1); // store long value in array
+ if (MemoryManagerConstants.USE_PRIMITIVE_LONG_ARRAYLETS) {
+ popLong(T2, T3); // F0 is value to store
+ genBoundsCheck();
+ Barriers.compileArrayStorePrimitiveLongBarrier(this);
+ } else {
+ popLongAsDouble(F0);
+ genBoundsCheck();
+ asm.emitSLWI(T1, T1, LOG_BYTES_IN_LONG); // convert index to offset
+ asm.emitSTFDX(F0, T0, T1); // store long value in array
+ }
}
/**
@@ -1005,10 +1097,16 @@
*/
@Override
protected final void emit_fastore() {
- popInt(T2); // T2 is value to store
- genBoundsCheck();
- asm.emitSLWI(T1, T1, LOG_BYTES_IN_FLOAT); // convert index to offset
- asm.emitSTWX(T2, T0, T1); // store float value in array
+ if (MemoryManagerConstants.USE_PRIMITIVE_FLOAT_ARRAYLETS) {
+ popFloat(F0);
+ genBoundsCheck();
+ Barriers.compileArrayStorePrimitiveFloatBarrier(this);
+ } else {
+ popInt(T2); // T2 is value to store
+ genBoundsCheck();
+ asm.emitSLWI(T1, T1, LOG_BYTES_IN_FLOAT); // convert index to offset
+ asm.emitSTWX(T2, T0, T1); // store float value in array
+ }
}
/**
@@ -1018,8 +1116,12 @@
protected final void emit_dastore() {
popDouble(F0); // F0 is value to store
genBoundsCheck();
- asm.emitSLWI(T1, T1, LOG_BYTES_IN_DOUBLE); // convert index to offset
- asm.emitSTFDX(F0, T0, T1); // store double value in array
+ if (MemoryManagerConstants.USE_PRIMITIVE_DOUBLE_ARRAYLETS) {
+ Barriers.compileArrayStorePrimitiveDoubleBarrier(this);
+ } else {
+ asm.emitSLWI(T1, T1, LOG_BYTES_IN_DOUBLE); // convert index to offset
+ asm.emitSTFDX(F0, T0, T1); // store double value in array
+ }
}
/**
@@ -1034,7 +1136,7 @@
asm.emitBCCTRL(); // checkstore(arrayref, value)
popAddr(T2); // T2 is value to store
genBoundsCheck();
- if (MemoryManagerConstants.NEEDS_WRITE_BARRIER) {
+ if (MemoryManagerConstants.NEEDS_WRITE_BARRIER || MemoryManagerConstants.USE_OBJECT_ARRAY_ACCESS_BARRIER) {
Barriers.compileArrayStoreBarrier(this);
} else {
asm.emitSLWI(T1, T1, LOG_BYTES_IN_ADDRESS); // convert index to offset
@@ -1049,7 +1151,11 @@
protected final void emit_bastore() {
popInt(T2); // T2 is value to store
genBoundsCheck();
- asm.emitSTBX(T2, T0, T1); // store byte value in array
+ if (MemoryManagerConstants.USE_PRIMITIVE_BYTE_ARRAYLETS) {
+ Barriers.compileArrayStorePrimitiveByteBarrier(this);
+ } else {
+ asm.emitSTBX(T2, T0, T1); // store byte value in array
+ }
}
/**
@@ -1059,8 +1165,12 @@
protected final void emit_castore() {
popInt(T2); // T2 is value to store
genBoundsCheck();
- asm.emitSLWI(T1, T1, LOG_BYTES_IN_CHAR); // convert index to offset
- asm.emitSTHX(T2, T0, T1); // store char value in array
+ if (MemoryManagerConstants.USE_PRIMITIVE_CHAR_ARRAYLETS) {
+ Barriers.compileArrayStorePrimitiveCharBarrier(this);
+ } else {
+ asm.emitSLWI(T1, T1, LOG_BYTES_IN_CHAR); // convert index to offset
+ asm.emitSTHX(T2, T0, T1); // store char value in array
+ }
}
/**
@@ -1070,8 +1180,12 @@
protected final void emit_sastore() {
popInt(T2); // T2 is value to store
genBoundsCheck();
- asm.emitSLWI(T1, T1, LOG_BYTES_IN_SHORT); // convert index to offset
- asm.emitSTHX(T2, T0, T1); // store short value in array
+ if (MemoryManagerConstants.USE_PRIMITIVE_SHORT_ARRAYLETS) {
+ Barriers.compileArrayStorePrimitiveShortBarrier(this);
+ } else {
+ asm.emitSLWI(T1, T1, LOG_BYTES_IN_SHORT); // convert index to offset
+ asm.emitSTHX(T2, T0, T1); // store short value in array
+ }
}
/*
@@ -3152,7 +3266,7 @@
if (DynamicTypeCheck.MIN_SUPERCLASS_IDS_SIZE <= LHSDepth) {
// must do arraybounds check of superclass display
asm.emitLIntOffset(T1, T0, ObjectModel.getArrayLengthOffset()); // T1 gets array length
- asm.emitLVAL(T2, LHSDepth);
+ asm.emitLVAL(T2, LHSDepth >> (LOG_BYTES_IN_WORD - LOG_BYTES_IN_CHAR));
asm.emitCMPL(T2, T1);
ForwardReference fr1 = asm.emitForwardBC(LT); // if in bounds, jump around trap. TODO: would like to encode "y" bit that this branch is expected to be takem.
asm.emitTWI(31, 12, TrapConstants.CHECKCAST_TRAP); // encoding of TRAP_ALWAYS CHECKCAST
@@ -3275,7 +3389,7 @@
if (DynamicTypeCheck.MIN_SUPERCLASS_IDS_SIZE <= LHSDepth) {
// must do arraybounds check of superclass display
asm.emitLIntOffset(T1, T0, ObjectModel.getArrayLengthOffset()); // T1 gets array length
- asm.emitLVAL(T2, LHSDepth);
+ asm.emitLVAL(T2, LHSDepth >> (LOG_BYTES_IN_WORD - LOG_BYTES_IN_CHAR));
asm.emitCMPL(T1, T2);
outOfBounds = asm.emitForwardBC(LE);
}
@@ -3720,10 +3834,13 @@
* @param reg The register to hold the counter array.
*/
private void loadCounterArray(int reg) {
- if (MemoryManagerConstants.NEEDS_READ_BARRIER) {
+ if (MemoryManagerConstants.NEEDS_READ_BARRIER || MemoryManagerConstants.USE_OBJECT_ARRAY_ACCESS_BARRIER_ON_EDGE_COUNTS) {
asm.emitLAddrToc(T0, Entrypoints.edgeCountersField.getOffset());
asm.emitLVAL(T1, getEdgeCounterIndex());
- Barriers.compileArrayLoadBarrier(this);
+ if (VM.BuildWithBaseBootImageCompiler && VM.BuildForAdaptiveSystem && MemoryManagerConstants.USE_REFERENCE_ARRAYLETS)
+ Barriers.compileHackArrayLoadBarrier(this);
+ else
+ Barriers.compileArrayLoadBarrier(this);
if (reg != T0) {
asm.emitORI(reg, T0, 0);
}
@@ -4569,18 +4686,71 @@
emit_resolved_newarray(type);
} else if (methodName == MagicNames.addressArrayLength) {
emit_arraylength();
+ } else if (methodName == MagicNames.addressArrayGetByte) {
+ popInt(T1); // T1 is array index
+ popAddr(T0); // T0 is array ref
+ asm.emitLBZX(T2, T0, T1);
+ asm.emitEXTSB(T2, T2);
+ pushInt(T2);
+ } else if (methodName == MagicNames.addressArrayGetChar) {
+ popInt(T1); // T1 is array index
+ popAddr(T0); // T0 is array ref
+ asm.emitSLWI(T1, T1, LOG_BYTES_IN_CHAR); // convert index to offset
+ asm.emitLHZX(T2, T0, T1); // load desired (char) array element
+ pushInt(T2);
+ } else if (methodName == MagicNames.addressArrayGetInt) {
+ popInt(T1); // T1 is array index
+ popAddr(T0); // T0 is array ref
+ asm.emitSLWI(T1, T1, LOG_BYTES_IN_INT); // convert index to offset
+ asm.emitLIntX(T2, T0, T1); // load desired int array element
+ pushInt(T2);
+ } else if (methodName == MagicNames.addressArrayGetLong) {
+ popInt(T1); // T1 is array index
+ popAddr(T0); // T0 is array ref
+ asm.emitSLWI(T1, T1, LOG_BYTES_IN_LONG); // convert index to offset
+ asm.emitLFDX(F0, T0, T1); // load desired (long) array element
+ pushLongAsDouble(F0);
} else if (methodName == MagicNames.addressArrayGet) {
if (VM.BuildFor32Addr || methodToBeCalled.getType() == TypeReference.CodeArray) {
- emit_iaload();
+ genBoundsCheck();
+ asm.emitSLWI(T1, T1, LOG_BYTES_IN_INT); // convert index to offset
+ asm.emitLIntX(T2, T0, T1); // load desired int array element
+ pushInt(T2);
} else {
genBoundsCheck();
asm.emitSLDI(T1, T1, LOG_BYTES_IN_ADDRESS); // convert index to offset
asm.emitLAddrX(T2, T0, T1); // load desired array element
pushAddr(T2);
}
+ } else if (methodName == MagicNames.addressArraySetByte) {
+ popInt(T2); // T2 is value to store
+ popInt(T1); // T1 is array index
+ popAddr(T0); // T0 is array ref
+ asm.emitSTBX(T2, T0, T1); // store byte value in array
+ } else if (methodName == MagicNames.addressArraySetChar) {
+ popInt(T2); // T2 is value to store
+ popInt(T1); // T1 is array index
+ popAddr(T0); // T0 is array ref
+ asm.emitSLWI(T1, T1, LOG_BYTES_IN_CHAR); // convert index to offset
+ asm.emitSTHX(T2, T0, T1); // store char value in array
+ } else if (methodName == MagicNames.addressArraySetInt) {
+ popInt(T2); // T2 is value to store
+ popInt(T1); // T1 is array index
+ popAddr(T0); // T0 is array ref
+ asm.emitSLWI(T1, T1, LOG_BYTES_IN_INT); // convert index to offset
+ asm.emitSTWX(T2, T0, T1); // store int value in array
+ } else if (methodName == MagicNames.addressArraySetLong) {
+ popLongAsDouble(F0); // F0 is value to store
+ popInt(T1); // T1 is array index
+ popAddr(T0); // T0 is array ref
+ asm.emitSLWI(T1, T1, LOG_BYTES_IN_LONG); // convert index to offset
+ asm.emitSTFDX(F0, T0, T1); // store long value in array
} else if (methodName == MagicNames.addressArraySet) {
if (VM.BuildFor32Addr || methodToBeCalled.getType() == TypeReference.CodeArray) {
- emit_iastore();
+ popInt(T2); // T2 is value to store
+ genBoundsCheck();
+ asm.emitSLWI(T1, T1, LOG_BYTES_IN_INT); // convert index to offset
+ asm.emitSTWX(T2, T0, T1); // store int value in array
} else {
popAddr(T2); // T2 is value to store
genBoundsCheck();
@@ -4805,6 +4975,7 @@
methodName == MagicNames.objectAsType ||
methodName == MagicNames.objectAsShortArray ||
methodName == MagicNames.objectAsIntArray ||
+ methodName == MagicNames.objectAsWordArray ||
methodName == MagicNames.objectAsProcessor ||
methodName == MagicNames.processorAsGreenProcessor ||
methodName == MagicNames.objectAsThread ||
diff -r 743a2cc2ed20 -r 058fdc3780ba rvm/src/org/jikesrvm/compilers/baseline/ppc/BaselineExceptionDeliverer.java
--- a/rvm/src/org/jikesrvm/compilers/baseline/ppc/BaselineExceptionDeliverer.java Tue Aug 04 11:04:15 2009 +1000
+++ b/rvm/src/org/jikesrvm/compilers/baseline/ppc/BaselineExceptionDeliverer.java Mon Nov 16 09:21:21 2009 +1100
@@ -104,7 +104,7 @@
for (int i = bcm.getLastFloatStackRegister(); i >= FIRST_FLOAT_LOCAL_REGISTER; --i) {
frameOffset = frameOffset.minus(BYTES_IN_DOUBLE);
long temp = Magic.getLongAtOffset(Magic.addressAsObject(fp), frameOffset);
- registers.fprs[i] = Magic.longBitsAsDouble(temp);
+ registers.fprs.setLong(i, temp);
}
for (int i = bcm.getLastFixedStackRegister(); i >= FIRST_FIXED_LOCAL_REGISTER; --i) {
diff -r 743a2cc2ed20 -r 058fdc3780ba rvm/src/org/jikesrvm/compilers/opt/bc2ir/BC2IR.java
--- a/rvm/src/org/jikesrvm/compilers/opt/bc2ir/BC2IR.java Tue Aug 04 11:04:15 2009 +1000
+++ b/rvm/src/org/jikesrvm/compilers/opt/bc2ir/BC2IR.java Mon Nov 16 09:21:21 2009 +1100
@@ -3377,9 +3377,9 @@
// Avoid upcasts of magic types to regular j.l.Objects
// if (VM.VerifyAssertions && (type == TypeReference.JavaLangObject))
// VM._assert(!r.getType().isMagicType());
- if (VM.VerifyAssertions) {
+ if (false && VM.VerifyAssertions) {
if ((type == TypeReference.JavaLangObject) &&
- (r.getType().isMagicType()) &&
+ (r.getType().isMagicType() && !r.getType().isWordArrayType()) &&
!gc.method.getDeclaringClass().getTypeRef().isMagicType()) {
throw new OptimizingCompilerException.IllegalUpcast(r.getType());
}
diff -r 743a2cc2ed20 -r 058fdc3780ba rvm/src/org/jikesrvm/compilers/opt/bc2ir/GenerateMagic.java
--- a/rvm/src/org/jikesrvm/compilers/opt/bc2ir/GenerateMagic.java Tue Aug 04 11:04:15 2009 +1000
+++ b/rvm/src/org/jikesrvm/compilers/opt/bc2ir/GenerateMagic.java Mon Nov 16 09:21:21 2009 +1100
@@ -213,6 +213,95 @@
Instruction s = GuardedUnary.create(ARRAYLENGTH, t, op1, bc2ir.getCurrentGuard());
bc2ir.push(t.copyD2U());
bc2ir.appendInstruction(s);
+ } else if (methodName == MagicNames.addressArrayGetByte ||
+ methodName == MagicNames.addressArrayGetChar ||
+ methodName == MagicNames.addressArrayGetInt ||
+ methodName == MagicNames.addressArrayGetLong) {
+ TypeReference elementType = meth.getReturnType();
+ Operand index = bc2ir.popInt();
+ Operand ref = bc2ir.popRef();
+ RegisterOperand result = gc.temps.makeTemp(elementType);
+
+ if (elementType == TypeReference.Byte) {
+ bc2ir.appendInstruction(Load.create(BYTE_LOAD,
+ result,
+ ref,
+ index,
+ new LocationOperand(elementType),
+ new TrueGuardOperand()));
+ } else {
+ RegisterOperand offsetI = gc.temps.makeTempInt();
+ RegisterOperand offset = gc.temps.makeTempOffset();
+ Operator op;
+ int logSize;
+ if (elementType == TypeReference.Char) {
+ op = USHORT_LOAD;
+ logSize = 1;
+ } else if (elementType == TypeReference.Int) {
+ op = INT_LOAD;
+ logSize = 2;
+ } else if (elementType == TypeReference.Long) {
+ op = LONG_LOAD;
+ logSize = 3;
+ } else {
+ throw MagicNotImplementedException.UNEXPECTED("Unexpected type");
+ }
+ bc2ir.appendInstruction(Binary.create(INT_SHL, offsetI, index, new IntConstantOperand(logSize)));
+ bc2ir.appendInstruction(Unary.create(INT_2ADDRZerExt, offset, offsetI.copy()));
+ bc2ir.appendInstruction(Load.create(op,
+ result,
+ ref,
+ offset.copy(),
+ new LocationOperand(elementType),
+ new TrueGuardOperand()));
+ }
+ if (methodName == MagicNames.addressArrayGetLong) {
+ bc2ir.pushDual(result.copyD2U());
+ } else {
+ bc2ir.push(result.copyD2U());
+ }
+ } else if (methodName == MagicNames.addressArraySetByte ||
+ methodName == MagicNames.addressArraySetChar ||
+ methodName == MagicNames.addressArraySetInt ||
+ methodName == MagicNames.addressArraySetLong) {
+ TypeReference elementType = meth.getParameterTypes()[1];
+ Operand val = (methodName == MagicNames.addressArraySetLong) ? bc2ir.popLong() : bc2ir.pop();
+ Operand index = bc2ir.popInt();
+ Operand ref = bc2ir.popRef();
+
+ if (elementType == TypeReference.Byte) {
+ bc2ir.appendInstruction(Store.create(BYTE_STORE,
+ val,
+ ref,
+ index,
+ new LocationOperand(elementType),
+ new TrueGuardOperand()));
+ } else {
+ RegisterOperand offsetI = gc.temps.makeTempInt();
+ RegisterOperand offset = gc.temps.makeTempOffset();
+ Operator op;
+ int logSize;
+ if (elementType == TypeReference.Char) {
+ op = SHORT_STORE;
+ logSize = 1;
+ } else if (elementType == TypeReference.Int) {
+ op = INT_STORE;
+ logSize = 2;
+ } else if (elementType == TypeReference.Long) {
+ op = LONG_STORE;
+ logSize = 3;
+ } else {
+ throw MagicNotImplementedException.UNEXPECTED("Unexpected type");
+ }
+ bc2ir.appendInstruction(Binary.create(INT_SHL, offsetI, index, new IntConstantOperand(logSize)));
+ bc2ir.appendInstruction(Unary.create(INT_2ADDRZerExt, offset, offsetI.copy()));
+ bc2ir.appendInstruction(Store.create(op,
+ val,
+ ref,
+ offset.copy(),
+ new LocationOperand(elementType),
+ new TrueGuardOperand()));
+ }
} else if (methodName == MagicNames.addressArrayGet) {
TypeReference elementType = meth.getReturnType();
if (meth.getType() == TypeReference.ProcessorTable) {
@@ -540,6 +629,10 @@
RegisterOperand reg = gc.temps.makeTemp(TypeReference.ShortArray);
bc2ir.appendInstruction(Move.create(REF_MOVE, reg, bc2ir.popRef()));
bc2ir.push(reg.copyD2U());
+ } else if (methodName == MagicNames.objectAsWordArray) {
+ RegisterOperand reg = gc.temps.makeTemp(TypeReference.WordArray);
+ bc2ir.appendInstruction(Move.create(REF_MOVE, reg, bc2ir.popRef()));
+ bc2ir.push(reg.copyD2U());
} else if (methodName == MagicNames.objectAsIntArray) {
RegisterOperand reg = gc.temps.makeTemp(TypeReference.IntArray);
bc2ir.appendInstruction(Move.create(REF_MOVE, reg, bc2ir.popRef()));
diff -r 743a2cc2ed20 -r 058fdc3780ba rvm/src/org/jikesrvm/compilers/opt/bc2ir/GenerationContext.java
--- a/rvm/src/org/jikesrvm/compilers/opt/bc2ir/GenerationContext.java Tue Aug 04 11:04:15 2009 +1000
+++ b/rvm/src/org/jikesrvm/compilers/opt/bc2ir/GenerationContext.java Mon Nov 16 09:21:21 2009 +1100
@@ -359,8 +359,10 @@
RegisterOperand objPtr = receiver.asRegister();
if (ClassLoaderProxy.includesType(child.method.getDeclaringClass().getTypeRef(), objPtr.getType()) != YES) {
// narrow type of actual to match formal static type implied by method
- objPtr.setType(child.method.getDeclaringClass().getTypeRef());
+ //jbs changed to make eclipse work - setType and clearPreciseType swapped order
objPtr.clearPreciseType(); // Can be precise but not assignable if enough classes aren't loaded
+ objPtr.setType(child.method.getDeclaringClass().getTypeRef());
+ //objPtr.clearPreciseType(); // Can be precise but not assignable if enough classes aren't loaded
objPtr.setDeclaredType();
}
local = child.makeLocal(localNum, objPtr);
diff -r 743a2cc2ed20 -r 058fdc3780ba rvm/src/org/jikesrvm/compilers/opt/escape/SimpleEscape.java
--- a/rvm/src/org/jikesrvm/compilers/opt/escape/SimpleEscape.java Tue Aug 04 11:04:15 2009 +1000
+++ b/rvm/src/org/jikesrvm/compilers/opt/escape/SimpleEscape.java Mon Nov 16 09:21:21 2009 +1100
@@ -62,6 +62,8 @@
import static org.jikesrvm.compilers.opt.ir.Operators.DOUBLE_STORE_opcode;
import static org.jikesrvm.compilers.opt.ir.Operators.FLOAT_ALOAD_opcode;
import static org.jikesrvm.compilers.opt.ir.Operators.FLOAT_ASTORE_opcode;
+import static org.jikesrvm.compilers.opt.ir.Operators.FLOAT_LOAD_opcode; //jbs added arraylet
+import static org.jikesrvm.compilers.opt.ir.Operators.FLOAT_STORE_opcode; //jbs added arraylet
import static org.jikesrvm.compilers.opt.ir.Operators.GETFIELD_opcode;
import static org.jikesrvm.compilers.opt.ir.Operators.GETSTATIC_opcode;
import static org.jikesrvm.compilers.opt.ir.Operators.GET_CAUGHT_EXCEPTION_opcode;
@@ -413,6 +415,7 @@
case INT_LOAD_opcode:
case LONG_LOAD_opcode:
case DOUBLE_LOAD_opcode:
+ case FLOAT_LOAD_opcode:
case REF_LOAD_opcode:
// all is OK, unless we load this register from memory
Operand result = ResultCarrier.getResult(inst);
@@ -432,6 +435,7 @@
case REF_STORE_opcode:
case INT_STORE_opcode:
case LONG_STORE_opcode:
+ case FLOAT_STORE_opcode:
case DOUBLE_STORE_opcode:
// as long as we don't store this operand elsewhere, all
// is OK. TODO: add more smarts.
@@ -609,6 +613,7 @@
case INT_LOAD_opcode:
case LONG_LOAD_opcode:
case DOUBLE_LOAD_opcode:
+ case FLOAT_LOAD_opcode:
case REF_LOAD_opcode:
// all is OK, unless we load this register from memory
Operand result = ResultCarrier.getResult(inst);
@@ -629,6 +634,7 @@
case INT_STORE_opcode:
case LONG_STORE_opcode:
case DOUBLE_STORE_opcode:
+ case FLOAT_STORE_opcode:
// as long as we don't store this operand elsewhere, all
// is OK. TODO: add more smarts.
value = Store.getValue(inst);
diff -r 743a2cc2ed20 -r 058fdc3780ba rvm/src/org/jikesrvm/compilers/opt/hir2lir/DynamicTypeCheckExpansion.java
--- a/rvm/src/org/jikesrvm/compilers/opt/hir2lir/DynamicTypeCheckExpansion.java Tue Aug 04 11:04:15 2009 +1000
+++ b/rvm/src/org/jikesrvm/compilers/opt/hir2lir/DynamicTypeCheckExpansion.java Mon Nov 16 09:21:21 2009 +1100
@@ -12,6 +12,9 @@
*/
package org.jikesrvm.compilers.opt.hir2lir;
+import gnu.javax.swing.text.html.parser.support.low.Constants;
+
+import org.jikesrvm.SizeConstants;
import org.jikesrvm.VM;
import org.jikesrvm.classloader.RVMArray;
import org.jikesrvm.classloader.RVMClass;
@@ -341,7 +344,7 @@
failBlock.appendInstruction(raiseError);
Operand RHStib = getTIB(s, ir, ref, guard);
- RegisterOperand doesImpl = InsertUnary(s, ir, GET_DOES_IMPLEMENT_FROM_TIB, TypeReference.IntArray, RHStib);
+ RegisterOperand doesImpl = InsertUnary(s, ir, GET_DOES_IMPLEMENT_FROM_TIB, TypeReference.WordArray, RHStib);
if (DynamicTypeCheck.MIN_DOES_IMPLEMENT_SIZE <= interfaceIndex) {
RegisterOperand doesImplLength =
@@ -520,7 +523,7 @@
InsertUnary(curBlock.lastInstruction(),
ir,
GET_SUPERCLASS_IDS_FROM_TIB,
- TypeReference.ShortArray,
+ TypeReference.WordArray,
rhsTIB.copy());
RegisterOperand lhsElemDepth =
getField(curBlock.lastInstruction(), ir, lhsElemType, Entrypoints.depthField, TG());
@@ -531,10 +534,17 @@
TypeReference.Int,
rhsSuperclassIds.copyD2U(),
TG());
+ RegisterOperand rhsSuperclassIdsChars =
+ insertBinary(curBlock.lastInstruction(),
+ ir,
+ INT_SHL,
+ TypeReference.Int,
+ rhsSuperclassIdsLength.copyD2U(),
+ IC(SizeConstants.LOG_BYTES_IN_WORD - SizeConstants.LOG_BYTES_IN_CHAR));
curBlock.appendInstruction(IfCmp.create(INT_IFCMP,
guardResult.copyRO(),
lhsElemDepth,
- rhsSuperclassIdsLength,
+ rhsSuperclassIdsChars.copyD2U(),
ConditionOperand.GREATER_EQUAL(),
trapBlock.makeJumpTarget(),
BranchProfileOperand.never()));
@@ -543,36 +553,27 @@
RegisterOperand lhsElemId =
getField(curBlock.lastInstruction(), ir, lhsElemType.copyD2U(), Entrypoints.idField, TG());
- RegisterOperand refCandidate = ir.regpool.makeTemp(TypeReference.Short);
- LocationOperand loc = new LocationOperand(TypeReference.Short);
- if (LOWER_ARRAY_ACCESS) {
- RegisterOperand lhsDepthOffset =
- insertBinary(curBlock.lastInstruction(),
- ir,
- INT_SHL,
- TypeReference.Int,
- lhsElemDepth.copyD2U(),
- IC(1));
- lhsDepthOffset =
- InsertUnary(curBlock.lastInstruction(),
- ir,
- INT_2ADDRZerExt,
- TypeReference.Offset,
- lhsDepthOffset.copy());
- curBlock.appendInstruction(Load.create(USHORT_LOAD,
- refCandidate,
- rhsSuperclassIds,
- lhsDepthOffset,
- loc,
- TG()));
- } else {
- curBlock.appendInstruction(ALoad.create(USHORT_ALOAD,
- refCandidate,
- rhsSuperclassIds,
- lhsElemDepth.copyRO(),
- loc,
- TG()));
- }
+ RegisterOperand refCandidate = ir.regpool.makeTemp(TypeReference.Char);
+ LocationOperand loc = new LocationOperand(TypeReference.Char);
+ RegisterOperand lhsDepthOffset =
+ insertBinary(curBlock.lastInstruction(),
+ ir,
+ INT_SHL,
+ TypeReference.Int,
+ lhsElemDepth.copyD2U(),
+ IC(1));
+ lhsDepthOffset =
+ InsertUnary(curBlock.lastInstruction(),
+ ir,
+ INT_2ADDRZerExt,
+ TypeReference.Offset,
+ lhsDepthOffset.copy());
+ curBlock.appendInstruction(Load.create(USHORT_LOAD,
+ refCandidate,
+ rhsSuperclassIds,
+ lhsDepthOffset,
+ loc,
+ TG()));
curBlock.appendInstruction(IfCmp.create(INT_IFCMP,
guardResult.copyRO(),
refCandidate.copyD2U(),
@@ -636,7 +637,7 @@
int interfaceIndex = LHSclass.getDoesImplementIndex();
int interfaceMask = LHSclass.getDoesImplementBitMask();
RegisterOperand doesImpl =
- InsertUnary(s, ir, GET_DOES_IMPLEMENT_FROM_TIB, TypeReference.IntArray, RHStib);
+ InsertUnary(s, ir, GET_DOES_IMPLEMENT_FROM_TIB, TypeReference.WordArray, RHStib);
RegisterOperand entry =
InsertLoadOffset(s,
ir,
@@ -658,6 +659,10 @@
if (DynamicTypeCheck.MIN_DOES_IMPLEMENT_SIZE <= interfaceIndex) {
RegisterOperand doesImplLength =
InsertGuardedUnary(s, ir, ARRAYLENGTH, TypeReference.Int, doesImpl.copy(), TG());
+ if ((SizeConstants.LOG_BYTES_IN_WORD - SizeConstants.LOG_BYTES_IN_INT) != 0) {
+ doesImplLength = insertBinary(s, ir, INT_SHL, TypeReference.Int, doesImplLength.copyD2U(),
+ IC(SizeConstants.LOG_BYTES_IN_WORD - SizeConstants.LOG_BYTES_IN_INT));
+ }
RegisterOperand boundscheck = ir.regpool.makeTempInt();
//save to use the cheaper ADDR version of BOOLEAN_CMP
s.insertBefore(BooleanCmp.create(BOOLEAN_CMP_ADDR,
@@ -690,15 +695,15 @@
int LHSDepth = LHSclass.getTypeDepth();
int LHSId = LHSclass.getId();
RegisterOperand superclassIds =
- InsertUnary(s, ir, GET_SUPERCLASS_IDS_FROM_TIB, TypeReference.ShortArray, RHStib);
+ InsertUnary(s, ir, GET_SUPERCLASS_IDS_FROM_TIB, TypeReference.WordArray, RHStib);
RegisterOperand refCandidate =
InsertLoadOffset(s,
ir,
USHORT_LOAD,
- TypeReference.Short,
+ TypeReference.Char,
superclassIds,
Offset.fromIntZeroExtend(LHSDepth << 1),
- new LocationOperand(TypeReference.Short),
+ new LocationOperand(TypeReference.Char),
TG());
//save to use the cheaper ADDR version of BOOLEAN_CMP
s.insertBefore(BooleanCmp.create(BOOLEAN_CMP_ADDR,
@@ -710,6 +715,8 @@
if (DynamicTypeCheck.MIN_SUPERCLASS_IDS_SIZE <= LHSDepth) {
RegisterOperand superclassIdsLength =
InsertGuardedUnary(s, ir, ARRAYLENGTH, TypeReference.Int, superclassIds.copyD2U(), TG());
+ superclassIdsLength = insertBinary(s, ir, INT_SHL, TypeReference.Int, superclassIdsLength.copyD2U(),
+ IC(SizeConstants.LOG_BYTES_IN_WORD - SizeConstants.LOG_BYTES_IN_CHAR));
RegisterOperand boundscheck = ir.regpool.makeTempInt();
//save to use the cheaper ADDR version of BOOLEAN_CMP
s.insertBefore(BooleanCmp.create(BOOLEAN_CMP_ADDR,
@@ -849,11 +856,15 @@
int interfaceIndex = LHSclass.getDoesImplementIndex();
int interfaceMask = LHSclass.getDoesImplementBitMask();
RegisterOperand doesImpl =
- InsertUnary(continueAt, ir, GET_DOES_IMPLEMENT_FROM_TIB, TypeReference.IntArray, RHStib);
+ InsertUnary(continueAt, ir, GET_DOES_IMPLEMENT_FROM_TIB, TypeReference.WordArray, RHStib);
if (DynamicTypeCheck.MIN_DOES_IMPLEMENT_SIZE <= interfaceIndex) {
RegisterOperand doesImplLength =
InsertGuardedUnary(continueAt, ir, ARRAYLENGTH, TypeReference.Int, doesImpl.copyD2U(), TG());
+ if ((SizeConstants.LOG_BYTES_IN_WORD - SizeConstants.LOG_BYTES_IN_INT) != 0) {
+ doesImplLength = insertBinary(s, ir, INT_SHL, TypeReference.Int, doesImplLength.copyD2U(),
+ IC(SizeConstants.LOG_BYTES_IN_WORD - SizeConstants.LOG_BYTES_IN_INT));
+ }
Instruction lengthCheck =
IfCmp.create(INT_IFCMP,
oldGuard,
@@ -908,10 +919,12 @@
int LHSDepth = LHSclass.getTypeDepth();
int LHSId = LHSclass.getId();
RegisterOperand superclassIds =
- InsertUnary(continueAt, ir, GET_SUPERCLASS_IDS_FROM_TIB, TypeReference.ShortArray, RHStib);
+ InsertUnary(continueAt, ir, GET_SUPERCLASS_IDS_FROM_TIB, TypeReference.WordArray, RHStib);
if (DynamicTypeCheck.MIN_SUPERCLASS_IDS_SIZE <= LHSDepth) {
RegisterOperand superclassIdsLength =
InsertGuardedUnary(continueAt, ir, ARRAYLENGTH, TypeReference.Int, superclassIds.copyD2U(), TG());
+ superclassIdsLength = insertBinary(continueAt, ir, INT_SHL, TypeReference.Int, superclassIdsLength.copyD2U(),
+ IC(SizeConstants.LOG_BYTES_IN_WORD - SizeConstants.LOG_BYTES_IN_CHAR));
Instruction lengthCheck =
IfCmp.create(INT_IFCMP,
oldGuard,
@@ -932,10 +945,10 @@
InsertLoadOffset(continueAt,
ir,
USHORT_LOAD,
- TypeReference.Short,
+ TypeReference.Char,
superclassIds,
Offset.fromIntZeroExtend(LHSDepth << 1),
- new LocationOperand(TypeReference.Short),
+ new LocationOperand(TypeReference.Char),
TG());
continueAt.insertBefore(IfCmp.create(INT_IFCMP,
oldGuard,
diff -r 743a2cc2ed20 -r 058fdc3780ba rvm/src/org/jikesrvm/compilers/opt/hir2lir/ExpandRuntimeServices.java
--- a/rvm/src/org/jikesrvm/compilers/opt/hir2lir/ExpandRuntimeServices.java Tue Aug 04 11:04:15 2009 +1000
+++ b/rvm/src/org/jikesrvm/compilers/opt/hir2lir/ExpandRuntimeServices.java Mon Nov 16 09:21:21 2009 +1100
@@ -18,6 +18,21 @@
import static org.jikesrvm.compilers.opt.ir.Operators.GETFIELD_opcode;
import static org.jikesrvm.compilers.opt.ir.Operators.GETSTATIC_opcode;
import static org.jikesrvm.compilers.opt.ir.Operators.INT_ASTORE;
+import static org.jikesrvm.compilers.opt.ir.Operators.SHORT_ALOAD_opcode;
+import static org.jikesrvm.compilers.opt.ir.Operators.SHORT_ASTORE_opcode;
+import static org.jikesrvm.compilers.opt.ir.Operators.LONG_ALOAD_opcode;
+import static org.jikesrvm.compilers.opt.ir.Operators.LONG_ASTORE_opcode;
+import static org.jikesrvm.compilers.opt.ir.Operators.DOUBLE_ALOAD_opcode;
+import static org.jikesrvm.compilers.opt.ir.Operators.DOUBLE_ASTORE_opcode;
+import static org.jikesrvm.compilers.opt.ir.Operators.FLOAT_ALOAD_opcode;
+import static org.jikesrvm.compilers.opt.ir.Operators.FLOAT_ASTORE_opcode;
+import static org.jikesrvm.compilers.opt.ir.Operators.BYTE_ALOAD_opcode;
+import static org.jikesrvm.compilers.opt.ir.Operators.UBYTE_ALOAD_opcode;
+import static org.jikesrvm.compilers.opt.ir.Operators.BYTE_ASTORE_opcode;
+import static org.jikesrvm.compilers.opt.ir.Operators.USHORT_ALOAD_opcode;
+import static org.jikesrvm.compilers.opt.ir.Operators.INT_ALOAD_opcode;
+import static org.jikesrvm.compilers.opt.ir.Operators.INT_ASTORE_opcode;
+
import static org.jikesrvm.compilers.opt.ir.Operators.MONITORENTER_opcode;
import static org.jikesrvm.compilers.opt.ir.Operators.MONITOREXIT_opcode;
import static org.jikesrvm.compilers.opt.ir.Operators.NEWARRAY_UNRESOLVED_opcode;
@@ -272,12 +287,36 @@
// Step 2: Assign the dimension values to dimArray
for (int i = 0; i < dimensions; i++) {
LocationOperand loc = new LocationOperand(TypeReference.Int);
+ /* if (MemoryManagerConstants.USE_PRIMITIVE_INT_ARRAYLETS) {
+ //jbs - FYI - next if might be unnecessary for longs, but was for shorts to distinguish from chars
+ //if (ALoad.getArray(inst).getType().peekType().isArrayType() && ALoad.getArray(inst).getType().peekType().asArray().isArrayletizable()) {// .getArrayElementType().isShortType()) {
+
+ RVMMethod target = Entrypoints.arrayStorePrimitiveIntWriteBarrierMethod;
+ Instruction wb =
+ Call.create3(CALL,
+ null,
+ IRTools.AC(target.getOffset()),
+ MethodOperand.STATIC(target),
+ IRTools.TG(), //AStore.getClearGuard(inst),
+ dimArray.copyD2U(), //AStore.getArray(inst).copy(),
+ IRTools.IC(i), //AStore.getIndex(inst).copy(),
+ Multianewarray.getClearDimension(inst, i)); //AStore.getValue(inst).copy());
+ wb.bcIndex = RUNTIME_SERVICES_BCI;
+ //wb.position = inst.position;
+ inst.insertBefore(wb);
+ //next = wb.prevInstructionInCodeOrder();
+ if (ir.options.INLINE_WRITE_BARRIER) {
+ inline(wb, ir, true);
+ }
+ //}
+ } else {*/
inst.insertBefore(AStore.create(INT_ASTORE,
Multianewarray.getClearDimension(inst, i),
dimArray.copyD2U(),
IRTools.IC(i),
loc,
IRTools.TG()));
+ //}
}
// Step 3. Plant call to OptLinker.newArrayArray
RVMMethod target = Entrypoints.optNewArrayArrayMethod;
@@ -371,8 +410,173 @@
}
break;
+ case SHORT_ASTORE_opcode: {
+ if (MemoryManagerConstants.USE_PRIMITIVE_SHORT_ARRAYLETS || MemoryManagerConstants.USE_PRIMITIVE_CHAR_ARRAYLETS) {
+ if (ALoad.getArray(inst).getType().peekType().isArrayType() && ALoad.getArray(inst).getType().peekType().asArray().isArrayletizable()) {// .getArrayElementType().isShortType()) {
+
+ RVMMethod target;
+ if (ALoad.getArray(inst).getType().peekType().asArray().getElementType().isShortType())
+ target = Entrypoints.arrayStorePrimitiveShortWriteBarrierMethod;
+ else
+ target = Entrypoints.arrayStorePrimitiveCharWriteBarrierMethod;
+
+ Instruction wb =
+ Call.create3(CALL,
+ null,
+ IRTools.AC(target.getOffset()),
+ MethodOperand.STATIC(target),
+ AStore.getClearGuard(inst),
+ AStore.getArray(inst).copy(),
+ AStore.getIndex(inst).copy(),
+ AStore.getValue(inst).copy());
+ wb.bcIndex = RUNTIME_SERVICES_BCI;
+ wb.position = inst.position;
+ inst.replace(wb);
+ next = wb.prevInstructionInCodeOrder();
+ if (ir.options.INLINE_WRITE_BARRIER) {
+ inline(wb, ir, true);
+ }
+ }
+ }
+ }
+ break;
+
+
+ case BYTE_ASTORE_opcode: {
+ if (MemoryManagerConstants.USE_PRIMITIVE_BYTE_ARRAYLETS) {
+ // if (ALoad.getArray(inst).getType().peekType().isArrayType() && ALoad.getArray(inst).getType().peekType().asArray().isArrayletizable()) {// .getArrayElementType().isShortType()) {
+
+ RVMMethod target = Entrypoints.arrayStorePrimitiveByteWriteBarrierMethod;
+ Instruction wb =
+ Call.create3(CALL,
+ null,
+ IRTools.AC(target.getOffset()),
+ MethodOperand.STATIC(target),
+ AStore.getClearGuard(inst),
+ AStore.getArray(inst).copy(),
+ AStore.getIndex(inst).copy(),
+ AStore.getValue(inst).copy());
+ wb.bcIndex = RUNTIME_SERVICES_BCI;
+ wb.position = inst.position;
+ inst.replace(wb);
+ next = wb.prevInstructionInCodeOrder();
+ if (ir.options.INLINE_WRITE_BARRIER) {
+ inline(wb, ir, true);
+ }
+ // }
+ }
+ }
+ break;
+
+ case FLOAT_ASTORE_opcode: {
+ if (MemoryManagerConstants.USE_PRIMITIVE_FLOAT_ARRAYLETS) {
+ //jbs - FYI - next if might be unnecessary for longs, but was for shorts to distinguish from chars
+ //if (ALoad.getArray(inst).getType().peekType().isArrayType() && ALoad.getArray(inst).getType().peekType().asArray().isArrayletizable()) {// .getArrayElementType().isShortType()) {
+
+ RVMMethod target = Entrypoints.arrayStorePrimitiveFloatWriteBarrierMethod;
+ Instruction wb =
+ Call.create3(CALL,
+ null,
+ IRTools.AC(target.getOffset()),
+ MethodOperand.STATIC(target),
+ AStore.getClearGuard(inst),
+ AStore.getArray(inst).copy(),
+ AStore.getIndex(inst).copy(),
+ AStore.getValue(inst).copy());
+ wb.bcIndex = RUNTIME_SERVICES_BCI;
+ wb.position = inst.position;
+ inst.replace(wb);
+ next = wb.prevInstructionInCodeOrder();
+ if (ir.options.INLINE_WRITE_BARRIER) {
+ inline(wb, ir, true);
+ }
+ //}
+ }
+ }
+ break;
+
+ case INT_ASTORE_opcode: {
+ if (MemoryManagerConstants.USE_PRIMITIVE_INT_ARRAYLETS) {
+ //jbs - FYI - next if might be unnecessary for longs, but was for shorts to distinguish from chars
+ // if (ALoad.getArray(inst).getType().peekType().isArrayType() && ALoad.getArray(inst).getType().peekType().asArray().isArrayletizable()) {// .getArrayElementType().isShortType()) {
+
+ RVMMethod target = Entrypoints.arrayStorePrimitiveIntWriteBarrierMethod;
+ Instruction wb =
+ Call.create3(CALL,
+ null,
+ IRTools.AC(target.getOffset()),
+ MethodOperand.STATIC(target),
+ AStore.getClearGuard(inst),
+ AStore.getArray(inst).copy(),
+ AStore.getIndex(inst).copy(),
+ AStore.getValue(inst).copy());
+ wb.bcIndex = RUNTIME_SERVICES_BCI;
+ wb.position = inst.position;
+ inst.replace(wb);
+ next = wb.prevInstructionInCodeOrder();
+ if (ir.options.INLINE_WRITE_BARRIER) {
+ inline(wb, ir, true);
+ }
+ // }
+ }
+ }
+ break;
+
+ case LONG_ASTORE_opcode: {
+ if (MemoryManagerConstants.USE_PRIMITIVE_LONG_ARRAYLETS) {
+ // if (ALoad.getArray(inst).getType().peekType().isArrayType() && ALoad.getArray(inst).getType().peekType().asArray().isArrayletizable()) {// .getArrayElementType().isShortType()) {
+
+ RVMMethod target = Entrypoints.arrayStorePrimitiveLongWriteBarrierMethod;
+ Instruction wb =
+ Call.create3(CALL,
+ null,
+ IRTools.AC(target.getOffset()),
+ MethodOperand.STATIC(target),
+ AStore.getClearGuard(inst),
+ AStore.getArray(inst).copy(),
+ AStore.getIndex(inst).copy(),
+ AStore.getValue(inst).copy());
+ wb.bcIndex = RUNTIME_SERVICES_BCI;
+ wb.position = inst.position;
+ inst.replace(wb);
+ next = wb.prevInstructionInCodeOrder();
+ if (ir.options.INLINE_WRITE_BARRIER) {
+ inline(wb, ir, true);
+ }
+ //}
+ }
+ }
+ break;
+
+ case DOUBLE_ASTORE_opcode: {
+ if (MemoryManagerConstants.USE_PRIMITIVE_DOUBLE_ARRAYLETS) {
+ // if (ALoad.getArray(inst).getType().peekType().isArrayType() && ALoad.getArray(inst).getType().peekType().asArray().isArrayletizable()) {// .getArrayElementType().isShortType()) {
+
+ RVMMethod target = Entrypoints.arrayStorePrimitiveDoubleWriteBarrierMethod;
+ Instruction wb =
+ Call.create3(CALL,
+ null,
+ IRTools.AC(target.getOffset()),
+ MethodOperand.STATIC(target),
+ AStore.getClearGuard(inst),
+ AStore.getArray(inst).copy(),
+ AStore.getIndex(inst).copy(),
+ AStore.getValue(inst).copy());
+ wb.bcIndex = RUNTIME_SERVICES_BCI;
+ wb.position = inst.position;
+ inst.replace(wb);
+ next = wb.prevInstructionInCodeOrder();
+ if (ir.options.INLINE_WRITE_BARRIER) {
+ inline(wb, ir, true);
+ }
+ // }
+ }
+ }
+ break;
+
case REF_ASTORE_opcode: {
- if (MemoryManagerConstants.NEEDS_WRITE_BARRIER) {
+ //jbs added arraylet
+ if (MemoryManagerConstants.NEEDS_WRITE_BARRIER || MemoryManagerConstants.USE_REFERENCE_ARRAYLETS || MemoryManagerConstants.USE_OBJECT_ARRAY_ACCESS_BARRIER) {
RVMMethod target = Entrypoints.arrayStoreWriteBarrierMethod;
Instruction wb =
Call.create3(CALL,
@@ -394,8 +598,212 @@
}
break;
+ case SHORT_ALOAD_opcode: {
+ if (MemoryManagerConstants.USE_PRIMITIVE_SHORT_ARRAYLETS || MemoryManagerConstants.USE_PRIMITIVE_CHAR_ARRAYLETS) {
+ if (ALoad.getArray(inst).getType().peekType().isArrayType() && ALoad.getArray(inst).getType().peekType().asArray().isArrayletizable()) {// .getArrayElementType().isShortType()) {
+
+ RVMMethod target;
+ if (ALoad.getArray(inst).getType().peekType().asArray().getElementType().isShortType()) {
+ target = Entrypoints.arrayLoadPrimitiveShortReadBarrierMethod;
+ } else {
+ target = Entrypoints.arrayLoadPrimitiveCharReadBarrierMethod;
+ }
+
+ Instruction rb =
+ Call.create2(CALL,
+ ALoad.getClearResult(inst),
+ IRTools.AC(target.getOffset()),
+ MethodOperand.STATIC(target),
+ ALoad.getClearGuard(inst),
+ ALoad.getArray(inst).copy(),
+ ALoad.getIndex(inst).copy());
+
+ rb.bcIndex = RUNTIME_SERVICES_BCI;
+ rb.position = inst.position;
+ inst.replace(rb);
+ next = rb.prevInstructionInCodeOrder();
+ inline(rb, ir, true);
+ }
+ }
+ }
+ break;
+
+ case USHORT_ALOAD_opcode: {
+ if (MemoryManagerConstants.USE_PRIMITIVE_CHAR_ARRAYLETS) {
+ if (ALoad.getArray(inst).getType().peekType().isArrayType() && ALoad.getArray(inst).getType().peekType().asArray().isArrayletizable()) {// .getArrayElementType().isShortType()) {
+
+ RVMMethod target;
+ target = Entrypoints.arrayLoadPrimitiveCharReadBarrierMethod;
+ Instruction rb =
+ Call.create2(CALL,
+ ALoad.getClearResult(inst),
+ IRTools.AC(target.getOffset()),
+ MethodOperand.STATIC(target),
+ ALoad.getClearGuard(inst),
+ ALoad.getArray(inst).copy(),
+ ALoad.getIndex(inst).copy());
+
+ rb.bcIndex = RUNTIME_SERVICES_BCI;
+ rb.position = inst.position;
+ inst.replace(rb);
+ next = rb.prevInstructionInCodeOrder();
+ inline(rb, ir, true);
+ }
+ }
+ }
+ break;
+
+ case UBYTE_ALOAD_opcode: {
+ if (MemoryManagerConstants.USE_PRIMITIVE_BYTE_ARRAYLETS) {
+ // if (ALoad.getArray(inst).getType().peekType().isArrayType() && ALoad.getArray(inst).getType().peekType().asArray().isArrayletizable()) {// .getArrayElementType().isShortType()) {
+
+ RVMMethod target = Entrypoints.arrayLoadPrimitiveByteReadBarrierMethod;
+
+ Instruction rb =
+ Call.create2(CALL,
+ ALoad.getClearResult(inst),
+ IRTools.AC(target.getOffset()),
+ MethodOperand.STATIC(target),
+ ALoad.getClearGuard(inst),
+ ALoad.getArray(inst).copy(),
+ ALoad.getIndex(inst).copy());
+
+ rb.bcIndex = RUNTIME_SERVICES_BCI;
+ rb.position = inst.position;
+ inst.replace(rb);
+ next = rb.prevInstructionInCodeOrder();
+ inline(rb, ir, true);
+ // }
+ }
+ }
+ break;
+
+ case BYTE_ALOAD_opcode: {
+ if (MemoryManagerConstants.USE_PRIMITIVE_BYTE_ARRAYLETS) {
+ // if (ALoad.getArray(inst).getType().peekType().isArrayType() && ALoad.getArray(inst).getType().peekType().asArray().isArrayletizable()) {// .getArrayElementType().isShortType()) {
+
+ RVMMethod target = Entrypoints.arrayLoadPrimitiveByteReadBarrierMethod;
+
+ Instruction rb =
+ Call.create2(CALL,
+ ALoad.getClearResult(inst),
+ IRTools.AC(target.getOffset()),
+ MethodOperand.STATIC(target),
+ ALoad.getClearGuard(inst),
+ ALoad.getArray(inst).copy(),
+ ALoad.getIndex(inst).copy());
+
+ rb.bcIndex = RUNTIME_SERVICES_BCI;
+ rb.position = inst.position;
+ inst.replace(rb);
+ next = rb.prevInstructionInCodeOrder();
+ inline(rb, ir, true);
+ // }
+ }
+ }
+ break;
+
+ case FLOAT_ALOAD_opcode: {
+ if (MemoryManagerConstants.USE_PRIMITIVE_FLOAT_ARRAYLETS) {
+ // if (ALoad.getArray(inst).getType().peekType().isArrayType() && ALoad.getArray(inst).getType().peekType().asArray().isArrayletizable()) {// .getArrayElementType().isShortType()) {
+
+ RVMMethod target = Entrypoints.arrayLoadPrimitiveFloatReadBarrierMethod;
+ Instruction rb =
+ Call.create2(CALL,
+ ALoad.getClearResult(inst),
+ IRTools.AC(target.getOffset()),
+ MethodOperand.STATIC(target),
+ ALoad.getClearGuard(inst),
+ ALoad.getArray(inst).copy(),
+ ALoad.getIndex(inst).copy());
+
+ rb.bcIndex = RUNTIME_SERVICES_BCI;
+ rb.position = inst.position;
+ inst.replace(rb);
+ next = rb.prevInstructionInCodeOrder();
+ inline(rb, ir, true);
+ // }
+ }
+ }
+ break;
+
+ case INT_ALOAD_opcode: {
+ if (MemoryManagerConstants.USE_PRIMITIVE_INT_ARRAYLETS) {
+ // if (ALoad.getArray(inst).getType().peekType().isArrayType() && ALoad.getArray(inst).getType().peekType().asArray().isArrayletizable()) {// .getArrayElementType().isShortType()) {
+
+ RVMMethod target = Entrypoints.arrayLoadPrimitiveIntReadBarrierMethod;
+
+ Instruction rb =
+ Call.create2(CALL,
+ ALoad.getClearResult(inst),
+ IRTools.AC(target.getOffset()),
+ MethodOperand.STATIC(target),
+ ALoad.getClearGuard(inst),
+ ALoad.getArray(inst).copy(),
+ ALoad.getIndex(inst).copy());
+
+ rb.bcIndex = RUNTIME_SERVICES_BCI;
+ rb.position = inst.position;
+ inst.replace(rb);
+ next = rb.prevInstructionInCodeOrder();
+ inline(rb, ir, true);
+ // }
+ }
+ }
+ break;
+
+ case LONG_ALOAD_opcode: {
+ if (MemoryManagerConstants.USE_PRIMITIVE_LONG_ARRAYLETS) {
+ // if (ALoad.getArray(inst).getType().peekType().isArrayType() && ALoad.getArray(inst).getType().peekType().asArray().isArrayletizable()) {// .getArrayElementType().isShortType()) {
+
+ RVMMethod target = Entrypoints.arrayLoadPrimitiveLongReadBarrierMethod;
+
+ Instruction rb =
+ Call.create2(CALL,
+ ALoad.getClearResult(inst),
+ IRTools.AC(target.getOffset()),
+ MethodOperand.STATIC(target),
+ ALoad.getClearGuard(inst),
+ ALoad.getArray(inst).copy(),
+ ALoad.getIndex(inst).copy());
+
+ rb.bcIndex = RUNTIME_SERVICES_BCI;
+ rb.position = inst.position;
+ inst.replace(rb);
+ next = rb.prevInstructionInCodeOrder();
+ inline(rb, ir, true);
+ //}
+ }
+ }
+ break;
+
+ case DOUBLE_ALOAD_opcode: {
+ if (MemoryManagerConstants.USE_PRIMITIVE_DOUBLE_ARRAYLETS) {
+ //if (ALoad.getArray(inst).getType().peekType().isArrayType() && ALoad.getArray(inst).getType().peekType().asArray().isArrayletizable()) {// .getArrayElementType().isShortType()) {
+
+ RVMMethod target = Entrypoints.arrayLoadPrimitiveDoubleReadBarrierMethod;
+
+ Instruction rb =
+ Call.create2(CALL,
+ ALoad.getClearResult(inst),
+ IRTools.AC(target.getOffset()),
+ MethodOperand.STATIC(target),
+ ALoad.getClearGuard(inst),
+ ALoad.getArray(inst).copy(),
+ ALoad.getIndex(inst).copy());
+
+ rb.bcIndex = RUNTIME_SERVICES_BCI;
+ rb.position = inst.position;
+ inst.replace(rb);
+ next = rb.prevInstructionInCodeOrder();
+ inline(rb, ir, true);
+ //}
+ }
+ }
+ break;
+
case REF_ALOAD_opcode: {
- if (MemoryManagerConstants.NEEDS_READ_BARRIER) {
+ if (MemoryManagerConstants.NEEDS_READ_BARRIER || MemoryManagerConstants.USE_REFERENCE_ARRAYLETS || MemoryManagerConstants.USE_OBJECT_ARRAY_ACCESS_BARRIER) {
RVMMethod target = Entrypoints.arrayLoadReadBarrierMethod;
Instruction rb =
Call.create2(CALL,
diff -r 743a2cc2ed20 -r 058fdc3780ba rvm/src/org/jikesrvm/compilers/opt/runtimesupport/OptCompiledMethod.java
--- a/rvm/src/org/jikesrvm/compilers/opt/runtimesupport/OptCompiledMethod.java Tue Aug 04 11:04:15 2009 +1000
+++ b/rvm/src/org/jikesrvm/compilers/opt/runtimesupport/OptCompiledMethod.java Mon Nov 16 09:21:21 2009 +1100
@@ -16,6 +16,7 @@
import org.jikesrvm.ArchitectureSpecific;
import org.jikesrvm.ArchitectureSpecificOpt;
+import org.jikesrvm.HeapLayoutConstants;
import org.jikesrvm.VM;
import org.jikesrvm.PrintLN;
import org.jikesrvm.classloader.RVMArray;
@@ -241,8 +242,20 @@
public int size() {
int size = TypeReference.ExceptionTable.peekType().asClass().getInstanceSize();
size += _mcMap.size();
- if (eTable != null) size += RVMArray.IntArray.getInstanceSize(eTable.length);
- if (patchMap != null) size += RVMArray.IntArray.getInstanceSize(patchMap.length);
+ if (eTable != null) {
+ if (Magic.objectAsAddress(eTable).LT(HeapLayoutConstants.BOOT_IMAGE_DATA_END)) {
+ size += RVMArray.IntArray.getBootImageContiguousInstanceSize(eTable.length);
+ } else {
+ size += RVMArray.IntArray.getInstanceSize(eTable.length);
+ }
+ }
+ if (patchMap != null) {
+ if (Magic.objectAsAddress(patchMap).LT(HeapLayoutConstants.BOOT_IMAGE_DATA_END)) {
+ size += RVMArray.IntArray.getBootImageContiguousInstanceSize(patchMap.length);
+ } else {
+ size += RVMArray.IntArray.getInstanceSize(patchMap.length);
+ }
+ }
return size;
}
diff -r 743a2cc2ed20 -r 058fdc3780ba rvm/src/org/jikesrvm/compilers/opt/runtimesupport/OptMachineCodeMap.java
--- a/rvm/src/org/jikesrvm/compilers/opt/runtimesupport/OptMachineCodeMap.java Tue Aug 04 11:04:15 2009 +1000
+++ b/rvm/src/org/jikesrvm/compilers/opt/runtimesupport/OptMachineCodeMap.java Mon Nov 16 09:21:21 2009 +1100
@@ -14,6 +14,7 @@
import java.util.ArrayList;
import org.jikesrvm.ArchitectureSpecific;
+import org.jikesrvm.HeapLayoutConstants;
import org.jikesrvm.VM;
import org.jikesrvm.Constants;
import org.jikesrvm.adaptive.database.callgraph.CallSite;
@@ -31,6 +32,7 @@
import org.jikesrvm.compilers.opt.ir.IR;
import org.jikesrvm.compilers.opt.ir.Instruction;
import org.jikesrvm.compilers.opt.ir.operand.MethodOperand;
+import org.jikesrvm.runtime.Magic;
import org.vmmagic.pragma.Inline;
import org.vmmagic.pragma.Uninterruptible;
import org.vmmagic.unboxed.Offset;
@@ -693,9 +695,27 @@
*/
int size() {
int size = TYPE.peekType().asClass().getInstanceSize();
- if (MCInformation != null) size += RVMArray.IntArray.getInstanceSize(MCInformation.length);
- if (inlineEncoding != null) size += RVMArray.IntArray.getInstanceSize(inlineEncoding.length);
- if (gcMaps != null) size += RVMArray.IntArray.getInstanceSize(gcMaps.length);
+ if (MCInformation != null) {
+ if (Magic.objectAsAddress(MCInformation).LT(HeapLayoutConstants.BOOT_IMAGE_DATA_END)) {
+ size += RVMArray.IntArray.getBootImageContiguousInstanceSize(MCInformation.length);
+ } else {
+ size += RVMArray.IntArray.getInstanceSize(MCInformation.length);
+ }
+ }
+ if (inlineEncoding != null) {
+ if (Magic.objectAsAddress(inlineEncoding).LT(HeapLayoutConstants.BOOT_IMAGE_DATA_END)) {
+ size += RVMArray.IntArray.getBootImageContiguousInstanceSize(inlineEncoding.length);
+ } else {
+ size += RVMArray.IntArray.getInstanceSize(inlineEncoding.length);
+ }
+ }
+ if (gcMaps != null) {
+ if (Magic.objectAsAddress(gcMaps).LT(HeapLayoutConstants.BOOT_IMAGE_DATA_END)) {
+ size += RVMArray.IntArray.getBootImageContiguousInstanceSize(gcMaps.length);
+ } else {
+ size += RVMArray.IntArray.getInstanceSize(gcMaps.length);
+ }
+ }
return size;
}
diff -r 743a2cc2ed20 -r 058fdc3780ba rvm/src/org/jikesrvm/compilers/opt/runtimesupport/ppc/OptExceptionDeliverer.java
--- a/rvm/src/org/jikesrvm/compilers/opt/runtimesupport/ppc/OptExceptionDeliverer.java Tue Aug 04 11:04:15 2009 +1000
+++ b/rvm/src/org/jikesrvm/compilers/opt/runtimesupport/ppc/OptExceptionDeliverer.java Mon Nov 16 09:21:21 2009 +1100
@@ -87,7 +87,7 @@
frameOffset = frameOffset.plus(7).toWord().and(Word.fromIntSignExtend(~7)).toOffset();
for (int i = firstFloat; i < 32; i++) {
long temp = Magic.getLongAtOffset(Magic.addressAsObject(fp), frameOffset);
- registers.fprs[i] = Magic.longBitsAsDouble(temp);
+ registers.fprs.setLong(i, temp);
frameOffset = frameOffset.plus(BYTES_IN_DOUBLE);
}
}
diff -r 743a2cc2ed20 -r 058fdc3780ba rvm/src/org/jikesrvm/ia32/MachineReflection.java
--- a/rvm/src/org/jikesrvm/ia32/MachineReflection.java Tue Aug 04 11:04:15 2009 +1000
+++ b/rvm/src/org/jikesrvm/ia32/MachineReflection.java Mon Nov 16 09:21:21 2009 +1100
@@ -16,6 +16,7 @@
import org.jikesrvm.Constants;
import org.jikesrvm.classloader.RVMMethod;
import org.jikesrvm.classloader.TypeReference;
+import org.jikesrvm.mm.mminterface.MemoryManager;
import org.jikesrvm.runtime.Magic;
import org.vmmagic.pragma.UnpreemptibleNoWarn;
import org.vmmagic.unboxed.Word;
@@ -94,9 +95,9 @@
@UnpreemptibleNoWarn("GC is disabled as Objects are turned into Words."+
"avoid preemption but still allow calls to preemptible unboxing routines")
public static void packageParameters(RVMMethod method, Object thisArg, Object[] otherArgs, WordArray GPRs,
- double[] FPRs, byte[] FPRmeta, WordArray Parameters) {
+ WordArray FPRs, WordArray FPRmeta, WordArray Parameters) {
int GPR = 0;
- int FPR = ArchConstants.SSE2_FULL ? 0 : FPRs.length;
+ int FPR = ArchConstants.SSE2_FULL ? 0 : MemoryManager.nativeLongBufferLength(FPRs);
int parameter = 0;
int gp = NUM_PARAMETER_GPRS; // 0, 1, 2
@@ -138,11 +139,11 @@
if (fp > 0) {
fp--;
if (ArchConstants.SSE2_FULL) {
- FPRs[FPR] = (Float)otherArgs[i];
- FPRmeta[FPR] = 0x0;
+ FPRs.setLong(FPR, Double.doubleToLongBits((Float)otherArgs[i]));
+ FPRmeta.setByte(FPR, (byte)0);
FPR++;
} else {
- FPRs[--FPR] = (Float)otherArgs[i];
+ FPRs.setLong(--FPR, Double.doubleToLongBits((Float)otherArgs[i]));
}
}
float f = (Float)otherArgs[i];
@@ -151,11 +152,11 @@
if (fp > 0) {
fp--;
if (ArchConstants.SSE2_FULL) {
- FPRs[FPR] = (Double)otherArgs[i];
- FPRmeta[FPR] = 0x1;
+ FPRs.setLong(FPR, Double.doubleToLongBits((Double)otherArgs[i]));
+ FPRmeta.setByte(FPR, (byte)1);
FPR++;
} else {
- FPRs[--FPR] = (Double)otherArgs[i];
+ FPRs.setLong(--FPR, Double.doubleToLongBits((Double)otherArgs[i]));
}
}
double d = (Double)otherArgs[i];
diff -r 743a2cc2ed20 -r 058fdc3780ba rvm/src/org/jikesrvm/ia32/Registers.java
--- a/rvm/src/org/jikesrvm/ia32/Registers.java Tue Aug 04 11:04:15 2009 +1000
+++ b/rvm/src/org/jikesrvm/ia32/Registers.java Mon Nov 16 09:21:21 2009 +1100
@@ -35,9 +35,9 @@
@Untraced
public final WordArray gprs; // general purpose registers
@Untraced
- public final double[] fprs; // floating point registers
- public final WordArray gprsShadow;
- public final double[] fprsShadow;
+ public final WordArray fprs; // floating point registers
+ public final Object gprsShadow;
+ public final Object fprsShadow;
public Address ip; // instruction address register
public Address fp; // frame pointer
@@ -47,8 +47,8 @@
public boolean inuse; // do exception registers currently contain live values?
public Registers() {
- gprs = gprsShadow = MemoryManager.newNonMovingWordArray(NUM_GPRS);
- fprs = fprsShadow = MemoryManager.newNonMovingDoubleArray(NUM_FPRS);
+ gprsShadow = gprs = MemoryManager.newNonMovingWordArray(NUM_GPRS);
+ fprsShadow = fprs = MemoryManager.newNonMovingWordArray(NUM_FPRS * 2);
}
/**
diff -r 743a2cc2ed20 -r 058fdc3780ba rvm/src/org/jikesrvm/jni/JNIFunctions.java
--- a/rvm/src/org/jikesrvm/jni/JNIFunctions.java Tue Aug 04 11:04:15 2009 +1000
+++ b/rvm/src/org/jikesrvm/jni/JNIFunctions.java Mon Nov 16 09:21:21 2009 +1100
@@ -12,6 +12,7 @@
*/
package org.jikesrvm.jni;
+import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
@@ -3834,7 +3835,7 @@
try {
final char[] contents = new char[len];
- Memory.memcopy(Magic.objectAsAddress(contents), uchars, len * 2);
+ Memory.nativeMarshal(uchars, 0, contents, 0, len);
return env.pushJNIRef(java.lang.JikesRVMSupport.newStringWithoutCopy(contents, 0, len));
} catch (Throwable unexpected) {
if (traceJNI) unexpected.printStackTrace(System.err);
@@ -3882,15 +3883,13 @@
int len = java.lang.JikesRVMSupport.getStringLength(str);
// alloc non moving buffer in C heap for a copy of string contents
- Address copyBuffer = sysCall.sysMalloc(len * 2);
+ Address copyBuffer = sysCall.sysMalloc(len << LOG_BYTES_IN_CHAR);
if (copyBuffer.isZero()) {
env.recordException(new OutOfMemoryError());
return Address.zero();
}
try {
- Address strBase = Magic.objectAsAddress(strChars);
- Address srcBase = strBase.plus(strOffset * 2);
- Memory.memcopy(copyBuffer, srcBase, len * 2);
+ Memory.nativeMarshal(strChars, strOffset, copyBuffer, 0, len);
/* Set caller's isCopy boolean to true, if we got a valid (non-null)
address */
@@ -4335,8 +4334,7 @@
env.recordException(new OutOfMemoryError());
return Address.zero();
}
-
- Memory.memcopy(copyBuffer, Magic.objectAsAddress(sourceArray), size);
+ Memory.nativeMarshal(sourceArray, copyBuffer);
/* Set caller's isCopy boolean to true, if we got a valid (non-null)
address */
@@ -4367,7 +4365,7 @@
byte[] sourceArray = (byte[]) env.getJNIRef(arrayJREF);
int size = sourceArray.length;
- if (MemoryManager.willNeverMove(sourceArray)) {
+ if (Memory.isNativeFormat(sourceArray) && MemoryManager.willNeverMove(sourceArray)) {
/* return a direct pointer */
JNIGenericHelpers.setBoolStar(isCopyAddress, false);
return Magic.objectAsAddress(sourceArray);
@@ -4379,8 +4377,7 @@
env.recordException(new OutOfMemoryError());
return Address.zero();
}
-
- Memory.memcopy(copyBuffer, Magic.objectAsAddress(sourceArray), size);
+ Memory.nativeMarshal(sourceArray, copyBuffer);
/* Set caller's isCopy boolean to true, if we got a valid (non-null)
address */
@@ -4412,18 +4409,17 @@
char[] sourceArray = (char[]) env.getJNIRef(arrayJREF);
int size = sourceArray.length;
- if (MemoryManager.willNeverMove(sourceArray)) {
- JNIGenericHelpers.setBoolStar(isCopyAddress, false);
- return Magic.objectAsAddress(sourceArray);
- } else {
- // alloc non moving buffer in C heap for a copy of string contents
- Address copyBuffer = sysCall.sysMalloc(size * BYTES_IN_CHAR);
- if (copyBuffer.isZero()) {
- env.recordException(new OutOfMemoryError());
- return Address.zero();
- }
-
- Memory.memcopy(copyBuffer, Magic.objectAsAddress(sourceArray), size * BYTES_IN_CHAR);
+ if (Memory.isNativeFormat(sourceArray) && MemoryManager.willNeverMove(sourceArray)) {
+ JNIGenericHelpers.setBoolStar(isCopyAddress, false);
+ return Magic.objectAsAddress(sourceArray);
+ } else {
+ // alloc non moving buffer in C heap for a copy of string contents
+ Address copyBuffer = sysCall.sysMalloc(size << LOG_BYTES_IN_CHAR);
+ if (copyBuffer.isZero()) {
+ env.recordException(new OutOfMemoryError());
+ return Address.zero();
+ }
+ Memory.nativeMarshal(sourceArray, copyBuffer);
/* Set caller's isCopy boolean to true, if we got a valid (non-null)
address */
@@ -4455,18 +4451,17 @@
short[] sourceArray = (short[]) env.getJNIRef(arrayJREF);
int size = sourceArray.length;
- if (MemoryManager.willNeverMove(sourceArray)) {
- JNIGenericHelpers.setBoolStar(isCopyAddress, false);
- return Magic.objectAsAddress(sourceArray);
- } else {
- // alloc non moving buffer in C heap for a copy of string contents
- Address copyBuffer = sysCall.sysMalloc(size * BYTES_IN_SHORT);
- if (copyBuffer.isZero()) {
- env.recordException(new OutOfMemoryError());
- return Address.zero();
- }
-
- Memory.memcopy(copyBuffer, Magic.objectAsAddress(sourceArray), size * BYTES_IN_SHORT);
+ if (Memory.isNativeFormat(sourceArray) && MemoryManager.willNeverMove(sourceArray)) {
+ JNIGenericHelpers.setBoolStar(isCopyAddress, false);
+ return Magic.objectAsAddress(sourceArray);
+ } else {
+ // alloc non moving buffer in C heap for a copy of string contents
+ Address copyBuffer = sysCall.sysMalloc(size << LOG_BYTES_IN_SHORT);
+ if (copyBuffer.isZero()) {
+ env.recordException(new OutOfMemoryError());
+ return Address.zero();
+ }
+ Memory.nativeMarshal(sourceArray, copyBuffer);
/* Set caller's isCopy boolean to true, if we got a valid (non-null)
address */
@@ -4498,7 +4493,7 @@
int[] sourceArray = (int[]) env.getJNIRef(arrayJREF);
int size = sourceArray.length;
- if (MemoryManager.willNeverMove(sourceArray)) {
+ if (Memory.isNativeFormat(sourceArray) && MemoryManager.willNeverMove(sourceArray)) {
JNIGenericHelpers.setBoolStar(isCopyAddress, false);
return Magic.objectAsAddress(sourceArray);
} else {
@@ -4508,7 +4503,7 @@
env.recordException(new OutOfMemoryError());
return Address.zero();
}
- Memory.memcopy(copyBuffer, Magic.objectAsAddress(sourceArray), size << LOG_BYTES_IN_INT);
+ Memory.nativeMarshal(sourceArray, copyBuffer);
/* Set caller's isCopy boolean to true, if we got a valid (non-null)
address */
@@ -4540,7 +4535,7 @@
long[] sourceArray = (long[]) env.getJNIRef(arrayJREF);
int size = sourceArray.length;
- if (MemoryManager.willNeverMove(sourceArray)) {
+ if (Memory.isNativeFormat(sourceArray) && MemoryManager.willNeverMove(sourceArray)) {
JNIGenericHelpers.setBoolStar(isCopyAddress, false);
return Magic.objectAsAddress(sourceArray);
} else {
@@ -4550,7 +4545,7 @@
env.recordException(new OutOfMemoryError());
return Address.zero();
}
- Memory.memcopy(copyBuffer, Magic.objectAsAddress(sourceArray), size << LOG_BYTES_IN_LONG);
+ Memory.nativeMarshal(sourceArray, copyBuffer);
/* Set caller's isCopy boolean to true, if we got a valid (non-null)
address */
@@ -4582,7 +4577,7 @@
float[] sourceArray = (float[]) env.getJNIRef(arrayJREF);
int size = sourceArray.length;
- if (MemoryManager.willNeverMove(sourceArray)) {
+ if (Memory.isNativeFormat(sourceArray) && MemoryManager.willNeverMove(sourceArray)) {
JNIGenericHelpers.setBoolStar(isCopyAddress, false);
return Magic.objectAsAddress(sourceArray);
} else {
@@ -4592,8 +4587,7 @@
env.recordException(new OutOfMemoryError());
return Address.zero();
}
-
- Memory.memcopy(copyBuffer, Magic.objectAsAddress(sourceArray), size << LOG_BYTES_IN_FLOAT);
+ Memory.nativeMarshal(sourceArray, copyBuffer);
/* Set caller's isCopy boolean to true, if we got a valid (non-null)
address */
@@ -4625,7 +4619,7 @@
double[] sourceArray = (double[]) env.getJNIRef(arrayJREF);
int size = sourceArray.length;
- if (MemoryManager.willNeverMove(sourceArray)) {
+ if (Memory.isNativeFormat(sourceArray) && MemoryManager.willNeverMove(sourceArray)) {
JNIGenericHelpers.setBoolStar(isCopyAddress, false);
return Magic.objectAsAddress(sourceArray);
} else {
@@ -4635,7 +4629,7 @@
env.recordException(new OutOfMemoryError());
return Address.zero();
}
- Memory.memcopy(copyBuffer, Magic.objectAsAddress(sourceArray), size << LOG_BYTES_IN_DOUBLE);
+ Memory.nativeMarshal(sourceArray, copyBuffer);
/* Set caller's isCopy boolean to true, if we got a valid (non-null)
address */
@@ -4727,7 +4721,7 @@
// mode 0 and mode 1: copy back the buffer
if ((releaseMode == 0 || releaseMode == 1) && size != 0) {
- Memory.memcopy(Magic.objectAsAddress(sourceArray), copyBufferAddress, size);
+ Memory.nativeMarshal(copyBufferAddress, sourceArray);
}
// mode 0 and mode 2: free the buffer
@@ -4768,7 +4762,7 @@
// mode 0 and mode 1: copy back the buffer
if ((releaseMode == 0 || releaseMode == 1) && size != 0) {
- Memory.memcopy(Magic.objectAsAddress(sourceArray), copyBufferAddress, size << LOG_BYTES_IN_CHAR);
+ Memory.nativeMarshal(copyBufferAddress, sourceArray);
}
// mode 0 and mode 2: free the buffer
@@ -4806,7 +4800,7 @@
// mode 0 and mode 1: copy back the buffer
if ((releaseMode == 0 || releaseMode == 1) && size != 0) {
- Memory.memcopy(Magic.objectAsAddress(sourceArray), copyBufferAddress, size << LOG_BYTES_IN_SHORT);
+ Memory.nativeMarshal(copyBufferAddress, sourceArray);
}
// mode 0 and mode 2: free the buffer
@@ -4844,7 +4838,7 @@
// mode 0 and mode 1: copy back the buffer
if (releaseMode == 0 || releaseMode == 1) {
- Memory.memcopy(Magic.objectAsAddress(sourceArray), copyBufferAddress, size << LOG_BYTES_IN_INT);
+ Memory.nativeMarshal(copyBufferAddress, sourceArray);
}
// mode 0 and mode 2: free the buffer
@@ -4882,7 +4876,7 @@
// mode 0 and mode 1: copy back the buffer
if (releaseMode == 0 || releaseMode == 1) {
- Memory.memcopy(Magic.objectAsAddress(sourceArray), copyBufferAddress, size << LOG_BYTES_IN_LONG);
+ Memory.nativeMarshal(copyBufferAddress, sourceArray);
}
// mode 0 and mode 2: free the buffer
@@ -4920,7 +4914,7 @@
// mode 0 and mode 1: copy back the buffer
if (releaseMode == 0 || releaseMode == 1) {
- Memory.memcopy(Magic.objectAsAddress(sourceArray), copyBufferAddress, size << LOG_BYTES_IN_FLOAT);
+ Memory.nativeMarshal(copyBufferAddress, sourceArray);
}
// mode 0 and mode 2: free the buffer
@@ -4958,7 +4952,7 @@
// mode 0 and mode 1: copy back the buffer
if (releaseMode == 0 || releaseMode == 1) {
- Memory.memcopy(Magic.objectAsAddress(sourceArray), copyBufferAddress, size << LOG_BYTES_IN_DOUBLE);
+ Memory.nativeMarshal(copyBufferAddress, sourceArray);
}
// mode 0 and mode 2: free the buffer
@@ -4993,7 +4987,7 @@
env.recordException(new ArrayIndexOutOfBoundsException());
return;
}
- Memory.memcopy(bufAddress, Magic.objectAsAddress(sourceArray).plus(startIndex), length);
+ Memory.nativeMarshal(sourceArray, startIndex, bufAddress, 0, length);
} catch (Throwable unexpected) {
if (traceJNI) unexpected.printStackTrace(System.err);
env.recordException(unexpected);
@@ -5022,7 +5016,7 @@
return;
}
- Memory.memcopy(bufAddress, Magic.objectAsAddress(sourceArray).plus(startIndex), length);
+ Memory.nativeMarshal(sourceArray, startIndex, bufAddress, 0, length);
} catch (Throwable unexpected) {
if (traceJNI) unexpected.printStackTrace(System.err);
env.recordException(unexpected);
@@ -5051,9 +5045,7 @@
return;
}
- Memory.memcopy(bufAddress,
- Magic.objectAsAddress(sourceArray).plus(startIndex << LOG_BYTES_IN_CHAR),
- length << LOG_BYTES_IN_CHAR);
+ Memory.nativeMarshal(sourceArray, startIndex, bufAddress, 0, length);
} catch (Throwable unexpected) {
if (traceJNI) unexpected.printStackTrace(System.err);
env.recordException(unexpected);
@@ -5082,9 +5074,7 @@
return;
}
- Memory.memcopy(bufAddress,
- Magic.objectAsAddress(sourceArray).plus(startIndex << LOG_BYTES_IN_SHORT),
- length << LOG_BYTES_IN_SHORT);
+ Memory.nativeMarshal(sourceArray, startIndex, bufAddress, 0, length);
} catch (Throwable unexpected) {
if (traceJNI) unexpected.printStackTrace(System.err);
env.recordException(unexpected);
@@ -5113,9 +5103,7 @@
return;
}
- Memory.memcopy(bufAddress,
- Magic.objectAsAddress(sourceArray).plus(startIndex << LOG_BYTES_IN_INT),
- length << LOG_BYTES_IN_INT);
+ Memory.nativeMarshal(sourceArray, startIndex, bufAddress, 0, length);
} catch (Throwable unexpected) {
if (traceJNI) unexpected.printStackTrace(System.err);
env.recordException(unexpected);
@@ -5144,9 +5132,7 @@
return;
}
- Memory.memcopy(bufAddress,
- Magic.objectAsAddress(sourceArray).plus(startIndex << LOG_BYTES_IN_LONG),
- length << LOG_BYTES_IN_LONG);
+ Memory.nativeMarshal(sourceArray, startIndex, bufAddress, 0, length);
} catch (Throwable unexpected) {
if (traceJNI) unexpected.printStackTrace(System.err);
env.recordException(unexpected);
@@ -5175,9 +5161,7 @@
return;
}
- Memory.memcopy(bufAddress,
- Magic.objectAsAddress(sourceArray).plus(startIndex << LOG_BYTES_IN_FLOAT),
- length << LOG_BYTES_IN_FLOAT);
+ Memory.nativeMarshal(sourceArray, startIndex, bufAddress, 0, length);
} catch (Throwable unexpected) {
if (traceJNI) unexpected.printStackTrace(System.err);
env.recordException(unexpected);
@@ -5206,9 +5190,7 @@
return;
}
- Memory.memcopy(bufAddress,
- Magic.objectAsAddress(sourceArray).plus(startIndex << LOG_BYTES_IN_DOUBLE),
- length << LOG_BYTES_IN_DOUBLE);
+ Memory.nativeMarshal(sourceArray, startIndex, bufAddress, 0, length);
} catch (Throwable unexpected) {
if (traceJNI) unexpected.printStackTrace(System.err);
env.recordException(unexpected);
@@ -5237,7 +5219,7 @@
return;
}
- Memory.memcopy(Magic.objectAsAddress(destinationArray).plus(startIndex), bufAddress, length);
+ Memory.nativeMarshal(bufAddress, 0, destinationArray, startIndex, length);
} catch (Throwable unexpected) {
if (traceJNI) unexpected.printStackTrace(System.err);
env.recordException(unexpected);
@@ -5266,7 +5248,7 @@
return;
}
- Memory.memcopy(Magic.objectAsAddress(destinationArray).plus(startIndex), bufAddress, length);
+ Memory.nativeMarshal(bufAddress, 0, destinationArray, startIndex, length);
} catch (Throwable unexpected) {
if (traceJNI) unexpected.printStackTrace(System.err);
env.recordException(unexpected);
@@ -5295,9 +5277,7 @@
return;
}
- Memory.memcopy(Magic.objectAsAddress(destinationArray).plus(startIndex << LOG_BYTES_IN_CHAR),
- bufAddress,
- length << LOG_BYTES_IN_CHAR);
+ Memory.nativeMarshal(bufAddress, 0, destinationArray, startIndex, length);
} catch (Throwable unexpected) {
if (traceJNI) unexpected.printStackTrace(System.err);
env.recordException(unexpected);
@@ -5326,9 +5306,7 @@
return;
}
- Memory.memcopy(Magic.objectAsAddress(destinationArray).plus(startIndex << LOG_BYTES_IN_SHORT),
- bufAddress,
- length << LOG_BYTES_IN_SHORT);
+ Memory.nativeMarshal(bufAddress, 0, destinationArray, startIndex, length);
} catch (Throwable unexpected) {
if (traceJNI) unexpected.printStackTrace(System.err);
env.recordException(unexpected);
@@ -5357,9 +5335,7 @@
return;
}
- Memory.memcopy(Magic.objectAsAddress(destinationArray).plus(startIndex << LOG_BYTES_IN_INT),
- bufAddress,
- length << LOG_BYTES_IN_INT);
+ Memory.nativeMarshal(bufAddress, 0, destinationArray, startIndex, length);
} catch (Throwable unexpected) {
if (traceJNI) unexpected.printStackTrace(System.err);
env.recordException(unexpected);
@@ -5388,9 +5364,7 @@
return;
}
- Memory.memcopy(Magic.objectAsAddress(destinationArray).plus(startIndex << LOG_BYTES_IN_LONG),
- bufAddress,
- length << LOG_BYTES_IN_LONG);
+ Memory.nativeMarshal(bufAddress, 0, destinationArray, startIndex, length);
} catch (Throwable unexpected) {
if (traceJNI) unexpected.printStackTrace(System.err);
env.recordException(unexpected);
@@ -5419,9 +5393,7 @@
return;
}
- Memory.memcopy(Magic.objectAsAddress(destinationArray).plus(startIndex << LOG_BYTES_IN_FLOAT),
- bufAddress,
- length << LOG_BYTES_IN_FLOAT);
+ Memory.nativeMarshal(bufAddress, 0, destinationArray, startIndex, length);
} catch (Throwable unexpected) {
if (traceJNI) unexpected.printStackTrace(System.err);
env.recordException(unexpected);
@@ -5450,9 +5422,7 @@
return;
}
- Memory.memcopy(Magic.objectAsAddress(destinationArray).plus(startIndex << LOG_BYTES_IN_DOUBLE),
- bufAddress,
- length << LOG_BYTES_IN_DOUBLE);
+ Memory.nativeMarshal(bufAddress, 0, destinationArray, startIndex, length);
} catch (Throwable unexpected) {
if (traceJNI) unexpected.printStackTrace(System.err);
env.recordException(unexpected);
@@ -5795,10 +5765,7 @@
env.recordException(new StringIndexOutOfBoundsException());
return;
}
- Address strBase = Magic.objectAsAddress(strChars);
- Address srcBase = strBase.plus(strOffset * 2).plus(start * 2);
- Memory.memcopy(buf, srcBase, len * 2);
-
+ Memory.nativeMarshal(strChars, start, buf, 0, len);
} catch (Throwable unexpected) {
if (traceJNI) unexpected.printStackTrace(System.err);
env.recordException(unexpected);
@@ -5853,18 +5820,139 @@
try {
Object primitiveArray = env.getJNIRef(arrayJREF);
- // not an array, return null
- if (!primitiveArray.getClass().isArray()) {
+ if (primitiveArray instanceof byte[]) {
+ byte[] array = (byte[])primitiveArray;
+ if (Memory.isNativeFormat(array)) {
+ JNIGenericHelpers.setBoolStar(isCopyAddress, false);
+ VM.disableGC(true);
+ return Magic.objectAsAddress(primitiveArray);
+ } else {
+ Address copyBuffer = sysCall.sysMalloc(array.length << LOG_BYTES_IN_BYTE);
+ if (copyBuffer.isZero()) {
+ env.recordException(new OutOfMemoryError());
+ return Address.zero();
+ }
+ Memory.nativeMarshal(array, copyBuffer);
+ JNIGenericHelpers.setBoolStar(isCopyAddress, true);
+ return copyBuffer;
+ }
+ } else if (primitiveArray instanceof boolean[]) {
+ boolean[] array = (boolean[])primitiveArray;
+ if (Memory.isNativeFormat(array)) {
+ JNIGenericHelpers.setBoolStar(isCopyAddress, false);
+ VM.disableGC(true);
+ return Magic.objectAsAddress(primitiveArray);
+ } else {
+ Address copyBuffer = sysCall.sysMalloc(array.length << LOG_BYTES_IN_BOOLEAN);
+ if (copyBuffer.isZero()) {
+ env.recordException(new OutOfMemoryError());
+ return Address.zero();
+ }
+ Memory.nativeMarshal(array, copyBuffer);
+ JNIGenericHelpers.setBoolStar(isCopyAddress, true);
+ return copyBuffer;
+ }
+ } else if (primitiveArray instanceof char[]) {
+ char[] array = (char[])primitiveArray;
+ if (Memory.isNativeFormat(array)) {
+ JNIGenericHelpers.setBoolStar(isCopyAddress, false);
+ VM.disableGC(true);
+ return Magic.objectAsAddress(primitiveArray);
+ } else {
+ Address copyBuffer = sysCall.sysMalloc(array.length << LOG_BYTES_IN_CHAR);
+ if (copyBuffer.isZero()) {
+ env.recordException(new OutOfMemoryError());
+ return Address.zero();
+ }
+ Memory.nativeMarshal(array, copyBuffer);
+ JNIGenericHelpers.setBoolStar(isCopyAddress, true);
+ return copyBuffer;
+ }
+ } else if (primitiveArray instanceof short[]) {
+ short[] array = (short[])primitiveArray;
+ if (Memory.isNativeFormat(array)) {
+ JNIGenericHelpers.setBoolStar(isCopyAddress, false);
+ VM.disableGC(true);
+ return Magic.objectAsAddress(primitiveArray);
+ } else {
+ Address copyBuffer = sysCall.sysMalloc(array.length << LOG_BYTES_IN_SHORT);
+ if (copyBuffer.isZero()) {
+ env.recordException(new OutOfMemoryError());
+ return Address.zero();
+ }
+ Memory.nativeMarshal(array, copyBuffer);
+ JNIGenericHelpers.setBoolStar(isCopyAddress, true);
+ return copyBuffer;
+ }
+ } else if (primitiveArray instanceof int[]) {
+ int[] array = (int[])primitiveArray;
+ if (Memory.isNativeFormat(array)) {
+ JNIGenericHelpers.setBoolStar(isCopyAddress, false);
+ VM.disableGC(true);
+ return Magic.objectAsAddress(primitiveArray);
+ } else {
+ Address copyBuffer = sysCall.sysMalloc(array.length << LOG_BYTES_IN_INT);
+ if (copyBuffer.isZero()) {
+ env.recordException(new OutOfMemoryError());
+ return Address.zero();
+ }
+ Memory.nativeMarshal(array, copyBuffer);
+ JNIGenericHelpers.setBoolStar(isCopyAddress, true);
+ return copyBuffer;
+ }
+ } else if (primitiveArray instanceof float[]) {
+ float[] array = (float[])primitiveArray;
+ if (Memory.isNativeFormat(array)) {
+ JNIGenericHelpers.setBoolStar(isCopyAddress, false);
+ VM.disableGC(true);
+ return Magic.objectAsAddress(primitiveArray);
+ } else {
+ Address copyBuffer = sysCall.sysMalloc(array.length << LOG_BYTES_IN_FLOAT);
+ if (copyBuffer.isZero()) {
+ env.recordException(new OutOfMemoryError());
+ return Address.zero();
+ }
+ Memory.nativeMarshal(array, copyBuffer);
+ JNIGenericHelpers.setBoolStar(isCopyAddress, true);
+ return copyBuffer;
+ }
+ } else if (primitiveArray instanceof long[]) {
+ long[] array = (long[])primitiveArray;
+ if (Memory.isNativeFormat(array)) {
+ JNIGenericHelpers.setBoolStar(isCopyAddress, false);
+ VM.disableGC(true);
+ return Magic.objectAsAddress(primitiveArray);
+ } else {
+ Address copyBuffer = sysCall.sysMalloc(array.length << LOG_BYTES_IN_LONG);
+ if (copyBuffer.isZero()) {
+ env.recordException(new OutOfMemoryError());
+ return Address.zero();
+ }
+ Memory.nativeMarshal(array, copyBuffer);
+ JNIGenericHelpers.setBoolStar(isCopyAddress, true);
+ return copyBuffer;
+ }
+ } else if (primitiveArray instanceof double[]) {
+ double[] array = (double[])primitiveArray;
+ if (Memory.isNativeFormat(array)) {
+ JNIGenericHelpers.setBoolStar(isCopyAddress, false);
+ VM.disableGC(true);
+ return Magic.objectAsAddress(primitiveArray);
+ } else {
+ Address copyBuffer = sysCall.sysMalloc(array.length << LOG_BYTES_IN_DOUBLE);
+ if (copyBuffer.isZero()) {
+ env.recordException(new OutOfMemoryError());
+ return Address.zero();
+ }
+ Memory.nativeMarshal(array, copyBuffer);
+ JNIGenericHelpers.setBoolStar(isCopyAddress, true);
+ return copyBuffer;
+ }
+ } else {
+ // not an array, return null
return Address.zero();
}
-
- /* Set caller's isCopy boolean to false, if we got a valid (non-null)
- address */
- JNIGenericHelpers.setBoolStar(isCopyAddress, false);
-
- // For array of primitive, return the object address, which is the array itself
- VM.disableGC(true);
- return Magic.objectAsAddress(primitiveArray);
+
} catch (Throwable unexpected) {
if (traceJNI) unexpected.printStackTrace(System.err);
env.recordException(unexpected);
@@ -5890,7 +5978,128 @@
RuntimeEntrypoints.checkJNICountDownToGC();
try {
- VM.enableGC(true);
+ Object primitiveArray = env.getJNIRef(arrayJREF);
+ if (primitiveArray instanceof byte[]) {
+ byte[] array = (byte[])primitiveArray;
+ if (Memory.isNativeFormat(array)) {
+ VM.enableGC(true);
+ } else {
+ // mode 0 and mode 1: copy back the buffer
+ if ((mode == 0 || mode == 1) && array.length != 0) {
+ Memory.nativeMarshal(arrayCopyAddress, array);
+ }
+
+ // mode 0 and mode 2: free the buffer
+ if (mode == 0 || mode == 2) {
+ sysCall.sysFree(arrayCopyAddress);
+ }
+ }
+ } else if (primitiveArray instanceof boolean[]) {
+ boolean[] array = (boolean[])primitiveArray;
+ if (Memory.isNativeFormat(array)) {
+ VM.enableGC(true);
+ } else {
+ // mode 0 and mode 1: copy back the buffer
+ if ((mode == 0 || mode == 1) && array.length != 0) {
+ Memory.nativeMarshal(arrayCopyAddress, array);
+ }
+
+ // mode 0 and mode 2: free the buffer
+ if (mode == 0 || mode == 2) {
+ sysCall.sysFree(arrayCopyAddress);
+ }
+ }
+ } else if (primitiveArray instanceof char[]) {
+ char[] array = (char[])primitiveArray;
+ if (Memory.isNativeFormat(array)) {
+ VM.enableGC(true);
+ } else {
+ // mode 0 and mode 1: copy back the buffer
+ if ((mode == 0 || mode == 1) && array.length != 0) {
+ Memory.nativeMarshal(arrayCopyAddress, array);
+ }
+
+ // mode 0 and mode 2: free the buffer
+ if (mode == 0 || mode == 2) {
+ sysCall.sysFree(arrayCopyAddress);
+ }
+ }
+ } else if (primitiveArray instanceof short[]) {
+ short[] array = (short[])primitiveArray;
+ if (Memory.isNativeFormat(array)) {
+ VM.enableGC(true);
+ } else {
+ // mode 0 and mode 1: copy back the buffer
+ if ((mode == 0 || mode == 1) && array.length != 0) {
+ Memory.nativeMarshal(arrayCopyAddress, array);
+ }
+
+ // mode 0 and mode 2: free the buffer
+ if (mode == 0 || mode == 2) {
+ sysCall.sysFree(arrayCopyAddress);
+ }
+ }
+ } else if (primitiveArray instanceof int[]) {
+ int[] array = (int[])primitiveArray;
+ if (Memory.isNativeFormat(array)) {
+ VM.enableGC(true);
+ } else {
+ // mode 0 and mode 1: copy back the buffer
+ if ((mode == 0 || mode == 1) && array.length != 0) {
+ Memory.nativeMarshal(arrayCopyAddress, array);
+ }
+
+ // mode 0 and mode 2: free the buffer
+ if (mode == 0 || mode == 2) {
+ sysCall.sysFree(arrayCopyAddress);
+ }
+ }
+ } else if (primitiveArray instanceof float[]) {
+ float[] array = (float[])primitiveArray;
+ if (Memory.isNativeFormat(array)) {
+ VM.enableGC(true);
+ } else {
+ // mode 0 and mode 1: copy back the buffer
+ if ((mode == 0 || mode == 1) && array.length != 0) {
+ Memory.nativeMarshal(arrayCopyAddress, array);
+ }
+
+ // mode 0 and mode 2: free the buffer
+ if (mode == 0 || mode == 2) {
+ sysCall.sysFree(arrayCopyAddress);
+ }
+ }
+ } else if (primitiveArray instanceof long[]) {
+ long[] array = (long[])primitiveArray;
+ if (Memory.isNativeFormat(array)) {
+ VM.enableGC(true);
+ } else {
+ // mode 0 and mode 1: copy back the buffer
+ if ((mode == 0 || mode == 1) && array.length != 0) {
+ Memory.nativeMarshal(arrayCopyAddress, array);
+ }
+
+ // mode 0 and mode 2: free the buffer
+ if (mode == 0 || mode == 2) {
+ sysCall.sysFree(arrayCopyAddress);
+ }
+ }
+ } else if (primitiveArray instanceof double[]) {
+ double[] array = (double[])primitiveArray;
+ if (Memory.isNativeFormat(array)) {
+ VM.enableGC(true);
+ } else {
+ // mode 0 and mode 1: copy back the buffer
+ if ((mode == 0 || mode == 1) && array.length != 0) {
+ Memory.nativeMarshal(arrayCopyAddress, array);
+ }
+
+ // mode 0 and mode 2: free the buffer
+ if (mode == 0 || mode == 2) {
+ sysCall.sysFree(arrayCopyAddress);
+ }
+ }
+ }
} catch (Throwable unexpected) {
if (traceJNI) unexpected.printStackTrace(System.err);
env.recordException(unexpected);
@@ -5911,17 +6120,44 @@
if (traceJNI) VM.sysWrite("JNI called: GetStringCritical \n");
RuntimeEntrypoints.checkJNICountDownToGC();
- String str = (String) env.getJNIRef(strJREF);
- char[] strChars = java.lang.JikesRVMSupport.getBackingCharArray(str);
- int strOffset = java.lang.JikesRVMSupport.getStringOffset(str);
-
- /* Set caller's isCopy boolean to false, if we got a valid (non-null)
- address */
- JNIGenericHelpers.setBoolStar(isCopyAddress, false);
-
- VM.disableGC(true);
- Address strBase = Magic.objectAsAddress(strChars);
- return strBase.plus(strOffset * 2);
+ try {
+ String str = (String) env.getJNIRef(strJREF);
+ char[] strChars = java.lang.JikesRVMSupport.getBackingCharArray(str);
+ int strOffset = java.lang.JikesRVMSupport.getStringOffset(str);
+ int strLen = java.lang.JikesRVMSupport.getStringLength(str);
+
+ if (Memory.isNativeFormat(strChars)) {
+ /* Set caller's isCopy boolean to false */
+ JNIGenericHelpers.setBoolStar(isCopyAddress, false);
+
+ VM.disableGC(true);
+ return Magic.objectAsAddress(strChars).plus(strOffset << LOG_BYTES_IN_CHAR);
+ } else {
+ // alloc non moving buffer in C heap for a copy of string contents
+ Address copyBuffer = sysCall.sysMalloc(strLen << LOG_BYTES_IN_CHAR);
+ if (copyBuffer.isZero()) {
+ env.recordException(new OutOfMemoryError());
+ return Address.zero();
+ }
+ try {
+ Memory.nativeMarshal(strChars, strOffset, copyBuffer, 0, strLen);
+
+ /* Set caller's isCopy boolean to true */
+ JNIGenericHelpers.setBoolStar(isCopyAddress, true);
+
+ return copyBuffer;
+ } catch (Throwable unexpected) {
+ sysCall.sysFree(copyBuffer);
+ if (traceJNI) unexpected.printStackTrace(System.err);
+ env.recordException(unexpected);
+ return Address.zero();
+ }
+ }
+ } catch (Throwable unexpected) {
+ if (traceJNI) unexpected.printStackTrace(System.err);
+ env.recordException(unexpected);
+ return Address.zero();
+ }
}
/**
@@ -5939,7 +6175,17 @@
RuntimeEntrypoints.checkJNICountDownToGC();
try {
- VM.enableGC(true);
+ String str = (String) env.getJNIRef(strJREF);
+ char[] strChars = java.lang.JikesRVMSupport.getBackingCharArray(str);
+ int strOffset = java.lang.JikesRVMSupport.getStringOffset(str);
+ int strLen = java.lang.JikesRVMSupport.getStringLength(str);
+
+ if (Memory.isNativeFormat(strChars)) {
+ VM.enableGC(true);
+ } else {
+ Memory.nativeMarshal(carray, 0, strChars, strOffset, strLen);
+ sysCall.sysFree(carray);
+ }
} catch (Throwable unexpected) {
if (traceJNI) unexpected.printStackTrace(System.err);
env.recordException(unexpected);
diff -r 743a2cc2ed20 -r 058fdc3780ba rvm/src/org/jikesrvm/jni/JNIGenericHelpers.java
--- a/rvm/src/org/jikesrvm/jni/JNIGenericHelpers.java Tue Aug 04 11:04:15 2009 +1000
+++ b/rvm/src/org/jikesrvm/jni/JNIGenericHelpers.java Mon Nov 16 09:21:21 2009 +1100
@@ -100,7 +100,7 @@
int length = strlen(stringAddress);
byte[] contents = new byte[length];
- Memory.memcopy(Magic.objectAsAddress(contents), stringAddress, length);
+ Memory.nativeMarshal(stringAddress, contents);
return contents;
}
diff -r 743a2cc2ed20 -r 058fdc3780ba rvm/src/org/jikesrvm/mm/mminterface/CollectorThread.java
--- a/rvm/src/org/jikesrvm/mm/mminterface/CollectorThread.java Tue Aug 04 11:04:15 2009 +1000
+++ b/rvm/src/org/jikesrvm/mm/mminterface/CollectorThread.java Mon Nov 16 09:21:21 2009 +1100
@@ -41,6 +41,7 @@
import org.vmmagic.pragma.UnpreemptibleNoWarn;
import org.vmmagic.unboxed.Address;
import org.vmmagic.unboxed.Offset;
+import org.vmmagic.unboxed.WordArray;
/**
* System thread used to perform garbage collections.
@@ -107,7 +108,7 @@
public static final int GC_ORDINAL_BASE = 1;
/** array of size 1 to count arriving collector threads */
- static final int[] participantCount;
+ static final WordArray participantCount;
/** maps processor id to assoicated collector thread */
static CollectorThread[] collectorThreads;
@@ -164,7 +165,7 @@
*/
static {
handshake = new Handshake();
- participantCount = new int[1]; // counter for threads starting a collection
+ participantCount = WordArray.create(1); // counter for threads starting a collection
}
/**
@@ -175,7 +176,7 @@
* @param processorAffinity The processor with which this thread is
* associated.
*/
- CollectorThread(byte[] stack, boolean isActive, GreenProcessor processorAffinity) {
+ CollectorThread(WordArray stack, boolean isActive, GreenProcessor processorAffinity) {
super(stack, myName);
makeDaemon(true); // this is redundant, but harmless
this.isActive = isActive;
@@ -241,7 +242,7 @@
*/
@Interruptible
public static CollectorThread createActiveCollectorThread(GreenProcessor processorAffinity) {
- byte[] stack = MemoryManager.newStack(ArchitectureSpecific.StackframeLayoutConstants.STACK_SIZE_COLLECTOR, true);
+ WordArray stack = MemoryManager.newStack(ArchitectureSpecific.StackframeLayoutConstants.STACK_SIZE_COLLECTOR, true);
return new CollectorThread(stack, true, processorAffinity);
}
@@ -257,7 +258,7 @@
* @return a new non-particpating collector thread
*/
@Interruptible
- static CollectorThread createPassiveCollectorThread(byte[] stack, GreenProcessor processorAffinity) {
+ static CollectorThread createPassiveCollectorThread(WordArray stack, GreenProcessor processorAffinity) {
return new CollectorThread(stack, false, processorAffinity);
}
@@ -306,7 +307,7 @@
*/
@Uninterruptible
public static int numCollectors() {
- return (participantCount[0]);
+ return participantCount.getInt(0);
}
/**
diff -r 743a2cc2ed20 -r 058fdc3780ba rvm/src/org/jikesrvm/mm/mminterface/ConcurrentCollectorThread.java
--- a/rvm/src/org/jikesrvm/mm/mminterface/ConcurrentCollectorThread.java Tue Aug 04 11:04:15 2009 +1000
+++ b/rvm/src/org/jikesrvm/mm/mminterface/ConcurrentCollectorThread.java Mon Nov 16 09:21:21 2009 +1100
@@ -22,6 +22,7 @@
import org.vmmagic.pragma.NonMoving;
import org.vmmagic.pragma.Uninterruptible;
import org.vmmagic.pragma.Unpreemptible;
+import org.vmmagic.unboxed.WordArray;
/**
* Threads that perform collector work while mutators are active. these
@@ -61,7 +62,7 @@
* @param processorAffinity The processor with which this thread is
* associated.
*/
- ConcurrentCollectorThread(byte[] stack, GreenProcessor processorAffinity) {
+ ConcurrentCollectorThread(WordArray stack, GreenProcessor processorAffinity) {
super(stack, myName);
makeDaemon(true); // this is redundant, but harmless
this.processorAffinity = processorAffinity;
@@ -89,7 +90,7 @@
*/
@Interruptible
public static ConcurrentCollectorThread createConcurrentCollectorThread(GreenProcessor processorAffinity) {
- byte[] stack = MemoryManager.newStack(ArchitectureSpecific.StackframeLayoutConstants.STACK_SIZE_COLLECTOR, true);
+ WordArray stack = MemoryManager.newStack(ArchitectureSpecific.StackframeLayoutConstants.STACK_SIZE_COLLECTOR, true);
return new ConcurrentCollectorThread(stack, processorAffinity);
}
diff -r 743a2cc2ed20 -r 058fdc3780ba rvm/src/org/jikesrvm/mm/mminterface/Handshake.java
--- a/rvm/src/org/jikesrvm/mm/mminterface/Handshake.java Tue Aug 04 11:04:15 2009 +1000
+++ b/rvm/src/org/jikesrvm/mm/mminterface/Handshake.java Mon Nov 16 09:21:21 2009 +1100
@@ -142,7 +142,7 @@
/* reset counter for collector threads arriving to participate in
* the collection */
- CollectorThread.participantCount[0] = 0;
+ CollectorThread.participantCount.setInt(0, 0);
/* reset rendezvous counters to 0, the decision about which
* collector threads will participate has moved to the run method
diff -r 743a2cc2ed20 -r 058fdc3780ba rvm/src/org/jikesrvm/mm/mminterface/MemoryManager.java
--- a/rvm/src/org/jikesrvm/mm/mminterface/MemoryManager.java Tue Aug 04 11:04:15 2009 +1000
+++ b/rvm/src/org/jikesrvm/mm/mminterface/MemoryManager.java Mon Nov 16 09:21:21 2009 +1100
@@ -12,10 +12,13 @@
*/
package org.jikesrvm.mm.mminterface;
+import static org.jikesrvm.mm.mminterface.MemoryManagerConstants.*;
+
import java.lang.ref.PhantomReference;
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;
import org.jikesrvm.ArchitectureSpecific.CodeArray;
+import org.jikesrvm.Constants;
import org.jikesrvm.VM;
import org.jikesrvm.HeapLayoutConstants;
import org.jikesrvm.classloader.RVMArray;
@@ -39,20 +42,25 @@
import org.jikesrvm.options.OptionSet;
import org.jikesrvm.runtime.BootRecord;
import org.jikesrvm.runtime.Magic;
+import org.jikesrvm.runtime.Memory;
import org.jikesrvm.scheduler.ProcessorTable;
import org.mmtk.plan.Plan;
+import org.mmtk.plan.generational.Gen;
import org.mmtk.policy.Space;
-import org.mmtk.utility.Constants;
-import org.mmtk.utility.Memory;
+import org.mmtk.policy.arraylet.Arraylet;
+import org.mmtk.policy.arraylet.ArrayletSpace;
+//import org.mmtk.utility.Memory;
import org.mmtk.utility.alloc.Allocator;
import org.mmtk.utility.gcspy.GCspy;
import org.mmtk.utility.heap.HeapGrowthManager;
import org.mmtk.utility.heap.Mmapper;
import org.mmtk.utility.options.Options;
+import org.mmtk.utility.statistics.EventCounter;
import org.vmmagic.pragma.Entrypoint;
import org.vmmagic.pragma.Inline;
import org.vmmagic.pragma.Interruptible;
import org.vmmagic.pragma.NoInline;
+import org.vmmagic.pragma.NonMovingAllocation;
import org.vmmagic.pragma.Pure;
import org.vmmagic.pragma.Uninterruptible;
import org.vmmagic.pragma.Unpreemptible;
@@ -63,6 +71,13 @@
import org.vmmagic.unboxed.Offset;
import org.vmmagic.unboxed.Word;
import org.vmmagic.unboxed.WordArray;
+import static org.mmtk.utility.Constants.AALOAD_READ_BARRIER;
+import static org.mmtk.utility.Constants.AASTORE_WRITE_BARRIER;
+import static org.mmtk.utility.Constants.GETFIELD_READ_BARRIER;
+import static org.mmtk.utility.Constants.PUTFIELD_WRITE_BARRIER;
+import static org.mmtk.utility.Constants.GETSTATIC_READ_BARRIER;
+import static org.mmtk.utility.Constants.PUTSTATIC_WRITE_BARRIER;
+import static org.mmtk.utility.Constants.MIN_ALIGNMENT;
/**
* The interface that the MMTk memory manager presents to Jikes RVM
@@ -85,6 +100,7 @@
* Hash the interface been booted yet?
*/
private static boolean booted = false;
+
/***********************************************************************
*
@@ -226,11 +242,416 @@
public static void putstaticWriteBarrier(Offset offset, Object value, int locationMetadata) {
ObjectReference src = ObjectReference.fromObject(Magic.getJTOC());
Selected.Mutator.get().writeBarrier(src,
- src.toAddress().plus(offset),
- ObjectReference.fromObject(value),
- offset.toWord(),
- Word.fromIntZeroExtend(locationMetadata),
- PUTSTATIC_WRITE_BARRIER);
+ src.toAddress().plus(offset),
+ ObjectReference.fromObject(value),
+ offset.toWord(),
+ Word.fromIntZeroExtend(locationMetadata),
+ PUTSTATIC_WRITE_BARRIER);
+ }
+
+ /**
+ * Store a byte to an array
+ *
+ * @param array The array object to which the byte is to be stored
+ * @param index The array index at which the byte is to be stored
+ * @param value The value to be stored
+ */
+ @Entrypoint
+ public static void arrayStorePrimitiveByteWriteBarrier(Object array, int index, byte value) {
+ if ((BOOT_IMAGE_IS_ARRAYLETIZED || ObjectReference.fromObject(array).toAddress().GE(HeapLayoutConstants.BOOT_IMAGE_DATA_END)) &&
+ (!DO_FIRSTN_OPT || (index >= FIRSTN_BYTE_ELEMS))) {
+ arrayletStoreByte(array, index, value);
+ } else {
+ Magic.setByteAtOffset(array, Offset.fromIntZeroExtend(index << LOG_BYTES_IN_BYTE), value);
+ if (DO_COLLECT_ARRAY_ACCESS_STATS) primWbFast++;
+ }
+ }
+
+ /**
+ * Perform an arrayletized store to a byte array. This code must find the
+ * appropriate arraylet and store the value to the appropriate slot within
+ * that arraylet. If we're using lazy allocation or zero compression, the
+ * target arraylet may be the zero arraylet, so if we're storing an non-zero
+ * value, we need to instantiate a new arraylet.
+ *
+ * @param array The array to which the store is to be made
+ * @param index The array index at which the byte is to be stored
+ * @param value The value to be stored
+ */
+ private static void arrayletStoreByte(Object array, int index, byte value) {
+ if (DO_COLLECT_ARRAY_ACCESS_STATS) primWbSlow++;
+ int arrayletNumber = (index - FIRSTN_BYTE_ELEMS)>>LOG_ELEMENTS_IN_BYTE_ARRAYLET;
+ Offset arrayletPtrOffset = Offset.fromIntZeroExtend(FIRSTN_BYTE_BYTES + (arrayletNumber<from
must have
@@ -74,10 +204,14 @@
private ObjectReference copyArray(ObjectReference from, TIB tib, RVMArray type, int allocator) {
int elements = Magic.getArrayLength(from.toObject());
int bytes = org.jikesrvm.objectmodel.ObjectModel.bytesRequiredWhenCopied(from.toObject(), type, elements);
+ int allocatorBytes = bytes;
+ if ((type.isArrayletizable() && MemoryManagerConstants.DO_PRETENURE_LARGE_ARRAYS)) { //assume that copyArray won't be used until after boot time
+ allocatorBytes = org.jikesrvm.objectmodel.ObjectModel.bytesRequiredWhenContiguousCopied(from.toObject(), type, elements);
+ }
int align = org.jikesrvm.objectmodel.ObjectModel.getAlignment(type, from.toObject());
int offset = org.jikesrvm.objectmodel.ObjectModel.getOffsetForAlignment(type, from);
Selected.Collector plan = Selected.Collector.get();
- allocator = plan.copyCheckAllocator(from, bytes, align, allocator);
+ allocator = plan.copyCheckAllocator(from, allocatorBytes/*bytes*/, align, allocator);
Address region = MemoryManager.allocateSpace(plan, bytes, align, offset,
allocator, from);
Object toObj = org.jikesrvm.objectmodel.ObjectModel.moveObject(region, from.toObject(), bytes, false, type);
@@ -89,6 +223,10 @@
int dataSize = bytes - org.jikesrvm.objectmodel.ObjectModel.computeHeaderSize(Magic.getObjectType(toObj));
org.jikesrvm.runtime.Memory.sync(to.toAddress(), dataSize);
}
+ //jbs added arraylet. jbs debug - added && to below
+ if (type.isArrayletizable()) {
+ MemoryManager.initializeDanglingPointer(to, elements, type.getLogElementSize());
+ }
return to;
}
diff -r 743a2cc2ed20 -r 058fdc3780ba MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/Scanning.java
--- a/MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/Scanning.java Tue Aug 04 11:04:15 2009 +1000
+++ b/MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/Scanning.java Mon Nov 16 09:21:21 2009 +1100
@@ -12,8 +12,10 @@
*/
package org.jikesrvm.mm.mmtk;
+import org.mmtk.plan.Plan;
import org.mmtk.plan.TraceLocal;
import org.mmtk.plan.TransitiveClosure;
+import org.mmtk.policy.Space;
import org.mmtk.utility.Constants;
import org.jikesrvm.jni.JNIEnvironment;
@@ -21,8 +23,10 @@
import org.jikesrvm.mm.mminterface.Selected;
import org.jikesrvm.mm.mminterface.CollectorThread;
import org.jikesrvm.mm.mminterface.MemoryManagerConstants;
+import org.jikesrvm.mm.mminterface.MemoryManager; //jbs added arraylet
import org.jikesrvm.mm.mminterface.SpecializedScanMethod;
import org.jikesrvm.VM;
+import org.jikesrvm.classloader.RVMArray;
import org.jikesrvm.classloader.RVMClass;
import org.jikesrvm.classloader.RVMType;
import org.jikesrvm.objectmodel.ObjectModel;
@@ -32,6 +36,10 @@
import org.jikesrvm.scheduler.Scheduler;
import org.jikesrvm.scheduler.RVMThread;
import org.jikesrvm.scheduler.greenthreads.GreenScheduler;
+import static org.jikesrvm.SizeConstants.LOG_BYTES_IN_LONG;
+import static org.jikesrvm.SizeConstants.LOG_BYTES_IN_DOUBLE; //jbs added arraylet
+import static org.jikesrvm.SizeConstants.LOG_BYTES_IN_FLOAT; //jbs added arraylet
+import static org.jikesrvm.SizeConstants.LOG_BYTES_IN_CHAR; //jbs added arraylet
import org.vmmagic.unboxed.*;
import org.vmmagic.pragma.*;
@@ -109,9 +117,10 @@
for(int i=0; i < offsets.length; i++) {
trace.processPrecopyEdge(object.toAddress().plus(offsets[i]), false);
}
- } else if (type.isArrayType() && type.asArray().getElementType().isReferenceType()) {
- for(int i=0; i < ObjectModel.getArrayLength(object.toObject()); i++) {
- trace.processPrecopyEdge(object.toAddress().plus(i << LOG_BYTES_IN_ADDRESS), false);
+ } else {
+ if (VM.VerifyAssertions) {
+ // Not required or supported for arrays.
+ VM._assert(false);
}
}
}
@@ -179,11 +188,11 @@
VM.sysWrite(ct.getGCOrdinal()," Old address ");
VM.sysWriteln(ObjectReference.fromObject(thread).toAddress());
}
- Address threadTableSlot = threadTable.toAddress().plus(threadIndex<Simple
instance. */
@Inline
diff -r 743a2cc2ed20 -r 058fdc3780ba MMTk/src/org/mmtk/plan/SimpleMutator.java
--- a/MMTk/src/org/mmtk/plan/SimpleMutator.java Tue Aug 04 11:04:15 2009 +1000
+++ b/MMTk/src/org/mmtk/plan/SimpleMutator.java Mon Nov 16 09:21:21 2009 +1100
@@ -56,12 +56,14 @@
if (phaseId == Simple.PREPARE) {
los.prepare(true);
+ arraylet.prepare(); //jbs added arraylet
VM.memory.collectorPrepareVMSpace();
return;
}
if (phaseId == Simple.RELEASE) {
los.release(true);
+ arraylet.release(); //jbs added arraylet
VM.memory.collectorReleaseVMSpace();
return;
}
diff -r 743a2cc2ed20 -r 058fdc3780ba MMTk/src/org/mmtk/plan/TraceLocal.java
--- a/MMTk/src/org/mmtk/plan/TraceLocal.java Tue Aug 04 11:04:15 2009 +1000
+++ b/MMTk/src/org/mmtk/plan/TraceLocal.java Mon Nov 16 09:21:21 2009 +1100
@@ -12,6 +12,7 @@
*/
package org.mmtk.plan;
+import static org.mmtk.policy.arraylet.ArrayletConstants.ELEMENTS_IN_ARRAYLET;
import org.mmtk.policy.Space;
import org.mmtk.utility.Constants;
import org.mmtk.utility.Log;
@@ -74,6 +75,16 @@
* Internally visible Object processing and tracing
*/
+ //jbs added arraylet
+ @Inline
+ public final void scanArraylet(Address arraylet) {
+ if (!arraylet.isZero()) {
+ for (int i = 0; i < ELEMENTS_IN_ARRAYLET; i++) {
+ processEdge(null, arraylet.plus(Offset.fromIntZeroExtend(i << LOG_BYTES_IN_ADDRESS)));
+ }
+ }
+ }
+
/**
* Trace a reference during GC. This involves determining which
* collection policy applies and calling the appropriate
@@ -183,6 +194,13 @@
*/
@Inline
public final void processNode(ObjectReference object) {
+ //jbs added
+ if (VM.COLLECT_ARRAYLET_STATS) {
+ int objSize = VM.objectModel.getSizeWhenCopied(object); // .getContiguousBytes(object);
+ if (!VM.objectModel.isArray(object)) {
+ SimpleCollector.NUM_GC_BYTES += objSize;
+ }
+ }
values.push(object);
}
@@ -258,6 +276,8 @@
return (Plan.SCAN_BOOT_IMAGE) ? object : Plan.vmSpace.traceObject(this, object);
if (Space.isInSpace(Plan.IMMORTAL, object))
return Plan.immortalSpace.traceObject(this, object);
+ if (Space.isInSpace(Plan.IMMORTAL_UNTRACED, object))
+ return Plan.immortalUntracedSpace.traceObject(this, object);
if (Space.isInSpace(Plan.LOS, object))
return Plan.loSpace.traceObject(this, object);
if (Space.isInSpace(Plan.NON_MOVING, object))
diff -r 743a2cc2ed20 -r 058fdc3780ba MMTk/src/org/mmtk/plan/generational/Gen.java
--- a/MMTk/src/org/mmtk/plan/generational/Gen.java Tue Aug 04 11:04:15 2009 +1000
+++ b/MMTk/src/org/mmtk/plan/generational/Gen.java Mon Nov 16 09:21:21 2009 +1100
@@ -88,7 +88,7 @@
public static final CopySpace nurserySpace = new CopySpace("nursery", DEFAULT_POLL_FREQUENCY, false, vmRequest);
public static final int NURSERY = nurserySpace.getDescriptor();
- private static final Address NURSERY_START = nurserySpace.getStart();
+ public static final Address NURSERY_START = nurserySpace.getStart();
/*****************************************************************************
*
@@ -250,7 +250,10 @@
}
}
-
+ //jbs added
+ if (VM.COLLECT_ARRAYLET_STATS && stressTestGCRequired()) {
+ return true;
+ }
return false;
}
@@ -349,6 +352,18 @@
return inNursery(obj.toAddress());
}
+
+ /**
+ * Return true if the object resides within the nursery
+ *
+ * @param obj The object to be tested
+ * @return true if the object resides within the nursery
+ */
+ @Inline
+ public static boolean inNursery(Object obj) {
+ return inNursery(ObjectReference.fromObject(obj).toAddress());
+ }
+
/**
* @return Does the mature space do copying ?
*/
diff -r 743a2cc2ed20 -r 058fdc3780ba MMTk/src/org/mmtk/plan/generational/GenCollector.java
--- a/MMTk/src/org/mmtk/plan/generational/GenCollector.java Tue Aug 04 11:04:15 2009 +1000
+++ b/MMTk/src/org/mmtk/plan/generational/GenCollector.java Mon Nov 16 09:21:21 2009 +1100
@@ -86,6 +86,7 @@
if (phaseId == Gen.PREPARE) {
los.prepare(true);
+ super.collectionPhase(phaseId, primary); //jbs added arraylet
global().arrayRemsetPool.prepareNonBlocking();
global().remsetPool.prepareNonBlocking();
global().modbufPool.prepareNonBlocking();
@@ -119,6 +120,7 @@
global().remsetPool.reset();
global().modbufPool.reset();
}
+ super.collectionPhase(phaseId, primary); //jbs added arraylet
return;
}
diff -r 743a2cc2ed20 -r 058fdc3780ba MMTk/src/org/mmtk/plan/generational/GenMutator.java
--- a/MMTk/src/org/mmtk/plan/generational/GenMutator.java Tue Aug 04 11:04:15 2009 +1000
+++ b/MMTk/src/org/mmtk/plan/generational/GenMutator.java Mon Nov 16 09:21:21 2009 +1100
@@ -15,6 +15,7 @@
import org.mmtk.plan.*;
import org.mmtk.policy.CopyLocal;
import org.mmtk.policy.Space;
+import org.mmtk.policy.arraylet.ArrayletConstants; //jbs added arraylet
import org.mmtk.utility.deque.*;
import org.mmtk.utility.alloc.Allocator;
import org.mmtk.utility.statistics.Stats;
@@ -168,7 +169,7 @@
modbuf.insert(src);
}
} else {
- if (!Gen.inNursery(slot) && Gen.inNursery(tgt)) {
+ if (!Gen.inNursery(src) && Gen.inNursery(tgt)) {
if (Gen.GATHER_WRITE_BARRIER_STATS) Gen.wbSlow.inc();
remset.insert(slot);
}
@@ -304,6 +305,7 @@
remset.resetLocal();
arrayRemset.resetLocal();
} else {
+ arraylet.prepare();
flushRememberedSets();
}
return;
@@ -312,6 +314,8 @@
if (phaseId == Gen.RELEASE) {
if (global().traceFullHeap()) {
super.collectionPhase(phaseId, primary);
+ } else {
+ arraylet.release();
}
assertRemsetsFlushed();
return;
diff -r 743a2cc2ed20 -r 058fdc3780ba MMTk/src/org/mmtk/plan/generational/marksweep/GenMSCollector.java
--- a/MMTk/src/org/mmtk/plan/generational/marksweep/GenMSCollector.java Tue Aug 04 11:04:15 2009 +1000
+++ b/MMTk/src/org/mmtk/plan/generational/marksweep/GenMSCollector.java Mon Nov 16 09:21:21 2009 +1100
@@ -87,7 +87,6 @@
}
if (allocator == Plan.ALLOC_LOS) {
- if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(Allocator.getMaximumAlignedSize(bytes, align) > Plan.LOS_SIZE_THRESHOLD);
return los.alloc(bytes, align, offset);
} else {
if (VM.VERIFY_ASSERTIONS) {
diff -r 743a2cc2ed20 -r 058fdc3780ba MMTk/src/org/mmtk/policy/ImmortalSpace.java
--- a/MMTk/src/org/mmtk/policy/ImmortalSpace.java Tue Aug 04 11:04:15 2009 +1000
+++ b/MMTk/src/org/mmtk/policy/ImmortalSpace.java Mon Nov 16 09:21:21 2009 +1100
@@ -107,6 +107,12 @@
return true;
}
+ //jbs added arraylet
+ @Inline
+ public boolean markObject(ObjectReference object) {
+ return testAndMark(object, markState);
+ }
+
/**
* Trace a reference to an object under an immortal collection
* policy. If the object is not already marked, enqueue the object
diff -r 743a2cc2ed20 -r 058fdc3780ba MMTk/src/org/mmtk/policy/arraylet/Arraylet.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/MMTk/src/org/mmtk/policy/arraylet/Arraylet.java Mon Nov 16 09:21:21 2009 +1100
@@ -0,0 +1,214 @@
+package org.mmtk.policy.arraylet;
+
+import static org.mmtk.policy.arraylet.ArrayletConstants.ARRAYLETS_IN_CHUNK;
+import static org.mmtk.policy.arraylet.ArrayletConstants.LOG_ARRAYLETS_IN_BLOCK;
+import static org.mmtk.policy.arraylet.ArrayletConstants.ARRAYLETS_IN_BLOCK;
+import static org.mmtk.policy.arraylet.ArrayletConstants.LOG_BYTES_IN_ARRAYLET;
+import static org.mmtk.policy.arraylet.ArrayletConstants.ARRAYLET_MASK;
+import static org.mmtk.policy.arraylet.ArrayletConstants.CHUNK_MASK;
+
+//import org.jikesrvm.mm.mminterface.MemoryManagerConstants;
+import org.mmtk.utility.Constants;
+import org.mmtk.utility.Log;
+import org.mmtk.vm.VM;
+import org.vmmagic.pragma.Inline;
+import org.vmmagic.pragma.Uninterruptible;
+import org.vmmagic.unboxed.Address;
+import org.vmmagic.unboxed.Offset;
+
+/* Written by jbs for Arraylet implementation. Summer 2008 */
+
+@Uninterruptible
+public class Arraylet implements Constants {
+
+ public static Address align(Address ptr) {
+ return ptr.toWord().and(ARRAYLET_MASK.not()).toAddress();
+ }
+
+ public static boolean isAligned(Address address) {
+ return address.EQ(align(address));
+ }
+
+ static int getChunkIndex(Address arraylet) {
+ return arraylet.toWord().and(CHUNK_MASK).rshl(LOG_BYTES_IN_ARRAYLET).toInt();
+ }
+
+ /***************************************************************************
+ * Arraylet marking
+ */
+ static void mark(Address address) {
+ /* if (Block.isUnused(Block.align(address))) {
+ //jbs debug
+ Log.write("In Arraylet mark, arraylet address is "); Log.write(address); Log.writeln();
+
+ }*/
+ if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(!Block.isUnused(Block.align(address)));
+ Address arrayletMark = getMarkAddress(address);
+ if (VM.DO_ANY_TYPES_COW) {
+ byte current = arrayletMark.loadByte();
+
+ /*Log.write(" For address "); Log.write(address);
+ Log.write(" In Arraylet mark, current is "); Log.write(current); Log.writeln();
+ */arrayletMark.store(((byte)(current | ARRAYLET_MARK_VALUE)));
+ } else {
+ arrayletMark.store(ARRAYLET_MARK_VALUE);
+ }
+ }
+
+ public static void addIncomingPointer(Address address) {
+ if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(!Block.isUnused(Block.align(address)));
+ Address arrayletMark = getMarkAddress(address);
+ byte current = arrayletMark.loadByte();
+ byte currCount = (byte)((current & ARRAYLET_INCOMING_PTR_MASK) >> ARRAYLET_INCOMING_PTR_COUNT_SHIFT);
+
+ if (currCount == ((ARRAYLET_INCOMING_PTR_MASK>> ARRAYLET_INCOMING_PTR_COUNT_SHIFT) - 1)) {
+ /*Log.write(" JBS ERROR, we are at highest incoming pointer count for an arraylet possible - could overflow!! BAD. Going to STICK IT! ");
+ Log.writeln();*/
+
+ }
+ if (currCount < (ARRAYLET_INCOMING_PTR_MASK>> ARRAYLET_INCOMING_PTR_COUNT_SHIFT) ) {
+ currCount++;
+ /* if (currCount == (ARRAYLET_INCOMING_PTR_MASK>> ARRAYLET_INCOMING_PTR_COUNT_SHIFT)) {
+ Log.write(" JBS ERROR, we are at highest incoming pointer count for an arraylet possible - could overflow!! BAD. ");
+ //Log.writeln();
+ } else if (currCount > (ARRAYLET_INCOMING_PTR_MASK>> ARRAYLET_INCOMING_PTR_COUNT_SHIFT)) {
+ currCount -=8; //(give it some room to grow)
+ Log.write(" JBS ERROR, we are overflowing incoming pointer count for an arraylet!! BAD. We are subtracting 8. ");
+ //Log.writeln();
+ }*/
+ byte newValue = (byte)((ARRAYLET_MARK_MASK & current) | (currCount << ARRAYLET_INCOMING_PTR_COUNT_SHIFT));
+ /* Log.write(" In Arraylet addIncomingPointer with address "); Log.write(address);
+ Log.write(" and previously byte was "); Log.write(current);
+ Log.write(" and count now is "); Log.write(currCount);
+ Log.write(" and we are going to store to mark byte "); Log.write(newValue);
+ Log.writeln();*/
+ //Log.write(" In Arraylet mark, current is "); Log.write(current); Log.writeln();
+ arrayletMark.store(newValue); /*current | *///ARRAYLET_MARK_VALUE);
+ }/* else {
+
+ Log.writeln("Keeping arraylet incoming pointer count stuck at highest value. ");
+ }*/
+ }
+
+ //currently unused
+ public static void addTwoIncomingPointers(Address address) {
+ if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(!Block.isUnused(Block.align(address)));
+ Address arrayletMark = getMarkAddress(address);
+ byte current = arrayletMark.loadByte();
+ byte currCount = (byte)((current & ARRAYLET_INCOMING_PTR_MASK) >> 3);
+ currCount+=2;
+ if (currCount >= 15) {
+ Log.write(" JBS ERROR, we are at highest incoming pointer count for an arraylet possible - could overflow!! BAD. ");
+ Log.writeln();
+ } byte newValue = (byte)((ARRAYLET_MARK_MASK & current) | (currCount << 3));
+ Log.write(" In Arraylet addTwoIncomingPointers with address "); Log.write(address);
+ Log.write(" and previously byte was "); Log.write(current);
+ Log.write(" and count now is "); Log.write(currCount);
+ Log.write(" and we are going to store to mark byte "); Log.write(newValue);
+ Log.writeln();
+ //Log.write(" In Arraylet mark, current is "); Log.write(current); Log.writeln();
+ arrayletMark.store(newValue); /*current | *///ARRAYLET_MARK_VALUE);
+ }
+
+ public static int subIncomingPointer(Address address) {
+ if (Block.isUnused(Block.align(address))) {
+
+ Log.write("In subIncomingPoitner for address "); Log.write(address);
+ Log.write(" and block seems to be unused.");
+ Address arrayletMark = getMarkAddress(address);
+ byte current = arrayletMark.loadByte();
+ Log.write(" and current mark byte is "); Log.write(current);
+ Log.writeln();
+ }
+ if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(!Block.isUnused(Block.align(address)));
+ Address arrayletMark = getMarkAddress(address);
+ byte current = arrayletMark.loadByte();
+ byte currCount = (byte)((current & ARRAYLET_INCOMING_PTR_MASK) >> ARRAYLET_INCOMING_PTR_COUNT_SHIFT);
+ int toReturn = -1;
+ if (currCount != 0 && currCount != (ARRAYLET_INCOMING_PTR_MASK>> ARRAYLET_INCOMING_PTR_COUNT_SHIFT)) {
+ currCount--;
+ toReturn = (int)currCount;
+
+
+ /*if (currCount >= 15) {
+ Log.write(" JBS ERROR, we are at highest incoming pointer count for an arraylet possible - could overflow!! BAD. ");
+ Log.writeln();
+ } */
+ byte newValue = (byte)((ARRAYLET_MARK_MASK & current) | (currCount << ARRAYLET_INCOMING_PTR_COUNT_SHIFT));
+ /*Log.write(" In Arraylet subIncomingPointer with address "); Log.write(address);
+ Log.write(" and previously byte was "); Log.write(current);
+ Log.write(" and count now is "); Log.write(currCount); Log.write(" and toReturn is "); Log.write(toReturn);
+ Log.write(" and we are going to store to mark byte "); Log.write(newValue);
+ Log.writeln();*/
+ //Log.write(" In Arraylet mark, current is "); Log.write(current); Log.writeln();
+ arrayletMark.store(newValue); /*current | *///ARRAYLET_MARK_VALUE);
+ } else if (currCount == (ARRAYLET_INCOMING_PTR_MASK>> ARRAYLET_INCOMING_PTR_COUNT_SHIFT)) {
+ return currCount;
+ }
+ return toReturn;
+ }
+
+ /***************************************************************************
+ * Scanning through arraylet marks
+ */
+ public static Address getChunkMarkTable(Address chunk) {
+ if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(Chunk.isAligned(chunk));
+ return getMarkAddress(chunk);
+ }
+
+ public static Address getBlockMarkTable(Address block) {
+ if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(Block.isAligned(block));
+ return getMarkAddress(block);
+ }
+
+ @Inline
+ public static int getNextUsed(Address baseArrayletMarkAddress, int arraylet) {
+ return getNext(baseArrayletMarkAddress, arraylet, ARRAYLET_MARK_VALUE);
+ }
+
+ @Inline
+ public static int getNextUnused(Address baseArrayletMarkAddress, int arraylet) {
+ return getNext(baseArrayletMarkAddress, arraylet, ARRAYLET_UNMARKED_VALUE);
+ }
+
+ @Inline
+ private static int getNext(Address baseArrayletMarkAddress, int arraylet, final byte test) {
+ while (arraylet < ARRAYLETS_IN_BLOCK &&
+ //baseArrayletMarkAddress.loadByte(Offset.fromIntZeroExtend(arraylet<from
must have
@@ -241,6 +242,10 @@
*/
/** @return The offset from array reference to element zero */
protected abstract Offset getArrayBaseOffset();
+
+ //jbs added
+ public abstract void printAndResetStats();
+ public abstract void resetHarnessStats();
/*
* NOTE: These methods should not be called by anything other than the
@@ -253,4 +258,16 @@
static Offset arrayBaseOffsetTrapdoor(ObjectModel o) {
return o.getArrayBaseOffset();
}
+ public abstract boolean getCollectArrayletStats();
+ static boolean collectArrayletStatsTrapdoor(ObjectModel o) {
+ return o.getCollectArrayletStats();
+ }
+ public abstract boolean getCollectAccessStats();
+ static boolean collectAccessStatsTrapdoor(ObjectModel o) {
+ return o.getCollectAccessStats();
+ }
+ public abstract boolean getDoAnyTypesCow();
+ static boolean doAnyTypesCowTrapdoor(ObjectModel o) {
+ return o.getDoAnyTypesCow();
+ }
}
diff -r 743a2cc2ed20 -r 058fdc3780ba MMTk/src/org/mmtk/vm/Statistics.java
--- a/MMTk/src/org/mmtk/vm/Statistics.java Tue Aug 04 11:04:15 2009 +1000
+++ b/MMTk/src/org/mmtk/vm/Statistics.java Mon Nov 16 09:21:21 2009 +1100
@@ -23,6 +23,9 @@
*/
public abstract int getCollectionCount();
+ //jbs added arraylet
+ public abstract void printArrayletStatistics();
+
/**
* Read cycle counter
*/
diff -r 743a2cc2ed20 -r 058fdc3780ba MMTk/src/org/mmtk/vm/VM.java
--- a/MMTk/src/org/mmtk/vm/VM.java Tue Aug 04 11:04:15 2009 +1000
+++ b/MMTk/src/org/mmtk/vm/VM.java Mon Nov 16 09:21:21 2009 +1100
@@ -78,6 +78,12 @@
public static final int ALIGNMENT_VALUE;
/** The offset from an array reference to element zero */
public static final Offset ARRAY_BASE_OFFSET;
+ /** The log of the number of elements per arraylet */
+ public static final int LOG_ARRAYLET_ELEMENTS;
+
+ public static final boolean COLLECT_ARRAYLET_STATS;
+ public static final boolean COLLECT_ACCESS_STATS;
+ public static final boolean DO_ANY_TYPES_COW;
/*
* VM-specific functionality captured in a series of singleton classs
@@ -175,6 +181,10 @@
MAX_BYTES_PADDING = Memory.maxBytesPaddingTrapdoor(memory);
ALIGNMENT_VALUE = Memory.alignmentValueTrapdoor(memory);
ARRAY_BASE_OFFSET = ObjectModel.arrayBaseOffsetTrapdoor(objectModel);
+ LOG_ARRAYLET_ELEMENTS = Memory.logArrayletElements(memory);
+ COLLECT_ARRAYLET_STATS = ObjectModel.collectArrayletStatsTrapdoor(objectModel);
+ COLLECT_ACCESS_STATS = ObjectModel.collectAccessStatsTrapdoor(objectModel);
+ DO_ANY_TYPES_COW = ObjectModel.doAnyTypesCowTrapdoor(objectModel);
}
/**
diff -r 743a2cc2ed20 -r 058fdc3780ba build.xml
--- a/build.xml Tue Aug 04 11:04:15 2009 +1000
+++ b/build.xml Mon Nov 16 09:21:21 2009 +1100
@@ -1975,7 +1975,7 @@
false
if it is not
*/
public static boolean instanceOfInterface(RVMClass LHSclass, TIB rhsTIB) {
- int[] doesImplement = rhsTIB.getDoesImplement();
+ WordArray doesImplement = rhsTIB.getDoesImplement();
int idx = LHSclass.getDoesImplementIndex();
int mask = LHSclass.getDoesImplementBitMask();
- return idx < doesImplement.length && ((doesImplement[idx] & mask) != 0);
+ return idx < MemoryManager.nativeIntBufferLength(doesImplement) && ((doesImplement.getInt(idx) & mask) != 0);
}
/**
diff -r 743a2cc2ed20 -r 058fdc3780ba rvm/src/org/jikesrvm/classloader/RVMArray.java
--- a/rvm/src/org/jikesrvm/classloader/RVMArray.java Tue Aug 04 11:04:15 2009 +1000
+++ b/rvm/src/org/jikesrvm/classloader/RVMArray.java Mon Nov 16 09:21:21 2009 +1100
@@ -12,6 +12,8 @@
*/
package org.jikesrvm.classloader;
+import static org.jikesrvm.mm.mminterface.MemoryManagerConstants.*;
+
import org.jikesrvm.ArchitectureSpecific;
import org.jikesrvm.VM;
import org.jikesrvm.Constants;
@@ -23,13 +25,23 @@
import org.jikesrvm.runtime.Memory;
import org.jikesrvm.runtime.RuntimeEntrypoints;
import org.jikesrvm.runtime.Statics;
+import org.jikesrvm.scheduler.Scheduler;
+import org.mmtk.plan.Plan;
+import org.mmtk.plan.generational.Gen;
+import org.mmtk.policy.Space;
+import org.mmtk.policy.arraylet.Arraylet;
import org.vmmagic.pragma.Entrypoint;
import org.vmmagic.pragma.Inline;
import org.vmmagic.pragma.NoInline;
import org.vmmagic.pragma.NonMoving;
import org.vmmagic.pragma.Pure;
import org.vmmagic.pragma.Uninterruptible;
+import org.vmmagic.unboxed.Address;
+import org.vmmagic.unboxed.Extent;
+import org.vmmagic.unboxed.ObjectReference;
import org.vmmagic.unboxed.Offset;
+import org.vmmagic.unboxed.Word;
+import org.vmmagic.unboxed.WordArray;
/**
* Description of a java "array" type.
@@ -938,8 +940,9 @@
public RVMClass[] getAllImplementedInterfaces() {
if (VM.VerifyAssertions) VM._assert(isResolved());
int count = 0;
- int[] doesImplement = getDoesImplement();
- for (int mask : doesImplement) {
+ WordArray doesImplement = getDoesImplement();
+ for (int i=0; i < MemoryManager.nativeIntBufferLength(doesImplement); i++) {
+ int mask = doesImplement.getInt(i);
while (mask != 0) {
count++;
mask &= (mask - 1); // clear lsb 1 bit
@@ -947,8 +950,8 @@
}
if (count == 0) return emptyVMClass;
RVMClass[] ans = new RVMClass[count];
- for (int i = 0, idx = 0; i < doesImplement.length; i++) {
- int mask = doesImplement[i];
+ for (int i = 0, idx = 0; i < MemoryManager.nativeIntBufferLength(doesImplement); i++) {
+ int mask = doesImplement.getInt(i);
if (mask != 0) {
for (int j = 0; j < 32; j++) {
if ((mask & (1 << j)) != 0) {
@@ -1224,6 +1227,12 @@
*/
static RVMClass readClass(TypeReference typeRef, DataInputStream input) throws ClassFormatError, IOException {
+ //jbs debugging
+ /*if (VM.runningVM) {
+ VM.sysWrite("In RVMClass readClass, input address is "); VM.sysWrite(Magic.objectAsAddress(input.buf));
+ VM.sysWriteln();
+ //Scheduler.dumpStack();
+ }*/
if (classLoadingDisabled) {
throw new RuntimeException("ClassLoading Disabled : " + typeRef);
}
@@ -1881,7 +1890,7 @@
* @param doesImplement The calculated does implement array
*/
@Uninterruptible
- private void publishResolved(TIB allocatedTib, short[] superclassIds, int[] doesImplement) {
+ private void publishResolved(TIB allocatedTib, WordArray superclassIds, WordArray doesImplement) {
Statics.setSlotContents(getTibOffset(), allocatedTib);
allocatedTib.setType(this);
allocatedTib.setSuperclassIds(superclassIds);
diff -r 743a2cc2ed20 -r 058fdc3780ba rvm/src/org/jikesrvm/classloader/RVMClassLoader.java
--- a/rvm/src/org/jikesrvm/classloader/RVMClassLoader.java Tue Aug 04 11:04:15 2009 +1000
+++ b/rvm/src/org/jikesrvm/classloader/RVMClassLoader.java Mon Nov 16 09:21:21 2009 +1100
@@ -230,6 +230,7 @@
// Names of special methods.
//
+ public static final Atom HackArrayMethodName = Atom.findOrCreateAsciiAtom("hackArrayLoadReadBarrier");
/** " src != dst || (scrPos >= dstPos + 4)
+ * and src and dst are 8Bit arrays.
+ * @param srcAddr the source address
+ * @param srcPos index in the source array to begin copy
+ * @param dstAddr the destination address
+ * @param dstPos index in the destination array to being copy
+ * @param len number of array elements to copy
+ */
+ public static void arraycopy8Bit(Address srcAddr, int srcPos, Address dstAddr, int dstPos, int len) {
if (USE_NATIVE && len > NATIVE_THRESHOLD) {
- memcopy(Magic.objectAsAddress(dst).plus(dstPos), Magic.objectAsAddress(src).plus(srcPos), len);
+ memcopy(dstAddr.plus(dstPos), srcAddr.plus(srcPos), len);
} else {
if (len >= BYTES_IN_COPY && (srcPos & (BYTES_IN_COPY - 1)) == (dstPos & (BYTES_IN_COPY - 1))) {
// relative alignment is the same
- Address srcPtr = Magic.objectAsAddress(src).plus(srcPos);
- Address dstPtr = Magic.objectAsAddress(dst).plus(dstPos);
+ Address srcPtr = srcAddr.plus(srcPos);
+ Address dstPtr = dstAddr.plus(dstPos);
Address endPtr = srcPtr.plus(len);
Address wordEndPtr = endPtr.toWord().and(Word.fromIntZeroExtend(BYTES_IN_COPY-1).not()).toAddress();
@@ -167,8 +197,8 @@
}
}
} else {
- Address srcPtr = Magic.objectAsAddress(src).plus(srcPos);
- Address dstPtr = Magic.objectAsAddress(dst).plus(dstPos);
+ Address srcPtr = srcAddr.plus(srcPos);
+ Address dstPtr = dstAddr.plus(dstPos);
Address endPtr = srcPtr.plus(len);
while (srcPtr.LT(endPtr)) {
dstPtr.store(srcPtr.loadByte());
@@ -191,17 +221,32 @@
* @param len number of array elements to copy
*/
public static void arraycopy16Bit(Object src, int srcPos, Object dst, int dstPos, int len) {
+ arraycopy16Bit(Magic.objectAsAddress(src), srcPos, Magic.objectAsAddress(dst), dstPos, len);
+ }
+
+ /**
+ * Low level copy of len elements from src[srcPos] to dst[dstPos].
+ *
+ * Assumption src != dst || (srcPos >= dstPos + 2).
+ *
+ * @param srcAddr the source address
+ * @param srcPos index in the source array to begin copy
+ * @param dstAddr the destination address
+ * @param dstPos index in the destination array to being copy
+ * @param len number of array elements to copy
+ */
+ public static void arraycopy16Bit(Address srcAddr, int srcPos, Address dstAddr, int dstPos, int len) {
if (USE_NATIVE && len > (NATIVE_THRESHOLD >> LOG_BYTES_IN_SHORT)) {
- memcopy(Magic.objectAsAddress(dst).plus(dstPos << LOG_BYTES_IN_SHORT),
- Magic.objectAsAddress(src).plus(srcPos << LOG_BYTES_IN_SHORT),
+ memcopy(dstAddr.plus(dstPos << LOG_BYTES_IN_SHORT),
+ srcAddr.plus(srcPos << LOG_BYTES_IN_SHORT),
len << LOG_BYTES_IN_SHORT);
} else {
if (len >= (BYTES_IN_COPY >>> LOG_BYTES_IN_SHORT) &&
(srcPos & ((BYTES_IN_COPY - 1) >>> LOG_BYTES_IN_SHORT)) ==
(dstPos & ((BYTES_IN_COPY - 1) >>> LOG_BYTES_IN_SHORT))) {
// relative alignment is the same
- Address srcPtr = Magic.objectAsAddress(src).plus(srcPos << LOG_BYTES_IN_SHORT);
- Address dstPtr = Magic.objectAsAddress(dst).plus(dstPos << LOG_BYTES_IN_SHORT);
+ Address srcPtr = srcAddr.plus(srcPos << LOG_BYTES_IN_SHORT);
+ Address dstPtr = dstAddr.plus(dstPos << LOG_BYTES_IN_SHORT);
Address endPtr = srcPtr.plus(len << LOG_BYTES_IN_SHORT);
Address wordEndPtr = endPtr.toWord().and(Word.fromIntZeroExtend(BYTES_IN_COPY-1).not()).toAddress();
@@ -248,8 +293,8 @@
}
}
} else {
- Address srcPtr = Magic.objectAsAddress(src).plus(srcPos << LOG_BYTES_IN_SHORT);
- Address dstPtr = Magic.objectAsAddress(dst).plus(dstPos << LOG_BYTES_IN_SHORT);
+ Address srcPtr = srcAddr.plus(srcPos << LOG_BYTES_IN_SHORT);
+ Address dstPtr = dstAddr.plus(dstPos << LOG_BYTES_IN_SHORT);
Address endPtr = srcPtr.plus(len << LOG_BYTES_IN_SHORT);
while (srcPtr.LT(endPtr)) {
copy2Bytes(dstPtr, srcPtr);
@@ -266,14 +311,29 @@
* Assumption: src != dst || (srcPos >= dstPos)
and element size is 4 bytes.
*
* @param src the source array
- * @param srcIdx index in the source array to begin copy
+ * @param srcPos index in the source array to begin copy
* @param dst the destination array
- * @param dstIdx index in the destination array to being copy
+ * @param dstPos index in the destination array to being copy
* @param len number of array elements to copy
*/
- public static void arraycopy32Bit(Object src, int srcIdx, Object dst, int dstIdx, int len) {
- Address srcPtr = Magic.objectAsAddress(src).plus(srcIdx << LOG_BYTES_IN_INT);
- Address dstPtr = Magic.objectAsAddress(dst).plus(dstIdx << LOG_BYTES_IN_INT);
+ public static void arraycopy32Bit(Object src, int srcPos, Object dst, int dstPos, int len) {
+ arraycopy32Bit(Magic.objectAsAddress(src), srcPos, Magic.objectAsAddress(dst), dstPos, len);
+ }
+
+ /**
+ * Low level copy of len
elements from src[srcPos]
to dst[dstPos]
.
+ *
+ * Assumption: src != dst || (srcPos >= dstPos)
and element size is 4 bytes.
+ *
+ * @param srcAddr the source address
+ * @param srcPos index in the source array to begin copy
+ * @param dstAddr the destination address
+ * @param dstPos index in the destination array to being copy
+ * @param len number of array elements to copy
+ */
+ public static void arraycopy32Bit(Address srcAddr, int srcPos, Address dstAddr, int dstPos, int len) {
+ Address srcPtr = srcAddr.plus(srcPos << LOG_BYTES_IN_INT);
+ Address dstPtr = dstAddr.plus(dstPos << LOG_BYTES_IN_INT);
int copyBytes = len << LOG_BYTES_IN_INT;
if (USE_NATIVE && len > (NATIVE_THRESHOLD >> LOG_BYTES_IN_INT)) {
memcopy(dstPtr, srcPtr, copyBytes);
@@ -297,14 +357,29 @@
* Assumption src != dst || (srcPos >= dstPos)
and element size is 8 bytes.
*
* @param src the source array
+ * @param srcPos index in the source array to begin copy
+ * @param dst the destination array
+ * @param dstPos index in the destination array to being copy
+ * @param len number of array elements to copy
+ */
+ public static void arraycopy64Bit(Object src, int srcPos, Object dst, int dstPos, int len) {
+ arraycopy64Bit(Magic.objectAsAddress(src), srcPos, Magic.objectAsAddress(dst), dstPos, len);
+ }
+
+ /**
+ * Low level copy of len
elements from src[srcPos]
to dst[dstPos]
.
+ *
+ * Assumption src != dst || (srcPos >= dstPos)
and element size is 8 bytes.
+ *
+ * @param srcAddr the source address
* @param srcIdx index in the source array to begin copy
- * @param dst the destination array
+ * @param dstAddr the destination address
* @param dstIdx index in the destination array to being copy
* @param len number of array elements to copy
*/
- public static void arraycopy64Bit(Object src, int srcIdx, Object dst, int dstIdx, int len) {
- Address srcPtr = Magic.objectAsAddress(src).plus(srcIdx << LOG_BYTES_IN_DOUBLE);
- Address dstPtr = Magic.objectAsAddress(dst).plus(dstIdx << LOG_BYTES_IN_DOUBLE);
+ public static void arraycopy64Bit(Address srcAddr, int srcPos, Address dstAddr, int dstPos, int len) {
+ Address srcPtr = srcAddr.plus(srcPos << LOG_BYTES_IN_DOUBLE);
+ Address dstPtr = dstAddr.plus(dstPos << LOG_BYTES_IN_DOUBLE);
int copyBytes = len << LOG_BYTES_IN_DOUBLE;
if (USE_NATIVE && len > (NATIVE_THRESHOLD >> LOG_BYTES_IN_DOUBLE)) {
memcopy(dstPtr, srcPtr, copyBytes);
@@ -321,6 +396,575 @@
}
/**
+ * Is this array in a native (contiguous) format?
+ */
+ public static boolean isNativeFormat(byte[] array) {
+ return !MemoryManagerConstants.USE_PRIMITIVE_BYTE_ARRAYLETS;
+ }
+
+ /**
+ * Is this array in a native (contiguous) format?
+ */
+ public static boolean isNativeFormat(boolean[] array) {
+ return !MemoryManagerConstants.USE_PRIMITIVE_BOOLEAN_ARRAYLETS;
+ }
+
+ /**
+ * Is this array in a native (contiguous) format?
+ */
+ public static boolean isNativeFormat(char[] array) {
+ return !MemoryManagerConstants.USE_PRIMITIVE_CHAR_ARRAYLETS;
+ }
+
+ /**
+ * Is this array in a native (contiguous) format?
+ */
+ public static boolean isNativeFormat(short[] array) {
+ return !MemoryManagerConstants.USE_PRIMITIVE_SHORT_ARRAYLETS;
+ }
+
+ /**
+ * Is this array in a native (contiguous) format?
+ */
+ public static boolean isNativeFormat(int[] array) {
+ return !MemoryManagerConstants.USE_PRIMITIVE_INT_ARRAYLETS;
+ }
+
+ /**
+ * Is this array in a native (contiguous) format?
+ */
+ public static boolean isNativeFormat(float[] array) {
+ return !MemoryManagerConstants.USE_PRIMITIVE_FLOAT_ARRAYLETS;
+ }
+
+ /**
+ * Is this array in a native (contiguous) format?
+ */
+ public static boolean isNativeFormat(long[] array) {
+ return !MemoryManagerConstants.USE_PRIMITIVE_LONG_ARRAYLETS;
+ }
+
+ /**
+ * Is this array in a native (contiguous) format?
+ */
+ public static boolean isNativeFormat(double[] array) {
+ return !MemoryManagerConstants.USE_PRIMITIVE_DOUBLE_ARRAYLETS;
+ }
+
+ /**
+ * Marshal between a native buffer and Java array.
+ */
+ public static void nativeMarshal(WordArray src, byte[] dst) {
+ nativeMarshal(Magic.objectAsAddress(src), 0, dst, 0, dst.length);
+ }
+
+ /**
+ * Marshal between a native buffer and Java array.
+ */
+ public static void nativeMarshal(byte[] src, WordArray dst) {
+ nativeMarshal(src, 0, Magic.objectAsAddress(dst), 0, src.length);
+ }
+
+ /**
+ * Marshal between a native buffer and Java array.
+ */
+ public static void nativeMarshal(WordArray src, boolean[] dst) {
+ nativeMarshal(Magic.objectAsAddress(src), 0, dst, 0, dst.length);
+ }
+
+ /**
+ * Marshal between a native buffer and Java array.
+ */
+ public static void nativeMarshal(boolean[] src, WordArray dst) {
+ nativeMarshal(src, 0, Magic.objectAsAddress(dst), 0, src.length);
+ }
+
+ /**
+ * Marshal between a native buffer and Java array.
+ */
+ public static void nativeMarshal(WordArray src, short[] dst) {
+ nativeMarshal(Magic.objectAsAddress(src), 0, dst, 0, dst.length);
+ }
+
+ /**
+ * Marshal between a native buffer and Java array.
+ */
+ public static void nativeMarshal(short[] src, WordArray dst) {
+ nativeMarshal(src, 0, Magic.objectAsAddress(dst), 0, src.length);
+ }
+
+ /**
+ * Marshal between a native buffer and Java array.
+ */
+ public static void nativeMarshal(WordArray src, char[] dst) {
+ nativeMarshal(Magic.objectAsAddress(src), 0, dst, 0, dst.length);
+ }
+
+ /**
+ * Marshal between a native buffer and Java array.
+ */
+ public static void nativeMarshal(char[] src, WordArray dst) {
+ nativeMarshal(src, 0, Magic.objectAsAddress(dst), 0, src.length);
+ }
+
+ /**
+ * Marshal between a native buffer and Java array.
+ */
+ public static void nativeMarshal(WordArray src, int[] dst) {
+ nativeMarshal(Magic.objectAsAddress(src), 0, dst, 0, dst.length);
+ }
+
+ /**
+ * Marshal between a native buffer and Java array.
+ */
+ public static void nativeMarshal(int[] src, WordArray dst) {
+ nativeMarshal(src, 0, Magic.objectAsAddress(dst), 0, src.length);
+ }
+
+ /**
+ * Marshal between a native buffer and Java array.
+ */
+ public static void nativeMarshal(WordArray src, float[] dst) {
+ nativeMarshal(Magic.objectAsAddress(src), 0, dst, 0, dst.length);
+ }
+
+ /**
+ * Marshal between a native buffer and Java array.
+ */
+ public static void nativeMarshal(float[] src, WordArray dst) {
+ nativeMarshal(src, 0, Magic.objectAsAddress(dst), 0, src.length);
+ }
+
+ /**
+ * Marshal between a native buffer and Java array.
+ */
+ public static void nativeMarshal(WordArray src, long[] dst) {
+ nativeMarshal(Magic.objectAsAddress(src), 0, dst, 0, dst.length);
+ }
+
+ /**
+ * Marshal between a native buffer and Java array.
+ */
+ public static void nativeMarshal(long[] src, WordArray dst) {
+ nativeMarshal(src, 0, Magic.objectAsAddress(dst), 0, src.length);
+ }
+
+ /**
+ * Marshal between a native buffer and Java array.
+ */
+ public static void nativeMarshal(WordArray src, double[] dst) {
+ nativeMarshal(Magic.objectAsAddress(src), 0, dst, 0, dst.length);
+ }
+
+ /**
+ * Marshal between a native buffer and Java array.
+ */
+ public static void nativeMarshal(double[] src, WordArray dst) {
+ nativeMarshal(src, 0, Magic.objectAsAddress(dst), 0, src.length);
+ }
+
+ /**
+ * Marshal between a native buffer and Java array.
+ */
+ public static void nativeMarshal(WordArray src, int srcPos, byte[] dst, int dstPos, int len) {
+ nativeMarshal(Magic.objectAsAddress(src), srcPos, dst, dstPos, len);
+ }
+
+ /**
+ * Marshal between a native buffer and Java array.
+ */
+ public static void nativeMarshal(byte[] src, int srcPos, WordArray dst, int dstPos, int len) {
+ nativeMarshal(src, srcPos, Magic.objectAsAddress(dst), dstPos, len);
+ }
+
+
+ /**
+ * Marshal between a native buffer and Java array.
+ */
+ public static void nativeMarshal(WordArray src, int srcPos, boolean[] dst, int dstPos, int len) {
+ nativeMarshal(Magic.objectAsAddress(src), srcPos, dst, dstPos, len);
+ }
+
+ /**
+ * Marshal between a native buffer and Java array.
+ */
+ public static void nativeMarshal(boolean[] src, int srcPos, WordArray dst, int dstPos, int len) {
+ nativeMarshal(src, srcPos, Magic.objectAsAddress(dst), dstPos, len);
+ }
+
+ /**
+ * Marshal between a native buffer and Java array.
+ */
+ public static void nativeMarshal(WordArray src, int srcPos, short[] dst, int dstPos, int len) {
+ nativeMarshal(Magic.objectAsAddress(src), srcPos, dst, dstPos, len);
+ }
+
+ /**
+ * Marshal between a native buffer and Java array.
+ */
+ public static void nativeMarshal(short[] src, int srcPos, WordArray dst, int dstPos, int len) {
+ nativeMarshal(src, srcPos, Magic.objectAsAddress(dst), dstPos, len);
+ }
+
+ /**
+ * Marshal between a native buffer and Java array.
+ */
+ public static void nativeMarshal(WordArray src, int srcPos, char[] dst, int dstPos, int len) {
+ nativeMarshal(Magic.objectAsAddress(src), srcPos, dst, dstPos, len);
+ }
+
+ /**
+ * Marshal between a native buffer and Java array.
+ */
+ public static void nativeMarshal(char[] src, int srcPos, WordArray dst, int dstPos, int len) {
+ nativeMarshal(src, srcPos, Magic.objectAsAddress(dst), dstPos, len);
+ }
+
+ /**
+ * Marshal between a native buffer and Java array.
+ */
+ public static void nativeMarshal(WordArray src, int srcPos, int[] dst, int dstPos, int len) {
+ nativeMarshal(Magic.objectAsAddress(src), srcPos, dst, dstPos, len);
+ }
+
+ /**
+ * Marshal between a native buffer and Java array.
+ */
+ public static void nativeMarshal(int[] src, int srcPos, WordArray dst, int dstPos, int len) {
+ nativeMarshal(src, srcPos, Magic.objectAsAddress(dst), dstPos, len);
+ }
+
+ /**
+ * Marshal between a native buffer and Java array.
+ */
+ public static void nativeMarshal(WordArray src, int srcPos, float[] dst, int dstPos, int len) {
+ nativeMarshal(Magic.objectAsAddress(src), srcPos, dst, dstPos, len);
+ }
+
+ /**
+ * Marshal between a native buffer and Java array.
+ */
+ public static void nativeMarshal(float[] src, int srcPos, WordArray dst, int dstPos, int len) {
+ nativeMarshal(src, srcPos, Magic.objectAsAddress(dst), dstPos, len);
+ }
+
+ /**
+ * Marshal between a native buffer and Java array.
+ */
+ public static void nativeMarshal(WordArray src, int srcPos, long[] dst, int dstPos, int len) {
+ nativeMarshal(Magic.objectAsAddress(src), srcPos, dst, dstPos, len);
+ }
+
+ /**
+ * Marshal between a native buffer and Java array.
+ */
+ public static void nativeMarshal(long[] src, int srcPos, WordArray dst, int dstPos, int len) {
+ nativeMarshal(src, srcPos, Magic.objectAsAddress(dst), dstPos, len);
+ }
+
+ /**
+ * Marshal between a native buffer and Java array.
+ */
+ public static void nativeMarshal(WordArray src, int srcPos, double[] dst, int dstPos, int len) {
+ nativeMarshal(Magic.objectAsAddress(src), srcPos, dst, dstPos, len);
+ }
+
+ /**
+ * Marshal between a native buffer and Java array.
+ */
+ public static void nativeMarshal(double[] src, int srcPos, WordArray dst, int dstPos, int len) {
+ nativeMarshal(src, srcPos, Magic.objectAsAddress(dst), dstPos, len);
+ }
+
+ /**
+ * Marshal between a native buffer and Java array.
+ */
+ public static void nativeMarshal(Address src, byte[] dst) {
+ nativeMarshal(src, 0, dst, 0, dst.length);
+ }
+
+ /**
+ * Marshal between a native buffer and Java array.
+ */
+ public static void nativeMarshal(byte[] src, Address dst) {
+ nativeMarshal(src, 0, dst, 0, src.length);
+ }
+
+ /**
+ * Marshal between a native buffer and Java array.
+ */
+ public static void nativeMarshal(Address src, boolean[] dst) {
+ nativeMarshal(src, 0, dst, 0, dst.length);
+ }
+
+ /**
+ * Marshal between a native buffer and Java array.
+ */
+ public static void nativeMarshal(boolean[] src, Address dst) {
+ nativeMarshal(src, 0, dst, 0, src.length);
+ }
+
+ /**
+ * Marshal between a native buffer and Java array.
+ */
+ public static void nativeMarshal(Address src, short[] dst) {
+ nativeMarshal(src, 0, dst, 0, dst.length);
+ }
+
+ /**
+ * Marshal between a native buffer and Java array.
+ */
+ public static void nativeMarshal(short[] src, Address dst) {
+ nativeMarshal(src, 0, dst, 0, src.length);
+ }
+
+ /**
+ * Marshal between a native buffer and Java array.
+ */
+ public static void nativeMarshal(Address src, char[] dst) {
+ nativeMarshal(src, 0, dst, 0, dst.length);
+ }
+
+ /**
+ * Marshal between a native buffer and Java array.
+ */
+ public static void nativeMarshal(char[] src, Address dst) {
+ nativeMarshal(src, 0, dst, 0, src.length);
+ }
+
+ /**
+ * Marshal between a native buffer and Java array.
+ */
+ public static void nativeMarshal(Address src, int[] dst) {
+ nativeMarshal(src, 0, dst, 0, dst.length);
+ }
+
+ /**
+ * Marshal between a native buffer and Java array.
+ */
+ public static void nativeMarshal(int[] src, Address dst) {
+ nativeMarshal(src, 0, dst, 0, src.length);
+ }
+
+ /**
+ * Marshal between a native buffer and Java array.
+ */
+ public static void nativeMarshal(Address src, float[] dst) {
+ nativeMarshal(src, 0, dst, 0, dst.length);
+ }
+
+ /**
+ * Marshal between a native buffer and Java array.
+ */
+ public static void nativeMarshal(float[] src, Address dst) {
+ nativeMarshal(src, 0, dst, 0, src.length);
+ }
+
+ /**
+ * Marshal between a native buffer and Java array.
+ */
+ public static void nativeMarshal(Address src, long[] dst) {
+ nativeMarshal(src, 0, dst, 0, dst.length);
+ }
+
+ /**
+ * Marshal between a native buffer and Java array.
+ */
+ public static void nativeMarshal(long[] src, Address dst) {
+ nativeMarshal(src, 0, dst, 0, src.length);
+ }
+
+ /**
+ * Marshal between a native buffer and Java array.
+ */
+ public static void nativeMarshal(Address src, double[] dst) {
+ nativeMarshal(src, 0, dst, 0, dst.length);
+ }
+
+ /**
+ * Marshal between a native buffer and Java array.
+ */
+ public static void nativeMarshal(double[] src, Address dst) {
+ nativeMarshal(src, 0, dst, 0, src.length);
+ }
+
+ /**
+ * Marshal between a native buffer and Java array.
+ */
+ public static void nativeMarshal(Address src, int srcPos, byte[] dst, int dstPos, int len) {
+ if (USE_PRIMITIVE_BYTE_ARRAYLETS) {
+ for (int idx = 0; idx < len; idx++)
+ dst[dstPos + idx] = src.loadByte(Offset.fromIntZeroExtend(srcPos + idx));
+ } else
+ arraycopy8Bit(src, srcPos, Magic.objectAsAddress(dst), dstPos, len);
+ }
+
+ /**
+ * Marshal between a native buffer and Java array.
+ */
+ public static void nativeMarshal(byte[] src, int srcPos, Address dst, int dstPos, int len) {
+ if (USE_PRIMITIVE_BYTE_ARRAYLETS) {
+ for (int idx = 0; idx < len; idx++)
+ dst.store(src[srcPos + idx], Offset.fromIntZeroExtend(dstPos + idx));
+ } else
+ arraycopy8Bit(Magic.objectAsAddress(src), srcPos, dst, dstPos, len);
+ }
+
+ /**
+ * Marshal between a native buffer and Java array.
+ */
+ public static void nativeMarshal(Address src, int srcPos, boolean[] dst, int dstPos, int len) {
+ if (USE_PRIMITIVE_BOOLEAN_ARRAYLETS) {
+ for (int idx = 0; idx < len; idx++)
+ dst[dstPos + idx] = src.loadByte(Offset.fromIntZeroExtend(srcPos + idx)) == 1;
+ } else
+ arraycopy8Bit(src, srcPos, Magic.objectAsAddress(dst), dstPos, len);
+ }
+
+ /**
+ * Marshal between a native buffer and Java array.
+ */
+ public static void nativeMarshal(boolean[] src, int srcPos, Address dst, int dstPos, int len) {
+ if (USE_PRIMITIVE_BOOLEAN_ARRAYLETS) {
+ for (int idx = 0; idx < len; idx++)
+ dst.store((byte) (src[srcPos + idx] ? 1 : 0), Offset.fromIntZeroExtend(dstPos + idx));
+ } else
+ arraycopy8Bit(Magic.objectAsAddress(src), srcPos, dst, dstPos, len);
+ }
+
+ /**
+ * Marshal between a native buffer and Java array.
+ */
+ public static void nativeMarshal(Address src, int srcPos, short[] dst, int dstPos, int len) {
+ if (USE_PRIMITIVE_SHORT_ARRAYLETS) {
+ for (int idx = 0; idx < len; idx++)
+ dst[dstPos + idx] = src.loadShort(Offset.fromIntZeroExtend((srcPos + idx)<