/* * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package test.com.sun.max.unsafe; import com.sun.max.memory.*; import com.sun.max.program.*; import com.sun.max.unsafe.*; public class PointerTest extends WordTestCase { public PointerTest(String name) { super(name); } public static void main(String[] args) { junit.textui.TestRunner.run(PointerTest.class); } private Pointer base; private long[] pointerValues; @Override public void setUp() { super.setUp(); final Size size = Size.fromInt(4 * 8192); base = Memory.mustAllocate(size); Memory.clearWords(base, size.dividedBy(Word.size()).toInt()); // We will test a bunch of differently aligned pointers: final int nPointers = 25; pointerValues = new long[nPointers]; // Cover all kinds of aligned and unaligned pointers around some // well-aligned one: pointerValues[0] = base.plus(8000).roundedUpBy(8192).minus(-10).toLong(); for (int i = 1; i < nPointers; i++) { pointerValues[i] = pointerValues[i - 1] + 1; } } @Override public void tearDown() throws Exception { Memory.deallocate(base); super.tearDown(); } public void test_toString() { String s = pointerLow.toString(); assertEquals(s, "^" + Integer.toHexString(low)); s = pointer0.toString(); assertEquals(s, "^0"); s = pointerMax.toString(); switch (wordWidth()) { case BITS_64: assertEquals(s, "^ffffffffffffffff"); break; case BITS_32: assertEquals(s, "^ffffffff"); break; default: throw ProgramError.unknownCase(); } } public void test_add_Address() { assertTrue(pointerMedium.plus(addressLow).toInt() == medium + low); assertTrue(pointer0.plus(address0).equals(pointer0)); assertTrue(pointerMax.plus(address1).toLong() == 0L); final long result = pointerHigh.plus(addressLow).toLong(); switch (wordWidth()) { case BITS_64: assertTrue(result == high + low); assertFalse(result == ((int) high + low)); break; case BITS_32: assertFalse(result == high + low); assertTrue(result == ((int) high + low)); break; default: throw ProgramError.unknownCase(); } } public void test_add_Offset() { assertTrue(pointer0.plus(offset1).equals(pointer1)); assertTrue(pointer1.plus(offset1.negate()).equals(pointer0)); assertTrue(pointerMedium.plus(Offset.fromInt(low)).toInt() == medium + low); assertTrue(pointerMedium.plus(Offset.fromInt(-low)).toInt() == medium - low); assertTrue(pointer0.plus(Offset.zero()).equals(pointer0)); assertTrue(pointerMax.plus(offset1).toLong() == 0L); assertTrue(pointer0.plus(offset1.negate()).equals(pointerMax)); long result = pointerHigh.plus(offsetLow).toLong(); switch (wordWidth()) { case BITS_64: assertTrue(result == high + low); assertFalse(result == ((int) high + low)); break; case BITS_32: assertFalse(result == high + low); assertTrue(result == ((int) high + low)); break; default: throw ProgramError.unknownCase(); } assertTrue(pointerLow.plus(offsetHigh).equals(Address.fromLong(result))); result = pointerLow.plus(offsetHigh.negate()).toLong(); final long difference = low - high; final long differenceLowBits = difference & 0xffffffffL; switch (wordWidth()) { case BITS_64: assertTrue(result == low - high); assertFalse(result == differenceLowBits); break; case BITS_32: assertFalse(result == low - high); assertTrue(result == differenceLowBits); break; default: throw ProgramError.unknownCase(); } } public void test_add_int() { assertTrue(pointer0.plus(1).equals(pointer1)); assertTrue(pointer1.plus(-1).equals(pointer0)); assertTrue(pointerMedium.plus(low).toInt() == medium + low); assertTrue(pointerMedium.plus(-low).toInt() == medium - low); assertTrue(pointer0.plus(0).equals(pointer0)); assertTrue(pointerMax.plus(1).toLong() == 0L); assertTrue(pointer0.plus(-1).equals(pointerMax)); final long result = pointerHigh.plus(low).toLong(); switch (wordWidth()) { case BITS_64: assertTrue(result == high + low); assertFalse(result == ((int) high + low)); break; case BITS_32: assertFalse(result == high + low); assertTrue(result == ((int) high + low)); break; default: throw ProgramError.unknownCase(); } assertTrue(pointerLow.plus((int) high).equals(Address.fromInt(low + (int) high))); } public void test_subtract_Address() { assertTrue(pointer1.minus(address1).equals(pointer0)); assertTrue(pointer0.minus(address1).equals(pointerMax)); assertTrue(pointerMedium.minus(addressLow).toInt() == medium - low); } public void test_subtract_Offset() { assertTrue(pointer1.minus(offset1).equals(pointer0)); assertTrue(pointerMedium.minus(offsetLow).toInt() == medium - low); assertTrue(pointer0.minus(offset1).equals(pointerMax)); switch (wordWidth()) { case BITS_64: { assertTrue(pointerLow.minus(offsetMedium).equals(offsetLow.minus(offsetMedium))); break; } case BITS_32: { final long v = ((long) low - (long) medium) & LOW_32_BITS_MASK; assertTrue(pointerLow.minus(offsetMedium).toLong() == v); break; } default: { throw ProgramError.unknownCase(); } } } public void test_subtract_int() { assertTrue(pointer1.minus(1).equals(pointer0)); assertTrue(pointerMedium.minus(low).toInt() == medium - low); assertTrue(pointerMedium.minus(low).equals(offsetLow.negate().plus(offsetMedium))); assertTrue(pointer0.minus(1).equals(pointerMax)); } public void test_divide() { try { pointerLow.dividedBy(0); fail(); } catch (ArithmeticException arithmeticException) { } try { pointerLow.dividedBy(-1); } catch (ArithmeticException arithmeticException) { } assertTrue(pointerLow.dividedBy(4).toInt() == low / 4); assertTrue(pointer0.dividedBy(42).toInt() == 0); } public void test_remainder() { try { pointerLow.remainder(0); fail(); } catch (ArithmeticException arithmeticException) { } try { pointerLow.remainder(-1); } catch (ArithmeticException arithmeticException) { } for (int i = 0; i < 10; i++) { assertTrue(Address.fromInt(i).remainder(4) == i % 4); } assertTrue(pointer0.remainder(42) == 0); } public void test_isRoundedBy() { try { pointerLow.isRoundedBy(0); fail(); } catch (ArithmeticException arithmeticException) { } try { pointerLow.isRoundedBy(-1); } catch (ArithmeticException arithmeticException) { } for (int i = 0; i < 10; i++) { assertTrue(Address.fromInt(i).isRoundedBy(4) == (i % 4 == 0)); } assertTrue(pointer0.isRoundedBy(42)); } private int roundedUpBy(int base, int number) { final int rest = number % base; if (rest == 0) { return number; } return number + base - rest; } public void test_roundedUpBy() { try { pointerLow.roundedUpBy(0); fail(); } catch (ArithmeticException arithmeticException) { } try { pointerLow.roundedUpBy(-1); } catch (ArithmeticException arithmeticException) { } for (int i = 0; i < 20; i++) { assertTrue(Address.fromInt(i).roundedUpBy(8).toInt() == roundedUpBy(8, i)); } assertTrue(pointer0.roundedUpBy(12).equals(pointer0)); } public void test_roundedDownBy() { try { pointerLow.roundedDownBy(0); fail(); } catch (ArithmeticException arithmeticException) { } try { pointerLow.roundedDownBy(-1); } catch (ArithmeticException arithmeticException) { } for (int i = 0; i < 20; i++) { assertTrue(Address.fromInt(i).roundedDownBy(8).toInt() == (i & ~7)); } assertTrue(pointer0.roundedDownBy(12).equals(pointer0)); } public void test_writeAndReadByte_Offset() { for (long pointerValue : pointerValues) { final Pointer pointer = Pointer.fromLong(pointerValue); pointer.writeByte(offset0, (byte) 55); pointer.writeByte(offset1, (byte) -44); pointer.writeByte(offset2, (byte) 33); assertTrue(pointer.readByte(0) == 55); assertTrue(pointer.readByte(offset1) == -44); assertTrue(pointer.readByte(offset2) == 33); } } public void test_writeAndReadByte_int() { for (long pointerValue : pointerValues) { final Pointer pointer = Pointer.fromLong(pointerValue); pointer.writeByte(0, (byte) -55); pointer.writeByte(1, (byte) 44); pointer.writeByte(2, (byte) -33); pointer.writeByte(-20, (byte) 123); assertTrue(pointer.readByte(offset0) == -55); assertTrue(pointer.readByte(1) == 44); assertTrue(pointer.readByte(2) == -33); assertTrue(pointer.readByte(-20) == 123); } } public void test_writeAndReadShort_Offset() { for (long pointerValue : pointerValues) { final Pointer pointer = Pointer.fromLong(pointerValue); pointer.writeShort(offset0, (short) -145); pointer.writeShort(offset2, (short) 83); pointer.writeShort(offset4, (short) -1); assertTrue(pointer.readShort(0) == -145); assertTrue(pointer.readShort(offset2) == 83); assertTrue(pointer.readShort(offset4) == -1); } } public void test_writeAndReadShort_int() { for (long pointerValue : pointerValues) { final Pointer pointer = Pointer.fromLong(pointerValue); pointer.writeShort(0, (short) 0x1278); pointer.writeShort(1, (short) 0x3456); pointer.writeShort(-9, (short) 576); switch (Word.endianness()) { case BIG: assertTrue(pointer.readByte(offset0) == 0x12); assertTrue(pointer.readByte(1) == 0x34); assertTrue(pointer.readShort(0) == 0x1234); assertTrue(pointer.readShort(1) == 0x3456); assertTrue(pointer.readShort(-9) == 576); break; case LITTLE: assertTrue(pointer.readByte(offset0) == 0x78); assertTrue(pointer.readByte(1) == 0x56); assertTrue(pointer.readShort(0) == 0x5678); assertTrue(pointer.readShort(1) == 0x3456); assertTrue(pointer.readShort(-9) == 576); break; default: throw ProgramError.unknownCase(); } } } public void test_writeAndReadInt_Offset() { for (long pointerValue : pointerValues) { final Pointer pointer = Pointer.fromLong(pointerValue); pointer.writeInt(offset0, 0x12345678); pointer.writeInt(offset4, 0xabcdef47); pointer.writeInt(offset8, Integer.MIN_VALUE); assertTrue(pointer.readInt(0) == 0x12345678); assertTrue(pointer.readInt(offset4) == 0xabcdef47); assertTrue(pointer.readInt(offset8) == Integer.MIN_VALUE); } } public void test_writeAndReadInt_int() { for (long pointerValue : pointerValues) { final Pointer pointer = Pointer.fromLong(pointerValue); pointer.writeInt(0, 0x12abcdef); pointer.writeInt(1, 0x34bbccdd); pointer.writeInt(2, 0x56eef712); pointer.writeInt(3, 0x78f78365); pointer.writeInt(-5, 12345678); switch (Word.endianness()) { case BIG: assertTrue(pointer.readInt(offset0) == 0x12345678); assertTrue(pointer.readInt(1) == 0x345678f7); assertTrue(pointer.readInt(2) == 0x5678f783); assertTrue(pointer.readInt(3) == 0x78f78365); assertTrue(pointer.readInt(-5) == 12345678); break; case LITTLE: assertTrue(pointer.readInt(offset0) == 0x6512ddef); assertTrue(pointer.readInt(1) == 0x836512dd); assertTrue(pointer.readInt(2) == 0xf7836512); assertTrue(pointer.readInt(3) == 0x78f78365); assertTrue(pointer.readInt(-5) == 12345678); break; default: throw ProgramError.unknownCase(); } } } public void test_writeAndReadLong_Offset() { for (long pointerValue : pointerValues) { final Pointer pointer = Pointer.fromLong(pointerValue); pointer.writeLong(offset0, 0x12345678abcdef18L); pointer.writeLong(offset8, 0x1a2b3c4d5e6f3a4bL); pointer.writeLong(offset16, Long.MAX_VALUE); assertTrue(pointer.readLong(0) == 0x12345678abcdef18L); assertTrue(pointer.readLong(offset8) == 0x1a2b3c4d5e6f3a4bL); assertTrue(pointer.readLong(offset16) == Long.MAX_VALUE); } } public void test_writeAndReadLong_int() { for (long pointerValue : pointerValues) { final Pointer pointer = Pointer.fromLong(pointerValue); pointer.writeLong(0, 0x12f3e4b5a6d7d527L); pointer.writeLong(1, 0x34bbccddeeff0011L); pointer.writeLong(2, 0x5678334455667788L); pointer.writeLong(4, 0xabcdef01aa0f0e0cL); pointer.writeLong(-40, 1234567812345678L); switch (Word.endianness()) { case BIG: assertTrue(pointer.readLong(offset0) == 0x12345678abcdef01L); assertTrue(pointer.readLong(4) == 0xabcdef01aa0f0e0cL); assertTrue(pointer.readLong(-40) == 1234567812345678L); break; case LITTLE: assertTrue(pointer.readLong(offset0) == 0xaa0f0e0c77881127L); assertTrue(pointer.readLong(4) == 0xabcdef01aa0f0e0cL); assertTrue(pointer.readLong(-40) == 1234567812345678L); break; default: throw ProgramError.unknownCase(); } } } public void test_writeAndReadChar_Offset() { for (long pointerValue : pointerValues) { final Pointer pointer = Pointer.fromLong(pointerValue); pointer.writeChar(offset0, (char) 78); pointer.writeChar(offset2, (char) 12583); pointer.writeChar(offset4, (char) -7564); pointer.readChar(0); assertTrue(pointer.readChar(0) == (char) 78); assertTrue(pointer.readChar(offset2) == (char) 12583); assertTrue(pointer.readChar(offset4) == (char) -7564); } } public void test_writeAndReadChar_int() { for (long pointerValue : pointerValues) { final Pointer pointer = Pointer.fromLong(pointerValue); pointer.writeChar(0, (char) 22); pointer.writeChar(123, (char) 1577); pointer.writeChar(-14, (char) 305); assertTrue(pointer.readChar(offset0) == (char) 22); assertTrue(pointer.readChar(123) == (char) 1577); assertTrue(pointer.readChar(-14) == (char) 305); } } public void test_writeAndReadFloat_Offset() { for (long pointerValue : pointerValues) { final Pointer pointer = Pointer.fromLong(pointerValue); pointer.writeFloat(offset0, 21.021f); pointer.writeFloat(offset4, 77123.1233f); pointer.writeFloat(offset8, -234.234e10f); assertTrue(pointer.readFloat(0) == 21.021f); assertTrue(pointer.readFloat(offset4) == 77123.1233f); assertTrue(pointer.readFloat(offset8) == -234.234e10f); } } public void test_writeAndReadFloat_int() { for (long pointerValue : pointerValues) { final Pointer pointer = Pointer.fromLong(pointerValue); pointer.writeFloat(0, 2.3f); pointer.writeFloat(71, -7736.4324f); pointer.writeFloat(-24, Float.MIN_VALUE); assertTrue(pointer.readFloat(offset0) == 2.3f); assertTrue(pointer.readFloat(71) == -7736.4324f); assertTrue(pointer.readFloat(-24) == Float.MIN_VALUE); } } public void test_writeAndReadDouble_Offset() { for (long pointerValue : pointerValues) { final Pointer pointer = Pointer.fromLong(pointerValue); pointer.writeDouble(offset0, 725448.2342499354); pointer.writeDouble(offset8, 7712323.1231233); pointer.writeDouble(16, -2323424.2364456456567e30); assertTrue(pointer.readDouble(0) == 725448.2342499354); assertTrue(pointer.readDouble(8) == 7712323.1231233); assertTrue(pointer.readDouble(offset16) == -2323424.2364456456567e30); } } public void test_writeAndReadDouble_int() { for (long pointerValue : pointerValues) { final Pointer pointer = Pointer.fromLong(pointerValue); pointer.writeDouble(0, -324543.3434); pointer.writeDouble(71, -1.0); pointer.writeDouble(-24, Double.MAX_VALUE); assertTrue(pointer.readDouble(offset0) == -324543.3434); assertTrue(pointer.readDouble(71) == -1.0); assertTrue(pointer.readDouble(-24) == Double.MAX_VALUE); } } public void test_writeAndReadWord_Offset() { for (long pointerValue : pointerValues) { final Pointer pointer = Pointer.fromLong(pointerValue); pointer.writeWord(offset0, addressLow); switch (wordWidth()) { case BITS_64: pointer.writeWord(offset8, offsetHigh); break; case BITS_32: pointer.writeWord(offset4, offsetHigh); break; default: throw ProgramError.unknownCase(); } switch (wordWidth()) { case BITS_64: pointer.writeWord(offset16, sizeMax); break; case BITS_32: pointer.writeWord(offset8, sizeMax); break; default: throw ProgramError.unknownCase(); } assertTrue(pointer.readWord(0).asAddress().equals(addressLow)); switch (wordWidth()) { case BITS_64: assertTrue(pointer.readWord(8).asOffset().equals(offsetHigh)); break; case BITS_32: assertTrue(pointer.readWord(4).asOffset().equals(offsetHigh)); break; default: throw ProgramError.unknownCase(); } switch (wordWidth()) { case BITS_64: assertTrue(pointer.readWord(offset16).asSize().equals(sizeMax)); break; case BITS_32: assertTrue(pointer.readWord(offset8).asSize().equals(sizeMax)); break; default: throw ProgramError.unknownCase(); } } } public void test_writeAndReadWord_int() { for (long pointerValue : pointerValues) { final Pointer pointer = Pointer.fromLong(pointerValue); pointer.writeWord(0, sizeHigh); pointer.writeWord(56, pointer); pointer.writeWord(-100, addressMedium); assertTrue(pointer.readWord(offset0).asSize().equals(sizeHigh)); assertTrue(pointer.readWord(56).asPointer().equals(pointer)); assertTrue(pointer.readWord(-100).asSize().equals(sizeMedium)); } } public void performSetAndGetByte(int displacement) { for (long pointerValue : pointerValues) { final Pointer pointer = Pointer.fromLong(pointerValue); pointer.setByte(displacement, 0, (byte) -55); pointer.setByte(displacement, 1, (byte) 44); pointer.setByte(displacement, 2, (byte) -33); pointer.setByte(displacement + 10, -20, (byte) 123); assertTrue(pointer.getByte(displacement, 0) == -55); assertTrue(pointer.getByte(displacement, 1) == 44); assertTrue(pointer.getByte(displacement, 2) == -33); assertTrue(pointer.getByte(displacement, -10) == 123); } } public void test_setAndGetByte() { for (int displacement = -9; displacement <= 9; displacement++) { performSetAndGetByte(displacement); } } public void performSetAndGetWord(int displacement) { for (long pointerValue : pointerValues) { final Pointer pointer = Pointer.fromLong(pointerValue); pointer.setWord(displacement, 0, sizeHigh); pointer.setWord(displacement, 56, pointer); pointer.setWord(displacement, -100, addressMedium); assertTrue(pointer.getWord(displacement, 0).asSize().equals(sizeHigh)); assertTrue(pointer.getWord(displacement + (6 * Word.size()), 50).asPointer().equals(pointer)); assertTrue(pointer.getWord(displacement, -100).asSize().equals(sizeMedium)); } } public void test_setAndGetWord() { for (int displacement = -16; displacement <= 16; displacement += 8) { performSetAndGetWord(displacement); } } }