diff --git a/JavaInJava/src/com/sun/max/annotate/FOLD.java b/JavaInJava/src/com/sun/max/annotate/FOLD.java
new file mode 100644
index 0000000..820dab8
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/annotate/FOLD.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.annotate;
+import java.lang.annotation.*;
+
+/**
+ * Every thus annotated method must must have no arguments (apart from a receiver for a non-static method).
+ * It must also be purely functional (without side-effects)
+ * and idempotent (not influenced by any changing state).
+ *
+ * If the method is static, it is to be meta-evaluated unconditionally by the CPS compiler.
+ * If the method is non-static, it will be meta-evaluated whenever its receiver is known at compile time.
+ *
+ * @author Bernd Mathiske
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface FOLD {
+}
diff --git a/JavaInJava/src/com/sun/max/annotate/UNSAFE.java b/JavaInJava/src/com/sun/max/annotate/UNSAFE.java
new file mode 100644
index 0000000..239a322
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/annotate/UNSAFE.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.annotate;
+
+import java.lang.annotation.*;
+
+/**
+ * Methods with this annotation must be compiled with the bootstrap compiler, not the JIT.
+ * Neither can they be interpreted.
+ *
+ * This is the case when a method uses values of type {@link Word} or
+ * any constant folding or dead code elimination must take place
+ * before the code makes sense in the target VM.
+ *
+ * Most of these methods are recognized automatically.
+ * Only those not captured during {@linkplain Intrinsics#run() intrinsification}
+ * need to be annotated.
+ *
+ * Some other annotations imply UNSAFE:
+ *
+ * - {@link BUILTIN}
+ * - {@link C_FUNCTION}
+ * - {@link VM_ENTRY_POINT}
+ * - {@link ACCESSOR}
+ * - {@link SUBSTITUTE}: the substitutee is unsafe
+ * - {@link LOCAL_SUBSTITUTION}: the substitutee is unsafe
+ *
+ *
+ * However, some must be pointed out manually with this annotation.
+ *
+ * @see ClassfileReader
+ *
+ * @author Bernd Mathiske
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD, ElementType.CONSTRUCTOR})
+public @interface UNSAFE {
+}
diff --git a/JavaInJava/src/com/sun/max/lang/DataModel.java b/JavaInJava/src/com/sun/max/lang/DataModel.java
new file mode 100644
index 0000000..cdc0052
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/lang/DataModel.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.lang;
+
+import java.io.*;
+
+import com.sun.max.program.*;
+import com.sun.max.unsafe.*;
+import com.sun.max.vm.compiler.builtin.*;
+import com.sun.max.vm.value.*;
+
+public class DataModel {
+
+ public final WordWidth wordWidth;
+ public final Endianness endianness;
+ public final int cacheAlignment;
+
+ public DataModel(WordWidth wordWidth, Endianness endianness, int cacheAlignment) {
+ this.wordWidth = wordWidth;
+ this.endianness = endianness;
+ this.cacheAlignment = cacheAlignment;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (!(other instanceof DataModel)) {
+ return false;
+ }
+ final DataModel dataModel = (DataModel) other;
+ return wordWidth.equals(dataModel.wordWidth) && endianness.equals(dataModel.endianness) && cacheAlignment == dataModel.cacheAlignment;
+ }
+
+ public byte[] toBytes(byte value) {
+ return endianness.toBytes(value);
+ }
+
+ public byte[] toBytes(boolean value) {
+ final byte[] result = new byte[1];
+ result[0] = value ? (byte) 1 : (byte) 0;
+ return result;
+ }
+
+ public byte[] toBytes(short value) {
+ return endianness.toBytes(value);
+ }
+
+ public byte[] toBytes(char value) {
+ final short shortValue = UnsafeCast.asShort(value);
+ return endianness.toBytes(shortValue);
+ }
+
+ public byte[] toBytes(int value) {
+ return endianness.toBytes(value);
+ }
+
+ public byte[] toBytes(float value) {
+ final int intValue = SpecialBuiltin.floatToInt(value);
+ return endianness.toBytes(intValue);
+ }
+
+ public byte[] toBytes(long value) {
+ return endianness.toBytes(value);
+ }
+
+ public byte[] toBytes(double value) {
+ final long longValue = SpecialBuiltin.doubleToLong(value);
+ return endianness.toBytes(longValue);
+ }
+
+ public byte[] toBytes(Word value) {
+ switch (wordWidth) {
+ case BITS_64:
+ return toBytes(value.asOffset().toLong());
+ case BITS_32:
+ return toBytes((int) value.asOffset().toLong());
+ case BITS_16:
+ return toBytes((short) value.asOffset().toLong());
+ case BITS_8:
+ return toBytes((byte) value.asOffset().toLong());
+ }
+ ProgramError.unknownCase();
+ return null;
+ }
+
+ public void write(OutputStream stream, Value value) throws IOException {
+ stream.write(value.toBytes(this));
+ }
+
+ @Override
+ public String toString() {
+ return wordWidth + "-bit, " + endianness + " endian, " + cacheAlignment + "-byte aligned cache";
+ }
+}
diff --git a/JavaInJava/src/com/sun/max/lang/Objects.java b/JavaInJava/src/com/sun/max/lang/Objects.java
new file mode 100644
index 0000000..3337422
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/lang/Objects.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.lang;
+
+import static com.sun.max.unsafe.WithoutAccessCheck.*;
+
+import java.lang.reflect.*;
+
+import com.sun.max.*;
+import com.sun.max.program.*;
+
+/**
+ * Basic generic utilities for objects.
+ *
+ * @author Bernd Mathiske
+ * @author Doug Simon
+ */
+public final class Objects {
+
+ private Objects() {
+ }
+
+ /**
+ * Compares two given objects for equality using {@link Object#equals(Object)}.
+ *
+ * @return true if both {@code o1} and {@code o2} are {@code null} || {@code o1.equals(o2)}
+ */
+ public static boolean equal(Object o1, Object o2) {
+ return o1 == null ? o2 == null : o1.equals(o2);
+ }
+
+ /**
+ * Copies the values of the instance fields in one object to another object.
+ *
+ * @param fromObject the object from which the field values are to be copied
+ * @param toObject the object to which the field values are to be copied
+ */
+ public static void copy(Object fromObject, Object toObject) {
+ assert fromObject.getClass() == toObject.getClass();
+ Class c = fromObject.getClass();
+ while (c != null) {
+ for (Field field : c.getDeclaredFields()) {
+ if ((field.getModifiers() & Modifier.STATIC) == 0) {
+ field.setAccessible(true);
+ try {
+ final Object value = field.get(fromObject);
+ field.set(toObject, value);
+ } catch (IllegalArgumentException illegalArgumentException) {
+ // This should never occur
+ throw ProgramError.unexpected(illegalArgumentException);
+ } catch (IllegalAccessException illegalAccessException) {
+ // This should never occur
+ throw ProgramError.unexpected(illegalAccessException);
+ }
+ }
+ }
+ c = c.getSuperclass();
+ }
+ }
+
+ /**
+ * Creates a new instance of a given class without calling any constructors. This call also ensures that {@code javaClass}
+ * has been initialized.
+ *
+ * @param javaClass the class to construct an instance of
+ * @return an uninitialized of {@code javaClass}
+ * @throws InstantiationException if the instantiation fails for any of the reasons described
+ * {@linkplain InstantiationException here}
+ */
+ public static Object allocateInstance(Class> javaClass) throws InstantiationException {
+ unsafe.ensureClassInitialized(javaClass);
+ return unsafe.allocateInstance(javaClass);
+ }
+
+ public static T allocateObject(Class javaClass) throws InstantiationException, NoSuchMethodException, IllegalAccessException, InvocationTargetException {
+ final Constructor constructor = javaClass.getDeclaredConstructor();
+ constructor.setAccessible(true);
+ final Object object = constructor.newInstance();
+ return Utils.cast(javaClass, object);
+ }
+}
diff --git a/JavaInJava/src/com/sun/max/lang/Unsigned.java b/JavaInJava/src/com/sun/max/lang/Unsigned.java
new file mode 100644
index 0000000..3fa0bec
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/lang/Unsigned.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.lang;
+
+import com.sun.max.annotate.*;
+import com.sun.max.unsafe.*;
+
+/**
+ * A collection of static methods for doing unsigned arithmetic on Java primitive types
+ * where the semantics of the arithmetics operations differ from the signed version.
+ * In addition to providing unsigned arithmetic semantics for the programmer,
+ * these methods also expose different optimization possibilities to the compiler as
+ * well as allowing for them to be implemented as compiler builtins.
+ *
+ * @author Doug Simon
+ */
+public class Unsigned {
+
+ /**
+ * Performs unsigned integer division.
+ */
+ @INLINE
+ @UNSAFE
+ public static int idiv(int dividend, int divisor) {
+ return Address.fromUnsignedInt(dividend).dividedBy(divisor).toInt();
+ }
+
+ /**
+ * Performs unsigned long division.
+ */
+ @INLINE
+ @UNSAFE
+ public static long ldiv(long dividend, long divisor) {
+ return Address.fromLong(dividend).dividedBy(Address.fromLong(divisor)).toLong();
+ }
+
+ /**
+ * Performs unsigned integer modulus.
+ */
+ @INLINE
+ @UNSAFE
+ public static int irem(int dividend, int divisor) {
+ return Address.fromUnsignedInt(dividend).remainder(divisor);
+ }
+
+ /**
+ * Performs unsigned long modulus.
+ */
+ @INLINE
+ @UNSAFE
+ public static long lrem(long dividend, long divisor) {
+ return Address.fromLong(dividend).remainder(Address.fromLong(divisor)).toLong();
+ }
+
+}
diff --git a/JavaInJava/src/com/sun/max/unsafe/Accessor.java b/JavaInJava/src/com/sun/max/unsafe/Accessor.java
new file mode 100644
index 0000000..a0e21d9
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/unsafe/Accessor.java
@@ -0,0 +1,534 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.unsafe;
+
+import com.sun.max.vm.reference.*;
+
+/**
+ * ATTENTION: DO NOT USE THIS INTERFACE UNLESS YOU KNOW EXACTLY WHAT YOU ARE DOING!!!
+ *
+ * Common interface for pointers and for object references.
+ *
+ * The object layout implementation is written ONCE against this type
+ * (instead of twice, once against Pointer and once against Reference).
+ *
+ * @author Bernd Mathiske
+ * @author Paul Caprioli
+ */
+public interface Accessor {
+
+ /**
+ * Tests whether this is zero.
+ * @return true if all bits are zero.
+ */
+ boolean isZero();
+
+ /**
+ * Reads a byte at an offset from this location.
+ * @param offset the signed offset in bytes from this
+ * @return the byte value
+ */
+ byte readByte(Offset offset);
+
+ /**
+ * Reads a byte at an offset from this location.
+ * @param offset the signed offset in bytes from this
+ * @return the byte value
+ */
+ byte readByte(int offset);
+
+ /**
+ * Gets a byte at index plus displacement from this location.
+ * @param displacement signed displacement in bytes
+ * @param index signed index measured in bytes
+ * @return the byte value
+ */
+ byte getByte(int displacement, int index);
+
+ /**
+ * Writes a byte at an offset from this location.
+ * @param offset the signed offset in bytes from this
+ * @param value the data to be written
+ */
+ void writeByte(Offset offset, byte value);
+
+ /**
+ * Writes a byte at an offset from this location.
+ * @param offset the signed offset in bytes from this
+ * @param value the data to be written
+ */
+ void writeByte(int offset, byte value);
+
+ /**
+ * Writes a byte at index plus displacement from this location.
+ * @param displacement signed displacement in bytes
+ * @param index signed index measured in bytes
+ * @param value the data to be written
+ */
+ void setByte(int displacement, int index, byte value);
+
+ /**
+ * Reads a boolean at an offset from this location.
+ * @param offset the signed offset in bytes from this
+ * @return the boolean value
+ */
+ boolean readBoolean(Offset offset);
+
+ /**
+ * Reads a boolean at an offset from this location.
+ * @param offset the signed offset in bytes from this
+ * @return the boolean value
+ */
+ boolean readBoolean(int offset);
+
+ /**
+ * Gets a boolean at index plus displacement from this location.
+ * @param displacement signed displacement in bytes
+ * @param index signed index measured in bytes
+ * @return the boolean value
+ */
+ boolean getBoolean(int displacement, int index);
+
+ /**
+ * Writes a boolean at an offset from this location.
+ * @param offset the signed offset in bytes from this
+ * @param value the data to be written
+ */
+ void writeBoolean(Offset offset, boolean value);
+
+ /**
+ * Writes a boolean at an offset from this location.
+ * @param offset the signed offset in bytes from this
+ * @param value the data to be written
+ */
+ void writeBoolean(int offset, boolean value);
+
+ /**
+ * Writes a boolean at index plus displacement from this location.
+ * @param displacement signed displacement in bytes
+ * @param index signed index measured in bytes
+ * @param value the data to be written
+ */
+ void setBoolean(int displacement, int index, boolean value);
+
+ /**
+ * Reads a short at an offset from this location.
+ * @param offset the signed offset in bytes from this
+ * @return the short value
+ */
+ short readShort(Offset offset);
+
+ /**
+ * Reads a short at an offset from this location.
+ * @param offset the signed offset in bytes from this
+ * @return the short value
+ */
+ short readShort(int offset);
+
+ /**
+ * Gets a short at the scaled index plus displacement from this location.
+ * @param displacement signed displacement in bytes
+ * @param index signed index measured in shorts
+ * @return the short value
+ */
+ short getShort(int displacement, int index);
+
+ /**
+ * Writes a short at an offset from this location.
+ * @param offset the signed offset in bytes from this
+ * @param value the data to be written
+ */
+ void writeShort(Offset offset, short value);
+
+ /**
+ * Writes a short at an offset from this location.
+ * @param offset the signed offset in bytes from this
+ * @param value the data to be written
+ */
+ void writeShort(int offset, short value);
+
+ /**
+ * Writes a short at index plus displacement from this location.
+ * @param displacement signed displacement in bytes
+ * @param index signed index measured in shorts
+ * @param value the data to be written
+ */
+ void setShort(int displacement, int index, short value);
+
+ /**
+ * Reads a character at an offset from this location.
+ * @param offset the signed offset in bytes from this
+ * @return the character value
+ */
+ char readChar(Offset offset);
+
+ /**
+ * Reads a character at an offset from this location.
+ * @param offset the signed offset in bytes from this
+ * @return the character value
+ */
+ char readChar(int offset);
+
+ /**
+ * Gets a character at the scaled index plus displacement from this location.
+ * @param displacement signed displacement in bytes
+ * @param index signed index measured in chars
+ * @return the character value
+ */
+ char getChar(int displacement, int index);
+
+ /**
+ * Writes a character at an offset from this location.
+ * @param offset the signed offset in bytes from this
+ * @param value the data to be written
+ */
+ void writeChar(Offset offset, char value);
+
+ /**
+ * Writes a character at an offset from this location.
+ * @param offset the signed offset in bytes from this
+ * @param value the data to be written
+ */
+ void writeChar(int offset, char value);
+
+ /**
+ * Writes a character at index plus displacement from this location.
+ * @param displacement signed displacement in bytes
+ * @param index signed index measured in characters
+ * @param value the data to be written
+ */
+ void setChar(int displacement, int index, char value);
+
+ /**
+ * Reads an integer at an offset from this location.
+ * @param offset the signed offset in bytes from this
+ * @return the integer value
+ */
+ int readInt(Offset offset);
+
+ /**
+ * Reads an integer at an offset from this location.
+ * @param offset the signed offset in bytes from this
+ * @return the integer value
+ */
+ int readInt(int offset);
+
+ /**
+ * Gets an integer at the scaled index plus displacement from this location.
+ * @param displacement signed displacement in bytes
+ * @param index signed index measured in ints
+ * @return the integer value
+ */
+ int getInt(int displacement, int index);
+
+ /**
+ * Writes an integer at an offset from this location.
+ * @param offset the signed offset in bytes from this
+ * @param value the data to be written
+ */
+ void writeInt(Offset offset, int value);
+ /**
+ * Writes an integer at an offset from this location.
+ * @param offset the signed offset in bytes from this
+ * @param value the data to be written
+ */
+ void writeInt(int offset, int value);
+
+ /**
+ * Writes an integer at index plus displacement from this location.
+ * @param displacement signed displacement in bytes
+ * @param index signed index measured in ints
+ * @param value the data to be written
+ */
+ void setInt(int displacement, int index, int value);
+
+ /**
+ * Reads a float at an offset from this location.
+ * @param offset the signed offset in bytes from this
+ * @return the float value
+ */
+ float readFloat(Offset offset);
+
+ /**
+ * Reads a float at an offset from this location.
+ * @param offset the signed offset in bytes from this
+ * @return the float value
+ */
+ float readFloat(int offset);
+
+ /**
+ * Gets a float at the scaled index plus displacement from this location.
+ * @param displacement signed displacement in bytes
+ * @param index signed index measured in floats
+ * @return the float value
+ */
+ float getFloat(int displacement, int index);
+
+ /**
+ * Writes a float at an offset from this location.
+ * @param offset the signed offset in bytes from this
+ * @param value the data to be written
+ */
+ void writeFloat(Offset offset, float value);
+
+ /**
+ * Writes a float at an offset from this location.
+ * @param offset the signed offset in bytes from this
+ * @param value the data to be written
+ */
+ void writeFloat(int offset, float value);
+
+ /**
+ * Writes a float at index plus displacement from this location.
+ * @param displacement signed displacement in bytes
+ * @param index signed index measured in floats
+ * @param value the data to be written
+ */
+ void setFloat(int displacement, int index, float value);
+
+ /**
+ * Reads a long at an offset from this location.
+ * @param offset the signed offset in bytes from this
+ * @return the long value
+ */
+ long readLong(Offset offset);
+
+ /**
+ * Reads a long at an offset from this location.
+ * @param offset the signed offset in bytes from this
+ * @return the long value
+ */
+ long readLong(int offset);
+
+ /**
+ * Gets a long at the scaled index plus displacement from this location.
+ * @param displacement signed displacement in bytes
+ * @param index signed index measured in longs
+ * @return the long value
+ */
+ long getLong(int displacement, int index);
+
+ /**
+ * Writes a long at an offset from this location.
+ * @param offset the signed offset in bytes from this
+ * @param value the data to be written
+ */
+ void writeLong(Offset offset, long value);
+
+ /**
+ * Writes a long at an offset from this location.
+ * @param offset the signed offset in bytes from this
+ * @param value the data to be written
+ */
+ void writeLong(int offset, long value);
+
+ /**
+ * Writes a long at index plus displacement from this location.
+ * @param displacement signed displacement in bytes
+ * @param index signed index measured in longs
+ * @param value the data to be written
+ */
+ void setLong(int displacement, int index, long value);
+
+ /**
+ * Reads a double at an offset from this location.
+ * @param offset the signed offset in bytes from this
+ * @return the double value
+ */
+ double readDouble(Offset offset);
+
+ /**
+ * Reads a double at an offset from this location.
+ * @param offset the signed offset in bytes from this
+ * @return the double value
+ */
+ double readDouble(int offset);
+
+ /**
+ * Gets a double at the scaled index plus displacement from this location.
+ * @param displacement signed displacement in bytes
+ * @param index signed index measured in doubles
+ * @return the double value
+ */
+ double getDouble(int displacement, int index);
+
+ /**
+ * Writes a double at an offset from this location.
+ * @param offset the signed offset in bytes from this
+ * @param value the data to be written
+ */
+ void writeDouble(Offset offset, double value);
+
+ /**
+ * Writes a double at an offset from this location.
+ * @param offset the signed offset in bytes from this
+ * @param value the data to be written
+ */
+ void writeDouble(int offset, double value);
+
+ /**
+ * Writes a double at index plus displacement from this location.
+ * @param displacement signed displacement in bytes
+ * @param index signed index measured in doubles
+ * @param value the data to be written
+ */
+ void setDouble(int displacement, int index, double value);
+
+ /**
+ * Reads a Word at an offset from this location.
+ * @param offset the signed offset in bytes from this
+ * @return the Word value
+ */
+ Word readWord(Offset offset);
+
+ /**
+ * Reads a Word at an offset from this location.
+ * @param offset the signed offset in bytes from this
+ * @return the Word value
+ */
+ Word readWord(int offset);
+
+ /**
+ * Gets a Word at the scaled index plus displacement from this location.
+ * @param displacement signed displacement in bytes
+ * @param index signed index measured in Words
+ * @return the Word value
+ */
+ Word getWord(int displacement, int index);
+
+ /**
+ * Writes a Word at an offset from this location.
+ * @param offset the signed offset in bytes from this
+ * @param value the data to be written
+ */
+ void writeWord(Offset offset, Word value);
+
+ /**
+ * Writes a Word at an offset from this location.
+ * @param offset the signed offset in bytes from this
+ * @param value the data to be written
+ */
+ void writeWord(int offset, Word value);
+
+ /**
+ * Writes a Word at index plus displacement from this location.
+ * @param displacement signed displacement in bytes
+ * @param index signed index measured in Words
+ * @param value the data to be written
+ */
+ void setWord(int displacement, int index, Word value);
+
+ /**
+ * Reads a Reference at an offset from this location.
+ * @param offset the signed offset in bytes from this
+ * @return the Reference value
+ */
+ Reference readReference(Offset offset);
+
+ /**
+ * Reads a Reference at an offset from this location.
+ * @param offset the signed offset in bytes from this
+ * @return the Reference value
+ */
+ Reference readReference(int offset);
+
+ /**
+ * Gets a Reference at the scaled index plus displacement from this location.
+ * @param displacement signed displacement in bytes
+ * @param index signed index measured in References
+ * @return the Reference value
+ */
+ Reference getReference(int displacement, int index);
+
+ /**
+ * Writes a Reference at an offset from this location.
+ * @param offset the signed offset in bytes from this
+ * @param value the data to be written
+ */
+ void writeReference(Offset offset, Reference value);
+
+ /**
+ * Writes a Reference at an offset from this location.
+ * @param offset the signed offset in bytes from this
+ * @param value the data to be written
+ */
+ void writeReference(int offset, Reference value);
+
+ /**
+ * Writes a Reference at index plus displacement from this location.
+ * @param displacement signed displacement in bytes
+ * @param index signed index measured in References
+ * @param value the data to be written
+ */
+ void setReference(int displacement, int index, Reference value);
+
+ /**
+ * Atomic compare and swap.
+ *
+ * Compares an expected value with the actual value in a location denoted by this accessor and a given offset.
+ * Iff they are same, {@code newValue} is placed into the location and the {@code expectedValue} is returned.
+ * Otherwise, the actual value is returned.
+ * All of the above is performed in one atomic hardware transaction.
+ *
+ * @param offset offset from accessor origin
+ * @param expectedValue if this value is currently in the accessor location, perform the swap
+ * @param newValue the new value to put into the accessor location
+ * @return either {@code expectedValue} or the actual value
+ */
+ int compareAndSwapInt(Offset offset, int expectedValue, int newValue);
+
+ /**
+ * @see #compareAndSwapInt(Offset, int, int)
+ */
+ int compareAndSwapInt(int offset, int expectedValue, int newValue);
+
+ /**
+ * @see #compareAndSwapInt(Offset, int, int)
+ */
+ Word compareAndSwapWord(Offset offset, Word expectedValue, Word newValue);
+
+ /**
+ * @see #compareAndSwapInt(Offset, int, int)
+ */
+ Word compareAndSwapWord(int offset, Word expectedValue, Word newValue);
+
+ /**
+ * @see #compareAndSwapInt(Offset, int, int)
+ */
+ Reference compareAndSwapReference(Offset offset, Reference expectedValue, Reference newValue);
+
+ /**
+ * @see #compareAndSwapInt(Offset, int, int)
+ */
+ Reference compareAndSwapReference(int offset, Reference expectedValue, Reference newValue);
+
+ /**
+ * Copies elements from this array into a given array.
+ *
+ * @param displacement signed displacement in bytes
+ * @param srcIndex the index in this array from which to copy
+ * @param dst the array into which the elements will be read
+ * @param dstIndex the index in {@code dst} to which to copy
+ * @param length the number of elements to copy
+ */
+ void copyElements(int displacement, int srcIndex, Object dst, int dstIndex, int length);
+}
+
diff --git a/JavaInJava/src/com/sun/max/unsafe/Address.java b/JavaInJava/src/com/sun/max/unsafe/Address.java
new file mode 100644
index 0000000..5be276f
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/unsafe/Address.java
@@ -0,0 +1,389 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.unsafe;
+
+import java.math.*;
+
+import com.sun.max.annotate.*;
+import com.sun.max.lang.*;
+import com.sun.max.program.*;
+
+/**
+ * A machine word interpreted as a linear address.
+ * An Address is unsigned and arithmetic is supported.
+ *
+ * @author Bernd Mathiske
+ * @author Paul Caprioli
+ */
+public abstract class Address extends Word {
+
+ protected Address() {
+ }
+
+ @INLINE
+ public static Address zero() {
+ return fromInt(0);
+ }
+
+ @INLINE
+ public static Address max() {
+ return fromLong(-1L);
+ }
+
+ /**
+ * Creates an Address value from a given int value. Note that unlike {@link #fromInt(int)},
+ * the given int value is not sign extended. Also note that on 32-bit platforms, this operation
+ * is effectively a no-op.
+ *
+ * @param value the value to be converted to an Address
+ */
+ @INLINE
+ public static Address fromUnsignedInt(int value) {
+ if (Word.width() == 64) {
+ final long longValue = value;
+ final long n = longValue & 0xffffffffL;
+ return UnsafeCast.asAddress(n);
+ }
+ return UnsafeCast.asAddress(value);
+ }
+
+ /**
+ * Creates an Address value from a given int value. Note that unlike {@link #fromUnsignedInt(int)},
+ * the given int value is sign extended first. Also note that on 32-bit platforms, this operation
+ * is effectively a no-op.
+ *
+ * @param value the value to be converted to an Address
+ */
+ @INLINE
+ public static Address fromInt(int value) {
+ if (Word.width() == 64) {
+ final long n = value;
+ return UnsafeCast.asAddress(n);
+ }
+ return UnsafeCast.asAddress(value);
+ }
+
+ @INLINE
+ public static Address fromLong(long value) {
+ if (Word.width() == 64) {
+ return UnsafeCast.asAddress(value);
+ }
+ final int n = (int) value;
+ return UnsafeCast.asAddress(n);
+ }
+
+ @Override
+ public String toString() {
+ return "@" + toHexString();
+ }
+
+ public String toUnsignedString(int radix) {
+ if (radix == 16) {
+ if (Word.width() == 64) {
+ return Long.toHexString(toLong());
+ }
+ assert Word.width() == 32;
+ return Integer.toHexString(toInt());
+ }
+ if (radix == 8) {
+ if (Word.width() == 64) {
+ return Long.toOctalString(toLong());
+ }
+ assert Word.width() == 32;
+ return Integer.toOctalString(toInt());
+ }
+ if (radix == 2) {
+ if (Word.width() == 64) {
+ return Long.toBinaryString(toLong());
+ }
+ assert Word.width() == 32;
+ return Integer.toBinaryString(toInt());
+ }
+ assert radix == 10;
+
+ final long n = toLong();
+ if (Word.width() == 32) {
+ if (n <= Integer.MAX_VALUE && n >= 0) {
+ return Integer.toString(toInt());
+ }
+ return Long.toString(n & 0xffffffffL);
+ }
+
+ final long low = n & 0xffffffffL;
+ final long high = n >>> 32;
+ return BigInteger.valueOf(high).shiftLeft(32).or(BigInteger.valueOf(low)).toString();
+ }
+
+ public static Address parse(String s, int radix) {
+ Address result = Address.zero();
+ for (int i = 0; i < s.length(); i++) {
+ result = result.times(radix);
+ result = result.plus(Integer.parseInt(String.valueOf(s.charAt(i)), radix));
+ }
+ return result;
+ }
+
+ @INLINE
+ public final int toInt() {
+ if (Word.width() == 64) {
+ final long n = UnsafeCast.asLong(this);
+ return (int) n;
+ }
+ return UnsafeCast.asInt(this);
+ }
+
+ @INLINE
+ public final long toLong() {
+ if (Word.width() == 64) {
+ return UnsafeCast.asLong(this);
+ }
+ return 0xffffffffL & UnsafeCast.asInt(this);
+ }
+
+ @INLINE
+ public final boolean equals(int other) {
+ return fromInt(other) == this;
+ }
+
+ @INLINE(override = true)
+ public Address plus(Address addend) {
+ return asOffset().plus(addend.asOffset()).asAddress();
+ }
+
+ @INLINE(override = true)
+ public Address plus(Offset offset) {
+ return asOffset().plus(offset).asAddress();
+ }
+
+ @INLINE(override = true)
+ public Address plus(int addend) {
+ return asOffset().plus(addend).asAddress();
+ }
+
+ @INLINE(override = true)
+ public Address plus(long addend) {
+ return asOffset().plus(addend).asAddress();
+ }
+
+ @INLINE(override = true)
+ public Address minus(Address subtrahend) {
+ return asOffset().minus(subtrahend.asOffset()).asAddress();
+ }
+
+ @INLINE(override = true)
+ public Address minus(Offset offset) {
+ return asOffset().minus(offset).asAddress();
+ }
+
+ @INLINE(override = true)
+ public Address minus(int subtrahend) {
+ return asOffset().minus(subtrahend).asAddress();
+ }
+
+ @INLINE(override = true)
+ public Address minus(long subtrahend) {
+ return asOffset().minus(subtrahend).asAddress();
+ }
+
+ @INLINE(override = true)
+ public Address times(Address factor) {
+ return asOffset().times(factor.asOffset()).asAddress();
+ }
+
+ @INLINE(override = true)
+ public Address times(int factor) {
+ return asOffset().times(factor).asAddress();
+ }
+
+ protected abstract Address dividedByAddress(Address divisor);
+
+ @INLINE(override = true)
+ public Address dividedBy(Address divisor) {
+ return dividedByAddress(divisor);
+ }
+
+ protected abstract Address dividedByInt(int divisor);
+
+ @INLINE(override = true)
+ public Address dividedBy(int divisor) {
+ return dividedByInt(divisor);
+ }
+
+ protected abstract Address remainderByAddress(Address divisor);
+
+ @INLINE(override = true)
+ public Address remainder(Address divisor) {
+ return remainderByAddress(divisor);
+ }
+
+ protected abstract int remainderByInt(int divisor);
+
+ @INLINE(override = true)
+ public final int remainder(int divisor) {
+ return remainderByInt(divisor);
+ }
+
+ @INLINE(override = true)
+ public final boolean isRoundedBy(Address nBytes) {
+ return remainder(nBytes).isZero();
+ }
+
+ @INLINE(override = true)
+ public final boolean isRoundedBy(int nBytes) {
+ return remainder(nBytes) == 0;
+ }
+
+ @INLINE(override = true)
+ public Address roundedUpBy(Address nBytes) {
+ if (isRoundedBy(nBytes)) {
+ return this;
+ }
+ return plus(nBytes.minus(remainder(nBytes)));
+ }
+
+ @INLINE(override = true)
+ public Address roundedUpBy(int nBytes) {
+ if (isRoundedBy(nBytes)) {
+ return this;
+ }
+ return plus(nBytes - remainder(nBytes));
+ }
+
+ @INLINE(override = true)
+ public Address roundedDownBy(int nBytes) {
+ return minus(remainder(nBytes));
+ }
+
+ @INLINE(override = true)
+ public Address wordAligned() {
+ final int n = Word.size();
+ return plus(n - 1).and(Address.fromInt(n - 1).not());
+ }
+
+ @INLINE(override = true)
+ public Address aligned(int alignment) {
+ return plus(alignment - 1).and(Address.fromInt(alignment - 1).not());
+ }
+
+ @INLINE(override = true)
+ public boolean isWordAligned() {
+ final int n = Word.size();
+ return and(n - 1).equals(Address.zero());
+ }
+
+ @INLINE(override = true)
+ public boolean isAligned(int alignment) {
+ return and(alignment - 1).equals(Address.zero());
+ }
+
+ @INLINE(override = true)
+ public final boolean isBitSet(int index) {
+ return (toLong() & (1L << index)) != 0;
+ }
+
+ @INLINE(override = true)
+ public Address bitSet(int index) {
+ return fromLong(toLong() | (1L << index));
+ }
+
+ @INLINE(override = true)
+ public Address bitClear(int index) {
+ return fromLong(toLong() & ~(1L << index));
+ }
+
+ @INLINE(override = true)
+ public Address and(Address operand) {
+ if (Word.width() == 64) {
+ return fromLong(toLong() & operand.toLong());
+ }
+ return fromInt(toInt() & operand.toInt());
+ }
+
+ @INLINE(override = true)
+ public Address and(int operand) {
+ return and(fromInt(operand));
+ }
+
+ @INLINE(override = true)
+ public Address and(long operand) {
+ return and(fromLong(operand));
+ }
+
+ @INLINE(override = true)
+ public Address or(Address operand) {
+ if (Word.width() == 64) {
+ return fromLong(toLong() | operand.toLong());
+ }
+ return fromInt(toInt() | operand.toInt());
+ }
+
+ @INLINE(override = true)
+ public Address or(int operand) {
+ return or(fromInt(operand));
+ }
+
+ @INLINE(override = true)
+ public Address or(long operand) {
+ return or(fromLong(operand));
+ }
+
+ @INLINE(override = true)
+ public Address not() {
+ if (Word.width() == 64) {
+ return fromLong(~toLong());
+ }
+ return fromInt(~toInt());
+ }
+
+ @INLINE(override = true)
+ public Address shiftedLeft(int nBits) {
+ if (Word.width() == 64) {
+ return fromLong(toLong() << nBits);
+ }
+ return fromInt(toInt() << nBits);
+ }
+
+ @INLINE(override = true)
+ public Address unsignedShiftedRight(int nBits) {
+ if (Word.width() == 64) {
+ return fromLong(toLong() >>> nBits);
+ }
+ return fromInt(toInt() >>> nBits);
+ }
+
+ @INLINE(override = true)
+ public final int numberOfEffectiveBits() {
+ if (Word.width() == 64) {
+ return 64 - Long.numberOfLeadingZeros(toLong());
+ }
+ return 32 - Integer.numberOfLeadingZeros(toInt());
+ }
+
+ public final WordWidth effectiveWidth() {
+ final int bit = numberOfEffectiveBits();
+ for (WordWidth width : WordWidth.VALUES) {
+ if (bit < width.numberOfBits) {
+ return width;
+ }
+ }
+ throw ProgramError.unexpected();
+ }
+}
diff --git a/JavaInJava/src/com/sun/max/unsafe/DataAccess.java b/JavaInJava/src/com/sun/max/unsafe/DataAccess.java
new file mode 100644
index 0000000..b95a19d
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/unsafe/DataAccess.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.unsafe;
+
+import java.nio.*;
+
+/**
+ * Reading/writing bytes and other primitive data kinds from/to a source/destination that can be identified by an {@link Address}.
+ * For each kind, methods support direct addressing, offset addressing, and indexed addressing for arrays.
+ *
+ * @author Bernd Mathiske
+ * @author Michael Van De Vanter
+ */
+public interface DataAccess extends DataIO {
+
+ void readFully(Address address, ByteBuffer buffer);
+ void readFully(Address address, byte[] bytes);
+ byte[] readFully(Address address, int length);
+
+ byte readByte(Address address);
+ byte readByte(Address address, Offset offset);
+ byte readByte(Address address, int offset);
+ byte getByte(Address address, int displacement, int index);
+
+ boolean readBoolean(Address address);
+ boolean readBoolean(Address address, Offset offset);
+ boolean readBoolean(Address address, int offset);
+ boolean getBoolean(Address address, int displacement, int index);
+
+ short readShort(Address address);
+ short readShort(Address address, Offset offset);
+ short readShort(Address address, int offset);
+ short getShort(Address address, int displacement, int index);
+
+ char readChar(Address address);
+ char readChar(Address address, Offset offset);
+ char readChar(Address address, int offset);
+ char getChar(Address address, int displacement, int index);
+
+ int readInt(Address address);
+ int readInt(Address address, Offset offset);
+ int readInt(Address address, int offset);
+ int getInt(Address address, int displacement, int index);
+
+ float readFloat(Address address);
+ float readFloat(Address address, Offset offset);
+ float readFloat(Address address, int offset);
+ float getFloat(Address address, int displacement, int index);
+
+ long readLong(Address address);
+ long readLong(Address address, Offset offset);
+ long readLong(Address address, int offset);
+ long getLong(Address address, int displacement, int index);
+
+ double readDouble(Address address);
+ double readDouble(Address address, Offset offset);
+ double readDouble(Address address, int offset);
+ double getDouble(Address address, int displacement, int index);
+
+ Word readWord(Address address);
+ Word readWord(Address address, Offset offset);
+ Word readWord(Address address, int offset);
+ Word getWord(Address address, int displacement, int index);
+
+ void writeBytes(Address address, byte[] bytes);
+ void writeBuffer(Address address, ByteBuffer buffer);
+
+ void writeByte(Address address, byte value);
+ void writeByte(Address address, Offset offset, byte value);
+ void writeByte(Address address, int offset, byte value);
+ void setByte(Address address, int displacement, int index, byte value);
+
+ void writeBoolean(Address address, boolean value);
+ void writeBoolean(Address address, Offset offset, boolean value);
+ void writeBoolean(Address address, int offset, boolean value);
+ void setBoolean(Address address, int displacement, int index, boolean value);
+
+ void writeShort(Address address, short value);
+ void writeShort(Address address, Offset offset, short value);
+ void writeShort(Address address, int offset, short value);
+ void setShort(Address address, int displacement, int index, short value);
+
+ void writeChar(Address address, char value);
+ void writeChar(Address address, Offset offset, char value);
+ void writeChar(Address address, int offset, char value);
+ void setChar(Address address, int displacement, int index, char value);
+
+ void writeInt(Address address, int value);
+ void writeInt(Address address, Offset offset, int value);
+ void writeInt(Address address, int offset, int value);
+ void setInt(Address address, int displacement, int index, int value);
+
+ void writeFloat(Address address, float value);
+ void writeFloat(Address address, Offset offset, float value);
+ void writeFloat(Address address, int offset, float value);
+ void setFloat(Address address, int displacement, int index, float value);
+
+ void writeLong(Address address, long value);
+ void writeLong(Address address, Offset offset, long value);
+ void writeLong(Address address, int offset, long value);
+ void setLong(Address address, int displacement, int index, long value);
+
+ void writeDouble(Address address, double value);
+ void writeDouble(Address address, Offset offset, double value);
+ void writeDouble(Address address, int offset, double value);
+ void setDouble(Address address, int displacement, int index, double value);
+
+ void writeWord(Address address, Word value);
+ void writeWord(Address address, Offset offset, Word value);
+ void writeWord(Address address, int offset, Word value);
+ void setWord(Address address, int displacement, int index, Word value);
+
+ void copyElements(Address address, int displacement, int srcIndex, Object dst, int dstIndex, int length);
+}
diff --git a/JavaInJava/src/com/sun/max/unsafe/DataIO.java b/JavaInJava/src/com/sun/max/unsafe/DataIO.java
new file mode 100644
index 0000000..9ed813d
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/unsafe/DataIO.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.unsafe;
+
+import java.nio.*;
+
+/**
+ * Buffered reading/writing of bytes from/to a source/destination that can be identified by an {@link Address}.
+ *
+ * @author Bernd Mathiske
+ * @author Michael Van De Vanter
+ */
+public interface DataIO {
+
+ /**
+ * Reads bytes from an address into a given byte buffer.
+ *
+ * Precondition:
+ * {@code buffer != null && offset >= 0 && offset < buffer.capacity() && length >= 0 && offset + length <= buffer.capacity()}
+ *
+ * @param src the address from which reading should start
+ * @param dst the buffer into which the bytes are read
+ * @param dstOffset the offset in {@code dst} at which the bytes are read
+ * @param length the maximum number of bytes to be read
+ * @return the number of bytes read into {@code dst}
+ *
+ * @throws DataIOError if some IO error occurs
+ * @throws IndexOutOfBoundsException if {@code offset} is negative, {@code length} is negative, or
+ * {@code length > buffer.limit() - offset}
+ */
+ int read(Address src, ByteBuffer dst, int dstOffset, int length) throws DataIOError, IndexOutOfBoundsException;
+
+ /**
+ * Writes bytes from a given byte buffer to a given address.
+ *
+ * Precondition:
+ * {@code buffer != null && offset >= 0 && offset < buffer.capacity() && length >= 0 && offset + length <= buffer.capacity()}
+ *
+ * @param src the buffer from which the bytes are written
+ * @param srcOffset the offset in {@code src} from which the bytes are written
+ * @param length the maximum number of bytes to be written
+ * @param dst the address at which writing should start
+ * @return the number of bytes written to {@code dst}
+ *
+ * @throws DataIOError if some IO error occurs
+ * @throws IndexOutOfBoundsException if {@code srcOffset} is negative, {@code length} is negative, or
+ * {@code length > src.limit() - srcOffset}
+ */
+ int write(ByteBuffer src, int srcOffset, int length, Address dst) throws DataIOError, IndexOutOfBoundsException;
+
+ public static class Static {
+
+ /**
+ * Fills a buffer by reading bytes from a source.
+ *
+ * @param dataIO the source of data to be read
+ * @param src the location in the source where reading should start
+ * @param dst the buffer to be filled with the data
+ */
+ public static void readFully(DataIO dataIO, Address src, ByteBuffer dst) {
+ final int length = dst.limit();
+ int n = 0;
+ assert dst.position() == 0;
+ while (n < length) {
+ final int count = dataIO.read(src.plus(n), dst, n, length - n);
+ if (count <= 0) {
+ throw new DataIOError(src, (length - n) + " of " + length + " bytes unread");
+ }
+ n += count;
+ dst.position(0);
+ }
+ }
+
+ /**
+ * Reads bytes from a source.
+ *
+ * @param dataIO the source of data to be read
+ * @param src the location in the source where reading should start
+ * @param length the total number of bytes to be read
+ * @return the bytes read from the source.
+ */
+ public static byte[] readFully(DataIO dataIO, Address src, int length) {
+ final ByteBuffer buffer = ByteBuffer.wrap(new byte[length]);
+ readFully(dataIO, src, buffer);
+ return buffer.array();
+ }
+
+ /**
+ * Checks the preconditions related to the destination buffer for {@link DataIO#read(Address, ByteBuffer, int, int)}.
+ */
+ public static void checkRead(ByteBuffer dst, int dstOffset, int length) {
+ if (dst == null) {
+ throw new NullPointerException();
+ } else if (dstOffset < 0 || length < 0 || length > dst.limit() - dstOffset) {
+ throw new IndexOutOfBoundsException();
+ }
+ }
+
+ /**
+ * Checks the preconditions related to the source buffer for {@link DataIO#write(ByteBuffer, int, int, Address)}.
+ */
+ public static void checkWrite(ByteBuffer src, int srcOffset, int length) {
+ if ((srcOffset < 0) || (srcOffset > src.limit()) || (length < 0) ||
+ ((srcOffset + length) > src.limit()) || ((srcOffset + length) < 0)) {
+ throw new IndexOutOfBoundsException();
+ }
+ }
+ }
+}
diff --git a/JavaInJava/src/com/sun/max/unsafe/DataIOError.java b/JavaInJava/src/com/sun/max/unsafe/DataIOError.java
new file mode 100644
index 0000000..f5fd3d6
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/unsafe/DataIOError.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.unsafe;
+
+/**
+ * Thrown when an error occurs accessing memory through a {@link DataIO} or {@link DataAccess}.
+ *
+ * @author Aritra Bandyopadhyay
+ */
+public class DataIOError extends Error {
+ private final Address faultAddress;
+
+ public DataIOError(Address address, String message) {
+ super("data access error at ^" + address.toPaddedHexString('0') + " (" + message + " )");
+ faultAddress = address;
+ }
+
+ public DataIOError(Address address) {
+ super("data access error at ^" + address.toPaddedHexString('0'));
+ faultAddress = address;
+ }
+
+ public Address getFaultAddress() {
+ return faultAddress;
+ }
+}
diff --git a/JavaInJava/src/com/sun/max/unsafe/Offset.java b/JavaInJava/src/com/sun/max/unsafe/Offset.java
new file mode 100644
index 0000000..4ed7556
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/unsafe/Offset.java
@@ -0,0 +1,358 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.unsafe;
+
+import com.sun.max.annotate.*;
+import com.sun.max.lang.*;
+import com.sun.max.program.*;
+
+/**
+ * Offsets from addresses or pointers. Unlike an 'Address', an 'Offset' can be negative. Both types have the identical
+ * number of bits used for representation. However, 'Offset' uses twos complement, whereas 'Address' is simply unsigned.
+ *
+ * @author Bernd Mathiske
+ */
+public abstract class Offset extends Word {
+
+ protected Offset() {
+ }
+
+ @INLINE
+ public static Offset zero() {
+ return fromInt(0);
+ }
+
+ @INLINE
+ public static Offset fromUnsignedInt(int value) {
+ return Address.fromUnsignedInt(value).asOffset();
+ }
+
+ @INLINE
+ public static Offset fromInt(int value) {
+ if (Word.width() == 64) {
+ final long n = value;
+ return UnsafeCast.asOffset(n);
+ }
+ return UnsafeCast.asOffset(value);
+ }
+
+ @INLINE
+ public static Offset fromLong(long value) {
+ if (Word.width() == 64) {
+ return UnsafeCast.asOffset(value);
+ }
+ final int n = (int) value;
+ return UnsafeCast.asOffset(n);
+ }
+
+ @Override
+ public String toString() {
+ return "&" + toHexString();
+ }
+
+ @INLINE
+ public final int toInt() {
+ if (Word.width() == 64) {
+ final long n = UnsafeCast.asLong(this);
+ return (int) n;
+ }
+ return UnsafeCast.asInt(this);
+ }
+
+ @INLINE
+ public final long toLong() {
+ if (Word.width() == 64) {
+ return UnsafeCast.asLong(this);
+ }
+ return UnsafeCast.asInt(this);
+ }
+
+ public final int compareTo(Offset other) {
+ if (greaterThan(other)) {
+ return 1;
+ }
+ if (lessThan(other)) {
+ return -1;
+ }
+ return 0;
+ }
+
+ @INLINE
+ public final boolean equals(int other) {
+ return fromInt(other) == this;
+ }
+
+ @INLINE
+ public final boolean lessEqual(Offset other) {
+ if (Word.width() == 64) {
+ return toLong() <= other.toLong();
+ }
+ return toInt() <= other.toInt();
+ }
+
+ @INLINE
+ public final boolean lessEqual(int other) {
+ return lessEqual(fromInt(other));
+ }
+
+ @INLINE
+ public final boolean lessThan(Offset other) {
+ if (Word.width() == 64) {
+ return toLong() < other.toLong();
+ }
+ return toInt() < other.toInt();
+ }
+
+ @INLINE
+ public final boolean lessThan(int other) {
+ return lessThan(fromInt(other));
+ }
+
+ @INLINE
+ public final boolean greaterEqual(Offset other) {
+ if (Word.width() == 64) {
+ return toLong() >= other.toLong();
+ }
+ return toInt() >= other.toInt();
+ }
+
+ @INLINE
+ public final boolean greaterEqual(int other) {
+ return greaterEqual(fromInt(other));
+ }
+
+ @INLINE
+ public final boolean greaterThan(Offset other) {
+ if (Word.width() == 64) {
+ return toLong() > other.toLong();
+ }
+ return toInt() > other.toInt();
+ }
+
+ @INLINE
+ public final boolean greaterThan(int other) {
+ return greaterThan(fromInt(other));
+ }
+
+ @INLINE
+ public final Offset negate() {
+ if (Word.width() == 64) {
+ return fromLong(-toLong());
+ }
+ return fromInt(-toInt());
+ }
+
+ @INLINE
+ public final boolean isNegative() {
+ if (Word.width() == 64) {
+ return toLong() < 0L;
+ }
+ return toInt() < 0;
+ }
+
+ @INLINE
+ public final Offset plus(Offset addend) {
+ if (Word.width() == 64) {
+ return fromLong(toLong() + addend.toLong());
+ }
+ return fromInt(toInt() + addend.toInt());
+ }
+
+ @INLINE
+ public final Offset plus(Size addend) {
+ return plus(addend.asOffset());
+ }
+
+ @INLINE
+ public final Offset plus(int addend) {
+ return plus(fromInt(addend));
+ }
+
+ @INLINE
+ public final Offset plus(long addend) {
+ return plus(fromLong(addend));
+ }
+
+ @INLINE
+ public final Offset minus(Offset subtrahend) {
+ if (Word.width() == 64) {
+ return fromLong(toLong() - subtrahend.toLong());
+ }
+ return fromInt(toInt() - subtrahend.toInt());
+ }
+
+ @INLINE
+ public final Offset minus(Size subtrahend) {
+ return minus(subtrahend.asOffset());
+ }
+
+ @INLINE
+ public final Offset minus(int subtrahend) {
+ return minus(fromInt(subtrahend));
+ }
+
+ @INLINE
+ public final Offset minus(long subtrahend) {
+ return minus(fromLong(subtrahend));
+ }
+
+ @INLINE
+ public final Offset times(Offset factor) {
+ if (Word.width() == 64) {
+ return fromLong(toLong() * factor.toLong());
+ }
+ return fromInt(toInt() * factor.toInt());
+ }
+
+ @INLINE
+ public final Offset times(Address factor) {
+ return times(factor.asOffset());
+ }
+
+ @INLINE
+ public final Offset times(int factor) {
+ return times(fromInt(factor));
+ }
+
+ @INLINE
+ public final Offset dividedBy(Offset divisor) throws ArithmeticException {
+ if (Word.width() == 64) {
+ return fromLong(toLong() / divisor.toLong());
+ }
+ return fromInt(toInt() / divisor.toInt());
+ }
+
+ @INLINE
+ public final Offset dividedBy(int divisor) throws ArithmeticException {
+ return dividedBy(fromInt(divisor));
+ }
+
+ @INLINE
+ public final Offset remainder(Offset divisor) throws ArithmeticException {
+ if (Word.width() == 64) {
+ return fromLong(toLong() % divisor.toLong());
+ }
+ return fromInt(toInt() % divisor.toInt());
+ }
+
+ @INLINE
+ public final int remainder(int divisor) throws ArithmeticException {
+ return remainder(fromInt(divisor)).toInt();
+ }
+
+ @INLINE
+ public final boolean isRoundedBy(int numberOfBytes) {
+ return remainder(numberOfBytes) == 0;
+ }
+
+ public final Offset roundedUpBy(int numberOfBytes) {
+ if (isRoundedBy(numberOfBytes)) {
+ return this;
+ }
+ return plus(numberOfBytes - remainder(numberOfBytes));
+ }
+
+ @INLINE(override = true)
+ public Offset and(Offset operand) {
+ if (Word.width() == 64) {
+ return fromLong(toLong() & operand.toLong());
+ }
+ return fromInt(toInt() & operand.toInt());
+ }
+
+ @INLINE(override = true)
+ public Offset and(int operand) {
+ return and(fromInt(operand));
+ }
+
+ @INLINE(override = true)
+ public Offset and(long operand) {
+ return and(fromLong(operand));
+ }
+
+ @INLINE(override = true)
+ public Offset or(Offset operand) {
+ if (Word.width() == 64) {
+ return fromLong(toLong() | operand.toLong());
+ }
+ return fromInt(toInt() | operand.toInt());
+ }
+
+ @INLINE(override = true)
+ public Offset or(int operand) {
+ return or(fromInt(operand));
+ }
+
+ @INLINE(override = true)
+ public Offset or(long operand) {
+ return or(fromLong(operand));
+ }
+
+ @INLINE(override = true)
+ public Offset not() {
+ if (Word.width() == 64) {
+ return fromLong(~toLong());
+ }
+ return fromInt(~toInt());
+ }
+
+ @INLINE
+ public final Offset roundedDownBy(int numberOfBytes) {
+ return minus(remainder(numberOfBytes));
+ }
+
+ @INLINE(override = true)
+ public final Offset aligned() {
+ final int n = Word.size();
+ return plus(n - 1).and(Offset.fromInt(n - 1).not());
+ }
+
+ @INLINE(override = true)
+ public final boolean isAligned() {
+ final int n = Word.size();
+ return and(n - 1).equals(Offset.zero());
+ }
+
+ public final int numberOfEffectiveBits() {
+ if (Word.width() == 64) {
+ final long n = toLong();
+ if (n >= 0) {
+ return 64 - Long.numberOfLeadingZeros(n);
+ }
+ return 65 - Long.numberOfLeadingZeros(~n);
+ }
+ final int n = toInt();
+ if (n >= 0) {
+ return 32 - Integer.numberOfLeadingZeros(n);
+ }
+ return 33 - Integer.numberOfLeadingZeros(~n);
+ }
+
+ public final WordWidth effectiveWidth() {
+ final int bit = numberOfEffectiveBits();
+ for (WordWidth width : WordWidth.values()) {
+ if (bit < width.numberOfBits) {
+ return width;
+ }
+ }
+ throw ProgramError.unexpected();
+ }
+}
diff --git a/JavaInJava/src/com/sun/max/unsafe/Package.java b/JavaInJava/src/com/sun/max/unsafe/Package.java
new file mode 100644
index 0000000..7f156ca
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/unsafe/Package.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.unsafe;
+
+import com.sun.max.*;
+
+/**
+ * @see MaxPackage
+ *
+ * @author Bernd Mathiske
+ */
+public class Package extends BasePackage {
+ public Package() {
+ super();
+ }
+
+ @Override
+ public Class[] wordSubclasses() {
+ return new Class[] {
+ Address.class,
+ Offset.class,
+ Pointer.class,
+ Size.class,
+ Word.class
+ };
+ }
+}
diff --git a/JavaInJava/src/com/sun/max/unsafe/Pointer.java b/JavaInJava/src/com/sun/max/unsafe/Pointer.java
new file mode 100644
index 0000000..ad085bd
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/unsafe/Pointer.java
@@ -0,0 +1,949 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.unsafe;
+
+import static com.sun.cri.bytecode.Bytecodes.*;
+
+import com.sun.cri.bytecode.*;
+import com.sun.max.annotate.*;
+import com.sun.max.asm.*;
+import com.sun.max.lang.*;
+import com.sun.max.lang.Bytes;
+import com.sun.max.platform.*;
+import com.sun.max.vm.reference.*;
+import com.sun.max.vm.runtime.*;
+import com.sun.max.vm.type.*;
+
+/**
+ * Pointers are addresses with extra methods to access memory.
+ *
+ * @author Bernd Mathiske
+ */
+public abstract class Pointer extends Address implements Accessor {
+
+ private static final int FLOAT_SIZE = 4;
+ private static final int DOUBLE_SIZE = 8;
+
+ protected Pointer() {
+ }
+
+ public interface Procedure {
+ void run(Pointer pointer);
+ }
+
+ public interface Predicate {
+ boolean evaluate(Pointer pointer);
+ }
+
+ @INLINE
+ public static Pointer zero() {
+ return fromInt(0);
+ }
+
+ @INLINE
+ public static Pointer fromUnsignedInt(int value) {
+ return Address.fromUnsignedInt(value).asPointer();
+ }
+
+ @INLINE
+ public static Pointer fromInt(int value) {
+ return Address.fromInt(value).asPointer();
+ }
+
+ @INLINE
+ public static Pointer fromLong(long value) {
+ return Address.fromLong(value).asPointer();
+ }
+
+ @Override
+ public final String toString() {
+ return "^" + toHexString();
+ }
+
+ @Override
+ @INLINE
+ public final Pointer plus(int addend) {
+ return asAddress().plus(addend).asPointer();
+ }
+
+ @Override
+ @INLINE
+ public final Pointer plus(long addend) {
+ return asAddress().plus(addend).asPointer();
+ }
+
+ @Override
+ @INLINE
+ public final Pointer plus(Address addend) {
+ return asAddress().plus(addend).asPointer();
+ }
+
+ @Override
+ @INLINE
+ public final Pointer plus(Offset addend) {
+ return asAddress().plus(addend).asPointer();
+ }
+
+ @INLINE
+ public final Pointer plusWords(int nWords) {
+ return plus(nWords * Word.size());
+ }
+
+ @Override
+ @INLINE
+ public final Pointer minus(Address subtrahend) {
+ return asAddress().minus(subtrahend).asPointer();
+ }
+
+ @Override
+ @INLINE
+ public final Pointer minus(int subtrahend) {
+ return asAddress().minus(subtrahend).asPointer();
+ }
+
+ @Override
+ @INLINE
+ public final Pointer minus(long subtrahend) {
+ return asAddress().minus(subtrahend).asPointer();
+ }
+
+ @INLINE
+ public final Pointer minusWords(int nWords) {
+ return minus(nWords * Word.size());
+ }
+
+ @Override
+ @INLINE
+ public final Pointer minus(Offset subtrahend) {
+ return asAddress().minus(subtrahend).asPointer();
+ }
+
+ @Override
+ @INLINE
+ public final Pointer times(Address factor) {
+ return asAddress().times(factor).asPointer();
+ }
+
+ @Override
+ @INLINE
+ public final Pointer times(int factor) {
+ return asAddress().times(factor).asPointer();
+ }
+
+ @Override
+ @INLINE
+ public final Pointer dividedBy(Address divisor) {
+ return asAddress().dividedBy(divisor).asPointer();
+ }
+
+ @Override
+ @INLINE
+ public final Pointer dividedBy(int divisor) {
+ return asAddress().dividedBy(divisor).asPointer();
+ }
+
+ @Override
+ @INLINE
+ public final Pointer remainder(Address divisor) {
+ return asAddress().remainder(divisor).asPointer();
+ }
+
+ @Override
+ @INLINE
+ public final Pointer roundedUpBy(Address nBytes) {
+ return asAddress().roundedUpBy(nBytes).asPointer();
+ }
+
+ @Override
+ @INLINE
+ public final Pointer roundedUpBy(int nBytes) {
+ return asAddress().roundedUpBy(nBytes).asPointer();
+ }
+
+ @Override
+ @INLINE
+ public final Pointer roundedDownBy(int nBytes) {
+ return asAddress().roundedDownBy(nBytes).asPointer();
+ }
+
+ @Override
+ @INLINE
+ public final Pointer wordAligned() {
+ return asAddress().wordAligned().asPointer();
+ }
+
+ @Override
+ @INLINE(override = true)
+ public final boolean isWordAligned() {
+ return asAddress().isWordAligned();
+ }
+
+ @Override
+ @INLINE
+ public final Pointer bitSet(int index) {
+ return asAddress().bitSet(index).asPointer();
+ }
+
+ @Override
+ @INLINE
+ public final Pointer bitClear(int index) {
+ return asAddress().bitClear(index).asPointer();
+ }
+
+ @Override
+ @INLINE
+ public final Pointer and(Address operand) {
+ return asAddress().and(operand).asPointer();
+ }
+
+ @Override
+ @INLINE
+ public final Pointer and(int operand) {
+ return asAddress().and(operand).asPointer();
+ }
+
+ @Override
+ @INLINE
+ public final Pointer and(long operand) {
+ return asAddress().and(operand).asPointer();
+ }
+
+ @Override
+ @INLINE
+ public final Pointer or(Address operand) {
+ return asAddress().or(operand).asPointer();
+ }
+
+ @Override
+ @INLINE
+ public final Pointer or(int operand) {
+ return asAddress().or(operand).asPointer();
+ }
+
+ @Override
+ @INLINE
+ public final Pointer or(long operand) {
+ return asAddress().or(operand).asPointer();
+ }
+
+ @Override
+ @INLINE
+ public final Pointer not() {
+ return asAddress().not().asPointer();
+ }
+
+ @Override
+ @INLINE
+ public final Pointer shiftedLeft(int nBits) {
+ return asAddress().shiftedLeft(nBits).asPointer();
+ }
+
+ @Override
+ @INLINE
+ public final Pointer unsignedShiftedRight(int nBits) {
+ return asAddress().unsignedShiftedRight(nBits).asPointer();
+ }
+
+ @UNSAFE
+ @FOLD
+ private static boolean risc() {
+ return Platform.platform().isa.category == ISA.Category.RISC;
+ }
+
+ public byte readByte(int offset) {
+ return readByte(Offset.fromInt(offset));
+ }
+
+ public abstract byte readByte(Offset offset);
+
+ private native byte builtinGetByte(int displacement, int index);
+
+ @INLINE
+ public final byte getByte(int displacement, int index) {
+ if (risc()) {
+ return readByte(Offset.fromInt(index).plus(displacement));
+ }
+ return builtinGetByte(displacement, index);
+ }
+
+ @INLINE
+ public final byte getByte(int index) {
+ return getByte(0, index);
+ }
+
+ @INLINE
+ public final byte getByte() {
+ return getByte(0);
+ }
+
+ @INLINE
+ public final boolean readBoolean(Offset offset) {
+ return UnsafeCast.asBoolean(readByte(offset));
+ }
+
+ @INLINE
+ public final boolean readBoolean(int offset) {
+ return UnsafeCast.asBoolean(readByte(offset));
+ }
+
+ @INLINE
+ public final boolean getBoolean(int displacement, int index) {
+ return UnsafeCast.asBoolean(getByte(displacement, index));
+ }
+
+ @INLINE
+ public final boolean getBoolean(int index) {
+ return getBoolean(0, index);
+ }
+
+ @INLINE
+ public final boolean getBoolean() {
+ return getBoolean(0);
+ }
+
+ public final short readShort(int offset) {
+ return readShort(Offset.fromInt(offset));
+ }
+
+ public abstract short readShort(Offset offset);
+
+ private native short builtinGetShort(int displacement, int index);
+
+ @INLINE
+ public final short getShort(int displacement, int index) {
+ if (risc()) {
+ return readShort(Offset.fromInt(index).times(Shorts.SIZE).plus(displacement));
+ }
+ return builtinGetShort(displacement, index);
+ }
+
+ @INLINE
+ public final short getShort(int index) {
+ return getShort(0, index);
+ }
+
+ @INLINE
+ public final short getShort() {
+ return getShort(0);
+ }
+
+ public final char readChar(int offset) {
+ return readChar(Offset.fromInt(offset));
+ }
+
+ public abstract char readChar(Offset offset);
+
+ private native char builtinGetChar(int displacement, int index);
+
+ @INLINE
+ public final char getChar(int displacement, int index) {
+ if (risc()) {
+ return readChar(Offset.fromInt(index).times(Chars.SIZE).plus(displacement));
+ }
+ return builtinGetChar(displacement, index);
+ }
+
+ @INLINE
+ public final char getChar(int index) {
+ return getChar(0, index);
+ }
+
+ @INLINE
+ public final char getChar() {
+ return getChar(0);
+ }
+
+ public final int readInt(int offset) {
+ return readInt(Offset.fromInt(offset));
+ }
+
+ public abstract int readInt(Offset offset);
+
+ private native int builtinGetInt(int displacement, int index);
+
+ @INLINE
+ public final int getInt(int displacement, int index) {
+ if (risc()) {
+ return readInt(Offset.fromInt(index).times(Ints.SIZE).plus(displacement));
+ }
+ return builtinGetInt(displacement, index);
+ }
+
+ @INLINE
+ public final int getInt(int index) {
+ return getInt(0, index);
+ }
+
+ @INLINE
+ public final int getInt() {
+ return getInt(0);
+ }
+
+ public final float readFloat(int offset) {
+ return readFloat(Offset.fromInt(offset));
+ }
+
+ public abstract float readFloat(Offset offset);
+
+ private native float builtinGetFloat(int displacement, int index);
+
+ @INLINE
+ public final float getFloat(int displacement, int index) {
+ if (risc()) {
+ return readFloat(Offset.fromInt(index).times(FLOAT_SIZE).plus(displacement));
+ }
+ return builtinGetFloat(displacement, index);
+ }
+
+ @INLINE
+ public final float getFloat(int index) {
+ return getFloat(0, index);
+ }
+
+ @INLINE
+ public final float getFloat() {
+ return getFloat(0);
+ }
+
+ public final long readLong(int offset) {
+ return readLong(Offset.fromInt(offset));
+ }
+
+ public abstract long readLong(Offset offset);
+
+ private native long builtinGetLong(int displacement, int index);
+
+ @INLINE
+ public final long getLong(int displacement, int index) {
+ if (risc()) {
+ return readLong(Offset.fromInt(index).times(Longs.SIZE).plus(displacement));
+ }
+ return builtinGetLong(displacement, index);
+ }
+
+ @INLINE
+ public final long getLong(int index) {
+ return getLong(0, index);
+ }
+
+ @INLINE
+ public final long getLong() {
+ return getLong(0);
+ }
+
+ public final double readDouble(int offset) {
+ return readDouble(Offset.fromInt(offset));
+ }
+
+ public abstract double readDouble(Offset offset);
+
+ private native double builtinGetDouble(int displacement, int index);
+
+ @INLINE
+ public final double getDouble(int displacement, int index) {
+ if (risc()) {
+ return readDouble(Offset.fromInt(index).times(DOUBLE_SIZE).plus(displacement));
+ }
+ return builtinGetDouble(displacement, index);
+ }
+
+ @INLINE
+ public final double getDouble(int index) {
+ return getDouble(0, index);
+ }
+
+ @INLINE
+ public final double getDouble() {
+ return getDouble(0);
+ }
+
+ public final Word readWord(int offset) {
+ return readWord(Offset.fromInt(offset));
+ }
+
+ public abstract Word readWord(Offset offset);
+
+ private native Word builtinGetWord(int displacement, int index);
+
+ @INLINE
+ public final Word getWord(int displacement, int index) {
+ if (risc()) {
+ return readWord(Offset.fromInt(index).times(Word.size()).plus(displacement));
+ }
+ return builtinGetWord(displacement, index);
+ }
+
+ @INLINE
+ public final Word getWord(int index) {
+ return getWord(0, index);
+ }
+
+ @INLINE
+ public final Word getWord() {
+ return getWord(0);
+ }
+
+ public final Reference readReference(int offset) {
+ return readReference(Offset.fromInt(offset));
+ }
+
+ public abstract Reference readReference(Offset offset);
+
+ private native Reference builtinGetReference(int displacement, int index);
+
+ @INLINE
+ public final Reference getReference(int displacement, int index) {
+ if (risc()) {
+ return readReference(Offset.fromInt(index).times(Word.size()).plus(displacement));
+ }
+ return builtinGetReference(displacement, index);
+ }
+
+ @INLINE
+ public final Reference getReference(int index) {
+ return getReference(0, index);
+ }
+
+ @INLINE
+ public final Reference getReference() {
+ return getReference(0);
+ }
+
+ public final void writeByte(int offset, byte value) {
+ writeByte(Offset.fromInt(offset), value);
+ }
+
+ public abstract void writeByte(Offset offset, byte value);
+
+ private native void builtinSetByte(int displacement, int index, byte value);
+
+ @INLINE
+ public final void setByte(int displacement, int index, byte value) {
+ if (risc()) {
+ writeByte(Offset.fromInt(index).plus(displacement), value);
+ } else {
+ builtinSetByte(displacement, index, value);
+ }
+ }
+
+ @INLINE
+ public final void setByte(int index, byte value) {
+ setByte(0, index, value);
+ }
+
+ @INLINE
+ public final void setByte(byte value) {
+ setByte(0, value);
+ }
+
+ @INLINE
+ public final void writeBoolean(Offset offset, boolean value) {
+ writeByte(offset, UnsafeCast.asByte(value));
+ }
+
+ @INLINE
+ public final void writeBoolean(int offset, boolean value) {
+ writeByte(offset, UnsafeCast.asByte(value));
+ }
+
+ @INLINE
+ public final void setBoolean(int displacement, int index, boolean value) {
+ setByte(displacement, index, UnsafeCast.asByte(value));
+ }
+
+ @INLINE
+ public final void setBoolean(int index, boolean value) {
+ setBoolean(0, index, value);
+ }
+
+ @INLINE
+ public final void setBoolean(boolean value) {
+ setBoolean(0, value);
+ }
+
+ public final void writeShort(int offset, short value) {
+ writeShort(Offset.fromInt(offset), value);
+ }
+
+ public abstract void writeShort(Offset offset, short value);
+
+ private native void builtinSetShort(int displacement, int index, short value);
+
+ @INLINE
+ public final void setShort(int displacement, int index, short value) {
+ if (risc()) {
+ writeShort(Offset.fromInt(index).times(Shorts.SIZE).plus(displacement), value);
+ } else {
+ builtinSetShort(displacement, index, value);
+ }
+ }
+
+ @INLINE
+ public final void setShort(int index, short value) {
+ setShort(0, index, value);
+ }
+
+ @INLINE
+ public final void setShort(short value) {
+ setShort(0, value);
+ }
+
+ @INLINE
+ public final void writeChar(Offset offset, char value) {
+ writeShort(offset, UnsafeCast.asShort(value));
+ }
+
+ @INLINE
+ public final void writeChar(int offset, char value) {
+ writeShort(offset, UnsafeCast.asShort(value));
+ }
+
+ @INLINE
+ public final void setChar(int displacement, int index, char value) {
+ setShort(displacement, index, UnsafeCast.asShort(value));
+ }
+
+ @INLINE
+ public final void setChar(int index, char value) {
+ setChar(0, index, value);
+ }
+
+ @INLINE
+ public final void setChar(char value) {
+ setChar(0, value);
+ }
+
+ public final void writeInt(int offset, int value) {
+ writeInt(Offset.fromInt(offset), value);
+ }
+
+ public abstract void writeInt(Offset offset, int value);
+
+ private native void builtinSetInt(int displacement, int index, int value);
+
+ @INLINE
+ public final void setInt(int displacement, int index, int value) {
+ if (risc()) {
+ writeInt(Offset.fromInt(index).times(Ints.SIZE).plus(displacement), value);
+ } else {
+ builtinSetInt(displacement, index, value);
+ }
+ }
+
+ @INLINE
+ public final void setInt(int index, int value) {
+ setInt(0, index, value);
+ }
+
+ @INLINE
+ public final void setInt(int value) {
+ setInt(0, value);
+ }
+
+ public final void writeFloat(int offset, float value) {
+ writeFloat(Offset.fromInt(offset), value);
+ }
+
+ public abstract void writeFloat(Offset offset, float value);
+
+ private native void builtinSetFloat(int displacement, int index, float value);
+
+ @INLINE
+ public final void setFloat(int displacement, int index, float value) {
+ if (risc()) {
+ writeFloat(Offset.fromInt(index).times(FLOAT_SIZE).plus(displacement), value);
+ } else {
+ builtinSetFloat(displacement, index, value);
+ }
+ }
+
+ @INLINE
+ public final void setFloat(int index, float value) {
+ setFloat(0, index, value);
+ }
+
+ @INLINE
+ public final void setFloat(float value) {
+ setFloat(0, value);
+ }
+
+ public final void writeLong(int offset, long value) {
+ writeLong(Offset.fromInt(offset), value);
+ }
+
+ public abstract void writeLong(Offset offset, long value);
+
+ private native void builtinSetLong(int displacement, int index, long value);
+
+ @INLINE
+ public final void setLong(int displacement, int index, long value) {
+ if (risc()) {
+ writeLong(Offset.fromInt(index).times(Longs.SIZE).plus(displacement), value);
+ } else {
+ builtinSetLong(displacement, index, value);
+ }
+ }
+
+ @INLINE
+ public final void setLong(int index, long value) {
+ setLong(0, index, value);
+ }
+
+ @INLINE
+ public final void setLong(long value) {
+ setLong(0, value);
+ }
+
+ public final void writeDouble(int offset, double value) {
+ writeDouble(Offset.fromInt(offset), value);
+ }
+
+ public abstract void writeDouble(Offset offset, double value);
+
+ private native void builtinSetDouble(int displacement, int index, double value);
+
+ @INLINE
+ public final void setDouble(int displacement, int index, double value) {
+ if (risc()) {
+ writeDouble(Offset.fromInt(index).times(DOUBLE_SIZE).plus(displacement), value);
+ } else {
+ builtinSetDouble(displacement, index, value);
+ }
+ }
+
+ @INLINE
+ public final void setDouble(int index, double value) {
+ setDouble(0, index, value);
+ }
+
+ @INLINE
+ public final void setDouble(double value) {
+ setDouble(0, value);
+ }
+
+ public final void writeWord(int offset, Word value) {
+ writeWord(Offset.fromInt(offset), value);
+ }
+
+ public abstract void writeWord(Offset offset, Word value);
+
+ private native void builtinSetWord(int displacement, int index, Word value);
+
+ @INLINE
+ public final void setWord(int displacement, int index, Word value) {
+ if (risc()) {
+ writeWord(Offset.fromInt(index).times(Word.size()).plus(displacement), value);
+ } else {
+ builtinSetWord(displacement, index, value);
+ }
+ }
+
+ @INLINE
+ public final void setWord(int index, Word value) {
+ setWord(0, index, value);
+ }
+
+ @INLINE
+ public final void setWord(Word value) {
+ setWord(0, value);
+ }
+
+ public final void writeReference(int offset, Reference value) {
+ writeReference(Offset.fromInt(offset), value);
+ }
+
+ public abstract void writeReference(Offset offset, Reference value);
+
+ private native void builtinSetReference(int displacement, int index, Reference value);
+
+ @INLINE
+ public final void setReference(int displacement, int index, Reference value) {
+ if (risc()) {
+ writeReference(Offset.fromInt(index).times(Word.size()).plus(displacement), value);
+ } else {
+ builtinSetReference(displacement, index, value);
+ }
+ }
+
+ @INLINE
+ public final void setReference(int index, Reference value) {
+ setReference(0, index, value);
+ }
+
+ @INLINE
+ public final void setReference(Reference value) {
+ setReference(0, value);
+ }
+
+ /**
+ * @see Accessor#compareAndSwapInt(Offset, int, int)
+ */
+ public native int compareAndSwapInt(int offset, int expectedValue, int newValue);
+
+ /**
+ * @see Accessor#compareAndSwapInt(Offset, int, int)
+ */
+ public native int compareAndSwapInt(Offset offset, int expectedValue, int newValue);
+
+ /**
+ * @see Accessor#compareAndSwapInt(Offset, int, int)
+ */
+ public native Word compareAndSwapWord(int offset, Word expectedValue, Word newValue);
+
+ /**
+ * @see Accessor#compareAndSwapInt(Offset, int, int)
+ */
+ public native Word compareAndSwapWord(Offset offset, Word expectedValue, Word newValue);
+
+ /**
+ * @see Accessor#compareAndSwapInt(Offset, int, int)
+ */
+ public native Reference compareAndSwapReference(int offset, Reference expectedValue, Reference newValue);
+
+ /**
+ * @see Accessor#compareAndSwapInt(Offset, int, int)
+ */
+ public native Reference compareAndSwapReference(Offset offset, Reference expectedValue, Reference newValue);
+
+ /**
+ * Sets a bit in the bit map whose base is denoted by the value of this pointer.
+ *
+ * ATTENTION: There is no protection against concurrent access to the affected byte.
+ *
+ * This method may read the affected byte first, then set the bit in it and then write the byte back.
+ *
+ * @param bitIndex the index of the bit to set
+ */
+ public void setBit(int bitIndex) {
+ final int byteIndex = Unsigned.idiv(bitIndex, Bytes.WIDTH);
+ byte byteValue = getByte(byteIndex);
+ byteValue |= 1 << (bitIndex % Bytes.WIDTH);
+ setByte(byteIndex, byteValue);
+ }
+
+ /**
+ * Modifies up to 8 bits in the bit map whose base is denoted by the value of this pointer
+ * by OR'ing in a given 8-bit mask.
+ *
+ * ATTENTION: There is no protection against concurrent access to affected bytes.
+ *
+ * This method may read each affected byte first, then set some bits in it and then write the byte back.
+ * There are either 1 or 2 affected bytes, depending on alignment of the bit index to bytes in memory.
+ *
+ * @param bitIndex the index of the first bit to set
+ * @param bits a mask of 8 bits OR'ed with the 8 bits in this bit map starting at {@code bitIndex}
+ */
+ public void setBits(int bitIndex, byte bits) {
+ // If we do not mask off the leading bits after a conversion to int right here,
+ // then the arithmetic operations below will convert implicitly to int and may insert sign bits.
+ final int intBits = bits & 0xff;
+
+ int byteIndex = Unsigned.idiv(bitIndex, Bytes.WIDTH);
+ final int rest = bitIndex % Bytes.WIDTH;
+ byte byteValue = getByte(byteIndex);
+ byteValue |= intBits << rest;
+ setByte(byteIndex, byteValue);
+ if (rest > 0) {
+ byteIndex++;
+ byteValue = getByte(byteIndex);
+ byteValue |= intBits >>> (Bytes.WIDTH - rest);
+ setByte(byteIndex, byteValue);
+ }
+ }
+
+ public final void copyElements(int displacement, int srcIndex, Object dst, int dstIndex, int length) {
+ Kind kind = Kind.fromJava(dst.getClass().getComponentType());
+ switch (kind.asEnum) {
+ case BOOLEAN: {
+ boolean[] arr = (boolean[]) dst;
+ for (int i = 0; i < length; ++i) {
+ arr[dstIndex + i] = getBoolean(displacement, srcIndex);
+ }
+ break;
+ }
+ case BYTE: {
+ byte[] arr = (byte[]) dst;
+ for (int i = 0; i < length; ++i) {
+ arr[dstIndex + i] = getByte(displacement, srcIndex);
+ }
+ break;
+ }
+ case CHAR: {
+ char[] arr = (char[]) dst;
+ for (int i = 0; i < length; ++i) {
+ arr[dstIndex + i] = getChar(displacement, srcIndex);
+ }
+ break;
+ }
+ case SHORT: {
+ short[] arr = (short[]) dst;
+ for (int i = 0; i < length; ++i) {
+ arr[dstIndex + i] = getShort(displacement, srcIndex);
+ }
+ break;
+ }
+ case INT: {
+ int[] arr = (int[]) dst;
+ for (int i = 0; i < length; ++i) {
+ arr[dstIndex + i] = getInt(displacement, srcIndex);
+ }
+ break;
+ }
+ case FLOAT: {
+ float[] arr = (float[]) dst;
+ for (int i = 0; i < length; ++i) {
+ arr[dstIndex + i] = getFloat(displacement, srcIndex);
+ }
+ break;
+ }
+ case LONG: {
+ long[] arr = (long[]) dst;
+ for (int i = 0; i < length; ++i) {
+ arr[dstIndex + i] = getLong(displacement, srcIndex);
+ }
+ break;
+ }
+ case DOUBLE: {
+ double[] arr = (double[]) dst;
+ for (int i = 0; i < length; ++i) {
+ arr[dstIndex + i] = getDouble(displacement, srcIndex);
+ }
+ break;
+ }
+ case REFERENCE: {
+ Reference[] arr = (Reference[]) dst;
+ for (int i = 0; i < length; ++i) {
+ arr[dstIndex + i] = getReference(displacement, srcIndex);
+ }
+ break;
+ }
+ case WORD: {
+ Word[] arr = (Word[]) dst;
+ for (int i = 0; i < length; ++i) {
+ WordArray.set(arr, dstIndex + i, getWord(displacement, srcIndex));
+ }
+ break;
+ }
+ default:
+ throw FatalError.unexpected("invalid type");
+ }
+ }
+}
diff --git a/JavaInJava/src/com/sun/max/unsafe/Size.java b/JavaInJava/src/com/sun/max/unsafe/Size.java
new file mode 100644
index 0000000..ccc05eb
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/unsafe/Size.java
@@ -0,0 +1,244 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.unsafe;
+
+import com.sun.max.annotate.*;
+import com.sun.max.lang.*;
+
+/**
+ * Use this type rather than Address to remark that you are referring to the size of something. A "size" is always
+ * referring to a number of bytes. (In contrast, a "length" is bound to a given snippet unit that may differ from
+ * bytes.)
+ *
+ * We delegate much of the implementation to Address.
+ * We only need this for running on the host VM,
+ * because there the actual types are BoxedSize and BoxedAddress.
+ *
+ * @author Bernd Mathiske
+ */
+public abstract class Size extends Address {
+
+ protected Size() {
+ }
+
+ @INLINE
+ public static Size zero() {
+ return fromInt(0);
+ }
+
+ public static final Size K = Size.fromInt(Ints.K);
+ public static final Size M = Size.fromInt(Ints.M);
+ public static final Size G = Size.fromLong(Longs.G);
+
+ @INLINE
+ public static Size fromUnsignedInt(int value) {
+ return Address.fromUnsignedInt(value).asSize();
+ }
+
+ @INLINE
+ public static Size fromInt(int value) {
+ return Address.fromInt(value).asSize();
+ }
+
+ @INLINE
+ public static Size fromLong(long value) {
+ return Address.fromLong(value).asSize();
+ }
+
+ @Override
+ public String toString() {
+ return "#" + toUnsignedString(10);
+ }
+
+ @INLINE
+ @Override
+ public final Size plus(int addend) {
+ return asAddress().plus(addend).asSize();
+ }
+
+ @INLINE
+ @Override
+ public final Size plus(long addend) {
+ return asAddress().plus(addend).asSize();
+ }
+
+ @INLINE
+ @Override
+ public final Size plus(Address addend) {
+ return asAddress().plus(addend).asSize();
+ }
+
+ @INLINE
+ @Override
+ public final Size plus(Offset addend) {
+ return asAddress().plus(addend).asSize();
+ }
+
+ @INLINE
+ @Override
+ public final Size minus(Address subtrahend) {
+ return asAddress().minus(subtrahend).asSize();
+ }
+
+ @INLINE
+ @Override
+ public final Size minus(int subtrahend) {
+ return asAddress().minus(subtrahend).asSize();
+ }
+
+ @INLINE
+ @Override
+ public final Size minus(long subtrahend) {
+ return asAddress().minus(subtrahend).asSize();
+ }
+
+ @INLINE
+ @Override
+ public final Size minus(Offset subtrahend) {
+ return asAddress().minus(subtrahend).asSize();
+ }
+
+ @INLINE
+ @Override
+ public final Size times(Address factor) {
+ return asAddress().times(factor).asSize();
+ }
+
+ @INLINE
+ @Override
+ public final Size times(int factor) {
+ return asAddress().times(factor).asSize();
+ }
+
+ @INLINE
+ @Override
+ public final Size dividedBy(Address divisor) {
+ return asAddress().dividedBy(divisor).asSize();
+ }
+
+ @INLINE
+ @Override
+ public final Size dividedBy(int divisor) {
+ return asAddress().dividedBy(divisor).asSize();
+ }
+
+ @INLINE
+ @Override
+ public final Size remainder(Address divisor) {
+ return asAddress().remainder(divisor).asSize();
+ }
+
+ @INLINE
+ @Override
+ public final Size roundedUpBy(int nBytes) {
+ return asAddress().roundedUpBy(nBytes).asSize();
+ }
+
+ @INLINE
+ @Override
+ public final Size roundedDownBy(int nBytes) {
+ return asAddress().roundedDownBy(nBytes).asSize();
+ }
+
+ @INLINE
+ @Override
+ public final Size wordAligned() {
+ return asAddress().wordAligned().asSize();
+ }
+
+ @INLINE(override = true)
+ @Override
+ public Size aligned(int alignment) {
+ return asAddress().aligned(alignment).asSize();
+ }
+
+ @INLINE(override = true)
+ @Override
+ public final boolean isWordAligned() {
+ return asAddress().isWordAligned();
+ }
+
+ @INLINE
+ @Override
+ public final Size bitSet(int index) {
+ return asAddress().bitSet(index).asSize();
+ }
+
+ @INLINE
+ @Override
+ public final Size bitClear(int index) {
+ return asAddress().bitClear(index).asSize();
+ }
+
+ @INLINE
+ @Override
+ public final Size and(Address operand) {
+ return asAddress().and(operand).asSize();
+ }
+
+ @INLINE
+ @Override
+ public final Size and(int operand) {
+ return asAddress().and(operand).asSize();
+ }
+
+ @INLINE
+ @Override
+ public final Size and(long operand) {
+ return asAddress().and(operand).asSize();
+ }
+
+ @INLINE
+ @Override
+ public final Size or(Address operand) {
+ return asAddress().or(operand).asSize();
+ }
+
+ @INLINE
+ @Override
+ public final Size or(int operand) {
+ return asAddress().or(operand).asSize();
+ }
+
+ @INLINE
+ @Override
+ public final Size or(long operand) {
+ return asAddress().or(operand).asSize();
+ }
+
+ @INLINE
+ @Override
+ public final Size not() {
+ return asAddress().not().asSize();
+ }
+
+ @INLINE
+ @Override
+ public final Size shiftedLeft(int nBits) {
+ return asAddress().shiftedLeft(nBits).asSize();
+ }
+
+ @INLINE
+ @Override
+ public final Size unsignedShiftedRight(int nBits) {
+ return asAddress().unsignedShiftedRight(nBits).asSize();
+ }
+}
diff --git a/JavaInJava/src/com/sun/max/unsafe/UnsafeCast.java b/JavaInJava/src/com/sun/max/unsafe/UnsafeCast.java
new file mode 100644
index 0000000..aa20ff6
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/unsafe/UnsafeCast.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.unsafe;
+
+import static com.sun.cri.bytecode.Bytecodes.*;
+
+import java.lang.ref.*;
+import java.security.*;
+
+import com.sun.cri.bytecode.*;
+import com.sun.max.annotate.*;
+import com.sun.max.vm.actor.holder.*;
+import com.sun.max.vm.actor.member.*;
+import com.sun.max.vm.object.*;
+import com.sun.max.vm.reflection.*;
+import com.sun.max.vm.stack.*;
+import com.sun.max.vm.thread.*;
+import com.sun.max.vm.type.*;
+
+/**
+ * Any method annotated with {@link INTRINSIC}(UNSAFE_CAST) exists solely to provide an escape hatch from Java's type checking. All
+ * such methods are recognized by the compiler to simply be an unsafe coercion from one type to another.
+ *
+ * Any method annotated with this annotation must take exactly one parameter (which will be the receiver if the method
+ * is non-static ), have a non-void, non-generic return type. The type of the parameter is the type being
+ * converted from and the return type is the type being converted to.
+ *
+ * The compiler must translate calls to these methods to simply replace the use of the result with the single parameter.
+ *
+ * A method annotated with the {@code INTRINSIC(UNSAFE_CAST)} may have an implementation (i.e. it is not {@code native} and not
+ * {@code abstract}). This implementation is used to fold (i.e. compile-time evaluate) the method. The implementation
+ * will simply be an explicit cast statement that results in a runtime type check when the method is
+ * evaluated.
+ *
+ * @author Bernd Mathiske
+ * @author Doug Simon
+ */
+public final class UnsafeCast {
+ @HOSTED_ONLY
+ private UnsafeCast() {
+ }
+
+ @INTRINSIC(UNSAFE_CAST) public static VmThread asVmThread(Object object) { return (VmThread) object; }
+ @INTRINSIC(UNSAFE_CAST) public static Object[] asObjectArray(Object object) { return (Object[]) object; }
+ @INTRINSIC(UNSAFE_CAST) public static Hybrid asHybrid(Object object) { return (Hybrid) object; }
+ @INTRINSIC(UNSAFE_CAST) public static StackUnwindingContext asStackUnwindingContext(Object object) { return (StackUnwindingContext) object; }
+ @INTRINSIC(UNSAFE_CAST) public static Class asClass(Object object) { return (Class) object; }
+ @INTRINSIC(UNSAFE_CAST) public static ClassRegistry asClassRegistry(Object object) { return (ClassRegistry) object; }
+ @INTRINSIC(UNSAFE_CAST) public static MethodInvocationStub asMethodInvocationStub(Object object) { return (MethodInvocationStub) object; }
+ @INTRINSIC(UNSAFE_CAST) public static ConstructorInvocationStub asConstructorInvocationStub(Object object) { return (ConstructorInvocationStub) object; }
+ @INTRINSIC(UNSAFE_CAST) public static Throwable asThrowable(Object object) { return (Throwable) object; }
+ @INTRINSIC(UNSAFE_CAST) public static int[] asIntArray(Object object) { return (int[]) object; }
+ @INTRINSIC(UNSAFE_CAST) public static DynamicHub asDynamicHub(Object object) { return (DynamicHub) object; }
+ @INTRINSIC(UNSAFE_CAST) public static Hub asHub(Object object) { return (Hub) object; }
+ @INTRINSIC(UNSAFE_CAST) public static ArrayClassActor asArrayClassActor(Object object) { return (ArrayClassActor) object; }
+ @INTRINSIC(UNSAFE_CAST) public static ClassActor asClassActor(Object object) { return (ClassActor) object; }
+ @INTRINSIC(UNSAFE_CAST) public static FieldActor asFieldActor(Object object) { return (FieldActor) object; }
+ @INTRINSIC(UNSAFE_CAST) public static MethodActor asClassMethodActor(Object object) { return (ClassMethodActor) object; }
+ @INTRINSIC(UNSAFE_CAST) public static StaticMethodActor asStaticMethodActor(Object object) { return (StaticMethodActor) object; }
+ @INTRINSIC(UNSAFE_CAST) public static VirtualMethodActor asVirtualMethodActor(Object object) { return (VirtualMethodActor) object; }
+ @INTRINSIC(UNSAFE_CAST) public static AccessControlContext asAccessControlContext(Object object) { return (AccessControlContext) object; }
+ @INTRINSIC(UNSAFE_CAST) public static Reference asJDKReference(Object object) { return (Reference) object; }
+ @INTRINSIC(UNSAFE_CAST) public static InterfaceActor asInterfaceActor(Object object) { return (InterfaceActor) object; }
+ @INTRINSIC(UNSAFE_CAST) public static InterfaceMethodActor asInterfaceMethodActor(Object object) { return (InterfaceMethodActor) object; }
+
+ @INTRINSIC(UNSAFE_CAST) public static Address asAddress(int value) { return Address.fromUnsignedInt(value); }
+ @INTRINSIC(UNSAFE_CAST) public static Address asAddress(long value) { return Address.fromLong(value); }
+ @INTRINSIC(UNSAFE_CAST) public static Offset asOffset(int value) { return Offset.fromUnsignedInt(value); }
+ @INTRINSIC(UNSAFE_CAST) public static Offset asOffset(long value) { return Offset.fromLong(value); }
+
+ @INTRINSIC(UNSAFE_CAST) public static int asInt(Word word) { return word.asAddress().toInt(); }
+ @INTRINSIC(UNSAFE_CAST) public static long asLong(Word word) { return word.asAddress().toLong(); }
+ @INTRINSIC(UNSAFE_CAST) public static boolean asBoolean(byte value) { return value != 0; }
+ @INTRINSIC(UNSAFE_CAST) public static byte asByte(boolean value) { return value ? 1 : (byte) 0; }
+ @INTRINSIC(UNSAFE_CAST) public static int asInt(boolean value) { return value ? 1 : 0; }
+ @INTRINSIC(UNSAFE_CAST) public static char asChar(short value) { return (char) value; }
+ @INTRINSIC(UNSAFE_CAST) public static short asShort(char value) { return (short) value; }
+}
diff --git a/JavaInJava/src/com/sun/max/unsafe/WithoutAccessCheck.java b/JavaInJava/src/com/sun/max/unsafe/WithoutAccessCheck.java
new file mode 100644
index 0000000..8a98d9e
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/unsafe/WithoutAccessCheck.java
@@ -0,0 +1,192 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.unsafe;
+
+import java.lang.reflect.*;
+
+import sun.misc.*;
+
+import com.sun.max.program.*;
+
+/**
+ * Bypass access checks for reflective operations.
+ *
+ * @author Bernd Mathiske
+ */
+public final class WithoutAccessCheck {
+ public static final Unsafe unsafe = (Unsafe) getStaticField(Unsafe.class, "theUnsafe");
+
+ private WithoutAccessCheck() {
+ }
+
+ private static Field findField(Class javaClass, String fieldName) {
+ Class c = javaClass;
+ while (c != null) {
+ try {
+ final Field field = c.getDeclaredField(fieldName);
+ field.setAccessible(true);
+ return field;
+ } catch (NoSuchFieldException noSuchFieldException) {
+ }
+ c = c.getSuperclass();
+ }
+ throw ProgramError.unexpected("could not find field " + fieldName);
+ }
+
+ private static void accessError(Field field) {
+ throw new IllegalAccessError("could not access field " + field);
+ }
+
+ public static Object getInstanceField(Object tuple, String fieldName) {
+ final Field field = findField(tuple.getClass(), fieldName);
+ try {
+ return field.get(tuple);
+ } catch (IllegalAccessException illegalAccessException) {
+ accessError(field);
+ return null;
+ }
+ }
+
+ public static void setInstanceField(Object tuple, String fieldName, Object value) {
+ final Field field = findField(tuple.getClass(), fieldName);
+ try {
+ field.set(tuple, value);
+ } catch (IllegalAccessException illegalAccessException) {
+ accessError(field);
+ }
+ }
+
+ public static Object getStaticField(Class javaClass, String fieldName) {
+ final Field field = findField(javaClass, fieldName);
+ try {
+ return field.get(javaClass);
+ } catch (IllegalAccessException illegalAccessException) {
+ accessError(field);
+ return null;
+ }
+ }
+
+ public static void setStaticField(Class javaClass, String fieldName, Object value) {
+ final Field field = findField(javaClass, fieldName);
+ try {
+ field.set(javaClass, value);
+ } catch (IllegalAccessException illegalAccessException) {
+ accessError(field);
+ }
+ }
+
+ public static Object newInstance(Class> javaClass) {
+ try {
+ final Constructor constructor = javaClass.getDeclaredConstructor();
+ constructor.setAccessible(true);
+ return constructor.newInstance();
+ } catch (Exception e) {
+ throw ProgramError.unexpected(e);
+ }
+ }
+
+ /**
+ * Return the named method with a method signature matching parameter classes from the given class.
+ */
+ private static Method getMethod(Class> instanceClass, String methodName, Class[] parameterClasses)
+ throws NoSuchMethodException {
+ if (instanceClass == null) {
+ throw new NoSuchMethodException("Invalid method : " + methodName);
+ }
+ try {
+ final Method declaredMethod = instanceClass.getDeclaredMethod(methodName, parameterClasses);
+ return declaredMethod;
+ } catch (NoSuchMethodException noSuchMethodException) {
+ return getMethod(instanceClass.getSuperclass(), methodName, parameterClasses);
+ }
+ }
+
+ private static Class getWrapperClass(Class primitiveClass) {
+ assert primitiveClass.isPrimitive();
+ String name = primitiveClass.getName();
+ if (name.equals("int")) {
+ name = "Integer";
+ } else if (name.equals("char")) {
+ name = "Character";
+ } else {
+ name = Character.toUpperCase(name.charAt(0)) + name.substring(1);
+ }
+ try {
+ return Class.forName("java.lang." + name);
+ } catch (Throwable throwable) {
+ throw ProgramError.unexpected();
+ }
+ }
+
+ private static boolean compatible(Class parameterClass, Object argument) {
+ if (parameterClass == null) {
+ return false;
+ }
+ if (parameterClass.isPrimitive()) {
+ if (argument == null) {
+ return false;
+ }
+ return getWrapperClass(parameterClass).isInstance(argument);
+ } else if (argument == null) {
+ return true;
+ }
+ return parameterClass.isInstance(argument);
+ }
+
+ private static boolean compatible(Class[] parameterClasses, Object[] arguments) {
+ if (arguments == null) {
+ return parameterClasses == null;
+ }
+ if (parameterClasses.length != arguments.length) {
+ return false;
+ }
+ for (int i = 0; i < parameterClasses.length; i++) {
+ if (!compatible(parameterClasses[i], arguments[i])) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Calls a method on the given object instance with the given arguments.
+ */
+ public static Object invokeVirtual(Object instance, String methodName, Class[] parameterClasses, Object[] arguments)
+ throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
+ assert compatible(parameterClasses, arguments);
+ final Method method = getMethod(instance.getClass(), methodName, parameterClasses);
+ method.setAccessible(true);
+ return method.invoke(instance, arguments);
+ }
+
+ public static Object invokeStatic(Class instanceClass, String methodName, Class[] parameterClasses, Object[] arguments) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
+ assert compatible(parameterClasses, arguments);
+ final Method method = getMethod(instanceClass, methodName, parameterClasses);
+ method.setAccessible(true);
+ return method.invoke(null, arguments);
+ }
+
+ public static Object invokeConstructor(Class> instanceClass) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
+ final Constructor constructor = instanceClass.getDeclaredConstructor(new Class[]{});
+ constructor.setAccessible(true);
+ return constructor.newInstance(new Object[]{});
+ }
+}
diff --git a/JavaInJava/src/com/sun/max/unsafe/Word.java b/JavaInJava/src/com/sun/max/unsafe/Word.java
new file mode 100644
index 0000000..4a35321
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/unsafe/Word.java
@@ -0,0 +1,216 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.unsafe;
+
+import static com.sun.cri.bytecode.Bytecodes.*;
+import static com.sun.max.platform.Platform.*;
+
+import java.io.*;
+import java.lang.reflect.*;
+import java.util.*;
+
+import com.sun.cri.bytecode.*;
+import com.sun.max.*;
+import com.sun.max.annotate.*;
+import com.sun.max.lang.*;
+import com.sun.max.program.*;
+import com.sun.max.vm.*;
+import com.sun.max.vm.compiler.builtin.*;
+import com.sun.max.vm.hosted.*;
+import com.sun.max.vm.jni.*;
+import com.sun.max.vm.value.*;
+
+/**
+ * A machine-word sized unboxed type. The {@code Word} type itself is mostly opaque, providing operations
+ * to determine the {@linkplain #size() size} (in bytes) and {@linkplain #width() width} (in bits) of a word.
+ * Subclasses define extra operations such as {@linkplain Offset signed} and {@linkplain Address unsigned}
+ * arithmetic, and {@linkplain Pointer pointer} operations.
+ *
+ * In a {@linkplain MaxineVM#isHosted() hosted} runtime, {@code Word} type values are implemented with
+ * {@linkplain Boxed boxed} values.
+ *
+ * The closure of {@code Word} types (i.e. all the classes that subclass {@link Word}) is {@linkplain #getSubclasses() discovered}
+ * during initialization in a hosted environment. This discovery mechanism relies on the same package based
+ * facility used to configure the schemes of a VM. Each package that defines one or more {@code Word} subclasses
+ * must also declare a subclass of {@link MaxPackage} named "Package" that overrides {@link MaxPackage#wordSubclasses()}.
+ *
+ * @see WordValue
+ *
+ * @author Bernd Mathiske
+ * @author Doug Simon
+ */
+public abstract class Word {
+
+ protected Word() {
+ }
+
+ @INLINE
+ public static Word zero() {
+ return Address.zero();
+ }
+
+ @INLINE
+ public static Word allOnes() {
+ return Address.max();
+ }
+
+ @FOLD
+ public static Endianness endianness() {
+ return platform().endianness();
+ }
+
+ @FOLD
+ public static WordWidth widthValue() {
+ return platform().wordWidth();
+ }
+
+ @FOLD
+ public static int width() {
+ return widthValue().numberOfBits;
+ }
+
+ @FOLD
+ public static int size() {
+ return widthValue().numberOfBytes;
+ }
+
+ public final Address asAddress() {
+ throw new UnsupportedOperationException("later");
+ }
+
+ public final Offset asOffset() {
+ throw new UnsupportedOperationException("later");
+ }
+
+ public final Size asSize() {
+ throw new UnsupportedOperationException("later");
+ }
+
+ public final Pointer asPointer() {
+ throw new UnsupportedOperationException("later");
+ }
+
+ /**
+ * @return bit index of the least significant bit set, or -1 if zero.
+ */
+ public final int leastSignificantBitSet() {
+ return SpecialBuiltin.leastSignificantBit(this);
+ }
+
+ /**
+ * @return bit index of the least significant bit set, or -1 if zero.
+ */
+ public final int mostSignificantBitSet() {
+ return SpecialBuiltin.mostSignificantBit(this);
+ }
+
+ public final String toHexString() {
+ String result = Long.toHexString(asAddress().toLong());
+ if (width() == 32 && result.length() > 8) {
+ result = result.substring(result.length() - 8);
+ }
+ return result;
+ }
+
+ public final String toPaddedHexString(char pad) {
+ if (Word.width() == 64) {
+ return Longs.toPaddedHexString(asAddress().toLong(), pad);
+ }
+ return Ints.toPaddedHexString(asAddress().toInt(), pad);
+ }
+
+ @Override
+ public String toString() {
+ return "$" + toHexString();
+ }
+
+ @Override
+ public final int hashCode() {
+ return asOffset().toInt();
+ }
+
+ @INLINE
+ public final boolean isZero() {
+ return equals(Word.zero());
+ }
+
+ @INLINE
+ public final boolean isAllOnes() {
+ return equals(Word.allOnes());
+ }
+
+ @INLINE
+ public final boolean equals(Word other) {
+ if (Word.width() == 64) {
+ return asOffset().toLong() == other.asOffset().toLong();
+ }
+ return asOffset().toInt() == other.asOffset().toInt();
+ }
+
+ @Override
+ public final boolean equals(Object other) {
+ throw ProgramError.unexpected("must not call equals(Object) with Word argument");
+ }
+
+ /**
+ * Reads an address from a given data input stream.
+ */
+ public static Word read(DataInput stream) throws IOException {
+ if (width() == 64) {
+ return Address.fromLong(stream.readLong());
+ }
+ return Address.fromInt(stream.readInt());
+ }
+
+ /**
+ * Writes this address to a given data output stream.
+ */
+ @INLINE
+ public final void write(DataOutput stream) throws IOException {
+ if (width() == 64) {
+ stream.writeLong(asAddress().toLong());
+ } else {
+ stream.writeInt(asAddress().toInt());
+ }
+ }
+
+ /**
+ * Reads an address from a given input stream using a given endianness.
+ */
+ public static Word read(InputStream inputStream, Endianness endianness) throws IOException {
+ if (width() == 64) {
+ return Address.fromLong(endianness.readLong(inputStream));
+ }
+ return Address.fromInt(endianness.readInt(inputStream));
+ }
+
+ /**
+ * Writes this address to a given output stream using a given endianness.
+ */
+ @INLINE
+ public final void write(OutputStream outputStream, Endianness endianness) throws IOException {
+ if (width() == 64) {
+ endianness.writeLong(outputStream, asAddress().toLong());
+ } else {
+ endianness.writeInt(outputStream, asAddress().toInt());
+ }
+ }
+}
diff --git a/JavaInJava/src/com/sun/max/unsafe/WordArray.java b/JavaInJava/src/com/sun/max/unsafe/WordArray.java
new file mode 100644
index 0000000..bbf1db3
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/unsafe/WordArray.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.unsafe;
+
+import com.sun.max.annotate.*;
+import com.sun.max.vm.object.*;
+
+/**
+ * Why we never directly use any arrays of any subtype of 'Word':
+ *
+ * The byte codes aaload and aastore have no clue whether the array reference on the stack refers to a Word array or an
+ * Object array. As long as we are unable to or unsure whether we can discern the difference STATICALLY, we must not
+ * allow aaload and aastore to deal with either case dynamically.
+ *
+ * Compare this to the situation between byte arrays and boolean arrays addressed by baload and bastore! In those cases,
+ * we CAN differentiate between the respective array types DYNAMICALLY and cause no harm to the GC, because both types
+ * are primitive types.
+ *
+ * In case of Object and Word, one calls for a stack map entry and the other does not. Therefore, a dynamic distinction
+ * would require support for dynamic stack map changes. So far we are not willing to afford the price for that
+ * (runtime, implementation effort, complexity).
+ *
+ * Instead, always use WordArray.set() and WordArray.get() instead of [] when addressing word array elements.
+ *
+ * @author Bernd Mathiske
+ */
+public final class WordArray {
+
+ private WordArray() {
+ }
+
+ public static void fill(Word[] array, Word value) {
+ for (int i = 0; i < array.length; i++) {
+ uncheckedSet(array, i, value);
+ }
+ }
+
+ @INLINE
+ public static Word uncheckedGet(Word[] array, int index) {
+ return ArrayAccess.getWord(array, index);
+ }
+
+ @INLINE
+ public static Word get(Word[] array, int index) {
+ ArrayAccess.checkIndex(array, index);
+ return ArrayAccess.getWord(array, index);
+ }
+
+ @INLINE
+ public static void uncheckedSet(Word[] array, int index, Word value) {
+ ArrayAccess.setWord(array, index, value);
+ }
+
+ @INLINE
+ public static void set(Word[] array, int index, Word value) {
+ ArrayAccess.checkIndex(array, index);
+ ArrayAccess.setWord(array, index, value);
+ }
+
+ public static void copyAll(Word[] fromArray, Word[] toArray) {
+ if (fromArray.length > toArray.length) {
+ throw new ArrayIndexOutOfBoundsException();
+ }
+ for (int i = 0; i < fromArray.length; i++) {
+ uncheckedSet(toArray, i, uncheckedGet(fromArray, i));
+ }
+ }
+}
diff --git a/JavaInJava/src/com/sun/max/unsafe/package-info.java b/JavaInJava/src/com/sun/max/unsafe/package-info.java
new file mode 100644
index 0000000..cab09ab
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/unsafe/package-info.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+/**
+ * "Unsafe" operations that transgress the safety guarantees of the core Java language specification:
+ * direct memory access, unchecked type casts, unchecked member access, etc.
+ *
+ * @author Bernd Mathiske
+ */
+package com.sun.max.unsafe;
diff --git a/JavaInJava/src/com/sun/max/vm/VMPackage.java b/JavaInJava/src/com/sun/max/vm/VMPackage.java
new file mode 100644
index 0000000..333cd2e
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/vm/VMPackage.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.vm;
+
+import com.sun.max.*;
+import com.sun.max.annotate.*;
+
+/**
+ * Denotes a package of classes that are (potentially) in the VM.
+ *
+ * @author Bernd Mathiske
+ * @author Doug Simon
+ */
+public abstract class VMPackage extends MaxPackage {
+ public VMPackage() {
+ }
+
+ public boolean isPartOfMaxineVM(VMConfiguration vmConfiguration) {
+ return true;
+ }
+
+ /**
+ * Determines if this package contains any classes annotated with {@link METHOD_SUBSTITUTIONS}.
+ * @return
+ */
+ public boolean containsMethodSubstitutions() {
+ return false;
+ }
+}
diff --git a/JavaInJava/src/com/sun/max/vm/VMScheme.java b/JavaInJava/src/com/sun/max/vm/VMScheme.java
new file mode 100644
index 0000000..c123bc2
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/vm/VMScheme.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.vm;
+
+import com.sun.max.*;
+
+/**
+ * @author Bernd Mathiske
+ */
+public interface VMScheme extends Scheme {
+
+ /**
+ * Gets the class embodying the specification of the scheme implemented by this object.
+ */
+ Class extends VMScheme> specification();
+
+ /**
+ * Performs any scheme specific actions when entering a given VM phase.
+ *
+ * @param phase the VM phase that has just been entered
+ */
+ void initialize(MaxineVM.Phase phase);
+
+}
diff --git a/JavaInJava/src/com/sun/max/vm/compiler/builtin/SpecialBuiltin.java b/JavaInJava/src/com/sun/max/vm/compiler/builtin/SpecialBuiltin.java
new file mode 100644
index 0000000..968f0c7
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/vm/compiler/builtin/SpecialBuiltin.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.vm.compiler.builtin;
+
+import com.sun.max.unsafe.*;
+
+/**
+ * @author Bernd Mathiske
+ */
+public abstract class SpecialBuiltin {
+
+ /**
+ * Returns the index of the least significant bit set in a given value.
+ *
+ * @param value the value to scan for the least significant bit
+ * @return the index of the least significant bit within {@code value} or {@code -1} if {@code value == 0}
+ */
+ public static int leastSignificantBit(Word value) {
+ long l = value.asAddress().toLong();
+ if (l == 0) {
+ return -1;
+ }
+ return Long.numberOfTrailingZeros(l);
+ }
+
+ /**
+ * Returns the index to the most significant bit set in a given value.
+ *
+ * @param value the value to scan for the most significant bit
+ * @return the index to the most significant bit within {@code value} or {@code -1} if {@code value == 0}
+ */
+ public static int mostSignificantBit(Word value) {
+ long l = value.asAddress().toLong();
+ if (l == 0) {
+ return -1;
+ }
+ return Long.numberOfTrailingZeros(l);
+ }
+
+ public static boolean aboveEqual(int value1, int value2) {
+ final long unsignedInt1 = value1 & 0xFFFFFFFFL;
+ final long unsignedInt2 = value2 & 0xFFFFFFFFL;
+ return unsignedInt1 >= unsignedInt2;
+ }
+
+ public static boolean aboveThan(int value1, int value2) {
+ final long unsignedInt1 = value1 & 0xFFFFFFFFL;
+ final long unsignedInt2 = value2 & 0xFFFFFFFFL;
+ return unsignedInt1 > unsignedInt2;
+ }
+
+ public static boolean belowEqual(int value1, int value2) {
+ final long unsignedInt1 = value1 & 0xFFFFFFFFL;
+ final long unsignedInt2 = value2 & 0xFFFFFFFFL;
+ return unsignedInt1 <= unsignedInt2;
+ }
+
+ public static boolean belowThan(int value1, int value2) {
+ final long unsignedInt1 = value1 & 0xFFFFFFFFL;
+ final long unsignedInt2 = value2 & 0xFFFFFFFFL;
+ return unsignedInt1 < unsignedInt2;
+ }
+
+ public static float intToFloat(int value) {
+ return Float.intBitsToFloat(value);
+ }
+
+ public static int floatToInt(float value) {
+ return Float.floatToRawIntBits(value);
+ }
+
+ public static double longToDouble(long value) {
+ return Double.longBitsToDouble(value);
+ }
+
+ public static long doubleToLong(double value) {
+ return Double.doubleToRawLongBits(value);
+ }
+}
diff --git a/JavaInJava/src/com/sun/max/vm/reference/Package.java b/JavaInJava/src/com/sun/max/vm/reference/Package.java
new file mode 100644
index 0000000..cb666b9
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/vm/reference/Package.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.vm.reference;
+
+import com.sun.max.*;
+import com.sun.max.vm.*;
+
+/**
+ * @see MaxPackage
+ *
+ * @author Bernd Mathiske
+ */
+public class Package extends VMPackage {
+ public Package() {
+ super();
+ }
+}
diff --git a/JavaInJava/src/com/sun/max/vm/reference/Reference.java b/JavaInJava/src/com/sun/max/vm/reference/Reference.java
new file mode 100644
index 0000000..3f4c188
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/vm/reference/Reference.java
@@ -0,0 +1,462 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.vm.reference;
+
+import static com.sun.max.vm.VMConfiguration.*;
+
+import com.sun.max.annotate.*;
+import com.sun.max.unsafe.*;
+import com.sun.max.vm.layout.*;
+
+/**
+ * @author Bernd Mathiske
+ */
+public abstract class Reference implements Accessor {
+
+ protected Reference() {
+ }
+
+ @UNSAFE
+ @FOLD
+ private static ReferenceScheme referenceScheme() {
+ return vmConfig().referenceScheme();
+ }
+
+ @INLINE
+ public static Reference fromJava(Object object) {
+ return referenceScheme().fromJava(object);
+ }
+
+ @INLINE
+ public final Object toJava() {
+ return referenceScheme().toJava(this);
+ }
+
+ @INLINE
+ public static Reference fromOrigin(Pointer origin) {
+ return referenceScheme().fromOrigin(origin);
+ }
+
+ @INLINE
+ public final Pointer toOrigin() {
+ return referenceScheme().toOrigin(this);
+ }
+
+ @INLINE
+ public final Reference readHubReference() {
+ return Layout.readHubReference(this);
+ }
+
+ @INLINE
+ public final boolean isZero() {
+ return referenceScheme().isZero(this);
+ }
+
+ @INLINE
+ public static Reference zero() {
+ return referenceScheme().zero();
+ }
+
+ @INLINE
+ public final boolean isAllOnes() {
+ return referenceScheme().isAllOnes(this);
+ }
+
+ @INLINE(override = true)
+ public boolean equals(Reference other) {
+ return other == this;
+ }
+
+ @INLINE
+ public final boolean isMarked() {
+ return referenceScheme().isMarked(this);
+ }
+
+ @INLINE
+ public final Reference marked() {
+ return referenceScheme().marked(this);
+ }
+
+ @INLINE
+ public final Reference unmarked() {
+ return referenceScheme().unmarked(this);
+ }
+
+ @INLINE
+ public final byte readByte(Offset offset) {
+ return referenceScheme().readByte(this, offset);
+ }
+
+ @INLINE
+ public final byte readByte(int offset) {
+ return referenceScheme().readByte(this, offset);
+ }
+
+ @INLINE
+ public final byte getByte(int displacement, int index) {
+ return referenceScheme().getByte(this, displacement, index);
+ }
+
+ @INLINE
+ public final boolean readBoolean(Offset offset) {
+ return referenceScheme().readBoolean(this, offset);
+ }
+
+ @INLINE
+ public final boolean readBoolean(int offset) {
+ return referenceScheme().readBoolean(this, offset);
+ }
+
+ @INLINE
+ public final boolean getBoolean(int displacement, int index) {
+ return referenceScheme().getBoolean(this, displacement, index);
+ }
+
+ @INLINE
+ public final short readShort(Offset offset) {
+ return referenceScheme().readShort(this, offset);
+ }
+
+ @INLINE
+ public final short readShort(int offset) {
+ return referenceScheme().readShort(this, offset);
+ }
+
+ @INLINE
+ public final short getShort(int displacement, int index) {
+ return referenceScheme().getShort(this, displacement, index);
+ }
+
+ @INLINE
+ public final char readChar(Offset offset) {
+ return referenceScheme().readChar(this, offset);
+ }
+
+ @INLINE
+ public final char readChar(int offset) {
+ return referenceScheme().readChar(this, offset);
+ }
+
+ @INLINE
+ public final char getChar(int displacement, int index) {
+ return referenceScheme().getChar(this, displacement, index);
+ }
+
+ @INLINE
+ public final int readInt(Offset offset) {
+ return referenceScheme().readInt(this, offset);
+ }
+
+ @INLINE
+ public final int readInt(int offset) {
+ return referenceScheme().readInt(this, offset);
+ }
+
+ @INLINE
+ public final int getInt(int displacement, int index) {
+ return referenceScheme().getInt(this, displacement, index);
+ }
+
+ @INLINE
+ public final float readFloat(Offset offset) {
+ return referenceScheme().readFloat(this, offset);
+ }
+
+ @INLINE
+ public final float readFloat(int offset) {
+ return referenceScheme().readFloat(this, offset);
+ }
+
+ @INLINE
+ public final float getFloat(int displacement, int index) {
+ return referenceScheme().getFloat(this, displacement, index);
+ }
+
+ @INLINE
+ public final long readLong(Offset offset) {
+ return referenceScheme().readLong(this, offset);
+ }
+
+ @INLINE
+ public final long readLong(int offset) {
+ return referenceScheme().readLong(this, offset);
+ }
+
+ @INLINE
+ public final long getLong(int displacement, int index) {
+ return referenceScheme().getLong(this, displacement, index);
+ }
+
+ @INLINE
+ public final double readDouble(Offset offset) {
+ return referenceScheme().readDouble(this, offset);
+ }
+
+ @INLINE
+ public final double readDouble(int offset) {
+ return referenceScheme().readDouble(this, offset);
+ }
+
+ @INLINE
+ public final double getDouble(int displacement, int index) {
+ return referenceScheme().getDouble(this, displacement, index);
+ }
+
+ @INLINE
+ public final Word readWord(Offset offset) {
+ return referenceScheme().readWord(this, offset);
+ }
+
+ @INLINE
+ public final Word readWord(int offset) {
+ return referenceScheme().readWord(this, offset);
+ }
+
+ @INLINE
+ public final Word getWord(int displacement, int index) {
+ return referenceScheme().getWord(this, displacement, index);
+ }
+
+ @INLINE
+ public final Reference readReference(Offset offset) {
+ return referenceScheme().readReference(this, offset);
+ }
+
+ @INLINE
+ public final Reference readReference(int offset) {
+ return referenceScheme().readReference(this, offset);
+ }
+
+ @INLINE
+ public final Reference getReference(int displacement, int index) {
+ return referenceScheme().getReference(this, displacement, index);
+ }
+
+ @INLINE
+ public final void writeByte(Offset offset, byte value) {
+ referenceScheme().writeByte(this, offset, value);
+ }
+
+ @INLINE
+ public final void writeByte(int offset, byte value) {
+ referenceScheme().writeByte(this, offset, value);
+ }
+
+ @INLINE
+ public final void setByte(int displacement, int index, byte value) {
+ referenceScheme().setByte(this, displacement, index, value);
+ }
+
+ @INLINE
+ public final void writeBoolean(Offset offset, boolean value) {
+ referenceScheme().writeBoolean(this, offset, value);
+ }
+
+ @INLINE
+ public final void writeBoolean(int offset, boolean value) {
+ referenceScheme().writeBoolean(this, offset, value);
+ }
+
+ @INLINE
+ public final void setBoolean(int displacement, int index, boolean value) {
+ referenceScheme().setBoolean(this, displacement, index, value);
+ }
+
+ @INLINE
+ public final void writeShort(Offset offset, short value) {
+ referenceScheme().writeShort(this, offset, value);
+ }
+
+ @INLINE
+ public final void writeShort(int offset, short value) {
+ referenceScheme().writeShort(this, offset, value);
+ }
+
+ @INLINE
+ public final void setShort(int displacement, int index, short value) {
+ referenceScheme().setShort(this, displacement, index, value);
+ }
+
+ @INLINE
+ public final void writeChar(Offset offset, char value) {
+ referenceScheme().writeChar(this, offset, value);
+ }
+
+ @INLINE
+ public final void writeChar(int offset, char value) {
+ referenceScheme().writeChar(this, offset, value);
+ }
+
+ @INLINE
+ public final void setChar(int displacement, int index, char value) {
+ referenceScheme().setChar(this, displacement, index, value);
+ }
+
+ @INLINE
+ public final void writeInt(Offset offset, int value) {
+ referenceScheme().writeInt(this, offset, value);
+ }
+
+ @INLINE
+ public final void writeInt(int offset, int value) {
+ referenceScheme().writeInt(this, offset, value);
+ }
+
+ @INLINE
+ public final void setInt(int displacement, int index, int value) {
+ referenceScheme().setInt(this, displacement, index, value);
+ }
+
+ @INLINE
+ public final void writeFloat(Offset offset, float value) {
+ referenceScheme().writeFloat(this, offset, value);
+ }
+
+ @INLINE
+ public final void writeFloat(int offset, float value) {
+ referenceScheme().writeFloat(this, offset, value);
+ }
+
+ @INLINE
+ public final void setFloat(int displacement, int index, float value) {
+ referenceScheme().setFloat(this, displacement, index, value);
+ }
+
+ @INLINE
+ public final void writeLong(Offset offset, long value) {
+ referenceScheme().writeLong(this, offset, value);
+ }
+
+ @INLINE
+ public final void writeLong(int offset, long value) {
+ referenceScheme().writeLong(this, offset, value);
+ }
+
+ @INLINE
+ public final void setLong(int displacement, int index, long value) {
+ referenceScheme().setLong(this, displacement, index, value);
+ }
+
+ @INLINE
+ public final void writeDouble(Offset offset, double value) {
+ referenceScheme().writeDouble(this, offset, value);
+ }
+
+ @INLINE
+ public final void writeDouble(int offset, double value) {
+ referenceScheme().writeDouble(this, offset, value);
+ }
+
+ @INLINE
+ public final void setDouble(int displacement, int index, double value) {
+ referenceScheme().setDouble(this, displacement, index, value);
+ }
+
+ @INLINE
+ public final void writeWord(Offset offset, Word value) {
+ referenceScheme().writeWord(this, offset, value);
+ }
+
+ @INLINE
+ public final void writeWord(int offset, Word value) {
+ referenceScheme().writeWord(this, offset, value);
+ }
+
+ @INLINE
+ public final void setWord(int displacement, int index, Word value) {
+ referenceScheme().setWord(this, displacement, index, value);
+ }
+
+ @INLINE
+ public final void writeReference(Offset offset, Reference value) {
+ referenceScheme().writeReference(this, offset, value);
+ }
+
+ @INLINE
+ public final void writeReference(int offset, Reference value) {
+ referenceScheme().writeReference(this, offset, value);
+ }
+
+ @INLINE
+ public final void setReference(int displacement, int index, Reference value) {
+ referenceScheme().setReference(this, displacement, index, value);
+ }
+
+ /**
+ * Atomically compares the contents of a memory location to a given value and, if they are the same, modifies the
+ * contents of that memory location to a given new value.
+ *
+ * @param offset the offset from this reference of the memory location to be tested and potentially updated
+ * @param expectedValue the value that must currently exist in the memory location for the update to occur
+ * @param newValue the value to which the memory is updated if its current value is {@code expectedValue}
+ * @return the value of the memory location before this call; if it is equal to {@code expectedValue}, then the
+ * update occurred, otherwise the update did not occur (assuming {@code expectedValue != newValue})
+ */
+ @INLINE
+ public final int compareAndSwapInt(Offset offset, int expectedValue, int newValue) {
+ return referenceScheme().compareAndSwapInt(this, offset, expectedValue, newValue);
+ }
+
+ /**
+ * @see #compareAndSwapInt(Offset, int, int)
+ */
+ @INLINE
+ public final int compareAndSwapInt(int offset, int expectedValue, int newValue) {
+ return referenceScheme().compareAndSwapInt(this, offset, expectedValue, newValue);
+ }
+
+ /**
+ * @see #compareAndSwapInt(Offset, int, int)
+ */
+ @INLINE
+ public final Word compareAndSwapWord(Offset offset, Word expectedValue, Word newValue) {
+ return referenceScheme().compareAndSwapWord(this, offset, expectedValue, newValue);
+ }
+
+ /**
+ * @see #compareAndSwapInt(Offset, int, int)
+ */
+ @INLINE
+ public final Word compareAndSwapWord(int offset, Word expectedValue, Word newValue) {
+ return referenceScheme().compareAndSwapWord(this, offset, expectedValue, newValue);
+ }
+
+ /**
+ * @see #compareAndSwapInt(Offset, int, int)
+ */
+ @INLINE
+ public final Reference compareAndSwapReference(Offset offset, Reference expectedValue, Reference newValue) {
+ return referenceScheme().compareAndSwapReference(this, offset, expectedValue, newValue);
+ }
+
+ /**
+ * @see #compareAndSwapInt(Offset, int, int)
+ */
+ @INLINE
+ public final Reference compareAndSwapReference(int offset, Reference expectedValue, Reference newValue) {
+ return referenceScheme().compareAndSwapReference(this, offset, expectedValue, newValue);
+ }
+
+ @INLINE
+ public final void copyElements(int displacement, int srcIndex, Object dst, int dstIndex, int length) {
+ referenceScheme().copyElements(displacement, this, displacement, dst, dstIndex, length);
+ }
+}
diff --git a/JavaInJava/src/com/sun/max/vm/reference/ReferenceScheme.java b/JavaInJava/src/com/sun/max/vm/reference/ReferenceScheme.java
new file mode 100644
index 0000000..2f9c9d2
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/vm/reference/ReferenceScheme.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.sun.max.vm.reference;
+
+import com.sun.max.unsafe.*;
+import com.sun.max.vm.*;
+
+/**
+ * Reference-based object access methods for mutator use.
+ *
+ * A "reference" is a runtime value of type 'java.lang.Object'.
+ * It can be stored in fields and array elements of other objects.
+ * The mutator refers to objects and parts thereof by using references.
+ *
+ * @author Bernd Mathiske
+ */
+public interface ReferenceScheme extends VMScheme {
+
+ Reference fromOrigin(Pointer origin);
+
+ Reference fromJava(Object object);
+
+ Object toJava(Reference reference);
+ Pointer toOrigin(Reference reference);
+
+ /**
+ * @return the "zero" ref that represents 'null'.
+ */
+ Reference zero();
+
+ boolean isZero(Reference ref);
+
+ boolean isAllOnes(Reference ref);
+
+ boolean isMarked(Reference ref);
+
+ Reference marked(Reference ref);
+
+ Reference unmarked(Reference ref);
+
+ byte readByte(Reference reference, Offset offset);
+ byte readByte(Reference reference, int offset);
+ byte getByte(Reference reference, int displacement, int index);
+
+ boolean readBoolean(Reference reference, Offset offset);
+ boolean readBoolean(Reference reference, int offset);
+ boolean getBoolean(Reference reference, int displacement, int index);
+
+ short readShort(Reference reference, Offset offset);
+ short readShort(Reference reference, int offset);
+ short getShort(Reference reference, int displacement, int index);
+
+ char readChar(Reference reference, Offset offset);
+ char readChar(Reference reference, int offset);
+ char getChar(Reference reference, int displacement, int index);
+
+ int readInt(Reference reference, Offset offset);
+ int readInt(Reference reference, int offset);
+ int getInt(Reference reference, int displacement, int index);
+
+ float readFloat(Reference reference, Offset offset);
+ float readFloat(Reference reference, int offset);
+ float getFloat(Reference reference, int displacement, int index);
+
+ long readLong(Reference reference, Offset offset);
+ long readLong(Reference reference, int offset);
+ long getLong(Reference reference, int displacement, int index);
+
+ double readDouble(Reference reference, Offset offset);
+ double readDouble(Reference reference, int offset);
+ double getDouble(Reference reference, int displacement, int index);
+
+ Word readWord(Reference reference, Offset offset);
+ Word readWord(Reference reference, int offset);
+ Word getWord(Reference reference, int displacement, int index);
+
+ Reference readReference(Reference reference, Offset offset);
+ Reference readReference(Reference reference, int offset);
+ Reference getReference(Reference reference, int displacement, int index);
+
+ void writeByte(Reference reference, Offset offset, byte value);
+ void writeByte(Reference reference, int offset, byte value);
+ void setByte(Reference reference, int displacement, int index, byte value);
+
+ void writeBoolean(Reference reference, Offset offset, boolean value);
+ void writeBoolean(Reference reference, int offset, boolean value);
+ void setBoolean(Reference reference, int displacement, int index, boolean value);
+
+ void writeShort(Reference reference, Offset offset, short value);
+ void writeShort(Reference reference, int offset, short value);
+ void setShort(Reference reference, int displacement, int index, short value);
+
+ void writeChar(Reference reference, Offset offset, char value);
+ void writeChar(Reference reference, int offset, char value);
+ void setChar(Reference reference, int displacement, int index, char value);
+
+ void writeInt(Reference reference, Offset offset, int value);
+ void writeInt(Reference reference, int offset, int value);
+ void setInt(Reference reference, int displacement, int index, int value);
+
+ void writeFloat(Reference reference, Offset offset, float value);
+ void writeFloat(Reference reference, int offset, float value);
+ void setFloat(Reference reference, int displacement, int index, float value);
+
+ void writeLong(Reference reference, Offset offset, long value);
+ void writeLong(Reference reference, int offset, long value);
+ void setLong(Reference reference, int displacement, int index, long value);
+
+ void writeDouble(Reference reference, Offset offset, double value);
+ void writeDouble(Reference reference, int offset, double value);
+ void setDouble(Reference reference, int displacement, int index, double value);
+
+ void writeWord(Reference reference, Offset offset, Word value);
+ void writeWord(Reference reference, int offset, Word value);
+ void setWord(Reference reference, int displacement, int index, Word value);
+
+ void writeReference(Reference reference, Offset offset, Reference value);
+ void writeReference(Reference reference, int offset, Reference value);
+ void setReference(Reference reference, int displacement, int index, Reference value);
+
+ /**
+ * Atomically compares the contents of the memory location addressed by adding {@code offset} to {@code reference}
+ * to a given value and, if they are the same, modifies the contents of that memory location to a given new value.
+ *
+ * @param reference the base of the memory location
+ * @param offset the offset of the memory location
+ * @param expectedValue the value that must currently exist in the memory location for the update to occur
+ * @param newValue the value to which the memory is updated if its current value is {@code expectedValue}
+ * @return the value of the memory location before this call; if it is equal to {@code expectedValue}, then the
+ * update occurred, otherwise the update did not occur (assuming {@code expectedValue != newValue})
+ */
+ int compareAndSwapInt(Reference reference, Offset offset, int expectedValue, int newValue);
+
+ /**
+ * @see #compareAndSwapInt(Reference, Offset, int, int)
+ */
+ int compareAndSwapInt(Reference reference, int offset, int expectedValue, int newValue);
+
+ /**
+ * @see #compareAndSwapInt(Reference, Offset, int, int)
+ */
+ Word compareAndSwapWord(Reference reference, Offset offset, Word expectedValue, Word newValue);
+
+ /**
+ * @see #compareAndSwapInt(Reference, Offset, int, int)
+ */
+ Word compareAndSwapWord(Reference reference, int offset, Word expectedValue, Word newValue);
+
+ Reference compareAndSwapReference(Reference reference, Offset offset, Reference expectedValue, Reference newValue);
+ Reference compareAndSwapReference(Reference reference, int offset, Reference expectedValue, Reference newValue);
+
+ void copyElements(int displacement, Reference src, int srcIndex, Object dst, int dstIndex, int length);
+}
diff --git a/JavaInJava/src/com/sun/max/vm/reference/package-info.java b/JavaInJava/src/com/sun/max/vm/reference/package-info.java
new file mode 100644
index 0000000..950319d
--- /dev/null
+++ b/JavaInJava/src/com/sun/max/vm/reference/package-info.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+/**
+ * Object reference specifications and operations.
+ *
+ * @author Bernd Mathiske
+ */
+package com.sun.max.vm.reference;