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