Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Licensed to the Apache Software Foundation (ASF) under one or more
0003  * contributor license agreements.  See the NOTICE file distributed with
0004  * this work for additional information regarding copyright ownership.
0005  * The ASF licenses this file to You under the Apache License, Version 2.0
0006  * (the "License"); you may not use this file except in compliance with
0007  * the License.  You may obtain a copy of the License at
0008  *
0009  *    http://www.apache.org/licenses/LICENSE-2.0
0010  *
0011  * Unless required by applicable law or agreed to in writing, software
0012  * distributed under the License is distributed on an "AS IS" BASIS,
0013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014  * See the License for the specific language governing permissions and
0015  * limitations under the License.
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     // The size is less than `HeapMemoryAllocator.POOLING_THRESHOLD_BYTES`,
0143     // allocate new memory every time.
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     // The size is greater than `HeapMemoryAllocator.POOLING_THRESHOLD_BYTES`,
0151     // reuse the previous memory which has released.
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 }