1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package libcore.libcore.io; 19 20 import dalvik.system.VMRuntime; 21 import java.util.Arrays; 22 import junit.framework.TestCase; 23 24 import libcore.io.Memory; 25 26 public class MemoryTest extends TestCase { testSetIntArray()27 public void testSetIntArray() { 28 int[] values = { 3, 7, 31, 127, 8191, 131071, 524287, 2147483647 }; 29 int[] swappedValues = new int[values.length]; 30 for (int i = 0; i < values.length; ++i) { 31 swappedValues[i] = Integer.reverseBytes(values[i]); 32 } 33 34 int scale = Integer.BYTES; 35 VMRuntime runtime = VMRuntime.getRuntime(); 36 byte[] array = (byte[]) runtime.newNonMovableArray(byte.class, scale * values.length + 1); 37 long base_ptr = runtime.addressOf(array); 38 39 for (int ptr_offset = 0; ptr_offset < 2; ++ptr_offset) { 40 long ptr = base_ptr + ptr_offset; // To test aligned and unaligned accesses. 41 Arrays.fill(array, (byte) 0); 42 43 // Regular copy. 44 Memory.pokeIntArray(ptr, values, 0, values.length, false); 45 assertIntsEqual(values, ptr, false); 46 assertIntsEqual(swappedValues, ptr, true); 47 48 // Swapped copy. 49 Memory.pokeIntArray(ptr, values, 0, values.length, true); 50 assertIntsEqual(values, ptr, true); 51 assertIntsEqual(swappedValues, ptr, false); 52 53 // Swapped copies of slices (to ensure we test non-zero offsets). 54 for (int i = 0; i < values.length; ++i) { 55 Memory.pokeIntArray(ptr + i * scale, values, i, 1, true); 56 } 57 assertIntsEqual(values, ptr, true); 58 assertIntsEqual(swappedValues, ptr, false); 59 } 60 } 61 assertIntsEqual(int[] expectedValues, long ptr, boolean swap)62 private void assertIntsEqual(int[] expectedValues, long ptr, boolean swap) { 63 for (int i = 0; i < expectedValues.length; ++i) { 64 assertEquals(expectedValues[i], Memory.peekInt(ptr + Integer.BYTES * i, swap)); 65 } 66 } 67 testSetLongArray()68 public void testSetLongArray() { 69 long[] values = { 0x1020304050607080L, 0xffeeddccbbaa9988L }; 70 long[] swappedValues = new long[values.length]; 71 for (int i = 0; i < values.length; ++i) { 72 swappedValues[i] = Long.reverseBytes(values[i]); 73 } 74 75 int scale = Long.BYTES; 76 VMRuntime runtime = VMRuntime.getRuntime(); 77 byte[] array = (byte[]) runtime.newNonMovableArray(byte.class, scale * values.length + 1); 78 long base_ptr = runtime.addressOf(array); 79 80 for (int ptr_offset = 0; ptr_offset < 2; ++ptr_offset) { 81 long ptr = base_ptr + ptr_offset; // To test aligned and unaligned accesses. 82 Arrays.fill(array, (byte) 0); 83 84 // Regular copy. 85 Memory.pokeLongArray(ptr, values, 0, values.length, false); 86 assertLongsEqual(values, ptr, false); 87 assertLongsEqual(swappedValues, ptr, true); 88 89 // Swapped copy. 90 Memory.pokeLongArray(ptr, values, 0, values.length, true); 91 assertLongsEqual(values, ptr, true); 92 assertLongsEqual(swappedValues, ptr, false); 93 94 // Swapped copies of slices (to ensure we test non-zero offsets). 95 for (int i = 0; i < values.length; ++i) { 96 Memory.pokeLongArray(ptr + i * scale, values, i, 1, true); 97 } 98 assertLongsEqual(values, ptr, true); 99 assertLongsEqual(swappedValues, ptr, false); 100 } 101 } 102 assertLongsEqual(long[] expectedValues, long ptr, boolean swap)103 private void assertLongsEqual(long[] expectedValues, long ptr, boolean swap) { 104 for (int i = 0; i < expectedValues.length; ++i) { 105 assertEquals(expectedValues[i], Memory.peekLong(ptr + Long.BYTES * i, swap)); 106 } 107 } 108 testSetShortArray()109 public void testSetShortArray() { 110 short[] values = { 0x0001, 0x0020, 0x0300, 0x4000 }; 111 short[] swappedValues = { 0x0100, 0x2000, 0x0003, 0x0040 }; 112 113 int scale = Short.BYTES; 114 VMRuntime runtime = VMRuntime.getRuntime(); 115 byte[] array = (byte[]) runtime.newNonMovableArray(byte.class, scale * values.length + 1); 116 long base_ptr = runtime.addressOf(array); 117 118 for (int ptr_offset = 0; ptr_offset < 2; ++ptr_offset) { 119 long ptr = base_ptr + ptr_offset; // To test aligned and unaligned accesses. 120 Arrays.fill(array, (byte) 0); 121 122 // Regular copy. 123 Memory.pokeShortArray(ptr, values, 0, values.length, false); 124 assertShortsEqual(values, ptr, false); 125 assertShortsEqual(swappedValues, ptr, true); 126 127 // Swapped copy. 128 Memory.pokeShortArray(ptr, values, 0, values.length, true); 129 assertShortsEqual(values, ptr, true); 130 assertShortsEqual(swappedValues, ptr, false); 131 132 // Swapped copies of slices (to ensure we test non-zero offsets). 133 for (int i = 0; i < values.length; ++i) { 134 Memory.pokeShortArray(ptr + i * scale, values, i, 1, true); 135 } 136 assertShortsEqual(values, ptr, true); 137 assertShortsEqual(swappedValues, ptr, false); 138 } 139 } 140 assertShortsEqual(short[] expectedValues, long ptr, boolean swap)141 private void assertShortsEqual(short[] expectedValues, long ptr, boolean swap) { 142 for (int i = 0; i < expectedValues.length; ++i) { 143 assertEquals(expectedValues[i], Memory.peekShort(ptr + Short.BYTES * i, swap)); 144 } 145 } 146 testMemmove()147 public void testMemmove() { 148 final int size = 100; 149 checkPartialMemmove(size, 0, 0, size); 150 checkPartialMemmove(size, 0, 0, size / 2); 151 checkPartialMemmove(size, size / 2, size / 2, size - size / 2); 152 checkPartialMemmove(size, 10, 20, 20); 153 154 checkOverlappingMemmove(size, 0, 0, size); 155 checkOverlappingMemmove(size, 10, 20, 30); 156 checkOverlappingMemmove(size, 20, 10, 30); 157 } 158 checkPartialMemmove(int size, int offsetDst, int offsetSrc, int count)159 private void checkPartialMemmove(int size, int offsetDst, int offsetSrc, int count) { 160 byte[] src = new byte[size]; 161 for (int i = 0; i < size; ++i) { 162 src[i] = (byte)i; 163 } 164 byte[] dst = new byte[size]; 165 Arrays.fill(dst, (byte)-1); 166 167 assertTrue(offsetSrc + count <= size); 168 assertTrue(offsetDst + count <= size); 169 Memory.memmove(dst, offsetDst, src, offsetSrc, count); 170 for (int i = 0; i < size; ++i) { 171 if (i >= offsetDst && i < offsetDst + count) { 172 assertEquals(src[i + (offsetSrc - offsetDst)], dst[i]); 173 } else { 174 assertEquals((byte)-1, dst[i]); 175 } 176 } 177 } 178 checkOverlappingMemmove(int size, int offsetDst, int offsetSrc, int count)179 private void checkOverlappingMemmove(int size, int offsetDst, int offsetSrc, int count) { 180 byte[] buf = new byte[size]; 181 for (int i = 0; i < size; ++i) { 182 buf[i] = (byte)i; 183 } 184 185 assertTrue(offsetSrc + count <= size); 186 assertTrue(offsetDst + count <= size); 187 Memory.memmove(buf, offsetDst, buf, offsetSrc, count); 188 for (int i = 0; i < size; ++i) { 189 if (i >= offsetDst && i < offsetDst + count) { 190 assertEquals(i + (offsetSrc - offsetDst), buf[i]); 191 } else { 192 assertEquals((byte)i, buf[i]); 193 } 194 } 195 } 196 } 197