From 55afaad510ff7d36579473cd4ac13b00d6df001a Mon Sep 17 00:00:00 2001 From: hborders Date: Tue, 28 Dec 2010 23:51:03 -0600 Subject: [PATCH 01/25] Added package com.sun.max.unsafe from Maxine VM. --- .../src/com/sun/max/unsafe/Accessor.java | 534 ++++++++ .../src/com/sun/max/unsafe/Address.java | 493 ++++++++ JavaInJava/src/com/sun/max/unsafe/Boxed.java | 45 + .../src/com/sun/max/unsafe/BoxedAddress.java | 143 +++ .../src/com/sun/max/unsafe/BoxedOffset.java | 70 + .../src/com/sun/max/unsafe/BoxedPointer.java | 215 ++++ .../src/com/sun/max/unsafe/BoxedSize.java | 101 ++ .../src/com/sun/max/unsafe/BoxedWord.java | 58 + .../src/com/sun/max/unsafe/CString.java | 446 +++++++ .../src/com/sun/max/unsafe/DataAccess.java | 132 ++ JavaInJava/src/com/sun/max/unsafe/DataIO.java | 127 ++ .../src/com/sun/max/unsafe/DataIOError.java | 44 + .../com/sun/max/unsafe/MemoryDataAccess.java | 360 ++++++ JavaInJava/src/com/sun/max/unsafe/Offset.java | 377 ++++++ .../src/com/sun/max/unsafe/Package.java | 45 + .../src/com/sun/max/unsafe/Pointer.java | 1125 +++++++++++++++++ JavaInJava/src/com/sun/max/unsafe/Size.java | 254 ++++ .../src/com/sun/max/unsafe/UnsafeCast.java | 96 ++ .../sun/max/unsafe/WithoutAccessCheck.java | 192 +++ JavaInJava/src/com/sun/max/unsafe/Word.java | 366 ++++++ .../src/com/sun/max/unsafe/WordArray.java | 129 ++ .../src/com/sun/max/unsafe/package-info.java | 27 + 22 files changed, 5379 insertions(+) create mode 100644 JavaInJava/src/com/sun/max/unsafe/Accessor.java create mode 100644 JavaInJava/src/com/sun/max/unsafe/Address.java create mode 100644 JavaInJava/src/com/sun/max/unsafe/Boxed.java create mode 100644 JavaInJava/src/com/sun/max/unsafe/BoxedAddress.java create mode 100644 JavaInJava/src/com/sun/max/unsafe/BoxedOffset.java create mode 100644 JavaInJava/src/com/sun/max/unsafe/BoxedPointer.java create mode 100644 JavaInJava/src/com/sun/max/unsafe/BoxedSize.java create mode 100644 JavaInJava/src/com/sun/max/unsafe/BoxedWord.java create mode 100644 JavaInJava/src/com/sun/max/unsafe/CString.java create mode 100644 JavaInJava/src/com/sun/max/unsafe/DataAccess.java create mode 100644 JavaInJava/src/com/sun/max/unsafe/DataIO.java create mode 100644 JavaInJava/src/com/sun/max/unsafe/DataIOError.java create mode 100644 JavaInJava/src/com/sun/max/unsafe/MemoryDataAccess.java create mode 100644 JavaInJava/src/com/sun/max/unsafe/Offset.java create mode 100644 JavaInJava/src/com/sun/max/unsafe/Package.java create mode 100644 JavaInJava/src/com/sun/max/unsafe/Pointer.java create mode 100644 JavaInJava/src/com/sun/max/unsafe/Size.java create mode 100644 JavaInJava/src/com/sun/max/unsafe/UnsafeCast.java create mode 100644 JavaInJava/src/com/sun/max/unsafe/WithoutAccessCheck.java create mode 100644 JavaInJava/src/com/sun/max/unsafe/Word.java create mode 100644 JavaInJava/src/com/sun/max/unsafe/WordArray.java create mode 100644 JavaInJava/src/com/sun/max/unsafe/package-info.java 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..2fcf45f --- /dev/null +++ b/JavaInJava/src/com/sun/max/unsafe/Address.java @@ -0,0 +1,493 @@ +/* + * 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.cri.bytecode.Bytecodes.UnsignedComparisons.*; +import static com.sun.max.vm.MaxineVM.*; + +import java.math.*; + +import com.sun.cri.bytecode.*; +import com.sun.max.annotate.*; +import com.sun.max.lang.*; +import com.sun.max.program.*; +import com.sun.max.vm.compiler.builtin.*; + +/** + * 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 isHosted() ? BoxedAddress.ZERO : fromInt(0); + } + + @INLINE + public static Address max() { + return isHosted() ? BoxedAddress.MAX : 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 (isHosted()) { + final long longValue = value; + final long n = longValue & 0xffffffffL; + return BoxedAddress.from(n); + } + 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 (isHosted()) { + final long n = value; + return BoxedAddress.from(n); + } + if (Word.width() == 64) { + final long n = value; + return UnsafeCast.asAddress(n); + } + return UnsafeCast.asAddress(value); + } + + @INLINE + public static Address fromLong(long value) { + if (isHosted()) { + return BoxedAddress.from(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 (isHosted()) { + final Boxed box = (Boxed) this; + return (int) box.value(); + } + if (Word.width() == 64) { + final long n = UnsafeCast.asLong(this); + return (int) n; + } + return UnsafeCast.asInt(this); + } + + @INLINE + public final long toLong() { + if (isHosted()) { + final Boxed box = (Boxed) this; + return box.value(); + } + if (Word.width() == 64) { + return UnsafeCast.asLong(this); + } + return 0xffffffffL & UnsafeCast.asInt(this); + } + + public final int compareTo(Address other) { + if (greaterThan(other)) { + return 1; + } + if (lessThan(other)) { + return -1; + } + return 0; + } + + @INLINE + public final boolean equals(int other) { + if (isHosted()) { + return toLong() == other; + } + return fromInt(other) == this; + } + + @BUILTIN(value = AddressBuiltin.GreaterThan.class) + @INTRINSIC(UWCMP | (ABOVE_THAN << 8)) + public final boolean greaterThan(Address other) { + assert isHosted(); + final long a = toLong(); + final long b = other.toLong(); + if (a < 0 == b < 0) { + return a > b; + } + return a < b; + } + + @INLINE(override = true) + public final boolean greaterThan(int other) { + return greaterThan(fromInt(other)); + } + + @BUILTIN(value = AddressBuiltin.GreaterEqual.class) + @INTRINSIC(UWCMP | (ABOVE_EQUAL << 8)) + public final boolean greaterEqual(Address other) { + assert isHosted(); + return !other.greaterThan(this); + } + + @INLINE(override = true) + public final boolean greaterEqual(int other) { + return greaterEqual(fromInt(other)); + } + + @BUILTIN(value = AddressBuiltin.LessThan.class) + @INTRINSIC(UWCMP | (BELOW_THAN << 8)) + public final boolean lessThan(Address other) { + assert isHosted(); + return other.greaterThan(this); + } + + @INLINE(override = true) + public final boolean lessThan(int other) { + return lessThan(fromInt(other)); + } + + @BUILTIN(value = AddressBuiltin.LessEqual.class) + @INTRINSIC(UWCMP | (BELOW_EQUAL << 8)) + public final boolean lessEqual(Address other) { + assert isHosted(); + return !greaterThan(other); + } + + @INLINE(override = true) + public final boolean lessEqual(int other) { + return lessEqual(fromInt(other)); + } + + @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(); + } + + @BUILTIN(value = AddressBuiltin.DividedByAddress.class) + @INTRINSIC(WDIV) + protected abstract Address dividedByAddress(Address divisor); + + @INLINE(override = true) + @INTRINSIC(WDIV) + public Address dividedBy(Address divisor) { + return dividedByAddress(divisor); + } + + @BUILTIN(value = AddressBuiltin.DividedByInt.class) + @INTRINSIC(WDIVI) + protected abstract Address dividedByInt(int divisor); + + @INLINE(override = true) + @INTRINSIC(WDIVI) + public Address dividedBy(int divisor) { + return dividedByInt(divisor); + } + + @BUILTIN(value = AddressBuiltin.RemainderByAddress.class) + @INTRINSIC(WREM) + protected abstract Address remainderByAddress(Address divisor); + + @INLINE(override = true) + @INTRINSIC(WREM) + public Address remainder(Address divisor) { + return remainderByAddress(divisor); + } + + @BUILTIN(value = AddressBuiltin.RemainderByInt.class) + @INTRINSIC(WREMI) + protected abstract int remainderByInt(int divisor); + + @INLINE(override = true) + @INTRINSIC(WREMI) + 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/Boxed.java b/JavaInJava/src/com/sun/max/unsafe/Boxed.java new file mode 100644 index 0000000..d839666 --- /dev/null +++ b/JavaInJava/src/com/sun/max/unsafe/Boxed.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.annotate.*; +import com.sun.max.vm.*; + +/** + * Interface implemented by boxed versions of {@link Word} types. + * These boxed implementations are used when executing in {@linkplain MaxineVM#isHosted() hosted} mode. + * + * A boxed type must be in the same package as its corresponding unboxed type and + * its name must be composed by added the prefix "Boxed" to the name of the unboxed type. + * This invariant enables the complete set of boxed types to be derived from the known + * set of unboxed types. + * + * @author Bernd Mathiske + * @author Doug Simon + */ +@HOSTED_ONLY +public interface Boxed { + + /** + * Gets the boxed value as a {@code long}. + */ + long value(); +} diff --git a/JavaInJava/src/com/sun/max/unsafe/BoxedAddress.java b/JavaInJava/src/com/sun/max/unsafe/BoxedAddress.java new file mode 100644 index 0000000..718205f --- /dev/null +++ b/JavaInJava/src/com/sun/max/unsafe/BoxedAddress.java @@ -0,0 +1,143 @@ +/* + * 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.*; + +/** + * Boxed version of Address. + * + * @see Address + * + * @author Bernd Mathiske + */ +@HOSTED_ONLY +public final class BoxedAddress extends Address implements Boxed { + + private long nativeWord; + + public static final BoxedAddress ZERO = new BoxedAddress(0); + public static final BoxedAddress MAX = new BoxedAddress(-1L); + + private static final class Cache { + private Cache() { + } + + static final int HIGHEST_VALUE = 1000; + + static final BoxedAddress[] cache = new BoxedAddress[HIGHEST_VALUE + 1]; + + static { + for (int i = 0; i < cache.length; i++) { + cache[i] = new BoxedAddress(i); + } + } + } + + public static BoxedAddress from(long value) { + if (value == 0) { + return ZERO; + } + if (value >= 0 && value <= Cache.HIGHEST_VALUE) { + return Cache.cache[(int) value]; + } + if (value == -1L) { + return MAX; + } + return new BoxedAddress(value); + } + + public static BoxedAddress from(int value) { + return from(value & BoxedWord.INT_MASK); + } + + private BoxedAddress(long value) { + if (Word.width() == 64) { + nativeWord = value; + } else { + nativeWord = value & BoxedWord.INT_MASK; + } + } + + public long value() { + return nativeWord; + } + + private static BigInteger bi(long unsigned) { + if (unsigned < 0) { + long signBit = 0x8000000000000000L; + long low63Bits = unsigned & ~signBit; + return BigInteger.valueOf(low63Bits).setBit(63); + } + return BigInteger.valueOf(unsigned); + } + + + private static long unsignedDivide(long dividend, long divisor) { + if (dividend >= 0 && divisor >= 0) { + return dividend / divisor; + } + return bi(dividend).divide(bi(divisor)).longValue(); + } + + @Override + public Address dividedByAddress(Address divisor) { + final BoxedAddress box = (BoxedAddress) divisor.asAddress(); + if (box.nativeWord == 0L) { + throw new ArithmeticException(); + } + return new BoxedAddress(unsignedDivide(nativeWord, box.nativeWord)); + } + + @Override + public Address dividedByInt(int divisor) { + if (divisor == 0) { + throw new ArithmeticException(); + } + return new BoxedAddress(unsignedDivide(nativeWord, divisor & BoxedWord.INT_MASK)); + } + + private static long unsignedRemainder(long dividend, long divisor) { + if (dividend >= 0 && divisor >= 0) { + return dividend % divisor; + } + return bi(dividend).remainder(bi(divisor)).longValue(); + } + + @Override + public Address remainderByAddress(Address divisor) { + final BoxedAddress box = (BoxedAddress) divisor.asAddress(); + if (box.nativeWord == 0L) { + throw new ArithmeticException(); + } + return new BoxedAddress(unsignedRemainder(nativeWord, box.nativeWord)); + } + + @Override + public int remainderByInt(int divisor) { + if (divisor == 0) { + throw new ArithmeticException(); + } + return (int) unsignedRemainder(nativeWord, divisor & BoxedWord.INT_MASK); + } +} diff --git a/JavaInJava/src/com/sun/max/unsafe/BoxedOffset.java b/JavaInJava/src/com/sun/max/unsafe/BoxedOffset.java new file mode 100644 index 0000000..287385e --- /dev/null +++ b/JavaInJava/src/com/sun/max/unsafe/BoxedOffset.java @@ -0,0 +1,70 @@ +/* + * 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.*; + +/** + * Boxed version of Offset. + * + * @author Bernd Mathiske + */ +@HOSTED_ONLY +public final class BoxedOffset extends Offset implements Boxed { + + private long nativeWord; + + public static final BoxedOffset ZERO = new BoxedOffset(0); + + private static final class Cache { + private Cache() { + } + + static final int LOWEST_VALUE = -100; + static final int HIGHEST_VALUE = 1000; + + static final BoxedOffset[] cache = new BoxedOffset[(HIGHEST_VALUE - LOWEST_VALUE) + 1]; + + static { + for (int i = 0; i < cache.length; i++) { + cache[i] = new BoxedOffset(i + LOWEST_VALUE); + } + } + } + + public static BoxedOffset from(long value) { + if (value == 0) { + return ZERO; + } + if (value >= Cache.LOWEST_VALUE && value <= Cache.HIGHEST_VALUE) { + return Cache.cache[(int) value - Cache.LOWEST_VALUE]; + } + return new BoxedOffset(value); + } + + private BoxedOffset(long value) { + nativeWord = value; + } + + public long value() { + return nativeWord; + } +} diff --git a/JavaInJava/src/com/sun/max/unsafe/BoxedPointer.java b/JavaInJava/src/com/sun/max/unsafe/BoxedPointer.java new file mode 100644 index 0000000..568c458 --- /dev/null +++ b/JavaInJava/src/com/sun/max/unsafe/BoxedPointer.java @@ -0,0 +1,215 @@ +/* + * 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.compiler.builtin.*; +import com.sun.max.vm.hosted.*; +import com.sun.max.vm.reference.*; + +/** + * Boxed version of Pointer. + * + * @see Pointer + * + * @author Bernd Mathiske + */ +@HOSTED_ONLY +public final class BoxedPointer extends Pointer implements Boxed { + + static { + // Ensure the native code is loaded + Prototype.loadHostedLibrary(); + } + + // ATTENTION: this field name must match the corresponding declaration in "pointer.c"! + private long nativeWord; + + public static final BoxedPointer ZERO = new BoxedPointer(0); + public static final BoxedPointer MAX = new BoxedPointer(-1L); + + private static final int HIGHEST_CACHED_VALUE = 1000000; + + private static final BoxedPointer[] cache = new BoxedPointer[HIGHEST_CACHED_VALUE + 1]; + + public static BoxedPointer from(long value) { + if (value == 0) { + return ZERO; + } + if (value >= 0 && value <= HIGHEST_CACHED_VALUE) { + int cacheIndex = (int) value; + BoxedPointer boxedPointer = cache[cacheIndex]; + if (boxedPointer == null) { + boxedPointer = new BoxedPointer(value); + cache[cacheIndex] = boxedPointer; + } + return boxedPointer; + } + if (value == -1L) { + return MAX; + } + return new BoxedPointer(value); + } + + private BoxedPointer(long value) { + nativeWord = value; + } + + public static BoxedPointer from(int value) { + return from(value & BoxedWord.INT_MASK); + } + + public long value() { + return nativeWord; + } + + @Override + protected Pointer dividedByAddress(Address divisor) { + return BoxedAddress.from(nativeWord).dividedByAddress(divisor).asPointer(); + } + + @Override + protected Pointer dividedByInt(int divisor) { + return BoxedAddress.from(nativeWord).dividedByInt(divisor).asPointer(); + } + + @Override + protected Pointer remainderByAddress(Address divisor) { + return BoxedAddress.from(nativeWord).remainderByAddress(divisor).asPointer(); + } + + @Override + protected int remainderByInt(int divisor) { + return BoxedAddress.from(nativeWord).remainderByInt(divisor); + } + + private static native byte nativeReadByte(long pointer, long offset); + + @Override + public byte readByte(Offset offset) { + return nativeReadByte(nativeWord, offset.toLong()); + } + + private static native short nativeReadShort(long pointer, long offset); + + @Override + public short readShort(Offset offset) { + return nativeReadShort(nativeWord, offset.toLong()); + } + + @Override + public char readChar(Offset offset) { + return (char) nativeReadShort(nativeWord, offset.toLong()); + } + + private static native int nativeReadInt(long pointer, long offset); + + @Override + public int readInt(Offset offset) { + return nativeReadInt(nativeWord, offset.toLong()); + } + + @Override + public float readFloat(Offset offset) { + return SpecialBuiltin.intToFloat(readInt(offset)); + } + + private static native long nativeReadLong(long pointer, long offset); + + @Override + public long readLong(Offset offset) { + return nativeReadLong(nativeWord, offset.toLong()); + } + + @Override + public double readDouble(Offset offset) { + return SpecialBuiltin.longToDouble(readLong(offset)); + } + + @Override + public Word readWord(Offset offset) { + if (Word.width() == 64) { + return Address.fromLong(readLong(offset)); + } + return Address.fromInt(readInt(offset)); + } + + private static native Object nativeReadObject(long offset); + + @Override + public Reference readReference(Offset offset) { + return Reference.fromJava(nativeReadObject(offset.toLong())); + } + + private static native void nativeWriteByte(long pointer, long offset, byte value); + + @Override + public void writeByte(Offset offset, byte value) { + nativeWriteByte(nativeWord, offset.toLong(), value); + } + + private static native void nativeWriteShort(long pointer, long offset, short value); + + @Override + public void writeShort(Offset offset, short value) { + nativeWriteShort(nativeWord, offset.toLong(), value); + } + + private static native void nativeWriteInt(long pointer, long offset, int value); + + @Override + public void writeInt(Offset offset, int value) { + nativeWriteInt(nativeWord, offset.toLong(), value); + } + + @Override + public void writeFloat(Offset offset, float value) { + writeInt(offset, SpecialBuiltin.floatToInt(value)); + } + + private static native void nativeWriteLong(long pointer, long offset, long value); + + @Override + public void writeLong(Offset offset, long value) { + nativeWriteLong(nativeWord, offset.toLong(), value); + } + + @Override + public void writeDouble(Offset offset, double value) { + writeLong(offset, SpecialBuiltin.doubleToLong(value)); + } + + @Override + public void writeWord(Offset offset, Word value) { + if (Word.width() == 64) { + writeLong(offset, value.asOffset().toLong()); + } else { + writeInt(offset, value.asOffset().toInt()); + } + } + + private static native void nativeWriteObject(long pointer, long offset, Object value); + + @Override + public void writeReference(Offset offset, Reference value) { + nativeWriteObject(nativeWord, offset.toLong(), value.toJava()); + } +} diff --git a/JavaInJava/src/com/sun/max/unsafe/BoxedSize.java b/JavaInJava/src/com/sun/max/unsafe/BoxedSize.java new file mode 100644 index 0000000..2627b57 --- /dev/null +++ b/JavaInJava/src/com/sun/max/unsafe/BoxedSize.java @@ -0,0 +1,101 @@ +/* + * 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.*; + +/** + * Boxed version of Size. + * + * @see Size + * + * @author Bernd Mathiske + */ +@HOSTED_ONLY +public final class BoxedSize extends Size implements Boxed { + + private long nativeWord; + + public static final BoxedSize ZERO = new BoxedSize(0); + public static final BoxedSize MAX = new BoxedSize(-1L); + + private static final class Cache { + private Cache() { + } + + static final int HIGHEST_VALUE = 1000; + + static final BoxedSize[] cache = new BoxedSize[HIGHEST_VALUE + 1]; + + static { + for (int i = 0; i < cache.length; i++) { + cache[i] = new BoxedSize(i); + } + } + } + + public static BoxedSize from(long value) { + if (value == 0) { + return ZERO; + } + if (value >= 0 && value <= Cache.HIGHEST_VALUE) { + return Cache.cache[(int) value]; + } + if (value == -1L) { + return MAX; + } + + return new BoxedSize(value); + } + + private BoxedSize(long value) { + nativeWord = value; + } + + public static BoxedSize from(int value) { + return from(value & BoxedWord.INT_MASK); + } + + public long value() { + return nativeWord; + } + + @Override + protected Size dividedByAddress(Address divisor) { + return BoxedAddress.from(nativeWord).dividedByAddress(divisor).asSize(); + } + + @Override + protected Size dividedByInt(int divisor) { + return BoxedAddress.from(nativeWord).dividedByInt(divisor).asSize(); + } + + @Override + protected Size remainderByAddress(Address divisor) { + return BoxedAddress.from(nativeWord).remainderByAddress(divisor).asSize(); + } + + @Override + protected int remainderByInt(int divisor) { + return BoxedAddress.from(nativeWord).remainderByInt(divisor); + } + +} diff --git a/JavaInJava/src/com/sun/max/unsafe/BoxedWord.java b/JavaInJava/src/com/sun/max/unsafe/BoxedWord.java new file mode 100644 index 0000000..741c42f --- /dev/null +++ b/JavaInJava/src/com/sun/max/unsafe/BoxedWord.java @@ -0,0 +1,58 @@ +/* + * 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.*; + +/** + * Boxed version of Word. + * + * @see Word + * + * @author Bernd Mathiske + */ +@HOSTED_ONLY +public final class BoxedWord extends Word implements Boxed { + + public static final long INT_MASK = 0x00000000ffffffffL; + + private long nativeWord; + + public BoxedWord(Boxed unsafeBox) { + nativeWord = unsafeBox.value(); + } + + public BoxedWord(int value) { + nativeWord = value & INT_MASK; + } + + public BoxedWord(long value) { + nativeWord = value; + } + + public BoxedWord(Word value) { + nativeWord = value.asOffset().toLong(); + } + + public long value() { + return nativeWord; + } +} diff --git a/JavaInJava/src/com/sun/max/unsafe/CString.java b/JavaInJava/src/com/sun/max/unsafe/CString.java new file mode 100644 index 0000000..512b0a9 --- /dev/null +++ b/JavaInJava/src/com/sun/max/unsafe/CString.java @@ -0,0 +1,446 @@ +/* + * 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.io.*; + +import com.sun.max.lang.*; +import com.sun.max.memory.*; +import com.sun.max.util.*; +import com.sun.max.vm.*; + +/** + * Utilities for converting between Java strings and C strings (encoded as UTF8 bytes). + * + * @author Bernd Mathiske + * @author Doug Simon + */ +public final class CString { + + private CString() { + } + + /** + * Determines the length of a NULL terminated C string located in natively {@link Memory#allocate(int) allocated} memory. + * @param cString the string for which to get the length + * @return the length + */ + public static Size length(Pointer cString) { + Pointer p = cString; + while (p.readByte(0) != (byte) 0) { + p = p.plus(1); + } + return p.minus(cString).asSize(); + } + + /** + * Gets the byte at given index in C string with bounds check. + * + * @param cString the C string + * @param length length of C string (@see length) + * @param index index of byte to get + * @return -1 if the index is out of range or the byte at the index + */ + public static int getByte(Pointer cString, Size length, Offset index) { + if (index.lessThan(length.asOffset())) { + return cString.readByte(index); + } + return -1; + } + + /** + * Converts a NULL terminated C string located in natively allocated memory to a Java string. + */ + public static String utf8ToJava(Pointer cString) throws Utf8Exception { + final int n = length(cString).toInt(); + final byte[] bytes = new byte[n]; + Memory.readBytes(cString, n, bytes); + return Utf8.utf8ToString(false, bytes); + } + + /** + * Creates a NULL terminated C string (in natively allocated} memory) from a Java string. + * The returned C string must be deallocated by {@link Memory#deallocate(Address)} when finished with. + */ + public static Pointer utf8FromJava(String string) { + final byte[] utf8 = Utf8.stringToUtf8(string); + final Pointer cString = Memory.mustAllocate(utf8.length + 1); + Pointer p = cString; + for (byte utf8Char : utf8) { + p.writeByte(0, utf8Char); + p = p.plus(1); + } + p.writeByte(0, (byte) 0); + return cString; + } + + public static byte[] read(InputStream stream) throws IOException { + final ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + while (true) { + final int ch = stream.read(); + if (ch < 0) { + throw new IOException(); + } + buffer.write(ch); + if (ch == 0) { + return buffer.toByteArray(); + } + } + } + + /** + * Fills a given buffer with a zero-terminated sequence of bytes from a source buffer. + * + * @param source the byte array containing the source bytes + * @param start the start offset in {@code source} of the bytes to be written (inclusive) + * @param end the end offset of {@code source} of the bytes to be written (exclusive) + * @param buffer a pointer to the beginning of the buffer + * @param bufferSize the size of the buffer + * @return an index into the next byte to be written which is start <= result <= end + */ + public static int writeBytes(byte[] source, int start, int end, Pointer buffer, int bufferSize) { + final int n = Math.min(bufferSize - 1, end - start); + for (int i = 0; i < n; i++) { + buffer.writeByte(i, source[start + i]); + } + buffer.writeByte(n, (byte) 0); + return start + n; + } + + /** + * Fills a given buffer with the bytes in the UTF8 representation of a string following by a terminating zero. The + * maximum number of bytes written to the buffer is limited to the number of leading characters of {@code string} + * that can be completely encoded in {@code bufferSize - 2} bytes. + * + * @param string the String to write to the buffer + * @param buffer a pointer to the beginning of the buffer + * @param bufferSize the size of the buffer + * @return a pointer to the position in the buffer following the terminating zero character + */ + public static Pointer writeUtf8(final String string, final Pointer buffer, final int bufferSize) { + int position = 0; + final int endPosition = bufferSize - 1; + for (int i = 0; i < string.length(); i++) { + final char ch = string.charAt(i); + if ((ch >= 0x0001) && (ch <= 0x007F)) { + if (position >= endPosition) { + break; + } + buffer.writeByte(position++, (byte) ch); + } else if (ch > 0x07FF) { + if (position + 2 >= endPosition) { + break; + } + buffer.writeByte(position++, (byte) (0xe0 | (byte) (ch >> 12))); + buffer.writeByte(position++, (byte) (0x80 | ((ch & 0xfc0) >> 6))); + buffer.writeByte(position++, (byte) (0x80 | (ch & 0x3f))); + } else { + if (position + 1 >= endPosition) { + break; + } + buffer.writeByte(position++, (byte) (0xc0 | (byte) (ch >> 6))); + buffer.writeByte(position++, (byte) (0x80 | (ch & 0x3f))); + } + } + buffer.writeByte(position, (byte) 0); + return buffer.plus(position + 1); + } + + /** + * Fills a given buffer with the bytes in the UTF8 representation of a string following by a terminating zero. The + * maximum number of bytes written to the buffer is limited to the number of leading characters of {@code string} + * that can be completely encoded in {@code bufferSize - 2} bytes. + * + * @param chars the characters to write to the buffer + * @param start the index of the character in {@code string} from which to start copying + * @param buffer a pointer to the beginning of the buffer + * @param bufferSize the size of the buffer + * @return the number of characters from {@code string} written to the buffer + */ + public static int writePartialUtf8(final char[] chars, final int start, final Pointer buffer, final int bufferSize) { + int position = 0; + final int endPosition = bufferSize - 1; + int i = start; + while (i < chars.length) { + final char ch = chars[i]; + if ((ch >= 0x0001) && (ch <= 0x007F)) { + if (position >= endPosition) { + break; + } + buffer.writeByte(position++, (byte) ch); + } else if (ch > 0x07FF) { + if (position + 2 >= endPosition) { + break; + } + buffer.writeByte(position++, (byte) (0xe0 | (byte) (ch >> 12))); + buffer.writeByte(position++, (byte) (0x80 | ((ch & 0xfc0) >> 6))); + buffer.writeByte(position++, (byte) (0x80 | (ch & 0x3f))); + } else { + if (position + 1 >= endPosition) { + break; + } + buffer.writeByte(position++, (byte) (0xc0 | (byte) (ch >> 6))); + buffer.writeByte(position++, (byte) (0x80 | (ch & 0x3f))); + } + i++; + } + buffer.writeByte(position, (byte) 0); + return i; + } + + /** + * Fills a given buffer with the bytes in the UTF8 representation of a string following by a terminating zero. The + * maximum number of bytes written to the buffer is limited to the number of leading characters of {@code string} + * that can be completely encoded in {@code bufferSize - 2} bytes. + * + * @param string the String to write to the buffer + * @param start the index of the character in {@code string} from which to start copying + * @param buffer a pointer to the beginning of the buffer + * @param bufferSize the size of the buffer + * @return the number of characters from {@code string} written to the buffer + */ + public static int writePartialUtf8(final String string, final int start, final Pointer buffer, final int bufferSize) { + int position = 0; + final int endPosition = bufferSize - 1; + int i = start; + while (i < string.length()) { + final char ch = string.charAt(i); + if ((ch >= 0x0001) && (ch <= 0x007F)) { + if (position >= endPosition) { + break; + } + buffer.writeByte(position++, (byte) ch); + } else if (ch > 0x07FF) { + if (position + 2 >= endPosition) { + break; + } + buffer.writeByte(position++, (byte) (0xe0 | (byte) (ch >> 12))); + buffer.writeByte(position++, (byte) (0x80 | ((ch & 0xfc0) >> 6))); + buffer.writeByte(position++, (byte) (0x80 | (ch & 0x3f))); + } else { + if (position + 1 >= endPosition) { + break; + } + buffer.writeByte(position++, (byte) (0xc0 | (byte) (ch >> 6))); + buffer.writeByte(position++, (byte) (0x80 | (ch & 0x3f))); + } + i++; + } + buffer.writeByte(position, (byte) 0); + return i; + } + + public static byte[] toByteArray(Pointer start, int length) { + final byte[] buffer = new byte[length]; + for (int i = 0; i < length; i++) { + buffer[i] = start.getByte(i); + } + return buffer; + } + + /** + * Copies an array of Java strings into a native array of C strings. The memory for the C string array and each + * element in the array is allocated in one memory chunk. The C string array is first in the chunk, followed by 0 if + * {@code appendNullDelimiter == true}, followed by {@code strings.length} null terminated C strings. De-allocating + * the memory for the buffer is the responsibility of the caller. + * + * @param strings an array of Java strings + * @param appendNullDelimiter {@code true} if a null delimiter character '\0' should be appended + * @return a native buffer than can be cast to the C type {@code char**} and used as the first argument to a C + * {@code main} function + */ + public static Pointer utf8ArrayFromStringArray(String[] strings, boolean appendNullDelimiter) { + final int nullDelimiter = appendNullDelimiter ? 1 : 0; + final int pointerArraySize = Word.size() * (strings.length + nullDelimiter); + int bufferSize = pointerArraySize; + final int[] utf8Lengths = new int[strings.length]; + for (int i = 0; i < strings.length; ++i) { + final String s = strings[i]; + final int utf8Length = Utf8.utf8Length(s); + utf8Lengths[i] = utf8Length; + bufferSize += utf8Length + 1; + } + final Pointer buffer = Memory.mustAllocate(bufferSize); + + Pointer stringPointer = buffer.plus(pointerArraySize); + for (int i = 0; i < strings.length; ++i) { + final String s = strings[i]; + buffer.setWord(i, stringPointer); + stringPointer = CString.writeUtf8(s, stringPointer, utf8Lengths[i] + 1); + } + if (appendNullDelimiter) { + buffer.setWord(strings.length, Word.zero()); + } + + return buffer; + } + + public static boolean equals(Pointer cstring, String string) { + if (cstring.isZero()) { + return false; + } + for (int i = 0; i < string.length(); i++) { + final byte ch = cstring.getByte(i); + if (ch == 0 || ch != string.charAt(i)) { + return false; + } + } + return cstring.getByte(string.length()) == 0; + } + + /** + * Determines if a given C string starts with a given prefix. + * + * @param cstring the C string to test + * @param prefix the prefix to test against + * @return {@code true} if {@code cstring} starts with {@code prefix} + */ + public static boolean startsWith(Pointer cstring, String prefix) { + if (cstring.isZero()) { + return false; + } + for (int i = 0; i < prefix.length(); i++) { + final byte ch = cstring.getByte(i); + if (ch == 0 || ch != prefix.charAt(i)) { + return false; + } + } + return true; + } + + /** + * Parse a size specification nX, where X := {K, M, G, T, P, k, m, g, t, p}. + * + * For backwards compatibility with HotSpot, + * lower case letters shall have the same respective meaning as the upper case ones, + * even though their non-colloquialized definitions would suggest otherwise. + * + * @param p a pointer to the C string + * @param length the maximum length of the C string + * @param startIndex the starting index into the C string pointed to by the first argument + * @return the scaled value or -1 if error + */ + public static long parseScaledValue(Pointer p, Size length, int startIndex) { + long result = 0L; + boolean done = false; + int index = startIndex; + while (index < length.toInt()) { + if (done) { + // having any additional characters is an error + return -1L; + } + final int character = getByte(p, length, Offset.fromInt(index)); + index++; + if ('0' <= character && character <= '9') { + result *= 10; + result += character - '0'; + } else { + done = true; + switch (character) { + case 'K': + case 'k': { + result *= Longs.K; + break; + } + case 'M': + case 'm': { + result *= Longs.M; + break; + } + case 'G': + case 'g': { + result *= Longs.G; + break; + } + case 'T': + case 't': { + result *= Longs.T; + break; + } + case 'P': + case 'p': { + result *= Longs.P; + break; + } + default: { + // illegal character + return -1L; + } + } + } + } + return result; + } + + public static int parseUnsignedInt(Pointer pointer) { + int result = 0; + Pointer ptr = pointer; + while (true) { + final char ch = (char) ptr.getByte(); + if (ch == 0) { + break; + } + if (ch >= '0' && ch <= '9') { + result *= 10; + result += ch - '0'; + } else { + return -1; + } + ptr = ptr.plus(1); + } + return result; + } + + public static long parseUnsignedLong(String string) { + long result = 0L; + for (int i = 0; i < string.length(); i++) { + final char ch = string.charAt(i); + if (ch >= '0' && ch <= '9') { + result *= 10L; + result += string.charAt(i) - '0'; + } else { + return -1L; + } + } + return result; + } + + /** + * Parses a given C string as a floating value. + * + * @param cstring the C string to parse + * @return the value of {@code cstring} as a float or {@link Float#NaN} if {@code cstring} does not contain a valid + * float value + */ + public static float parseFloat(Pointer cstring) { + if (MaxineVM.isHosted()) { + try { + return Float.parseFloat(utf8ToJava(cstring)); + } catch (Exception e) { + return Float.NaN; + } + } + // Defer to native code so that all the FloatingDecimal logic does not + // have to be in the VM boot image. + return MaxineVM.native_parseFloat(cstring, Float.NaN); + } +} 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/MemoryDataAccess.java b/JavaInJava/src/com/sun/max/unsafe/MemoryDataAccess.java new file mode 100644 index 0000000..ce97ac0 --- /dev/null +++ b/JavaInJava/src/com/sun/max/unsafe/MemoryDataAccess.java @@ -0,0 +1,360 @@ +/* + * 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.*; + +import com.sun.max.memory.*; +import com.sun.max.vm.runtime.*; + +/** + * Implementation of {@link DataAccess} by direct main memory access. + * + * @author Bernd Mathiske + */ +public final class MemoryDataAccess implements DataAccess { + + private MemoryDataAccess() { + } + + public static final MemoryDataAccess MEMORY_DATA_ACCESS = new MemoryDataAccess(); + + public void readFully(Address address, ByteBuffer buffer) { + DataIO.Static.readFully(this, address, buffer); + } + + public byte[] readFully(Address address, int length) { + return DataIO.Static.readFully(this, address, length); + } + + public void readFully(Address address, byte[] buffer) { + readFully(address, ByteBuffer.wrap(buffer)); + } + + public int read(Address address, ByteBuffer buffer, int offset, int length) { + throw FatalError.unimplemented(); + } + + public int write(ByteBuffer buffer, int offset, int length, Address toAddress) throws DataIOError { + throw FatalError.unimplemented(); + } + + public void writeBuffer(Address address, ByteBuffer buffer) { + throw FatalError.unimplemented(); + } + + public byte readByte(Address address) { + return address.asPointer().readByte(0); + } + + public byte readByte(Address address, Offset offset) { + return address.asPointer().readByte(offset); + } + + public byte readByte(Address address, int offset) { + return address.asPointer().readByte(offset); + } + + public byte getByte(Address address, int displacement, int index) { + return address.asPointer().getByte(displacement, index); + } + + public boolean readBoolean(Address address) { + return address.asPointer().readBoolean(0); + } + + public boolean readBoolean(Address address, Offset offset) { + return address.asPointer().readBoolean(offset); + } + + public boolean readBoolean(Address address, int offset) { + return address.asPointer().readBoolean(offset); + } + + public boolean getBoolean(Address address, int displacement, int index) { + return address.asPointer().getBoolean(displacement, index); + } + + public short readShort(Address address) { + return address.asPointer().readShort(0); + } + + public short readShort(Address address, Offset offset) { + return address.asPointer().readShort(offset); + } + + public short readShort(Address address, int offset) { + return address.asPointer().readShort(offset); + } + + public short getShort(Address address, int displacement, int index) { + return address.asPointer().getShort(displacement, index); + } + + public char readChar(Address address) { + return address.asPointer().readChar(0); + } + + public char readChar(Address address, Offset offset) { + return address.asPointer().readChar(offset); + } + + public char readChar(Address address, int offset) { + return address.asPointer().readChar(offset); + } + + public char getChar(Address address, int displacement, int index) { + return address.asPointer().getChar(displacement, index); + } + + public int readInt(Address address) { + return address.asPointer().readInt(0); + } + + public int readInt(Address address, Offset offset) { + return address.asPointer().readInt(offset); + } + + public int readInt(Address address, int offset) { + return address.asPointer().readInt(offset); + } + + public int getInt(Address address, int displacement, int index) { + return address.asPointer().getInt(displacement, index); + } + + public float readFloat(Address address) { + return address.asPointer().readFloat(0); + } + + public float readFloat(Address address, Offset offset) { + return address.asPointer().readFloat(offset); + } + + public float readFloat(Address address, int offset) { + return address.asPointer().readFloat(offset); + } + + public float getFloat(Address address, int displacement, int index) { + return address.asPointer().getFloat(displacement, index); + } + + public long readLong(Address address) { + return address.asPointer().readLong(0); + } + + public long readLong(Address address, Offset offset) { + return address.asPointer().readLong(offset); + } + + public long readLong(Address address, int offset) { + return address.asPointer().readLong(offset); + } + + public long getLong(Address address, int displacement, int index) { + return address.asPointer().getLong(displacement, index); + } + + public double readDouble(Address address) { + return address.asPointer().readDouble(0); + } + + public double readDouble(Address address, Offset offset) { + return address.asPointer().readDouble(offset); + } + + public double readDouble(Address address, int offset) { + return address.asPointer().readDouble(offset); + } + + public double getDouble(Address address, int displacement, int index) { + return address.asPointer().getDouble(displacement, index); + } + + public Word readWord(Address address) { + return address.asPointer().readWord(0); + } + + public Word readWord(Address address, Offset offset) { + return address.asPointer().readWord(offset); + } + + public Word readWord(Address address, int offset) { + return address.asPointer().readWord(offset); + } + + public Word getWord(Address address, int displacement, int index) { + return address.asPointer().getWord(displacement, index); + } + + public void writeBytes(Address address, byte[] bytes) { + Memory.writeBytes(bytes, address.asPointer()); + } + + public void writeByte(Address address, byte value) { + address.asPointer().writeByte(0, value); + } + + public void writeByte(Address address, Offset offset, byte value) { + address.asPointer().writeByte(offset, value); + } + + public void writeByte(Address address, int offset, byte value) { + address.asPointer().writeByte(offset, value); + } + + public void setByte(Address address, int displacement, int index, byte value) { + address.asPointer().setByte(displacement, index, value); + } + + public void writeBoolean(Address address, boolean value) { + address.asPointer().writeBoolean(0, value); + } + + public void writeBoolean(Address address, Offset offset, boolean value) { + address.asPointer().writeBoolean(offset, value); + } + + public void writeBoolean(Address address, int offset, boolean value) { + address.asPointer().writeBoolean(offset, value); + } + + public void setBoolean(Address address, int displacement, int index, boolean value) { + address.asPointer().setBoolean(displacement, index, value); + } + + public void writeShort(Address address, short value) { + address.asPointer().writeShort(0, value); + } + + public void writeShort(Address address, Offset offset, short value) { + address.asPointer().writeShort(offset, value); + } + + public void writeShort(Address address, int offset, short value) { + address.asPointer().writeShort(offset, value); + } + + public void setShort(Address address, int displacement, int index, short value) { + address.asPointer().setShort(displacement, index, value); + } + + public void writeChar(Address address, char value) { + address.asPointer().writeChar(0, value); + } + + public void writeChar(Address address, Offset offset, char value) { + address.asPointer().writeChar(offset, value); + } + + public void writeChar(Address address, int offset, char value) { + address.asPointer().writeChar(offset, value); + } + + public void setChar(Address address, int displacement, int index, char value) { + address.asPointer().setChar(displacement, index, value); + } + + public void writeInt(Address address, int value) { + address.asPointer().writeInt(0, value); + } + + public void writeInt(Address address, Offset offset, int value) { + address.asPointer().writeInt(offset, value); + } + + public void writeInt(Address address, int offset, int value) { + address.asPointer().writeInt(offset, value); + } + + public void setInt(Address address, int displacement, int index, int value) { + address.asPointer().setInt(displacement, index, value); + } + + public void writeFloat(Address address, float value) { + address.asPointer().writeFloat(0, value); + } + + public void writeFloat(Address address, Offset offset, float value) { + address.asPointer().writeFloat(offset, value); + } + + public void writeFloat(Address address, int offset, float value) { + address.asPointer().writeFloat(offset, value); + } + + public void setFloat(Address address, int displacement, int index, float value) { + address.asPointer().setFloat(displacement, index, value); + } + + public void writeLong(Address address, long value) { + address.asPointer().writeLong(0, value); + } + + public void writeLong(Address address, Offset offset, long value) { + address.asPointer().writeLong(offset, value); + } + + public void writeLong(Address address, int offset, long value) { + address.asPointer().writeLong(offset, value); + } + + public void setLong(Address address, int displacement, int index, long value) { + address.asPointer().setLong(displacement, index, value); + } + + public void writeDouble(Address address, double value) { + address.asPointer().writeDouble(0, value); + } + + public void writeDouble(Address address, Offset offset, double value) { + address.asPointer().writeDouble(offset, value); + } + + public void writeDouble(Address address, int offset, double value) { + address.asPointer().writeDouble(offset, value); + } + + public void setDouble(Address address, int displacement, int index, double value) { + address.asPointer().setDouble(displacement, index, value); + } + + public void writeWord(Address address, Word value) { + address.asPointer().writeWord(0, value); + } + + public void writeWord(Address address, Offset offset, Word value) { + address.asPointer().writeWord(offset, value); + } + + public void writeWord(Address address, int offset, Word value) { + address.asPointer().writeWord(offset, value); + } + + public void setWord(Address address, int displacement, int index, Word value) { + address.asPointer().setWord(displacement, index, value); + } + + @Override + public void copyElements(Address address, int displacement, int srcIndex, Object dst, int dstIndex, int length) { + address.asPointer().copyElements(displacement, srcIndex, dst, dstIndex, length); + } +} 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..2bedb81 --- /dev/null +++ b/JavaInJava/src/com/sun/max/unsafe/Offset.java @@ -0,0 +1,377 @@ +/* + * 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.max.vm.MaxineVM.*; + +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 isHosted() ? BoxedOffset.ZERO : fromInt(0); + } + + @INLINE + public static Offset fromUnsignedInt(int value) { + return Address.fromUnsignedInt(value).asOffset(); + } + + @INLINE + public static Offset fromInt(int value) { + if (isHosted()) { + return BoxedOffset.from(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 (isHosted()) { + return BoxedOffset.from(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 (isHosted()) { + final BoxedOffset box = (BoxedOffset) this; + return (int) box.value(); + } + if (Word.width() == 64) { + final long n = UnsafeCast.asLong(this); + return (int) n; + } + return UnsafeCast.asInt(this); + } + + @INLINE + public final long toLong() { + if (isHosted()) { + final BoxedOffset box = (BoxedOffset) this; + return box.value(); + } + 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) { + if (isHosted()) { + return toLong() == 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..eddcf9a --- /dev/null +++ b/JavaInJava/src/com/sun/max/unsafe/Pointer.java @@ -0,0 +1,1125 @@ +/* + * 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.vm.MaxineVM.*; + +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.compiler.builtin.PointerAtomicBuiltin.CompareAndSwapInt; +import com.sun.max.vm.compiler.builtin.PointerAtomicBuiltin.CompareAndSwapIntAtIntOffset; +import com.sun.max.vm.compiler.builtin.PointerAtomicBuiltin.CompareAndSwapReference; +import com.sun.max.vm.compiler.builtin.PointerAtomicBuiltin.CompareAndSwapReferenceAtIntOffset; +import com.sun.max.vm.compiler.builtin.PointerAtomicBuiltin.CompareAndSwapWord; +import com.sun.max.vm.compiler.builtin.PointerAtomicBuiltin.CompareAndSwapWordAtIntOffset; +import com.sun.max.vm.compiler.builtin.PointerLoadBuiltin.GetByte; +import com.sun.max.vm.compiler.builtin.PointerLoadBuiltin.GetChar; +import com.sun.max.vm.compiler.builtin.PointerLoadBuiltin.GetDouble; +import com.sun.max.vm.compiler.builtin.PointerLoadBuiltin.GetFloat; +import com.sun.max.vm.compiler.builtin.PointerLoadBuiltin.GetInt; +import com.sun.max.vm.compiler.builtin.PointerLoadBuiltin.GetLong; +import com.sun.max.vm.compiler.builtin.PointerLoadBuiltin.GetReference; +import com.sun.max.vm.compiler.builtin.PointerLoadBuiltin.GetShort; +import com.sun.max.vm.compiler.builtin.PointerLoadBuiltin.GetWord; +import com.sun.max.vm.compiler.builtin.PointerLoadBuiltin.ReadByte; +import com.sun.max.vm.compiler.builtin.PointerLoadBuiltin.ReadByteAtIntOffset; +import com.sun.max.vm.compiler.builtin.PointerLoadBuiltin.ReadChar; +import com.sun.max.vm.compiler.builtin.PointerLoadBuiltin.ReadCharAtIntOffset; +import com.sun.max.vm.compiler.builtin.PointerLoadBuiltin.ReadDouble; +import com.sun.max.vm.compiler.builtin.PointerLoadBuiltin.ReadDoubleAtIntOffset; +import com.sun.max.vm.compiler.builtin.PointerLoadBuiltin.ReadFloat; +import com.sun.max.vm.compiler.builtin.PointerLoadBuiltin.ReadFloatAtIntOffset; +import com.sun.max.vm.compiler.builtin.PointerLoadBuiltin.ReadInt; +import com.sun.max.vm.compiler.builtin.PointerLoadBuiltin.ReadIntAtIntOffset; +import com.sun.max.vm.compiler.builtin.PointerLoadBuiltin.ReadLong; +import com.sun.max.vm.compiler.builtin.PointerLoadBuiltin.ReadLongAtIntOffset; +import com.sun.max.vm.compiler.builtin.PointerLoadBuiltin.ReadReference; +import com.sun.max.vm.compiler.builtin.PointerLoadBuiltin.ReadReferenceAtIntOffset; +import com.sun.max.vm.compiler.builtin.PointerLoadBuiltin.ReadShort; +import com.sun.max.vm.compiler.builtin.PointerLoadBuiltin.ReadShortAtIntOffset; +import com.sun.max.vm.compiler.builtin.PointerLoadBuiltin.ReadWord; +import com.sun.max.vm.compiler.builtin.PointerLoadBuiltin.ReadWordAtIntOffset; +import com.sun.max.vm.compiler.builtin.PointerStoreBuiltin.SetByte; +import com.sun.max.vm.compiler.builtin.PointerStoreBuiltin.SetDouble; +import com.sun.max.vm.compiler.builtin.PointerStoreBuiltin.SetFloat; +import com.sun.max.vm.compiler.builtin.PointerStoreBuiltin.SetInt; +import com.sun.max.vm.compiler.builtin.PointerStoreBuiltin.SetLong; +import com.sun.max.vm.compiler.builtin.PointerStoreBuiltin.SetReference; +import com.sun.max.vm.compiler.builtin.PointerStoreBuiltin.SetShort; +import com.sun.max.vm.compiler.builtin.PointerStoreBuiltin.SetWord; +import com.sun.max.vm.compiler.builtin.PointerStoreBuiltin.WriteByte; +import com.sun.max.vm.compiler.builtin.PointerStoreBuiltin.WriteByteAtIntOffset; +import com.sun.max.vm.compiler.builtin.PointerStoreBuiltin.WriteDouble; +import com.sun.max.vm.compiler.builtin.PointerStoreBuiltin.WriteDoubleAtIntOffset; +import com.sun.max.vm.compiler.builtin.PointerStoreBuiltin.WriteFloat; +import com.sun.max.vm.compiler.builtin.PointerStoreBuiltin.WriteFloatAtIntOffset; +import com.sun.max.vm.compiler.builtin.PointerStoreBuiltin.WriteInt; +import com.sun.max.vm.compiler.builtin.PointerStoreBuiltin.WriteIntAtIntOffset; +import com.sun.max.vm.compiler.builtin.PointerStoreBuiltin.WriteLong; +import com.sun.max.vm.compiler.builtin.PointerStoreBuiltin.WriteLongAtIntOffset; +import com.sun.max.vm.compiler.builtin.PointerStoreBuiltin.WriteReference; +import com.sun.max.vm.compiler.builtin.PointerStoreBuiltin.WriteReferenceAtIntOffset; +import com.sun.max.vm.compiler.builtin.PointerStoreBuiltin.WriteShort; +import com.sun.max.vm.compiler.builtin.PointerStoreBuiltin.WriteShortAtIntOffset; +import com.sun.max.vm.compiler.builtin.PointerStoreBuiltin.WriteWord; +import com.sun.max.vm.compiler.builtin.PointerStoreBuiltin.WriteWordAtIntOffset; +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 + @INTRINSIC(WCONST_0) + public static Pointer zero() { + return isHosted() ? BoxedPointer.ZERO : 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 + @INTRINSIC(WDIV) + public final Pointer dividedBy(Address divisor) { + return asAddress().dividedBy(divisor).asPointer(); + } + + @Override + @INLINE + @INTRINSIC(WDIVI) + public final Pointer dividedBy(int divisor) { + return asAddress().dividedBy(divisor).asPointer(); + } + + @Override + @INLINE + @INTRINSIC(WREM) + 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; + } + + @BUILTIN(ReadByteAtIntOffset.class) + @INTRINSIC(PREAD_BYTE_I) + public byte readByte(int offset) { + return readByte(Offset.fromInt(offset)); + } + + @BUILTIN(ReadByte.class) + @INTRINSIC(PREAD_BYTE) + public abstract byte readByte(Offset offset); + + @BUILTIN(GetByte.class) + @INTRINSIC(PGET_BYTE) + private native byte builtinGetByte(int displacement, int index); + + @INLINE + public final byte getByte(int displacement, int index) { + if (risc() || isHosted()) { + 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); + } + + @BUILTIN(ReadShortAtIntOffset.class) + @INTRINSIC(PREAD_SHORT_I) + public final short readShort(int offset) { + return readShort(Offset.fromInt(offset)); + } + + @BUILTIN(ReadShort.class) + @INTRINSIC(PREAD_SHORT) + public abstract short readShort(Offset offset); + + @BUILTIN(GetShort.class) + @INTRINSIC(PGET_SHORT) + private native short builtinGetShort(int displacement, int index); + + @INLINE + public final short getShort(int displacement, int index) { + if (risc() || isHosted()) { + 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); + } + + @BUILTIN(ReadCharAtIntOffset.class) + @INTRINSIC(PREAD_CHAR_I) + public final char readChar(int offset) { + return readChar(Offset.fromInt(offset)); + } + + @BUILTIN(ReadChar.class) + @INTRINSIC(PREAD_CHAR) + public abstract char readChar(Offset offset); + + @BUILTIN(GetChar.class) + @INTRINSIC(PGET_CHAR) + private native char builtinGetChar(int displacement, int index); + + @INLINE + public final char getChar(int displacement, int index) { + if (risc() || isHosted()) { + 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); + } + + @BUILTIN(ReadIntAtIntOffset.class) + @INTRINSIC(PREAD_INT_I) + public final int readInt(int offset) { + return readInt(Offset.fromInt(offset)); + } + + @BUILTIN(ReadInt.class) + @INTRINSIC(PREAD_INT) + public abstract int readInt(Offset offset); + + @BUILTIN(GetInt.class) + @INTRINSIC(PGET_INT) + private native int builtinGetInt(int displacement, int index); + + @INLINE + public final int getInt(int displacement, int index) { + if (risc() || isHosted()) { + 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); + } + + @BUILTIN(ReadFloatAtIntOffset.class) + @INTRINSIC(PREAD_FLOAT_I) + public final float readFloat(int offset) { + return readFloat(Offset.fromInt(offset)); + } + + @BUILTIN(ReadFloat.class) + @INTRINSIC(PREAD_FLOAT) + public abstract float readFloat(Offset offset); + + @BUILTIN(GetFloat.class) + @INTRINSIC(PGET_FLOAT) + private native float builtinGetFloat(int displacement, int index); + + @INLINE + public final float getFloat(int displacement, int index) { + if (risc() || isHosted()) { + 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); + } + + @BUILTIN(ReadLongAtIntOffset.class) + @INTRINSIC(PREAD_LONG_I) + public final long readLong(int offset) { + return readLong(Offset.fromInt(offset)); + } + + @BUILTIN(ReadLong.class) + @INTRINSIC(PREAD_LONG) + public abstract long readLong(Offset offset); + + @BUILTIN(GetLong.class) + @INTRINSIC(PGET_LONG) + private native long builtinGetLong(int displacement, int index); + + @INLINE + public final long getLong(int displacement, int index) { + if (risc() || isHosted()) { + 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); + } + + @BUILTIN(ReadDoubleAtIntOffset.class) + @INTRINSIC(PREAD_DOUBLE_I) + public final double readDouble(int offset) { + return readDouble(Offset.fromInt(offset)); + } + + @BUILTIN(ReadDouble.class) + @INTRINSIC(PREAD_DOUBLE) + public abstract double readDouble(Offset offset); + + @BUILTIN(GetDouble.class) + @INTRINSIC(PGET_DOUBLE) + private native double builtinGetDouble(int displacement, int index); + + @INLINE + public final double getDouble(int displacement, int index) { + if (risc() || isHosted()) { + 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); + } + + @BUILTIN(ReadWordAtIntOffset.class) + @INTRINSIC(PREAD_WORD_I) + public final Word readWord(int offset) { + return readWord(Offset.fromInt(offset)); + } + + @BUILTIN(ReadWord.class) + @INTRINSIC(PREAD_WORD) + public abstract Word readWord(Offset offset); + + @BUILTIN(GetWord.class) + @INTRINSIC(PGET_WORD) + private native Word builtinGetWord(int displacement, int index); + + @INLINE + public final Word getWord(int displacement, int index) { + if (risc() || isHosted()) { + 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); + } + + @BUILTIN(ReadReferenceAtIntOffset.class) + @INTRINSIC(PREAD_REFERENCE_I) + public final Reference readReference(int offset) { + return readReference(Offset.fromInt(offset)); + } + + @BUILTIN(ReadReference.class) + @INTRINSIC(PREAD_REFERENCE) + public abstract Reference readReference(Offset offset); + + @BUILTIN(GetReference.class) + @INTRINSIC(PGET_REFERENCE) + private native Reference builtinGetReference(int displacement, int index); + + @INLINE + public final Reference getReference(int displacement, int index) { + if (risc() || isHosted()) { + 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); + } + + @BUILTIN(WriteByteAtIntOffset.class) + @INTRINSIC(PWRITE_BYTE_I) + public final void writeByte(int offset, byte value) { + writeByte(Offset.fromInt(offset), value); + } + + @BUILTIN(WriteByte.class) + @INTRINSIC(PWRITE_BYTE) + public abstract void writeByte(Offset offset, byte value); + + @BUILTIN(SetByte.class) + @INTRINSIC(PSET_BYTE) + private native void builtinSetByte(int displacement, int index, byte value); + + @INLINE + public final void setByte(int displacement, int index, byte value) { + if (risc() || isHosted()) { + 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); + } + + @BUILTIN(WriteShortAtIntOffset.class) + @INTRINSIC(PWRITE_SHORT_I) + public final void writeShort(int offset, short value) { + writeShort(Offset.fromInt(offset), value); + } + + @BUILTIN(WriteShort.class) + @INTRINSIC(PWRITE_SHORT) + public abstract void writeShort(Offset offset, short value); + + @BUILTIN(SetShort.class) + @INTRINSIC(PSET_SHORT) + private native void builtinSetShort(int displacement, int index, short value); + + @INLINE + public final void setShort(int displacement, int index, short value) { + if (risc() || isHosted()) { + 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); + } + + @BUILTIN(WriteIntAtIntOffset.class) + @INTRINSIC(PWRITE_INT_I) + public final void writeInt(int offset, int value) { + writeInt(Offset.fromInt(offset), value); + } + + @BUILTIN(WriteInt.class) + @INTRINSIC(PWRITE_INT) + public abstract void writeInt(Offset offset, int value); + + @BUILTIN(SetInt.class) + @INTRINSIC(PSET_INT) + private native void builtinSetInt(int displacement, int index, int value); + + @INLINE + public final void setInt(int displacement, int index, int value) { + if (risc() || isHosted()) { + 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); + } + + @BUILTIN(WriteFloatAtIntOffset.class) + @INTRINSIC(PWRITE_FLOAT_I) + public final void writeFloat(int offset, float value) { + writeFloat(Offset.fromInt(offset), value); + } + + @BUILTIN(WriteFloat.class) + @INTRINSIC(PWRITE_FLOAT) + public abstract void writeFloat(Offset offset, float value); + + @BUILTIN(SetFloat.class) + @INTRINSIC(PSET_FLOAT) + private native void builtinSetFloat(int displacement, int index, float value); + + @INLINE + public final void setFloat(int displacement, int index, float value) { + if (risc() || isHosted()) { + 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); + } + + @BUILTIN(WriteLongAtIntOffset.class) + @INTRINSIC(PWRITE_LONG_I) + public final void writeLong(int offset, long value) { + writeLong(Offset.fromInt(offset), value); + } + + @BUILTIN(WriteLong.class) + @INTRINSIC(PWRITE_LONG) + public abstract void writeLong(Offset offset, long value); + + @BUILTIN(SetLong.class) + @INTRINSIC(PSET_LONG) + private native void builtinSetLong(int displacement, int index, long value); + + @INLINE + public final void setLong(int displacement, int index, long value) { + if (risc() || isHosted()) { + 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); + } + + @BUILTIN(WriteDoubleAtIntOffset.class) + @INTRINSIC(PWRITE_DOUBLE_I) + public final void writeDouble(int offset, double value) { + writeDouble(Offset.fromInt(offset), value); + } + + @BUILTIN(WriteDouble.class) + @INTRINSIC(PWRITE_DOUBLE) + public abstract void writeDouble(Offset offset, double value); + + @BUILTIN(SetDouble.class) + @INTRINSIC(PSET_DOUBLE) + private native void builtinSetDouble(int displacement, int index, double value); + + @INLINE + public final void setDouble(int displacement, int index, double value) { + if (risc() || isHosted()) { + 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); + } + + @BUILTIN(WriteWordAtIntOffset.class) + @INTRINSIC(PWRITE_WORD_I) + public final void writeWord(int offset, Word value) { + writeWord(Offset.fromInt(offset), value); + } + + @BUILTIN(WriteWord.class) + @INTRINSIC(PWRITE_WORD) + public abstract void writeWord(Offset offset, Word value); + + @BUILTIN(SetWord.class) + @INTRINSIC(PSET_WORD) + private native void builtinSetWord(int displacement, int index, Word value); + + @INLINE + public final void setWord(int displacement, int index, Word value) { + if (risc() || isHosted()) { + 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); + } + + @BUILTIN(WriteReferenceAtIntOffset.class) + @INTRINSIC(PWRITE_REFERENCE_I) + public final void writeReference(int offset, Reference value) { + writeReference(Offset.fromInt(offset), value); + } + + @BUILTIN(WriteReference.class) + @INTRINSIC(PWRITE_REFERENCE) + public abstract void writeReference(Offset offset, Reference value); + + @BUILTIN(SetReference.class) + @INTRINSIC(PSET_REFERENCE) + private native void builtinSetReference(int displacement, int index, Reference value); + + @INLINE + public final void setReference(int displacement, int index, Reference value) { + if (risc() || isHosted()) { + 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) + */ + @BUILTIN(CompareAndSwapIntAtIntOffset.class) + @INTRINSIC(PCMPSWP_INT_I) + public native int compareAndSwapInt(int offset, int expectedValue, int newValue); + + /** + * @see Accessor#compareAndSwapInt(Offset, int, int) + */ + @BUILTIN(CompareAndSwapInt.class) + @INTRINSIC(PCMPSWP_INT) + public native int compareAndSwapInt(Offset offset, int expectedValue, int newValue); + + /** + * @see Accessor#compareAndSwapInt(Offset, int, int) + */ + @BUILTIN(CompareAndSwapWordAtIntOffset.class) + @INTRINSIC(PCMPSWP_WORD_I) + public native Word compareAndSwapWord(int offset, Word expectedValue, Word newValue); + + /** + * @see Accessor#compareAndSwapInt(Offset, int, int) + */ + @BUILTIN(CompareAndSwapWord.class) + @INTRINSIC(PCMPSWP_WORD) + public native Word compareAndSwapWord(Offset offset, Word expectedValue, Word newValue); + + /** + * @see Accessor#compareAndSwapInt(Offset, int, int) + */ + @BUILTIN(CompareAndSwapReferenceAtIntOffset.class) + @INTRINSIC(PCMPSWP_REFERENCE_I) + public native Reference compareAndSwapReference(int offset, Reference expectedValue, Reference newValue); + + /** + * @see Accessor#compareAndSwapInt(Offset, int, int) + */ + @BUILTIN(CompareAndSwapReference.class) + @INTRINSIC(PCMPSWP_REFERENCE) + 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..3df74c3 --- /dev/null +++ b/JavaInJava/src/com/sun/max/unsafe/Size.java @@ -0,0 +1,254 @@ +/* + * 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.max.vm.MaxineVM.*; + +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 isHosted() ? BoxedSize.ZERO : 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(); + } + + public static Size min(Size a, Size b) { + if (a.lessThan(b)) { + return a; + } + return b; + } + +} 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..9bc5629 --- /dev/null +++ b/JavaInJava/src/com/sun/max/unsafe/Word.java @@ -0,0 +1,366 @@ +/* + * 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 static com.sun.max.vm.MaxineVM.*; + +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 { + + /** + * The array of all the subclasses of {@link Word} that are accessible on the classpath when + * in hosted mode. This value of this array and {@link #unboxedToBoxedTypes} is constructed + * by scanning the classpath for all classes named "Package" that subclasses {@link MaxPackage}. + * An instance of each such class is instantiated and its {@link MaxPackage#wordSubclasses()} method + * is invoked to obtain the set of classes in the denoted package that subclass {@code Word}. + */ + @HOSTED_ONLY + private static Class[] classes; + + /** + * Constructed as a side effect of the first call to {@link #getSubclasses()}. + */ + @HOSTED_ONLY + private static Map unboxedToBoxedTypes; + + /** + * Gets all the classes on the current classpath that subclass {@link Word}. + */ + @HOSTED_ONLY + public static Class[] getSubclasses() { + if (classes == null) { + final Map map = new HashMap(); + final Classpath cp = HostedBootClassLoader.HOSTED_BOOT_CLASS_LOADER.classpath(); + new ClassSearch() { + @Override + protected boolean visitClass(String className) { + if (className.endsWith(".Package")) { + try { + Class packageClass = Class.forName(className); + if (MaxPackage.class.isAssignableFrom(packageClass)) { + MaxPackage p = (MaxPackage) packageClass.newInstance(); + Class[] wordClasses = p.wordSubclasses(); + if (wordClasses != null) { + for (Class wordClass : wordClasses) { + String wordClassName = wordClass.getName(); + assert !Boxed.class.isAssignableFrom(wordClass) : "Boxed types should not be explicitly registered: " + wordClass.getName(); + assert Classes.getPackageName(wordClassName).equals(p.name()) : + "Word subclass " + wordClass.getName() + " should be registered by " + + Classes.getPackageName(wordClassName) + ".Package not " + p + ".Package"; + Class unboxedClass = wordClass; + String boxedClassName = Classes.getPackageName(unboxedClass.getName()) + ".Boxed" + unboxedClass.getSimpleName(); + try { + Class boxedClass = Class.forName(boxedClassName, false, Word.class.getClassLoader()); + map.put(unboxedClass, boxedClass); + } catch (ClassNotFoundException e) { + // There is no boxed version for this unboxed type + map.put(unboxedClass, unboxedClass); + } + } + } + } + } catch (Exception e) { + ProgramWarning.message(e.toString()); + } + } + return true; + } + }.run(cp); + + HashSet allClasses = new HashSet(); + allClasses.addAll(map.keySet()); + allClasses.addAll(map.values()); + classes = allClasses.toArray(new Class[allClasses.size()]); + unboxedToBoxedTypes = map; + } + + return classes; + } + + protected Word() { + } + + @INLINE + @INTRINSIC(WCONST_0) + 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; + } + + @INTRINSIC(UNSAFE_CAST) + public final JniHandle asJniHandle() { + if (this instanceof BoxedJniHandle) { + return (BoxedJniHandle) this; + } + final Boxed box = (Boxed) this; + return BoxedJniHandle.from(box.value()); + } + + @INTRINSIC(UNSAFE_CAST) + public final Address asAddress() { + if (this instanceof BoxedAddress) { + return (BoxedAddress) this; + } + final Boxed box = (Boxed) this; + return BoxedAddress.from(box.value()); + } + + @INTRINSIC(UNSAFE_CAST) + public final Offset asOffset() { + if (this instanceof BoxedOffset) { + return (BoxedOffset) this; + } + final Boxed box = (Boxed) this; + return BoxedOffset.from(box.value()); + } + + @INTRINSIC(UNSAFE_CAST) + public final Size asSize() { + if (this instanceof BoxedSize) { + return (BoxedSize) this; + } + final Boxed box = (Boxed) this; + return BoxedSize.from(box.value()); + } + + @INTRINSIC(UNSAFE_CAST) + public final Pointer asPointer() { + if (this instanceof BoxedPointer) { + return (BoxedPointer) this; + } + final Boxed box = (Boxed) this; + return BoxedPointer.from(box.value()); + } + + /** + * @return bit index of the least significant bit set, or -1 if zero. + */ + @INTRINSIC(LSB) + public final int leastSignificantBitSet() { + return SpecialBuiltin.leastSignificantBit(this); + } + + /** + * @return bit index of the least significant bit set, or -1 if zero. + */ + @INTRINSIC(MSB) + public final int mostSignificantBitSet() { + return SpecialBuiltin.mostSignificantBit(this); + } + + @HOSTED_ONLY + public static Class getBoxedType(Class wordType) { + if (Boxed.class.isAssignableFrom(wordType)) { + return wordType; + } + final Class> type = null; + return Utils.cast(type, unboxedToBoxedTypes.get(wordType)); + } + + @HOSTED_ONLY + public final Word_Type as(Class wordType) { + if (wordType.isInstance(this)) { + return wordType.cast(this); + } + if (Pointer.class.isAssignableFrom(wordType)) { + return wordType.cast(asPointer()); + } + if (Size.class.isAssignableFrom(wordType)) { + return wordType.cast(asSize()); + } + if (Address.class.isAssignableFrom(wordType)) { + return wordType.cast(asAddress()); + } + if (Offset.class.isAssignableFrom(wordType)) { + return wordType.cast(asOffset()); + } + try { + final Constructor constructor = getBoxedType(wordType).getConstructor(Boxed.class); + return wordType.cast(constructor.newInstance((Boxed) this)); + } catch (Throwable throwable) { + throw ProgramError.unexpected(throwable); + } + } + + 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() { + if (isHosted()) { + final Boxed box = (Boxed) this; + return box.value() == 0; + } + return equals(Word.zero()); + } + + @INLINE + public final boolean isAllOnes() { + if (isHosted()) { + final Boxed box = (Boxed) this; + return box.value() == -1; + } + return equals(Word.allOnes()); + } + + @INLINE + public final boolean equals(Word other) { + if (isHosted()) { + final Boxed thisBox = (Boxed) this; + final Boxed otherBox = (Boxed) other; + return thisBox.value() == otherBox.value(); + } + 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..0b78850 --- /dev/null +++ b/JavaInJava/src/com/sun/max/unsafe/WordArray.java @@ -0,0 +1,129 @@ +/* + * 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() { + } + + /** + * Replaces all {@code null} entries in a given word array with the appropriately typed boxed zero value. + */ + @HOSTED_ONLY + private static void replaceNullWithZero(Word[] array) { + final Word zero = Word.zero(); + for (int i = 0; i != array.length; ++i) { + if (array[i] == null) { + array[i] = zero; + } + } + } + + public static void fill(Word[] array, Word value) { + for (int i = 0; i < array.length; i++) { + uncheckedSet(array, i, value); + } + } + + // Substituted by uncheckedGet_() + public static Word uncheckedGet(Word[] array, int index) { + if (array[index] == null) { + replaceNullWithZero(array); + } + return array[index]; + } + + @LOCAL_SUBSTITUTION + @INLINE + private static Word uncheckedGet_(Word[] array, int index) { + return ArrayAccess.getWord(array, index); + } + + // Substituted by get_() + public static Word get(Word[] array, int index) { + if (array[index] == null) { + replaceNullWithZero(array); + } + return array[index]; + } + + @LOCAL_SUBSTITUTION + @INLINE + private static Word get_(Word[] array, int index) { + ArrayAccess.checkIndex(array, index); + return ArrayAccess.getWord(array, index); + } + + // Substituted by uncheckedSet_() + public static void uncheckedSet(Word[] array, int index, Word value) { + array[index] = value; + } + + @LOCAL_SUBSTITUTION + @INLINE + private static void uncheckedSet_(Word[] array, int index, Word value) { + ArrayAccess.setWord(array, index, value); + } + + // Substituted by set_() + public static void set(Word[] array, int index, Word value) { + array[index] = value; + } + + @LOCAL_SUBSTITUTION + @INLINE + private 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; From c746770971e78772e670bc9973c541f723cb4459 Mon Sep 17 00:00:00 2001 From: hborders Date: Wed, 29 Dec 2010 00:01:50 -0600 Subject: [PATCH 02/25] Removed HOSTED methods. Manually performed LOCAL_SUBSTITUTION swaps. --- .../src/com/sun/max/unsafe/WordArray.java | 51 ++----------------- 1 file changed, 4 insertions(+), 47 deletions(-) diff --git a/JavaInJava/src/com/sun/max/unsafe/WordArray.java b/JavaInJava/src/com/sun/max/unsafe/WordArray.java index 0b78850..bbf1db3 100644 --- a/JavaInJava/src/com/sun/max/unsafe/WordArray.java +++ b/JavaInJava/src/com/sun/max/unsafe/WordArray.java @@ -47,73 +47,30 @@ public final class WordArray { private WordArray() { } - /** - * Replaces all {@code null} entries in a given word array with the appropriately typed boxed zero value. - */ - @HOSTED_ONLY - private static void replaceNullWithZero(Word[] array) { - final Word zero = Word.zero(); - for (int i = 0; i != array.length; ++i) { - if (array[i] == null) { - array[i] = zero; - } - } - } - public static void fill(Word[] array, Word value) { for (int i = 0; i < array.length; i++) { uncheckedSet(array, i, value); } } - // Substituted by uncheckedGet_() - public static Word uncheckedGet(Word[] array, int index) { - if (array[index] == null) { - replaceNullWithZero(array); - } - return array[index]; - } - - @LOCAL_SUBSTITUTION @INLINE - private static Word uncheckedGet_(Word[] array, int index) { + public static Word uncheckedGet(Word[] array, int index) { return ArrayAccess.getWord(array, index); } - // Substituted by get_() - public static Word get(Word[] array, int index) { - if (array[index] == null) { - replaceNullWithZero(array); - } - return array[index]; - } - - @LOCAL_SUBSTITUTION @INLINE - private static Word get_(Word[] array, int index) { + public static Word get(Word[] array, int index) { ArrayAccess.checkIndex(array, index); return ArrayAccess.getWord(array, index); } - // Substituted by uncheckedSet_() - public static void uncheckedSet(Word[] array, int index, Word value) { - array[index] = value; - } - - @LOCAL_SUBSTITUTION @INLINE - private static void uncheckedSet_(Word[] array, int index, Word value) { + public static void uncheckedSet(Word[] array, int index, Word value) { ArrayAccess.setWord(array, index, value); } - // Substituted by set_() - public static void set(Word[] array, int index, Word value) { - array[index] = value; - } - - @LOCAL_SUBSTITUTION @INLINE - private static void set_(Word[] array, int index, Word value) { + public static void set(Word[] array, int index, Word value) { ArrayAccess.checkIndex(array, index); ArrayAccess.setWord(array, index, value); } From 4ffb5ab81dc7091f169a8ab45bdbcccceb8e80ba Mon Sep 17 00:00:00 2001 From: hborders Date: Wed, 29 Dec 2010 00:12:38 -0600 Subject: [PATCH 03/25] Removed INTRINSIC annotations and HOSTED_ONLY members. --- JavaInJava/src/com/sun/max/unsafe/Word.java | 126 -------------------- 1 file changed, 126 deletions(-) diff --git a/JavaInJava/src/com/sun/max/unsafe/Word.java b/JavaInJava/src/com/sun/max/unsafe/Word.java index 9bc5629..4a8c1df 100644 --- a/JavaInJava/src/com/sun/max/unsafe/Word.java +++ b/JavaInJava/src/com/sun/max/unsafe/Word.java @@ -22,7 +22,6 @@ import static com.sun.cri.bytecode.Bytecodes.*; import static com.sun.max.platform.Platform.*; -import static com.sun.max.vm.MaxineVM.*; import java.io.*; import java.lang.reflect.*; @@ -60,81 +59,10 @@ */ public abstract class Word { - /** - * The array of all the subclasses of {@link Word} that are accessible on the classpath when - * in hosted mode. This value of this array and {@link #unboxedToBoxedTypes} is constructed - * by scanning the classpath for all classes named "Package" that subclasses {@link MaxPackage}. - * An instance of each such class is instantiated and its {@link MaxPackage#wordSubclasses()} method - * is invoked to obtain the set of classes in the denoted package that subclass {@code Word}. - */ - @HOSTED_ONLY - private static Class[] classes; - - /** - * Constructed as a side effect of the first call to {@link #getSubclasses()}. - */ - @HOSTED_ONLY - private static Map unboxedToBoxedTypes; - - /** - * Gets all the classes on the current classpath that subclass {@link Word}. - */ - @HOSTED_ONLY - public static Class[] getSubclasses() { - if (classes == null) { - final Map map = new HashMap(); - final Classpath cp = HostedBootClassLoader.HOSTED_BOOT_CLASS_LOADER.classpath(); - new ClassSearch() { - @Override - protected boolean visitClass(String className) { - if (className.endsWith(".Package")) { - try { - Class packageClass = Class.forName(className); - if (MaxPackage.class.isAssignableFrom(packageClass)) { - MaxPackage p = (MaxPackage) packageClass.newInstance(); - Class[] wordClasses = p.wordSubclasses(); - if (wordClasses != null) { - for (Class wordClass : wordClasses) { - String wordClassName = wordClass.getName(); - assert !Boxed.class.isAssignableFrom(wordClass) : "Boxed types should not be explicitly registered: " + wordClass.getName(); - assert Classes.getPackageName(wordClassName).equals(p.name()) : - "Word subclass " + wordClass.getName() + " should be registered by " + - Classes.getPackageName(wordClassName) + ".Package not " + p + ".Package"; - Class unboxedClass = wordClass; - String boxedClassName = Classes.getPackageName(unboxedClass.getName()) + ".Boxed" + unboxedClass.getSimpleName(); - try { - Class boxedClass = Class.forName(boxedClassName, false, Word.class.getClassLoader()); - map.put(unboxedClass, boxedClass); - } catch (ClassNotFoundException e) { - // There is no boxed version for this unboxed type - map.put(unboxedClass, unboxedClass); - } - } - } - } - } catch (Exception e) { - ProgramWarning.message(e.toString()); - } - } - return true; - } - }.run(cp); - - HashSet allClasses = new HashSet(); - allClasses.addAll(map.keySet()); - allClasses.addAll(map.values()); - classes = allClasses.toArray(new Class[allClasses.size()]); - unboxedToBoxedTypes = map; - } - - return classes; - } - protected Word() { } @INLINE - @INTRINSIC(WCONST_0) public static Word zero() { return Address.zero(); } @@ -164,7 +92,6 @@ public static int size() { return widthValue().numberOfBytes; } - @INTRINSIC(UNSAFE_CAST) public final JniHandle asJniHandle() { if (this instanceof BoxedJniHandle) { return (BoxedJniHandle) this; @@ -173,7 +100,6 @@ public final JniHandle asJniHandle() { return BoxedJniHandle.from(box.value()); } - @INTRINSIC(UNSAFE_CAST) public final Address asAddress() { if (this instanceof BoxedAddress) { return (BoxedAddress) this; @@ -182,7 +108,6 @@ public final Address asAddress() { return BoxedAddress.from(box.value()); } - @INTRINSIC(UNSAFE_CAST) public final Offset asOffset() { if (this instanceof BoxedOffset) { return (BoxedOffset) this; @@ -191,7 +116,6 @@ public final Offset asOffset() { return BoxedOffset.from(box.value()); } - @INTRINSIC(UNSAFE_CAST) public final Size asSize() { if (this instanceof BoxedSize) { return (BoxedSize) this; @@ -200,7 +124,6 @@ public final Size asSize() { return BoxedSize.from(box.value()); } - @INTRINSIC(UNSAFE_CAST) public final Pointer asPointer() { if (this instanceof BoxedPointer) { return (BoxedPointer) this; @@ -212,7 +135,6 @@ public final Pointer asPointer() { /** * @return bit index of the least significant bit set, or -1 if zero. */ - @INTRINSIC(LSB) public final int leastSignificantBitSet() { return SpecialBuiltin.leastSignificantBit(this); } @@ -220,45 +142,10 @@ public final int leastSignificantBitSet() { /** * @return bit index of the least significant bit set, or -1 if zero. */ - @INTRINSIC(MSB) public final int mostSignificantBitSet() { return SpecialBuiltin.mostSignificantBit(this); } - @HOSTED_ONLY - public static Class getBoxedType(Class wordType) { - if (Boxed.class.isAssignableFrom(wordType)) { - return wordType; - } - final Class> type = null; - return Utils.cast(type, unboxedToBoxedTypes.get(wordType)); - } - - @HOSTED_ONLY - public final Word_Type as(Class wordType) { - if (wordType.isInstance(this)) { - return wordType.cast(this); - } - if (Pointer.class.isAssignableFrom(wordType)) { - return wordType.cast(asPointer()); - } - if (Size.class.isAssignableFrom(wordType)) { - return wordType.cast(asSize()); - } - if (Address.class.isAssignableFrom(wordType)) { - return wordType.cast(asAddress()); - } - if (Offset.class.isAssignableFrom(wordType)) { - return wordType.cast(asOffset()); - } - try { - final Constructor constructor = getBoxedType(wordType).getConstructor(Boxed.class); - return wordType.cast(constructor.newInstance((Boxed) this)); - } catch (Throwable throwable) { - throw ProgramError.unexpected(throwable); - } - } - public final String toHexString() { String result = Long.toHexString(asAddress().toLong()); if (width() == 32 && result.length() > 8) { @@ -286,29 +173,16 @@ public final int hashCode() { @INLINE public final boolean isZero() { - if (isHosted()) { - final Boxed box = (Boxed) this; - return box.value() == 0; - } return equals(Word.zero()); } @INLINE public final boolean isAllOnes() { - if (isHosted()) { - final Boxed box = (Boxed) this; - return box.value() == -1; - } return equals(Word.allOnes()); } @INLINE public final boolean equals(Word other) { - if (isHosted()) { - final Boxed thisBox = (Boxed) this; - final Boxed otherBox = (Boxed) other; - return thisBox.value() == otherBox.value(); - } if (Word.width() == 64) { return asOffset().toLong() == other.asOffset().toLong(); } From 3ac5eef9416851e36e923c0d48a1a55c7b5961a3 Mon Sep 17 00:00:00 2001 From: hborders Date: Wed, 29 Dec 2010 00:14:48 -0600 Subject: [PATCH 04/25] Added FOLD annotation from com.sun.max.annotate package in Maxine VM. --- JavaInJava/src/com/sun/max/annotate/FOLD.java | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 JavaInJava/src/com/sun/max/annotate/FOLD.java 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 { +} From a2b7c60681b40ee45e5a1ddc1cbd6371f6d0d526 Mon Sep 17 00:00:00 2001 From: hborders Date: Wed, 29 Dec 2010 00:19:26 -0600 Subject: [PATCH 05/25] Added only needed static methods from com.sun.max.vm.compiler.builtin.SpecialBuiltin from Maxine VM. --- .../vm/compiler/builtin/SpecialBuiltin.java | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 JavaInJava/src/com/sun/max/vm/compiler/builtin/SpecialBuiltin.java 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..74e4ea7 --- /dev/null +++ b/JavaInJava/src/com/sun/max/vm/compiler/builtin/SpecialBuiltin.java @@ -0,0 +1,57 @@ +/* + * 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.Word; + +/** + * @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); + } +} From 8b1436de21206da4dab4e2adecb1464f4adc5048 Mon Sep 17 00:00:00 2001 From: hborders Date: Wed, 29 Dec 2010 00:29:21 -0600 Subject: [PATCH 06/25] Removed hosted-only code. --- JavaInJava/src/com/sun/max/unsafe/Size.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/JavaInJava/src/com/sun/max/unsafe/Size.java b/JavaInJava/src/com/sun/max/unsafe/Size.java index 3df74c3..fa35541 100644 --- a/JavaInJava/src/com/sun/max/unsafe/Size.java +++ b/JavaInJava/src/com/sun/max/unsafe/Size.java @@ -20,8 +20,6 @@ */ package com.sun.max.unsafe; -import static com.sun.max.vm.MaxineVM.*; - import com.sun.max.annotate.*; import com.sun.max.lang.*; @@ -43,7 +41,7 @@ protected Size() { @INLINE public static Size zero() { - return isHosted() ? BoxedSize.ZERO : fromInt(0); + return fromInt(0); } public static final Size K = Size.fromInt(Ints.K); From 88d7ecdaccc1a22e07366b043625cf4f5857a4c6 Mon Sep 17 00:00:00 2001 From: hborders Date: Wed, 29 Dec 2010 00:35:34 -0600 Subject: [PATCH 07/25] Removed BUILTIN and INTRINSIC annotations and hosted-only code. --- .../src/com/sun/max/unsafe/Pointer.java | 152 ++---------------- 1 file changed, 17 insertions(+), 135 deletions(-) diff --git a/JavaInJava/src/com/sun/max/unsafe/Pointer.java b/JavaInJava/src/com/sun/max/unsafe/Pointer.java index eddcf9a..b1e2ed7 100644 --- a/JavaInJava/src/com/sun/max/unsafe/Pointer.java +++ b/JavaInJava/src/com/sun/max/unsafe/Pointer.java @@ -112,9 +112,8 @@ public interface Predicate { } @INLINE - @INTRINSIC(WCONST_0) public static Pointer zero() { - return isHosted() ? BoxedPointer.ZERO : fromInt(0); + return fromInt(0); } @INLINE @@ -209,21 +208,18 @@ public final Pointer times(int factor) { @Override @INLINE - @INTRINSIC(WDIV) public final Pointer dividedBy(Address divisor) { return asAddress().dividedBy(divisor).asPointer(); } @Override @INLINE - @INTRINSIC(WDIVI) public final Pointer dividedBy(int divisor) { return asAddress().dividedBy(divisor).asPointer(); } @Override @INLINE - @INTRINSIC(WREM) public final Pointer remainder(Address divisor) { return asAddress().remainder(divisor).asPointer(); } @@ -330,23 +326,17 @@ private static boolean risc() { return Platform.platform().isa.category == ISA.Category.RISC; } - @BUILTIN(ReadByteAtIntOffset.class) - @INTRINSIC(PREAD_BYTE_I) public byte readByte(int offset) { return readByte(Offset.fromInt(offset)); } - @BUILTIN(ReadByte.class) - @INTRINSIC(PREAD_BYTE) public abstract byte readByte(Offset offset); - @BUILTIN(GetByte.class) - @INTRINSIC(PGET_BYTE) private native byte builtinGetByte(int displacement, int index); @INLINE public final byte getByte(int displacement, int index) { - if (risc() || isHosted()) { + if (risc()) { return readByte(Offset.fromInt(index).plus(displacement)); } return builtinGetByte(displacement, index); @@ -387,23 +377,17 @@ public final boolean getBoolean() { return getBoolean(0); } - @BUILTIN(ReadShortAtIntOffset.class) - @INTRINSIC(PREAD_SHORT_I) public final short readShort(int offset) { return readShort(Offset.fromInt(offset)); } - @BUILTIN(ReadShort.class) - @INTRINSIC(PREAD_SHORT) public abstract short readShort(Offset offset); - @BUILTIN(GetShort.class) - @INTRINSIC(PGET_SHORT) private native short builtinGetShort(int displacement, int index); @INLINE public final short getShort(int displacement, int index) { - if (risc() || isHosted()) { + if (risc()) { return readShort(Offset.fromInt(index).times(Shorts.SIZE).plus(displacement)); } return builtinGetShort(displacement, index); @@ -419,23 +403,17 @@ public final short getShort() { return getShort(0); } - @BUILTIN(ReadCharAtIntOffset.class) - @INTRINSIC(PREAD_CHAR_I) public final char readChar(int offset) { return readChar(Offset.fromInt(offset)); } - @BUILTIN(ReadChar.class) - @INTRINSIC(PREAD_CHAR) public abstract char readChar(Offset offset); - @BUILTIN(GetChar.class) - @INTRINSIC(PGET_CHAR) private native char builtinGetChar(int displacement, int index); @INLINE public final char getChar(int displacement, int index) { - if (risc() || isHosted()) { + if (risc()) { return readChar(Offset.fromInt(index).times(Chars.SIZE).plus(displacement)); } return builtinGetChar(displacement, index); @@ -451,23 +429,17 @@ public final char getChar() { return getChar(0); } - @BUILTIN(ReadIntAtIntOffset.class) - @INTRINSIC(PREAD_INT_I) public final int readInt(int offset) { return readInt(Offset.fromInt(offset)); } - @BUILTIN(ReadInt.class) - @INTRINSIC(PREAD_INT) public abstract int readInt(Offset offset); - @BUILTIN(GetInt.class) - @INTRINSIC(PGET_INT) private native int builtinGetInt(int displacement, int index); @INLINE public final int getInt(int displacement, int index) { - if (risc() || isHosted()) { + if (risc()) { return readInt(Offset.fromInt(index).times(Ints.SIZE).plus(displacement)); } return builtinGetInt(displacement, index); @@ -483,23 +455,17 @@ public final int getInt() { return getInt(0); } - @BUILTIN(ReadFloatAtIntOffset.class) - @INTRINSIC(PREAD_FLOAT_I) public final float readFloat(int offset) { return readFloat(Offset.fromInt(offset)); } - @BUILTIN(ReadFloat.class) - @INTRINSIC(PREAD_FLOAT) public abstract float readFloat(Offset offset); - @BUILTIN(GetFloat.class) - @INTRINSIC(PGET_FLOAT) private native float builtinGetFloat(int displacement, int index); @INLINE public final float getFloat(int displacement, int index) { - if (risc() || isHosted()) { + if (risc()) { return readFloat(Offset.fromInt(index).times(FLOAT_SIZE).plus(displacement)); } return builtinGetFloat(displacement, index); @@ -515,23 +481,17 @@ public final float getFloat() { return getFloat(0); } - @BUILTIN(ReadLongAtIntOffset.class) - @INTRINSIC(PREAD_LONG_I) public final long readLong(int offset) { return readLong(Offset.fromInt(offset)); } - @BUILTIN(ReadLong.class) - @INTRINSIC(PREAD_LONG) public abstract long readLong(Offset offset); - @BUILTIN(GetLong.class) - @INTRINSIC(PGET_LONG) private native long builtinGetLong(int displacement, int index); @INLINE public final long getLong(int displacement, int index) { - if (risc() || isHosted()) { + if (risc()) { return readLong(Offset.fromInt(index).times(Longs.SIZE).plus(displacement)); } return builtinGetLong(displacement, index); @@ -547,23 +507,17 @@ public final long getLong() { return getLong(0); } - @BUILTIN(ReadDoubleAtIntOffset.class) - @INTRINSIC(PREAD_DOUBLE_I) public final double readDouble(int offset) { return readDouble(Offset.fromInt(offset)); } - @BUILTIN(ReadDouble.class) - @INTRINSIC(PREAD_DOUBLE) public abstract double readDouble(Offset offset); - @BUILTIN(GetDouble.class) - @INTRINSIC(PGET_DOUBLE) private native double builtinGetDouble(int displacement, int index); @INLINE public final double getDouble(int displacement, int index) { - if (risc() || isHosted()) { + if (risc()) { return readDouble(Offset.fromInt(index).times(DOUBLE_SIZE).plus(displacement)); } return builtinGetDouble(displacement, index); @@ -579,23 +533,17 @@ public final double getDouble() { return getDouble(0); } - @BUILTIN(ReadWordAtIntOffset.class) - @INTRINSIC(PREAD_WORD_I) public final Word readWord(int offset) { return readWord(Offset.fromInt(offset)); } - @BUILTIN(ReadWord.class) - @INTRINSIC(PREAD_WORD) public abstract Word readWord(Offset offset); - @BUILTIN(GetWord.class) - @INTRINSIC(PGET_WORD) private native Word builtinGetWord(int displacement, int index); @INLINE public final Word getWord(int displacement, int index) { - if (risc() || isHosted()) { + if (risc()) { return readWord(Offset.fromInt(index).times(Word.size()).plus(displacement)); } return builtinGetWord(displacement, index); @@ -611,18 +559,12 @@ public final Word getWord() { return getWord(0); } - @BUILTIN(ReadReferenceAtIntOffset.class) - @INTRINSIC(PREAD_REFERENCE_I) public final Reference readReference(int offset) { return readReference(Offset.fromInt(offset)); } - @BUILTIN(ReadReference.class) - @INTRINSIC(PREAD_REFERENCE) public abstract Reference readReference(Offset offset); - @BUILTIN(GetReference.class) - @INTRINSIC(PGET_REFERENCE) private native Reference builtinGetReference(int displacement, int index); @INLINE @@ -643,23 +585,17 @@ public final Reference getReference() { return getReference(0); } - @BUILTIN(WriteByteAtIntOffset.class) - @INTRINSIC(PWRITE_BYTE_I) public final void writeByte(int offset, byte value) { writeByte(Offset.fromInt(offset), value); } - @BUILTIN(WriteByte.class) - @INTRINSIC(PWRITE_BYTE) public abstract void writeByte(Offset offset, byte value); - @BUILTIN(SetByte.class) - @INTRINSIC(PSET_BYTE) private native void builtinSetByte(int displacement, int index, byte value); @INLINE public final void setByte(int displacement, int index, byte value) { - if (risc() || isHosted()) { + if (risc()) { writeByte(Offset.fromInt(index).plus(displacement), value); } else { builtinSetByte(displacement, index, value); @@ -701,23 +637,17 @@ public final void setBoolean(boolean value) { setBoolean(0, value); } - @BUILTIN(WriteShortAtIntOffset.class) - @INTRINSIC(PWRITE_SHORT_I) public final void writeShort(int offset, short value) { writeShort(Offset.fromInt(offset), value); } - @BUILTIN(WriteShort.class) - @INTRINSIC(PWRITE_SHORT) public abstract void writeShort(Offset offset, short value); - @BUILTIN(SetShort.class) - @INTRINSIC(PSET_SHORT) private native void builtinSetShort(int displacement, int index, short value); @INLINE public final void setShort(int displacement, int index, short value) { - if (risc() || isHosted()) { + if (risc()) { writeShort(Offset.fromInt(index).times(Shorts.SIZE).plus(displacement), value); } else { builtinSetShort(displacement, index, value); @@ -759,23 +689,17 @@ public final void setChar(char value) { setChar(0, value); } - @BUILTIN(WriteIntAtIntOffset.class) - @INTRINSIC(PWRITE_INT_I) public final void writeInt(int offset, int value) { writeInt(Offset.fromInt(offset), value); } - @BUILTIN(WriteInt.class) - @INTRINSIC(PWRITE_INT) public abstract void writeInt(Offset offset, int value); - @BUILTIN(SetInt.class) - @INTRINSIC(PSET_INT) private native void builtinSetInt(int displacement, int index, int value); @INLINE public final void setInt(int displacement, int index, int value) { - if (risc() || isHosted()) { + if (risc()) { writeInt(Offset.fromInt(index).times(Ints.SIZE).plus(displacement), value); } else { builtinSetInt(displacement, index, value); @@ -792,23 +716,17 @@ public final void setInt(int value) { setInt(0, value); } - @BUILTIN(WriteFloatAtIntOffset.class) - @INTRINSIC(PWRITE_FLOAT_I) public final void writeFloat(int offset, float value) { writeFloat(Offset.fromInt(offset), value); } - @BUILTIN(WriteFloat.class) - @INTRINSIC(PWRITE_FLOAT) public abstract void writeFloat(Offset offset, float value); - @BUILTIN(SetFloat.class) - @INTRINSIC(PSET_FLOAT) private native void builtinSetFloat(int displacement, int index, float value); @INLINE public final void setFloat(int displacement, int index, float value) { - if (risc() || isHosted()) { + if (risc()) { writeFloat(Offset.fromInt(index).times(FLOAT_SIZE).plus(displacement), value); } else { builtinSetFloat(displacement, index, value); @@ -825,23 +743,17 @@ public final void setFloat(float value) { setFloat(0, value); } - @BUILTIN(WriteLongAtIntOffset.class) - @INTRINSIC(PWRITE_LONG_I) public final void writeLong(int offset, long value) { writeLong(Offset.fromInt(offset), value); } - @BUILTIN(WriteLong.class) - @INTRINSIC(PWRITE_LONG) public abstract void writeLong(Offset offset, long value); - @BUILTIN(SetLong.class) - @INTRINSIC(PSET_LONG) private native void builtinSetLong(int displacement, int index, long value); @INLINE public final void setLong(int displacement, int index, long value) { - if (risc() || isHosted()) { + if (risc()) { writeLong(Offset.fromInt(index).times(Longs.SIZE).plus(displacement), value); } else { builtinSetLong(displacement, index, value); @@ -858,23 +770,17 @@ public final void setLong(long value) { setLong(0, value); } - @BUILTIN(WriteDoubleAtIntOffset.class) - @INTRINSIC(PWRITE_DOUBLE_I) public final void writeDouble(int offset, double value) { writeDouble(Offset.fromInt(offset), value); } - @BUILTIN(WriteDouble.class) - @INTRINSIC(PWRITE_DOUBLE) public abstract void writeDouble(Offset offset, double value); - @BUILTIN(SetDouble.class) - @INTRINSIC(PSET_DOUBLE) private native void builtinSetDouble(int displacement, int index, double value); @INLINE public final void setDouble(int displacement, int index, double value) { - if (risc() || isHosted()) { + if (risc()) { writeDouble(Offset.fromInt(index).times(DOUBLE_SIZE).plus(displacement), value); } else { builtinSetDouble(displacement, index, value); @@ -891,23 +797,17 @@ public final void setDouble(double value) { setDouble(0, value); } - @BUILTIN(WriteWordAtIntOffset.class) - @INTRINSIC(PWRITE_WORD_I) public final void writeWord(int offset, Word value) { writeWord(Offset.fromInt(offset), value); } - @BUILTIN(WriteWord.class) - @INTRINSIC(PWRITE_WORD) public abstract void writeWord(Offset offset, Word value); - @BUILTIN(SetWord.class) - @INTRINSIC(PSET_WORD) private native void builtinSetWord(int displacement, int index, Word value); @INLINE public final void setWord(int displacement, int index, Word value) { - if (risc() || isHosted()) { + if (risc()) { writeWord(Offset.fromInt(index).times(Word.size()).plus(displacement), value); } else { builtinSetWord(displacement, index, value); @@ -924,23 +824,17 @@ public final void setWord(Word value) { setWord(0, value); } - @BUILTIN(WriteReferenceAtIntOffset.class) - @INTRINSIC(PWRITE_REFERENCE_I) public final void writeReference(int offset, Reference value) { writeReference(Offset.fromInt(offset), value); } - @BUILTIN(WriteReference.class) - @INTRINSIC(PWRITE_REFERENCE) public abstract void writeReference(Offset offset, Reference value); - @BUILTIN(SetReference.class) - @INTRINSIC(PSET_REFERENCE) private native void builtinSetReference(int displacement, int index, Reference value); @INLINE public final void setReference(int displacement, int index, Reference value) { - if (risc() || isHosted()) { + if (risc()) { writeReference(Offset.fromInt(index).times(Word.size()).plus(displacement), value); } else { builtinSetReference(displacement, index, value); @@ -960,43 +854,31 @@ public final void setReference(Reference value) { /** * @see Accessor#compareAndSwapInt(Offset, int, int) */ - @BUILTIN(CompareAndSwapIntAtIntOffset.class) - @INTRINSIC(PCMPSWP_INT_I) public native int compareAndSwapInt(int offset, int expectedValue, int newValue); /** * @see Accessor#compareAndSwapInt(Offset, int, int) */ - @BUILTIN(CompareAndSwapInt.class) - @INTRINSIC(PCMPSWP_INT) public native int compareAndSwapInt(Offset offset, int expectedValue, int newValue); /** * @see Accessor#compareAndSwapInt(Offset, int, int) */ - @BUILTIN(CompareAndSwapWordAtIntOffset.class) - @INTRINSIC(PCMPSWP_WORD_I) public native Word compareAndSwapWord(int offset, Word expectedValue, Word newValue); /** * @see Accessor#compareAndSwapInt(Offset, int, int) */ - @BUILTIN(CompareAndSwapWord.class) - @INTRINSIC(PCMPSWP_WORD) public native Word compareAndSwapWord(Offset offset, Word expectedValue, Word newValue); /** * @see Accessor#compareAndSwapInt(Offset, int, int) */ - @BUILTIN(CompareAndSwapReferenceAtIntOffset.class) - @INTRINSIC(PCMPSWP_REFERENCE_I) public native Reference compareAndSwapReference(int offset, Reference expectedValue, Reference newValue); /** * @see Accessor#compareAndSwapInt(Offset, int, int) */ - @BUILTIN(CompareAndSwapReference.class) - @INTRINSIC(PCMPSWP_REFERENCE) public native Reference compareAndSwapReference(Offset offset, Reference expectedValue, Reference newValue); /** From 117f74b0c811617b8c7d388f69b21377f617bf6a Mon Sep 17 00:00:00 2001 From: hborders Date: Wed, 29 Dec 2010 00:36:32 -0600 Subject: [PATCH 08/25] Added UNSAFE from com.sun.max.annotate in Maxine VM. --- .../src/com/sun/max/annotate/UNSAFE.java | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 JavaInJava/src/com/sun/max/annotate/UNSAFE.java 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 { +} From 5c63483d649a7d2c89ef661f482e420f50dd0d10 Mon Sep 17 00:00:00 2001 From: hborders Date: Wed, 29 Dec 2010 00:39:03 -0600 Subject: [PATCH 09/25] Added com.sun.max.lang.Unsigned from Maxine VM. --- JavaInJava/src/com/sun/max/lang/Unsigned.java | 73 +++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 JavaInJava/src/com/sun/max/lang/Unsigned.java 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(); + } + +} From 664b38a9f58e4e12dd7a1ba82b4630f6e5ad540f Mon Sep 17 00:00:00 2001 From: hborders Date: Wed, 29 Dec 2010 00:41:22 -0600 Subject: [PATCH 10/25] Cleaned up imports. Removed more hosted-only code. --- .../src/com/sun/max/unsafe/Pointer.java | 60 +------------------ 1 file changed, 1 insertion(+), 59 deletions(-) diff --git a/JavaInJava/src/com/sun/max/unsafe/Pointer.java b/JavaInJava/src/com/sun/max/unsafe/Pointer.java index b1e2ed7..ad085bd 100644 --- a/JavaInJava/src/com/sun/max/unsafe/Pointer.java +++ b/JavaInJava/src/com/sun/max/unsafe/Pointer.java @@ -21,7 +21,6 @@ package com.sun.max.unsafe; import static com.sun.cri.bytecode.Bytecodes.*; -import static com.sun.max.vm.MaxineVM.*; import com.sun.cri.bytecode.*; import com.sun.max.annotate.*; @@ -29,63 +28,6 @@ import com.sun.max.lang.*; import com.sun.max.lang.Bytes; import com.sun.max.platform.*; -import com.sun.max.vm.compiler.builtin.PointerAtomicBuiltin.CompareAndSwapInt; -import com.sun.max.vm.compiler.builtin.PointerAtomicBuiltin.CompareAndSwapIntAtIntOffset; -import com.sun.max.vm.compiler.builtin.PointerAtomicBuiltin.CompareAndSwapReference; -import com.sun.max.vm.compiler.builtin.PointerAtomicBuiltin.CompareAndSwapReferenceAtIntOffset; -import com.sun.max.vm.compiler.builtin.PointerAtomicBuiltin.CompareAndSwapWord; -import com.sun.max.vm.compiler.builtin.PointerAtomicBuiltin.CompareAndSwapWordAtIntOffset; -import com.sun.max.vm.compiler.builtin.PointerLoadBuiltin.GetByte; -import com.sun.max.vm.compiler.builtin.PointerLoadBuiltin.GetChar; -import com.sun.max.vm.compiler.builtin.PointerLoadBuiltin.GetDouble; -import com.sun.max.vm.compiler.builtin.PointerLoadBuiltin.GetFloat; -import com.sun.max.vm.compiler.builtin.PointerLoadBuiltin.GetInt; -import com.sun.max.vm.compiler.builtin.PointerLoadBuiltin.GetLong; -import com.sun.max.vm.compiler.builtin.PointerLoadBuiltin.GetReference; -import com.sun.max.vm.compiler.builtin.PointerLoadBuiltin.GetShort; -import com.sun.max.vm.compiler.builtin.PointerLoadBuiltin.GetWord; -import com.sun.max.vm.compiler.builtin.PointerLoadBuiltin.ReadByte; -import com.sun.max.vm.compiler.builtin.PointerLoadBuiltin.ReadByteAtIntOffset; -import com.sun.max.vm.compiler.builtin.PointerLoadBuiltin.ReadChar; -import com.sun.max.vm.compiler.builtin.PointerLoadBuiltin.ReadCharAtIntOffset; -import com.sun.max.vm.compiler.builtin.PointerLoadBuiltin.ReadDouble; -import com.sun.max.vm.compiler.builtin.PointerLoadBuiltin.ReadDoubleAtIntOffset; -import com.sun.max.vm.compiler.builtin.PointerLoadBuiltin.ReadFloat; -import com.sun.max.vm.compiler.builtin.PointerLoadBuiltin.ReadFloatAtIntOffset; -import com.sun.max.vm.compiler.builtin.PointerLoadBuiltin.ReadInt; -import com.sun.max.vm.compiler.builtin.PointerLoadBuiltin.ReadIntAtIntOffset; -import com.sun.max.vm.compiler.builtin.PointerLoadBuiltin.ReadLong; -import com.sun.max.vm.compiler.builtin.PointerLoadBuiltin.ReadLongAtIntOffset; -import com.sun.max.vm.compiler.builtin.PointerLoadBuiltin.ReadReference; -import com.sun.max.vm.compiler.builtin.PointerLoadBuiltin.ReadReferenceAtIntOffset; -import com.sun.max.vm.compiler.builtin.PointerLoadBuiltin.ReadShort; -import com.sun.max.vm.compiler.builtin.PointerLoadBuiltin.ReadShortAtIntOffset; -import com.sun.max.vm.compiler.builtin.PointerLoadBuiltin.ReadWord; -import com.sun.max.vm.compiler.builtin.PointerLoadBuiltin.ReadWordAtIntOffset; -import com.sun.max.vm.compiler.builtin.PointerStoreBuiltin.SetByte; -import com.sun.max.vm.compiler.builtin.PointerStoreBuiltin.SetDouble; -import com.sun.max.vm.compiler.builtin.PointerStoreBuiltin.SetFloat; -import com.sun.max.vm.compiler.builtin.PointerStoreBuiltin.SetInt; -import com.sun.max.vm.compiler.builtin.PointerStoreBuiltin.SetLong; -import com.sun.max.vm.compiler.builtin.PointerStoreBuiltin.SetReference; -import com.sun.max.vm.compiler.builtin.PointerStoreBuiltin.SetShort; -import com.sun.max.vm.compiler.builtin.PointerStoreBuiltin.SetWord; -import com.sun.max.vm.compiler.builtin.PointerStoreBuiltin.WriteByte; -import com.sun.max.vm.compiler.builtin.PointerStoreBuiltin.WriteByteAtIntOffset; -import com.sun.max.vm.compiler.builtin.PointerStoreBuiltin.WriteDouble; -import com.sun.max.vm.compiler.builtin.PointerStoreBuiltin.WriteDoubleAtIntOffset; -import com.sun.max.vm.compiler.builtin.PointerStoreBuiltin.WriteFloat; -import com.sun.max.vm.compiler.builtin.PointerStoreBuiltin.WriteFloatAtIntOffset; -import com.sun.max.vm.compiler.builtin.PointerStoreBuiltin.WriteInt; -import com.sun.max.vm.compiler.builtin.PointerStoreBuiltin.WriteIntAtIntOffset; -import com.sun.max.vm.compiler.builtin.PointerStoreBuiltin.WriteLong; -import com.sun.max.vm.compiler.builtin.PointerStoreBuiltin.WriteLongAtIntOffset; -import com.sun.max.vm.compiler.builtin.PointerStoreBuiltin.WriteReference; -import com.sun.max.vm.compiler.builtin.PointerStoreBuiltin.WriteReferenceAtIntOffset; -import com.sun.max.vm.compiler.builtin.PointerStoreBuiltin.WriteShort; -import com.sun.max.vm.compiler.builtin.PointerStoreBuiltin.WriteShortAtIntOffset; -import com.sun.max.vm.compiler.builtin.PointerStoreBuiltin.WriteWord; -import com.sun.max.vm.compiler.builtin.PointerStoreBuiltin.WriteWordAtIntOffset; import com.sun.max.vm.reference.*; import com.sun.max.vm.runtime.*; import com.sun.max.vm.type.*; @@ -569,7 +511,7 @@ public final Reference readReference(int offset) { @INLINE public final Reference getReference(int displacement, int index) { - if (risc() || isHosted()) { + if (risc()) { return readReference(Offset.fromInt(index).times(Word.size()).plus(displacement)); } return builtinGetReference(displacement, index); From f67fcce06c2c064bee437cd8cf937e2df79c41b8 Mon Sep 17 00:00:00 2001 From: hborders Date: Wed, 29 Dec 2010 21:48:47 -0600 Subject: [PATCH 11/25] Removed hosted-only code. --- JavaInJava/src/com/sun/max/unsafe/Offset.java | 21 +------------------ 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/JavaInJava/src/com/sun/max/unsafe/Offset.java b/JavaInJava/src/com/sun/max/unsafe/Offset.java index 2bedb81..4ed7556 100644 --- a/JavaInJava/src/com/sun/max/unsafe/Offset.java +++ b/JavaInJava/src/com/sun/max/unsafe/Offset.java @@ -20,8 +20,6 @@ */ package com.sun.max.unsafe; -import static com.sun.max.vm.MaxineVM.*; - import com.sun.max.annotate.*; import com.sun.max.lang.*; import com.sun.max.program.*; @@ -39,7 +37,7 @@ protected Offset() { @INLINE public static Offset zero() { - return isHosted() ? BoxedOffset.ZERO : fromInt(0); + return fromInt(0); } @INLINE @@ -49,9 +47,6 @@ public static Offset fromUnsignedInt(int value) { @INLINE public static Offset fromInt(int value) { - if (isHosted()) { - return BoxedOffset.from(value); - } if (Word.width() == 64) { final long n = value; return UnsafeCast.asOffset(n); @@ -61,9 +56,6 @@ public static Offset fromInt(int value) { @INLINE public static Offset fromLong(long value) { - if (isHosted()) { - return BoxedOffset.from(value); - } if (Word.width() == 64) { return UnsafeCast.asOffset(value); } @@ -78,10 +70,6 @@ public String toString() { @INLINE public final int toInt() { - if (isHosted()) { - final BoxedOffset box = (BoxedOffset) this; - return (int) box.value(); - } if (Word.width() == 64) { final long n = UnsafeCast.asLong(this); return (int) n; @@ -91,10 +79,6 @@ public final int toInt() { @INLINE public final long toLong() { - if (isHosted()) { - final BoxedOffset box = (BoxedOffset) this; - return box.value(); - } if (Word.width() == 64) { return UnsafeCast.asLong(this); } @@ -113,9 +97,6 @@ public final int compareTo(Offset other) { @INLINE public final boolean equals(int other) { - if (isHosted()) { - return toLong() == other; - } return fromInt(other) == this; } From f249e8bc1832e164fd02f788b0e811545c413d87 Mon Sep 17 00:00:00 2001 From: hborders Date: Wed, 29 Dec 2010 21:56:30 -0600 Subject: [PATCH 12/25] Removed MemoryDataAccess because it and its interface, DataAccess, are not used by TeleInterpreter. --- .../com/sun/max/unsafe/MemoryDataAccess.java | 360 ------------------ 1 file changed, 360 deletions(-) delete mode 100644 JavaInJava/src/com/sun/max/unsafe/MemoryDataAccess.java diff --git a/JavaInJava/src/com/sun/max/unsafe/MemoryDataAccess.java b/JavaInJava/src/com/sun/max/unsafe/MemoryDataAccess.java deleted file mode 100644 index ce97ac0..0000000 --- a/JavaInJava/src/com/sun/max/unsafe/MemoryDataAccess.java +++ /dev/null @@ -1,360 +0,0 @@ -/* - * 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.*; - -import com.sun.max.memory.*; -import com.sun.max.vm.runtime.*; - -/** - * Implementation of {@link DataAccess} by direct main memory access. - * - * @author Bernd Mathiske - */ -public final class MemoryDataAccess implements DataAccess { - - private MemoryDataAccess() { - } - - public static final MemoryDataAccess MEMORY_DATA_ACCESS = new MemoryDataAccess(); - - public void readFully(Address address, ByteBuffer buffer) { - DataIO.Static.readFully(this, address, buffer); - } - - public byte[] readFully(Address address, int length) { - return DataIO.Static.readFully(this, address, length); - } - - public void readFully(Address address, byte[] buffer) { - readFully(address, ByteBuffer.wrap(buffer)); - } - - public int read(Address address, ByteBuffer buffer, int offset, int length) { - throw FatalError.unimplemented(); - } - - public int write(ByteBuffer buffer, int offset, int length, Address toAddress) throws DataIOError { - throw FatalError.unimplemented(); - } - - public void writeBuffer(Address address, ByteBuffer buffer) { - throw FatalError.unimplemented(); - } - - public byte readByte(Address address) { - return address.asPointer().readByte(0); - } - - public byte readByte(Address address, Offset offset) { - return address.asPointer().readByte(offset); - } - - public byte readByte(Address address, int offset) { - return address.asPointer().readByte(offset); - } - - public byte getByte(Address address, int displacement, int index) { - return address.asPointer().getByte(displacement, index); - } - - public boolean readBoolean(Address address) { - return address.asPointer().readBoolean(0); - } - - public boolean readBoolean(Address address, Offset offset) { - return address.asPointer().readBoolean(offset); - } - - public boolean readBoolean(Address address, int offset) { - return address.asPointer().readBoolean(offset); - } - - public boolean getBoolean(Address address, int displacement, int index) { - return address.asPointer().getBoolean(displacement, index); - } - - public short readShort(Address address) { - return address.asPointer().readShort(0); - } - - public short readShort(Address address, Offset offset) { - return address.asPointer().readShort(offset); - } - - public short readShort(Address address, int offset) { - return address.asPointer().readShort(offset); - } - - public short getShort(Address address, int displacement, int index) { - return address.asPointer().getShort(displacement, index); - } - - public char readChar(Address address) { - return address.asPointer().readChar(0); - } - - public char readChar(Address address, Offset offset) { - return address.asPointer().readChar(offset); - } - - public char readChar(Address address, int offset) { - return address.asPointer().readChar(offset); - } - - public char getChar(Address address, int displacement, int index) { - return address.asPointer().getChar(displacement, index); - } - - public int readInt(Address address) { - return address.asPointer().readInt(0); - } - - public int readInt(Address address, Offset offset) { - return address.asPointer().readInt(offset); - } - - public int readInt(Address address, int offset) { - return address.asPointer().readInt(offset); - } - - public int getInt(Address address, int displacement, int index) { - return address.asPointer().getInt(displacement, index); - } - - public float readFloat(Address address) { - return address.asPointer().readFloat(0); - } - - public float readFloat(Address address, Offset offset) { - return address.asPointer().readFloat(offset); - } - - public float readFloat(Address address, int offset) { - return address.asPointer().readFloat(offset); - } - - public float getFloat(Address address, int displacement, int index) { - return address.asPointer().getFloat(displacement, index); - } - - public long readLong(Address address) { - return address.asPointer().readLong(0); - } - - public long readLong(Address address, Offset offset) { - return address.asPointer().readLong(offset); - } - - public long readLong(Address address, int offset) { - return address.asPointer().readLong(offset); - } - - public long getLong(Address address, int displacement, int index) { - return address.asPointer().getLong(displacement, index); - } - - public double readDouble(Address address) { - return address.asPointer().readDouble(0); - } - - public double readDouble(Address address, Offset offset) { - return address.asPointer().readDouble(offset); - } - - public double readDouble(Address address, int offset) { - return address.asPointer().readDouble(offset); - } - - public double getDouble(Address address, int displacement, int index) { - return address.asPointer().getDouble(displacement, index); - } - - public Word readWord(Address address) { - return address.asPointer().readWord(0); - } - - public Word readWord(Address address, Offset offset) { - return address.asPointer().readWord(offset); - } - - public Word readWord(Address address, int offset) { - return address.asPointer().readWord(offset); - } - - public Word getWord(Address address, int displacement, int index) { - return address.asPointer().getWord(displacement, index); - } - - public void writeBytes(Address address, byte[] bytes) { - Memory.writeBytes(bytes, address.asPointer()); - } - - public void writeByte(Address address, byte value) { - address.asPointer().writeByte(0, value); - } - - public void writeByte(Address address, Offset offset, byte value) { - address.asPointer().writeByte(offset, value); - } - - public void writeByte(Address address, int offset, byte value) { - address.asPointer().writeByte(offset, value); - } - - public void setByte(Address address, int displacement, int index, byte value) { - address.asPointer().setByte(displacement, index, value); - } - - public void writeBoolean(Address address, boolean value) { - address.asPointer().writeBoolean(0, value); - } - - public void writeBoolean(Address address, Offset offset, boolean value) { - address.asPointer().writeBoolean(offset, value); - } - - public void writeBoolean(Address address, int offset, boolean value) { - address.asPointer().writeBoolean(offset, value); - } - - public void setBoolean(Address address, int displacement, int index, boolean value) { - address.asPointer().setBoolean(displacement, index, value); - } - - public void writeShort(Address address, short value) { - address.asPointer().writeShort(0, value); - } - - public void writeShort(Address address, Offset offset, short value) { - address.asPointer().writeShort(offset, value); - } - - public void writeShort(Address address, int offset, short value) { - address.asPointer().writeShort(offset, value); - } - - public void setShort(Address address, int displacement, int index, short value) { - address.asPointer().setShort(displacement, index, value); - } - - public void writeChar(Address address, char value) { - address.asPointer().writeChar(0, value); - } - - public void writeChar(Address address, Offset offset, char value) { - address.asPointer().writeChar(offset, value); - } - - public void writeChar(Address address, int offset, char value) { - address.asPointer().writeChar(offset, value); - } - - public void setChar(Address address, int displacement, int index, char value) { - address.asPointer().setChar(displacement, index, value); - } - - public void writeInt(Address address, int value) { - address.asPointer().writeInt(0, value); - } - - public void writeInt(Address address, Offset offset, int value) { - address.asPointer().writeInt(offset, value); - } - - public void writeInt(Address address, int offset, int value) { - address.asPointer().writeInt(offset, value); - } - - public void setInt(Address address, int displacement, int index, int value) { - address.asPointer().setInt(displacement, index, value); - } - - public void writeFloat(Address address, float value) { - address.asPointer().writeFloat(0, value); - } - - public void writeFloat(Address address, Offset offset, float value) { - address.asPointer().writeFloat(offset, value); - } - - public void writeFloat(Address address, int offset, float value) { - address.asPointer().writeFloat(offset, value); - } - - public void setFloat(Address address, int displacement, int index, float value) { - address.asPointer().setFloat(displacement, index, value); - } - - public void writeLong(Address address, long value) { - address.asPointer().writeLong(0, value); - } - - public void writeLong(Address address, Offset offset, long value) { - address.asPointer().writeLong(offset, value); - } - - public void writeLong(Address address, int offset, long value) { - address.asPointer().writeLong(offset, value); - } - - public void setLong(Address address, int displacement, int index, long value) { - address.asPointer().setLong(displacement, index, value); - } - - public void writeDouble(Address address, double value) { - address.asPointer().writeDouble(0, value); - } - - public void writeDouble(Address address, Offset offset, double value) { - address.asPointer().writeDouble(offset, value); - } - - public void writeDouble(Address address, int offset, double value) { - address.asPointer().writeDouble(offset, value); - } - - public void setDouble(Address address, int displacement, int index, double value) { - address.asPointer().setDouble(displacement, index, value); - } - - public void writeWord(Address address, Word value) { - address.asPointer().writeWord(0, value); - } - - public void writeWord(Address address, Offset offset, Word value) { - address.asPointer().writeWord(offset, value); - } - - public void writeWord(Address address, int offset, Word value) { - address.asPointer().writeWord(offset, value); - } - - public void setWord(Address address, int displacement, int index, Word value) { - address.asPointer().setWord(displacement, index, value); - } - - @Override - public void copyElements(Address address, int displacement, int srcIndex, Object dst, int dstIndex, int length) { - address.asPointer().copyElements(displacement, srcIndex, dst, dstIndex, length); - } -} From 98ff241d0b86fce2b7038a07de72b4ba132f9bbb Mon Sep 17 00:00:00 2001 From: hborders Date: Wed, 29 Dec 2010 21:59:18 -0600 Subject: [PATCH 13/25] Removed CString because it isn't used by TeleInterpreter. --- .../src/com/sun/max/unsafe/CString.java | 446 ------------------ 1 file changed, 446 deletions(-) delete mode 100644 JavaInJava/src/com/sun/max/unsafe/CString.java diff --git a/JavaInJava/src/com/sun/max/unsafe/CString.java b/JavaInJava/src/com/sun/max/unsafe/CString.java deleted file mode 100644 index 512b0a9..0000000 --- a/JavaInJava/src/com/sun/max/unsafe/CString.java +++ /dev/null @@ -1,446 +0,0 @@ -/* - * 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.io.*; - -import com.sun.max.lang.*; -import com.sun.max.memory.*; -import com.sun.max.util.*; -import com.sun.max.vm.*; - -/** - * Utilities for converting between Java strings and C strings (encoded as UTF8 bytes). - * - * @author Bernd Mathiske - * @author Doug Simon - */ -public final class CString { - - private CString() { - } - - /** - * Determines the length of a NULL terminated C string located in natively {@link Memory#allocate(int) allocated} memory. - * @param cString the string for which to get the length - * @return the length - */ - public static Size length(Pointer cString) { - Pointer p = cString; - while (p.readByte(0) != (byte) 0) { - p = p.plus(1); - } - return p.minus(cString).asSize(); - } - - /** - * Gets the byte at given index in C string with bounds check. - * - * @param cString the C string - * @param length length of C string (@see length) - * @param index index of byte to get - * @return -1 if the index is out of range or the byte at the index - */ - public static int getByte(Pointer cString, Size length, Offset index) { - if (index.lessThan(length.asOffset())) { - return cString.readByte(index); - } - return -1; - } - - /** - * Converts a NULL terminated C string located in natively allocated memory to a Java string. - */ - public static String utf8ToJava(Pointer cString) throws Utf8Exception { - final int n = length(cString).toInt(); - final byte[] bytes = new byte[n]; - Memory.readBytes(cString, n, bytes); - return Utf8.utf8ToString(false, bytes); - } - - /** - * Creates a NULL terminated C string (in natively allocated} memory) from a Java string. - * The returned C string must be deallocated by {@link Memory#deallocate(Address)} when finished with. - */ - public static Pointer utf8FromJava(String string) { - final byte[] utf8 = Utf8.stringToUtf8(string); - final Pointer cString = Memory.mustAllocate(utf8.length + 1); - Pointer p = cString; - for (byte utf8Char : utf8) { - p.writeByte(0, utf8Char); - p = p.plus(1); - } - p.writeByte(0, (byte) 0); - return cString; - } - - public static byte[] read(InputStream stream) throws IOException { - final ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - while (true) { - final int ch = stream.read(); - if (ch < 0) { - throw new IOException(); - } - buffer.write(ch); - if (ch == 0) { - return buffer.toByteArray(); - } - } - } - - /** - * Fills a given buffer with a zero-terminated sequence of bytes from a source buffer. - * - * @param source the byte array containing the source bytes - * @param start the start offset in {@code source} of the bytes to be written (inclusive) - * @param end the end offset of {@code source} of the bytes to be written (exclusive) - * @param buffer a pointer to the beginning of the buffer - * @param bufferSize the size of the buffer - * @return an index into the next byte to be written which is start <= result <= end - */ - public static int writeBytes(byte[] source, int start, int end, Pointer buffer, int bufferSize) { - final int n = Math.min(bufferSize - 1, end - start); - for (int i = 0; i < n; i++) { - buffer.writeByte(i, source[start + i]); - } - buffer.writeByte(n, (byte) 0); - return start + n; - } - - /** - * Fills a given buffer with the bytes in the UTF8 representation of a string following by a terminating zero. The - * maximum number of bytes written to the buffer is limited to the number of leading characters of {@code string} - * that can be completely encoded in {@code bufferSize - 2} bytes. - * - * @param string the String to write to the buffer - * @param buffer a pointer to the beginning of the buffer - * @param bufferSize the size of the buffer - * @return a pointer to the position in the buffer following the terminating zero character - */ - public static Pointer writeUtf8(final String string, final Pointer buffer, final int bufferSize) { - int position = 0; - final int endPosition = bufferSize - 1; - for (int i = 0; i < string.length(); i++) { - final char ch = string.charAt(i); - if ((ch >= 0x0001) && (ch <= 0x007F)) { - if (position >= endPosition) { - break; - } - buffer.writeByte(position++, (byte) ch); - } else if (ch > 0x07FF) { - if (position + 2 >= endPosition) { - break; - } - buffer.writeByte(position++, (byte) (0xe0 | (byte) (ch >> 12))); - buffer.writeByte(position++, (byte) (0x80 | ((ch & 0xfc0) >> 6))); - buffer.writeByte(position++, (byte) (0x80 | (ch & 0x3f))); - } else { - if (position + 1 >= endPosition) { - break; - } - buffer.writeByte(position++, (byte) (0xc0 | (byte) (ch >> 6))); - buffer.writeByte(position++, (byte) (0x80 | (ch & 0x3f))); - } - } - buffer.writeByte(position, (byte) 0); - return buffer.plus(position + 1); - } - - /** - * Fills a given buffer with the bytes in the UTF8 representation of a string following by a terminating zero. The - * maximum number of bytes written to the buffer is limited to the number of leading characters of {@code string} - * that can be completely encoded in {@code bufferSize - 2} bytes. - * - * @param chars the characters to write to the buffer - * @param start the index of the character in {@code string} from which to start copying - * @param buffer a pointer to the beginning of the buffer - * @param bufferSize the size of the buffer - * @return the number of characters from {@code string} written to the buffer - */ - public static int writePartialUtf8(final char[] chars, final int start, final Pointer buffer, final int bufferSize) { - int position = 0; - final int endPosition = bufferSize - 1; - int i = start; - while (i < chars.length) { - final char ch = chars[i]; - if ((ch >= 0x0001) && (ch <= 0x007F)) { - if (position >= endPosition) { - break; - } - buffer.writeByte(position++, (byte) ch); - } else if (ch > 0x07FF) { - if (position + 2 >= endPosition) { - break; - } - buffer.writeByte(position++, (byte) (0xe0 | (byte) (ch >> 12))); - buffer.writeByte(position++, (byte) (0x80 | ((ch & 0xfc0) >> 6))); - buffer.writeByte(position++, (byte) (0x80 | (ch & 0x3f))); - } else { - if (position + 1 >= endPosition) { - break; - } - buffer.writeByte(position++, (byte) (0xc0 | (byte) (ch >> 6))); - buffer.writeByte(position++, (byte) (0x80 | (ch & 0x3f))); - } - i++; - } - buffer.writeByte(position, (byte) 0); - return i; - } - - /** - * Fills a given buffer with the bytes in the UTF8 representation of a string following by a terminating zero. The - * maximum number of bytes written to the buffer is limited to the number of leading characters of {@code string} - * that can be completely encoded in {@code bufferSize - 2} bytes. - * - * @param string the String to write to the buffer - * @param start the index of the character in {@code string} from which to start copying - * @param buffer a pointer to the beginning of the buffer - * @param bufferSize the size of the buffer - * @return the number of characters from {@code string} written to the buffer - */ - public static int writePartialUtf8(final String string, final int start, final Pointer buffer, final int bufferSize) { - int position = 0; - final int endPosition = bufferSize - 1; - int i = start; - while (i < string.length()) { - final char ch = string.charAt(i); - if ((ch >= 0x0001) && (ch <= 0x007F)) { - if (position >= endPosition) { - break; - } - buffer.writeByte(position++, (byte) ch); - } else if (ch > 0x07FF) { - if (position + 2 >= endPosition) { - break; - } - buffer.writeByte(position++, (byte) (0xe0 | (byte) (ch >> 12))); - buffer.writeByte(position++, (byte) (0x80 | ((ch & 0xfc0) >> 6))); - buffer.writeByte(position++, (byte) (0x80 | (ch & 0x3f))); - } else { - if (position + 1 >= endPosition) { - break; - } - buffer.writeByte(position++, (byte) (0xc0 | (byte) (ch >> 6))); - buffer.writeByte(position++, (byte) (0x80 | (ch & 0x3f))); - } - i++; - } - buffer.writeByte(position, (byte) 0); - return i; - } - - public static byte[] toByteArray(Pointer start, int length) { - final byte[] buffer = new byte[length]; - for (int i = 0; i < length; i++) { - buffer[i] = start.getByte(i); - } - return buffer; - } - - /** - * Copies an array of Java strings into a native array of C strings. The memory for the C string array and each - * element in the array is allocated in one memory chunk. The C string array is first in the chunk, followed by 0 if - * {@code appendNullDelimiter == true}, followed by {@code strings.length} null terminated C strings. De-allocating - * the memory for the buffer is the responsibility of the caller. - * - * @param strings an array of Java strings - * @param appendNullDelimiter {@code true} if a null delimiter character '\0' should be appended - * @return a native buffer than can be cast to the C type {@code char**} and used as the first argument to a C - * {@code main} function - */ - public static Pointer utf8ArrayFromStringArray(String[] strings, boolean appendNullDelimiter) { - final int nullDelimiter = appendNullDelimiter ? 1 : 0; - final int pointerArraySize = Word.size() * (strings.length + nullDelimiter); - int bufferSize = pointerArraySize; - final int[] utf8Lengths = new int[strings.length]; - for (int i = 0; i < strings.length; ++i) { - final String s = strings[i]; - final int utf8Length = Utf8.utf8Length(s); - utf8Lengths[i] = utf8Length; - bufferSize += utf8Length + 1; - } - final Pointer buffer = Memory.mustAllocate(bufferSize); - - Pointer stringPointer = buffer.plus(pointerArraySize); - for (int i = 0; i < strings.length; ++i) { - final String s = strings[i]; - buffer.setWord(i, stringPointer); - stringPointer = CString.writeUtf8(s, stringPointer, utf8Lengths[i] + 1); - } - if (appendNullDelimiter) { - buffer.setWord(strings.length, Word.zero()); - } - - return buffer; - } - - public static boolean equals(Pointer cstring, String string) { - if (cstring.isZero()) { - return false; - } - for (int i = 0; i < string.length(); i++) { - final byte ch = cstring.getByte(i); - if (ch == 0 || ch != string.charAt(i)) { - return false; - } - } - return cstring.getByte(string.length()) == 0; - } - - /** - * Determines if a given C string starts with a given prefix. - * - * @param cstring the C string to test - * @param prefix the prefix to test against - * @return {@code true} if {@code cstring} starts with {@code prefix} - */ - public static boolean startsWith(Pointer cstring, String prefix) { - if (cstring.isZero()) { - return false; - } - for (int i = 0; i < prefix.length(); i++) { - final byte ch = cstring.getByte(i); - if (ch == 0 || ch != prefix.charAt(i)) { - return false; - } - } - return true; - } - - /** - * Parse a size specification nX, where X := {K, M, G, T, P, k, m, g, t, p}. - * - * For backwards compatibility with HotSpot, - * lower case letters shall have the same respective meaning as the upper case ones, - * even though their non-colloquialized definitions would suggest otherwise. - * - * @param p a pointer to the C string - * @param length the maximum length of the C string - * @param startIndex the starting index into the C string pointed to by the first argument - * @return the scaled value or -1 if error - */ - public static long parseScaledValue(Pointer p, Size length, int startIndex) { - long result = 0L; - boolean done = false; - int index = startIndex; - while (index < length.toInt()) { - if (done) { - // having any additional characters is an error - return -1L; - } - final int character = getByte(p, length, Offset.fromInt(index)); - index++; - if ('0' <= character && character <= '9') { - result *= 10; - result += character - '0'; - } else { - done = true; - switch (character) { - case 'K': - case 'k': { - result *= Longs.K; - break; - } - case 'M': - case 'm': { - result *= Longs.M; - break; - } - case 'G': - case 'g': { - result *= Longs.G; - break; - } - case 'T': - case 't': { - result *= Longs.T; - break; - } - case 'P': - case 'p': { - result *= Longs.P; - break; - } - default: { - // illegal character - return -1L; - } - } - } - } - return result; - } - - public static int parseUnsignedInt(Pointer pointer) { - int result = 0; - Pointer ptr = pointer; - while (true) { - final char ch = (char) ptr.getByte(); - if (ch == 0) { - break; - } - if (ch >= '0' && ch <= '9') { - result *= 10; - result += ch - '0'; - } else { - return -1; - } - ptr = ptr.plus(1); - } - return result; - } - - public static long parseUnsignedLong(String string) { - long result = 0L; - for (int i = 0; i < string.length(); i++) { - final char ch = string.charAt(i); - if (ch >= '0' && ch <= '9') { - result *= 10L; - result += string.charAt(i) - '0'; - } else { - return -1L; - } - } - return result; - } - - /** - * Parses a given C string as a floating value. - * - * @param cstring the C string to parse - * @return the value of {@code cstring} as a float or {@link Float#NaN} if {@code cstring} does not contain a valid - * float value - */ - public static float parseFloat(Pointer cstring) { - if (MaxineVM.isHosted()) { - try { - return Float.parseFloat(utf8ToJava(cstring)); - } catch (Exception e) { - return Float.NaN; - } - } - // Defer to native code so that all the FloatingDecimal logic does not - // have to be in the VM boot image. - return MaxineVM.native_parseFloat(cstring, Float.NaN); - } -} From 330b45f6d070f0df22448bd66da0470003cb8fe8 Mon Sep 17 00:00:00 2001 From: hborders Date: Wed, 29 Dec 2010 21:59:56 -0600 Subject: [PATCH 14/25] Removed hosted-only classes. --- JavaInJava/src/com/sun/max/unsafe/Boxed.java | 45 ---- .../src/com/sun/max/unsafe/BoxedAddress.java | 143 ------------ .../src/com/sun/max/unsafe/BoxedOffset.java | 70 ------ .../src/com/sun/max/unsafe/BoxedPointer.java | 215 ------------------ .../src/com/sun/max/unsafe/BoxedSize.java | 101 -------- .../src/com/sun/max/unsafe/BoxedWord.java | 58 ----- 6 files changed, 632 deletions(-) delete mode 100644 JavaInJava/src/com/sun/max/unsafe/Boxed.java delete mode 100644 JavaInJava/src/com/sun/max/unsafe/BoxedAddress.java delete mode 100644 JavaInJava/src/com/sun/max/unsafe/BoxedOffset.java delete mode 100644 JavaInJava/src/com/sun/max/unsafe/BoxedPointer.java delete mode 100644 JavaInJava/src/com/sun/max/unsafe/BoxedSize.java delete mode 100644 JavaInJava/src/com/sun/max/unsafe/BoxedWord.java diff --git a/JavaInJava/src/com/sun/max/unsafe/Boxed.java b/JavaInJava/src/com/sun/max/unsafe/Boxed.java deleted file mode 100644 index d839666..0000000 --- a/JavaInJava/src/com/sun/max/unsafe/Boxed.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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.*; - -/** - * Interface implemented by boxed versions of {@link Word} types. - * These boxed implementations are used when executing in {@linkplain MaxineVM#isHosted() hosted} mode. - * - * A boxed type must be in the same package as its corresponding unboxed type and - * its name must be composed by added the prefix "Boxed" to the name of the unboxed type. - * This invariant enables the complete set of boxed types to be derived from the known - * set of unboxed types. - * - * @author Bernd Mathiske - * @author Doug Simon - */ -@HOSTED_ONLY -public interface Boxed { - - /** - * Gets the boxed value as a {@code long}. - */ - long value(); -} diff --git a/JavaInJava/src/com/sun/max/unsafe/BoxedAddress.java b/JavaInJava/src/com/sun/max/unsafe/BoxedAddress.java deleted file mode 100644 index 718205f..0000000 --- a/JavaInJava/src/com/sun/max/unsafe/BoxedAddress.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * 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.*; - -/** - * Boxed version of Address. - * - * @see Address - * - * @author Bernd Mathiske - */ -@HOSTED_ONLY -public final class BoxedAddress extends Address implements Boxed { - - private long nativeWord; - - public static final BoxedAddress ZERO = new BoxedAddress(0); - public static final BoxedAddress MAX = new BoxedAddress(-1L); - - private static final class Cache { - private Cache() { - } - - static final int HIGHEST_VALUE = 1000; - - static final BoxedAddress[] cache = new BoxedAddress[HIGHEST_VALUE + 1]; - - static { - for (int i = 0; i < cache.length; i++) { - cache[i] = new BoxedAddress(i); - } - } - } - - public static BoxedAddress from(long value) { - if (value == 0) { - return ZERO; - } - if (value >= 0 && value <= Cache.HIGHEST_VALUE) { - return Cache.cache[(int) value]; - } - if (value == -1L) { - return MAX; - } - return new BoxedAddress(value); - } - - public static BoxedAddress from(int value) { - return from(value & BoxedWord.INT_MASK); - } - - private BoxedAddress(long value) { - if (Word.width() == 64) { - nativeWord = value; - } else { - nativeWord = value & BoxedWord.INT_MASK; - } - } - - public long value() { - return nativeWord; - } - - private static BigInteger bi(long unsigned) { - if (unsigned < 0) { - long signBit = 0x8000000000000000L; - long low63Bits = unsigned & ~signBit; - return BigInteger.valueOf(low63Bits).setBit(63); - } - return BigInteger.valueOf(unsigned); - } - - - private static long unsignedDivide(long dividend, long divisor) { - if (dividend >= 0 && divisor >= 0) { - return dividend / divisor; - } - return bi(dividend).divide(bi(divisor)).longValue(); - } - - @Override - public Address dividedByAddress(Address divisor) { - final BoxedAddress box = (BoxedAddress) divisor.asAddress(); - if (box.nativeWord == 0L) { - throw new ArithmeticException(); - } - return new BoxedAddress(unsignedDivide(nativeWord, box.nativeWord)); - } - - @Override - public Address dividedByInt(int divisor) { - if (divisor == 0) { - throw new ArithmeticException(); - } - return new BoxedAddress(unsignedDivide(nativeWord, divisor & BoxedWord.INT_MASK)); - } - - private static long unsignedRemainder(long dividend, long divisor) { - if (dividend >= 0 && divisor >= 0) { - return dividend % divisor; - } - return bi(dividend).remainder(bi(divisor)).longValue(); - } - - @Override - public Address remainderByAddress(Address divisor) { - final BoxedAddress box = (BoxedAddress) divisor.asAddress(); - if (box.nativeWord == 0L) { - throw new ArithmeticException(); - } - return new BoxedAddress(unsignedRemainder(nativeWord, box.nativeWord)); - } - - @Override - public int remainderByInt(int divisor) { - if (divisor == 0) { - throw new ArithmeticException(); - } - return (int) unsignedRemainder(nativeWord, divisor & BoxedWord.INT_MASK); - } -} diff --git a/JavaInJava/src/com/sun/max/unsafe/BoxedOffset.java b/JavaInJava/src/com/sun/max/unsafe/BoxedOffset.java deleted file mode 100644 index 287385e..0000000 --- a/JavaInJava/src/com/sun/max/unsafe/BoxedOffset.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * 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.*; - -/** - * Boxed version of Offset. - * - * @author Bernd Mathiske - */ -@HOSTED_ONLY -public final class BoxedOffset extends Offset implements Boxed { - - private long nativeWord; - - public static final BoxedOffset ZERO = new BoxedOffset(0); - - private static final class Cache { - private Cache() { - } - - static final int LOWEST_VALUE = -100; - static final int HIGHEST_VALUE = 1000; - - static final BoxedOffset[] cache = new BoxedOffset[(HIGHEST_VALUE - LOWEST_VALUE) + 1]; - - static { - for (int i = 0; i < cache.length; i++) { - cache[i] = new BoxedOffset(i + LOWEST_VALUE); - } - } - } - - public static BoxedOffset from(long value) { - if (value == 0) { - return ZERO; - } - if (value >= Cache.LOWEST_VALUE && value <= Cache.HIGHEST_VALUE) { - return Cache.cache[(int) value - Cache.LOWEST_VALUE]; - } - return new BoxedOffset(value); - } - - private BoxedOffset(long value) { - nativeWord = value; - } - - public long value() { - return nativeWord; - } -} diff --git a/JavaInJava/src/com/sun/max/unsafe/BoxedPointer.java b/JavaInJava/src/com/sun/max/unsafe/BoxedPointer.java deleted file mode 100644 index 568c458..0000000 --- a/JavaInJava/src/com/sun/max/unsafe/BoxedPointer.java +++ /dev/null @@ -1,215 +0,0 @@ -/* - * 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.compiler.builtin.*; -import com.sun.max.vm.hosted.*; -import com.sun.max.vm.reference.*; - -/** - * Boxed version of Pointer. - * - * @see Pointer - * - * @author Bernd Mathiske - */ -@HOSTED_ONLY -public final class BoxedPointer extends Pointer implements Boxed { - - static { - // Ensure the native code is loaded - Prototype.loadHostedLibrary(); - } - - // ATTENTION: this field name must match the corresponding declaration in "pointer.c"! - private long nativeWord; - - public static final BoxedPointer ZERO = new BoxedPointer(0); - public static final BoxedPointer MAX = new BoxedPointer(-1L); - - private static final int HIGHEST_CACHED_VALUE = 1000000; - - private static final BoxedPointer[] cache = new BoxedPointer[HIGHEST_CACHED_VALUE + 1]; - - public static BoxedPointer from(long value) { - if (value == 0) { - return ZERO; - } - if (value >= 0 && value <= HIGHEST_CACHED_VALUE) { - int cacheIndex = (int) value; - BoxedPointer boxedPointer = cache[cacheIndex]; - if (boxedPointer == null) { - boxedPointer = new BoxedPointer(value); - cache[cacheIndex] = boxedPointer; - } - return boxedPointer; - } - if (value == -1L) { - return MAX; - } - return new BoxedPointer(value); - } - - private BoxedPointer(long value) { - nativeWord = value; - } - - public static BoxedPointer from(int value) { - return from(value & BoxedWord.INT_MASK); - } - - public long value() { - return nativeWord; - } - - @Override - protected Pointer dividedByAddress(Address divisor) { - return BoxedAddress.from(nativeWord).dividedByAddress(divisor).asPointer(); - } - - @Override - protected Pointer dividedByInt(int divisor) { - return BoxedAddress.from(nativeWord).dividedByInt(divisor).asPointer(); - } - - @Override - protected Pointer remainderByAddress(Address divisor) { - return BoxedAddress.from(nativeWord).remainderByAddress(divisor).asPointer(); - } - - @Override - protected int remainderByInt(int divisor) { - return BoxedAddress.from(nativeWord).remainderByInt(divisor); - } - - private static native byte nativeReadByte(long pointer, long offset); - - @Override - public byte readByte(Offset offset) { - return nativeReadByte(nativeWord, offset.toLong()); - } - - private static native short nativeReadShort(long pointer, long offset); - - @Override - public short readShort(Offset offset) { - return nativeReadShort(nativeWord, offset.toLong()); - } - - @Override - public char readChar(Offset offset) { - return (char) nativeReadShort(nativeWord, offset.toLong()); - } - - private static native int nativeReadInt(long pointer, long offset); - - @Override - public int readInt(Offset offset) { - return nativeReadInt(nativeWord, offset.toLong()); - } - - @Override - public float readFloat(Offset offset) { - return SpecialBuiltin.intToFloat(readInt(offset)); - } - - private static native long nativeReadLong(long pointer, long offset); - - @Override - public long readLong(Offset offset) { - return nativeReadLong(nativeWord, offset.toLong()); - } - - @Override - public double readDouble(Offset offset) { - return SpecialBuiltin.longToDouble(readLong(offset)); - } - - @Override - public Word readWord(Offset offset) { - if (Word.width() == 64) { - return Address.fromLong(readLong(offset)); - } - return Address.fromInt(readInt(offset)); - } - - private static native Object nativeReadObject(long offset); - - @Override - public Reference readReference(Offset offset) { - return Reference.fromJava(nativeReadObject(offset.toLong())); - } - - private static native void nativeWriteByte(long pointer, long offset, byte value); - - @Override - public void writeByte(Offset offset, byte value) { - nativeWriteByte(nativeWord, offset.toLong(), value); - } - - private static native void nativeWriteShort(long pointer, long offset, short value); - - @Override - public void writeShort(Offset offset, short value) { - nativeWriteShort(nativeWord, offset.toLong(), value); - } - - private static native void nativeWriteInt(long pointer, long offset, int value); - - @Override - public void writeInt(Offset offset, int value) { - nativeWriteInt(nativeWord, offset.toLong(), value); - } - - @Override - public void writeFloat(Offset offset, float value) { - writeInt(offset, SpecialBuiltin.floatToInt(value)); - } - - private static native void nativeWriteLong(long pointer, long offset, long value); - - @Override - public void writeLong(Offset offset, long value) { - nativeWriteLong(nativeWord, offset.toLong(), value); - } - - @Override - public void writeDouble(Offset offset, double value) { - writeLong(offset, SpecialBuiltin.doubleToLong(value)); - } - - @Override - public void writeWord(Offset offset, Word value) { - if (Word.width() == 64) { - writeLong(offset, value.asOffset().toLong()); - } else { - writeInt(offset, value.asOffset().toInt()); - } - } - - private static native void nativeWriteObject(long pointer, long offset, Object value); - - @Override - public void writeReference(Offset offset, Reference value) { - nativeWriteObject(nativeWord, offset.toLong(), value.toJava()); - } -} diff --git a/JavaInJava/src/com/sun/max/unsafe/BoxedSize.java b/JavaInJava/src/com/sun/max/unsafe/BoxedSize.java deleted file mode 100644 index 2627b57..0000000 --- a/JavaInJava/src/com/sun/max/unsafe/BoxedSize.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * 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.*; - -/** - * Boxed version of Size. - * - * @see Size - * - * @author Bernd Mathiske - */ -@HOSTED_ONLY -public final class BoxedSize extends Size implements Boxed { - - private long nativeWord; - - public static final BoxedSize ZERO = new BoxedSize(0); - public static final BoxedSize MAX = new BoxedSize(-1L); - - private static final class Cache { - private Cache() { - } - - static final int HIGHEST_VALUE = 1000; - - static final BoxedSize[] cache = new BoxedSize[HIGHEST_VALUE + 1]; - - static { - for (int i = 0; i < cache.length; i++) { - cache[i] = new BoxedSize(i); - } - } - } - - public static BoxedSize from(long value) { - if (value == 0) { - return ZERO; - } - if (value >= 0 && value <= Cache.HIGHEST_VALUE) { - return Cache.cache[(int) value]; - } - if (value == -1L) { - return MAX; - } - - return new BoxedSize(value); - } - - private BoxedSize(long value) { - nativeWord = value; - } - - public static BoxedSize from(int value) { - return from(value & BoxedWord.INT_MASK); - } - - public long value() { - return nativeWord; - } - - @Override - protected Size dividedByAddress(Address divisor) { - return BoxedAddress.from(nativeWord).dividedByAddress(divisor).asSize(); - } - - @Override - protected Size dividedByInt(int divisor) { - return BoxedAddress.from(nativeWord).dividedByInt(divisor).asSize(); - } - - @Override - protected Size remainderByAddress(Address divisor) { - return BoxedAddress.from(nativeWord).remainderByAddress(divisor).asSize(); - } - - @Override - protected int remainderByInt(int divisor) { - return BoxedAddress.from(nativeWord).remainderByInt(divisor); - } - -} diff --git a/JavaInJava/src/com/sun/max/unsafe/BoxedWord.java b/JavaInJava/src/com/sun/max/unsafe/BoxedWord.java deleted file mode 100644 index 741c42f..0000000 --- a/JavaInJava/src/com/sun/max/unsafe/BoxedWord.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * 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.*; - -/** - * Boxed version of Word. - * - * @see Word - * - * @author Bernd Mathiske - */ -@HOSTED_ONLY -public final class BoxedWord extends Word implements Boxed { - - public static final long INT_MASK = 0x00000000ffffffffL; - - private long nativeWord; - - public BoxedWord(Boxed unsafeBox) { - nativeWord = unsafeBox.value(); - } - - public BoxedWord(int value) { - nativeWord = value & INT_MASK; - } - - public BoxedWord(long value) { - nativeWord = value; - } - - public BoxedWord(Word value) { - nativeWord = value.asOffset().toLong(); - } - - public long value() { - return nativeWord; - } -} From 2e1fb225a290a3f69b3f16c68990f4259a925da4 Mon Sep 17 00:00:00 2001 From: hborders Date: Wed, 29 Dec 2010 22:05:02 -0600 Subject: [PATCH 15/25] Removed hosted-only code. --- .../src/com/sun/max/unsafe/Address.java | 90 +------------------ 1 file changed, 2 insertions(+), 88 deletions(-) diff --git a/JavaInJava/src/com/sun/max/unsafe/Address.java b/JavaInJava/src/com/sun/max/unsafe/Address.java index 2fcf45f..597f28e 100644 --- a/JavaInJava/src/com/sun/max/unsafe/Address.java +++ b/JavaInJava/src/com/sun/max/unsafe/Address.java @@ -46,12 +46,12 @@ protected Address() { @INLINE public static Address zero() { - return isHosted() ? BoxedAddress.ZERO : fromInt(0); + return fromInt(0); } @INLINE public static Address max() { - return isHosted() ? BoxedAddress.MAX : fromLong(-1L); + return fromLong(-1L); } /** @@ -63,11 +63,6 @@ public static Address max() { */ @INLINE public static Address fromUnsignedInt(int value) { - if (isHosted()) { - final long longValue = value; - final long n = longValue & 0xffffffffL; - return BoxedAddress.from(n); - } if (Word.width() == 64) { final long longValue = value; final long n = longValue & 0xffffffffL; @@ -85,10 +80,6 @@ public static Address fromUnsignedInt(int value) { */ @INLINE public static Address fromInt(int value) { - if (isHosted()) { - final long n = value; - return BoxedAddress.from(n); - } if (Word.width() == 64) { final long n = value; return UnsafeCast.asAddress(n); @@ -98,9 +89,6 @@ public static Address fromInt(int value) { @INLINE public static Address fromLong(long value) { - if (isHosted()) { - return BoxedAddress.from(value); - } if (Word.width() == 64) { return UnsafeCast.asAddress(value); } @@ -161,10 +149,6 @@ public static Address parse(String s, int radix) { @INLINE public final int toInt() { - if (isHosted()) { - final Boxed box = (Boxed) this; - return (int) box.value(); - } if (Word.width() == 64) { final long n = UnsafeCast.asLong(this); return (int) n; @@ -174,87 +158,17 @@ public final int toInt() { @INLINE public final long toLong() { - if (isHosted()) { - final Boxed box = (Boxed) this; - return box.value(); - } if (Word.width() == 64) { return UnsafeCast.asLong(this); } return 0xffffffffL & UnsafeCast.asInt(this); } - public final int compareTo(Address other) { - if (greaterThan(other)) { - return 1; - } - if (lessThan(other)) { - return -1; - } - return 0; - } - @INLINE public final boolean equals(int other) { - if (isHosted()) { - return toLong() == other; - } return fromInt(other) == this; } - @BUILTIN(value = AddressBuiltin.GreaterThan.class) - @INTRINSIC(UWCMP | (ABOVE_THAN << 8)) - public final boolean greaterThan(Address other) { - assert isHosted(); - final long a = toLong(); - final long b = other.toLong(); - if (a < 0 == b < 0) { - return a > b; - } - return a < b; - } - - @INLINE(override = true) - public final boolean greaterThan(int other) { - return greaterThan(fromInt(other)); - } - - @BUILTIN(value = AddressBuiltin.GreaterEqual.class) - @INTRINSIC(UWCMP | (ABOVE_EQUAL << 8)) - public final boolean greaterEqual(Address other) { - assert isHosted(); - return !other.greaterThan(this); - } - - @INLINE(override = true) - public final boolean greaterEqual(int other) { - return greaterEqual(fromInt(other)); - } - - @BUILTIN(value = AddressBuiltin.LessThan.class) - @INTRINSIC(UWCMP | (BELOW_THAN << 8)) - public final boolean lessThan(Address other) { - assert isHosted(); - return other.greaterThan(this); - } - - @INLINE(override = true) - public final boolean lessThan(int other) { - return lessThan(fromInt(other)); - } - - @BUILTIN(value = AddressBuiltin.LessEqual.class) - @INTRINSIC(UWCMP | (BELOW_EQUAL << 8)) - public final boolean lessEqual(Address other) { - assert isHosted(); - return !greaterThan(other); - } - - @INLINE(override = true) - public final boolean lessEqual(int other) { - return lessEqual(fromInt(other)); - } - @INLINE(override = true) public Address plus(Address addend) { return asOffset().plus(addend.asOffset()).asAddress(); From 42014ff2090ea8dadc163f27e0067992e45656a9 Mon Sep 17 00:00:00 2001 From: hborders Date: Wed, 29 Dec 2010 22:06:02 -0600 Subject: [PATCH 16/25] Removed BUILTIN and INTRINSIC annotations. --- JavaInJava/src/com/sun/max/unsafe/Address.java | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/JavaInJava/src/com/sun/max/unsafe/Address.java b/JavaInJava/src/com/sun/max/unsafe/Address.java index 597f28e..5be276f 100644 --- a/JavaInJava/src/com/sun/max/unsafe/Address.java +++ b/JavaInJava/src/com/sun/max/unsafe/Address.java @@ -20,17 +20,11 @@ */ package com.sun.max.unsafe; -import static com.sun.cri.bytecode.Bytecodes.*; -import static com.sun.cri.bytecode.Bytecodes.UnsignedComparisons.*; -import static com.sun.max.vm.MaxineVM.*; - import java.math.*; -import com.sun.cri.bytecode.*; import com.sun.max.annotate.*; import com.sun.max.lang.*; import com.sun.max.program.*; -import com.sun.max.vm.compiler.builtin.*; /** * A machine word interpreted as a linear address. @@ -219,42 +213,30 @@ public Address times(int factor) { return asOffset().times(factor).asAddress(); } - @BUILTIN(value = AddressBuiltin.DividedByAddress.class) - @INTRINSIC(WDIV) protected abstract Address dividedByAddress(Address divisor); @INLINE(override = true) - @INTRINSIC(WDIV) public Address dividedBy(Address divisor) { return dividedByAddress(divisor); } - @BUILTIN(value = AddressBuiltin.DividedByInt.class) - @INTRINSIC(WDIVI) protected abstract Address dividedByInt(int divisor); @INLINE(override = true) - @INTRINSIC(WDIVI) public Address dividedBy(int divisor) { return dividedByInt(divisor); } - @BUILTIN(value = AddressBuiltin.RemainderByAddress.class) - @INTRINSIC(WREM) protected abstract Address remainderByAddress(Address divisor); @INLINE(override = true) - @INTRINSIC(WREM) public Address remainder(Address divisor) { return remainderByAddress(divisor); } - @BUILTIN(value = AddressBuiltin.RemainderByInt.class) - @INTRINSIC(WREMI) protected abstract int remainderByInt(int divisor); @INLINE(override = true) - @INTRINSIC(WREMI) public final int remainder(int divisor) { return remainderByInt(divisor); } From 71de50ec13aea68fd46b668c38794147294b4f44 Mon Sep 17 00:00:00 2001 From: hborders Date: Wed, 29 Dec 2010 22:20:00 -0600 Subject: [PATCH 17/25] Added com.sun.max.vm.reference package from Maxine VM. --- .../src/com/sun/max/vm/reference/Package.java | 35 ++ .../com/sun/max/vm/reference/Reference.java | 462 ++++++++++++++++++ .../sun/max/vm/reference/ReferenceScheme.java | 188 +++++++ .../sun/max/vm/reference/package-info.java | 26 + 4 files changed, 711 insertions(+) create mode 100644 JavaInJava/src/com/sun/max/vm/reference/Package.java create mode 100644 JavaInJava/src/com/sun/max/vm/reference/Reference.java create mode 100644 JavaInJava/src/com/sun/max/vm/reference/ReferenceScheme.java create mode 100644 JavaInJava/src/com/sun/max/vm/reference/package-info.java 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..b1e3ad9 --- /dev/null +++ b/JavaInJava/src/com/sun/max/vm/reference/ReferenceScheme.java @@ -0,0 +1,188 @@ +/* + * 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.annotate.*; +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); + + /** + * Gets the byte pattern for a reference to be written into the boot image. + * + * @param origin the origin of the reference to be written + */ + @HOSTED_ONLY + byte[] asBytes(Pointer origin); + + /** + * Gets the byte pattern for a null reference to be written into the boot image. + */ + @HOSTED_ONLY + byte[] nullAsBytes(); + + +} 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; From 009a7480080dfa3b5a7f67c1ecbfa3670d5c449c Mon Sep 17 00:00:00 2001 From: hborders Date: Wed, 29 Dec 2010 22:49:30 -0600 Subject: [PATCH 18/25] Added dependent file for com.sun.max.vm.reference package. --- JavaInJava/src/com/sun/max/vm/VMScheme.java | 42 +++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 JavaInJava/src/com/sun/max/vm/VMScheme.java 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 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); + +} From 596e0e62cc6f368c7b449e79f8817344452452e9 Mon Sep 17 00:00:00 2001 From: hborders Date: Wed, 29 Dec 2010 22:50:46 -0600 Subject: [PATCH 19/25] Removed hosted-only code. --- .../sun/max/vm/reference/ReferenceScheme.java | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/JavaInJava/src/com/sun/max/vm/reference/ReferenceScheme.java b/JavaInJava/src/com/sun/max/vm/reference/ReferenceScheme.java index b1e3ad9..2f9c9d2 100644 --- a/JavaInJava/src/com/sun/max/vm/reference/ReferenceScheme.java +++ b/JavaInJava/src/com/sun/max/vm/reference/ReferenceScheme.java @@ -20,7 +20,6 @@ */ package com.sun.max.vm.reference; -import com.sun.max.annotate.*; import com.sun.max.unsafe.*; import com.sun.max.vm.*; @@ -169,20 +168,4 @@ public interface ReferenceScheme extends VMScheme { Reference compareAndSwapReference(Reference reference, int offset, Reference expectedValue, Reference newValue); void copyElements(int displacement, Reference src, int srcIndex, Object dst, int dstIndex, int length); - - /** - * Gets the byte pattern for a reference to be written into the boot image. - * - * @param origin the origin of the reference to be written - */ - @HOSTED_ONLY - byte[] asBytes(Pointer origin); - - /** - * Gets the byte pattern for a null reference to be written into the boot image. - */ - @HOSTED_ONLY - byte[] nullAsBytes(); - - } From aff1c4f74b7cf245b7a20a81ab257c97d4ef5a14 Mon Sep 17 00:00:00 2001 From: hborders Date: Wed, 29 Dec 2010 23:06:16 -0600 Subject: [PATCH 20/25] Removed hosted-only method. --- JavaInJava/src/com/sun/max/unsafe/Size.java | 8 -------- 1 file changed, 8 deletions(-) diff --git a/JavaInJava/src/com/sun/max/unsafe/Size.java b/JavaInJava/src/com/sun/max/unsafe/Size.java index fa35541..ccc05eb 100644 --- a/JavaInJava/src/com/sun/max/unsafe/Size.java +++ b/JavaInJava/src/com/sun/max/unsafe/Size.java @@ -241,12 +241,4 @@ public final Size shiftedLeft(int nBits) { public final Size unsignedShiftedRight(int nBits) { return asAddress().unsignedShiftedRight(nBits).asSize(); } - - public static Size min(Size a, Size b) { - if (a.lessThan(b)) { - return a; - } - return b; - } - } From fbe82ffeefbac1a033fb5045541028035a1a2eb3 Mon Sep 17 00:00:00 2001 From: hborders Date: Wed, 29 Dec 2010 23:24:08 -0600 Subject: [PATCH 21/25] Added dependent class for com.sun.max.vm.reference --- JavaInJava/src/com/sun/max/vm/VMPackage.java | 47 ++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 JavaInJava/src/com/sun/max/vm/VMPackage.java 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; + } +} From 7ab35a35400f03bd91e921538072a13ad1f4870e Mon Sep 17 00:00:00 2001 From: hborders Date: Wed, 29 Dec 2010 23:38:02 -0600 Subject: [PATCH 22/25] Removed hosted-only code. Left API in place as a guess that it will be necessary later. --- JavaInJava/src/com/sun/max/unsafe/Word.java | 32 +++------------------ 1 file changed, 4 insertions(+), 28 deletions(-) diff --git a/JavaInJava/src/com/sun/max/unsafe/Word.java b/JavaInJava/src/com/sun/max/unsafe/Word.java index 4a8c1df..4a35321 100644 --- a/JavaInJava/src/com/sun/max/unsafe/Word.java +++ b/JavaInJava/src/com/sun/max/unsafe/Word.java @@ -92,44 +92,20 @@ public static int size() { return widthValue().numberOfBytes; } - public final JniHandle asJniHandle() { - if (this instanceof BoxedJniHandle) { - return (BoxedJniHandle) this; - } - final Boxed box = (Boxed) this; - return BoxedJniHandle.from(box.value()); - } - public final Address asAddress() { - if (this instanceof BoxedAddress) { - return (BoxedAddress) this; - } - final Boxed box = (Boxed) this; - return BoxedAddress.from(box.value()); + throw new UnsupportedOperationException("later"); } public final Offset asOffset() { - if (this instanceof BoxedOffset) { - return (BoxedOffset) this; - } - final Boxed box = (Boxed) this; - return BoxedOffset.from(box.value()); + throw new UnsupportedOperationException("later"); } public final Size asSize() { - if (this instanceof BoxedSize) { - return (BoxedSize) this; - } - final Boxed box = (Boxed) this; - return BoxedSize.from(box.value()); + throw new UnsupportedOperationException("later"); } public final Pointer asPointer() { - if (this instanceof BoxedPointer) { - return (BoxedPointer) this; - } - final Boxed box = (Boxed) this; - return BoxedPointer.from(box.value()); + throw new UnsupportedOperationException("later"); } /** From a121539c9e08028db3782371c39b76e80f0e2018 Mon Sep 17 00:00:00 2001 From: hborders Date: Thu, 30 Dec 2010 21:39:24 -0600 Subject: [PATCH 23/25] Added com.sun.max.lang package from Maxine VM. --- .../src/com/sun/max/lang/DataModel.java | 111 ++++++++++++++++++ JavaInJava/src/com/sun/max/lang/Objects.java | 99 ++++++++++++++++ JavaInJava/src/com/sun/max/lang/Unsigned.java | 73 ++++++++++++ 3 files changed, 283 insertions(+) create mode 100644 JavaInJava/src/com/sun/max/lang/DataModel.java create mode 100644 JavaInJava/src/com/sun/max/lang/Objects.java create mode 100644 JavaInJava/src/com/sun/max/lang/Unsigned.java 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(); + } + +} From 1b83702ebc25553eb42127774d19b0376311719d Mon Sep 17 00:00:00 2001 From: hborders Date: Thu, 30 Dec 2010 21:41:30 -0600 Subject: [PATCH 24/25] Added dependent annotation. --- .../src/com/sun/max/annotate/UNSAFE.java | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 JavaInJava/src/com/sun/max/annotate/UNSAFE.java 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 { +} From d01053f4f633c78f2dc50d3703986547ebbaf87c Mon Sep 17 00:00:00 2001 From: hborders Date: Thu, 30 Dec 2010 22:52:05 -0600 Subject: [PATCH 25/25] Added all other non-native (mostly bit twiddling) methods. --- .../vm/compiler/builtin/SpecialBuiltin.java | 42 ++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/JavaInJava/src/com/sun/max/vm/compiler/builtin/SpecialBuiltin.java b/JavaInJava/src/com/sun/max/vm/compiler/builtin/SpecialBuiltin.java index 74e4ea7..968f0c7 100644 --- a/JavaInJava/src/com/sun/max/vm/compiler/builtin/SpecialBuiltin.java +++ b/JavaInJava/src/com/sun/max/vm/compiler/builtin/SpecialBuiltin.java @@ -20,7 +20,7 @@ */ package com.sun.max.vm.compiler.builtin; -import com.sun.max.unsafe.Word; +import com.sun.max.unsafe.*; /** * @author Bernd Mathiske @@ -54,4 +54,44 @@ public static int mostSignificantBit(Word value) { } 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); + } }