0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 package org.apache.spark.unsafe;
0019
0020 import org.apache.spark.unsafe.memory.HeapMemoryAllocator;
0021 import org.apache.spark.unsafe.memory.MemoryAllocator;
0022 import org.apache.spark.unsafe.memory.MemoryBlock;
0023
0024 import org.junit.Assert;
0025 import org.junit.Test;
0026
0027 public class PlatformUtilSuite {
0028
0029 @Test
0030 public void overlappingCopyMemory() {
0031 byte[] data = new byte[3 * 1024 * 1024];
0032 int size = 2 * 1024 * 1024;
0033 for (int i = 0; i < data.length; ++i) {
0034 data[i] = (byte)i;
0035 }
0036
0037 Platform.copyMemory(data, Platform.BYTE_ARRAY_OFFSET, data, Platform.BYTE_ARRAY_OFFSET, size);
0038 for (int i = 0; i < data.length; ++i) {
0039 Assert.assertEquals((byte)i, data[i]);
0040 }
0041
0042 Platform.copyMemory(
0043 data,
0044 Platform.BYTE_ARRAY_OFFSET + 1,
0045 data,
0046 Platform.BYTE_ARRAY_OFFSET,
0047 size);
0048 for (int i = 0; i < size; ++i) {
0049 Assert.assertEquals((byte)(i + 1), data[i]);
0050 }
0051
0052 for (int i = 0; i < data.length; ++i) {
0053 data[i] = (byte)i;
0054 }
0055 Platform.copyMemory(
0056 data,
0057 Platform.BYTE_ARRAY_OFFSET,
0058 data,
0059 Platform.BYTE_ARRAY_OFFSET + 1,
0060 size);
0061 for (int i = 0; i < size; ++i) {
0062 Assert.assertEquals((byte)i, data[i + 1]);
0063 }
0064 }
0065
0066 @Test
0067 public void onHeapMemoryAllocatorPoolingReUsesLongArrays() {
0068 MemoryBlock block1 = MemoryAllocator.HEAP.allocate(1024 * 1024);
0069 Object baseObject1 = block1.getBaseObject();
0070 MemoryAllocator.HEAP.free(block1);
0071 MemoryBlock block2 = MemoryAllocator.HEAP.allocate(1024 * 1024);
0072 Object baseObject2 = block2.getBaseObject();
0073 Assert.assertSame(baseObject1, baseObject2);
0074 MemoryAllocator.HEAP.free(block2);
0075 }
0076
0077 @Test
0078 public void freeingOnHeapMemoryBlockResetsBaseObjectAndOffset() {
0079 MemoryBlock block = MemoryAllocator.HEAP.allocate(1024);
0080 Assert.assertNotNull(block.getBaseObject());
0081 MemoryAllocator.HEAP.free(block);
0082 Assert.assertNull(block.getBaseObject());
0083 Assert.assertEquals(0, block.getBaseOffset());
0084 Assert.assertEquals(MemoryBlock.FREED_IN_ALLOCATOR_PAGE_NUMBER, block.pageNumber);
0085 }
0086
0087 @Test
0088 public void freeingOffHeapMemoryBlockResetsOffset() {
0089 MemoryBlock block = MemoryAllocator.UNSAFE.allocate(1024);
0090 Assert.assertNull(block.getBaseObject());
0091 Assert.assertNotEquals(0, block.getBaseOffset());
0092 MemoryAllocator.UNSAFE.free(block);
0093 Assert.assertNull(block.getBaseObject());
0094 Assert.assertEquals(0, block.getBaseOffset());
0095 Assert.assertEquals(MemoryBlock.FREED_IN_ALLOCATOR_PAGE_NUMBER, block.pageNumber);
0096 }
0097
0098 @Test(expected = AssertionError.class)
0099 public void onHeapMemoryAllocatorThrowsAssertionErrorOnDoubleFree() {
0100 MemoryBlock block = MemoryAllocator.HEAP.allocate(1024);
0101 MemoryAllocator.HEAP.free(block);
0102 MemoryAllocator.HEAP.free(block);
0103 }
0104
0105 @Test(expected = AssertionError.class)
0106 public void offHeapMemoryAllocatorThrowsAssertionErrorOnDoubleFree() {
0107 MemoryBlock block = MemoryAllocator.UNSAFE.allocate(1024);
0108 MemoryAllocator.UNSAFE.free(block);
0109 MemoryAllocator.UNSAFE.free(block);
0110 }
0111
0112 @Test
0113 public void memoryDebugFillEnabledInTest() {
0114 Assert.assertTrue(MemoryAllocator.MEMORY_DEBUG_FILL_ENABLED);
0115 MemoryBlock onheap = MemoryAllocator.HEAP.allocate(1);
0116 Assert.assertEquals(
0117 MemoryAllocator.MEMORY_DEBUG_FILL_CLEAN_VALUE,
0118 Platform.getByte(onheap.getBaseObject(), onheap.getBaseOffset()));
0119
0120 MemoryBlock onheap1 = MemoryAllocator.HEAP.allocate(1024 * 1024);
0121 Object onheap1BaseObject = onheap1.getBaseObject();
0122 long onheap1BaseOffset = onheap1.getBaseOffset();
0123 MemoryAllocator.HEAP.free(onheap1);
0124 Assert.assertEquals(
0125 MemoryAllocator.MEMORY_DEBUG_FILL_FREED_VALUE,
0126 Platform.getByte(onheap1BaseObject, onheap1BaseOffset));
0127 MemoryBlock onheap2 = MemoryAllocator.HEAP.allocate(1024 * 1024);
0128 Assert.assertEquals(
0129 MemoryAllocator.MEMORY_DEBUG_FILL_CLEAN_VALUE,
0130 Platform.getByte(onheap2.getBaseObject(), onheap2.getBaseOffset()));
0131
0132 MemoryBlock offheap = MemoryAllocator.UNSAFE.allocate(1);
0133 Assert.assertEquals(
0134 MemoryAllocator.MEMORY_DEBUG_FILL_CLEAN_VALUE,
0135 Platform.getByte(offheap.getBaseObject(), offheap.getBaseOffset()));
0136 MemoryAllocator.UNSAFE.free(offheap);
0137 }
0138
0139 @Test
0140 public void heapMemoryReuse() {
0141 MemoryAllocator heapMem = new HeapMemoryAllocator();
0142
0143
0144 MemoryBlock onheap1 = heapMem.allocate(513);
0145 Object obj1 = onheap1.getBaseObject();
0146 heapMem.free(onheap1);
0147 MemoryBlock onheap2 = heapMem.allocate(514);
0148 Assert.assertNotEquals(obj1, onheap2.getBaseObject());
0149
0150
0151
0152 MemoryBlock onheap3 = heapMem.allocate(1024 * 1024 + 1);
0153 Assert.assertEquals(1024 * 1024 + 1, onheap3.size());
0154 Object obj3 = onheap3.getBaseObject();
0155 heapMem.free(onheap3);
0156 MemoryBlock onheap4 = heapMem.allocate(1024 * 1024 + 7);
0157 Assert.assertEquals(1024 * 1024 + 7, onheap4.size());
0158 Assert.assertEquals(obj3, onheap4.getBaseObject());
0159 }
0160 }