119656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov/* 219656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov * Copyright (C) 2013 The Android Open Source Project 319656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov * 419656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov * Licensed under the Apache License, Version 2.0 (the "License"); 519656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov * you may not use this file except in compliance with the License. 619656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov * You may obtain a copy of the License at 719656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov * 819656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov * http://www.apache.org/licenses/LICENSE-2.0 919656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov * 1019656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov * Unless required by applicable law or agreed to in writing, software 1119656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov * distributed under the License is distributed on an "AS IS" BASIS, 1219656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1319656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov * See the License for the specific language governing permissions and 1419656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov * limitations under the License. 1519656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov */ 1619656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov 1719656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov#include <stdlib.h> 1819656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov#include <string.h> 1919656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov#include <sys/mman.h> 2019656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov 2119656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov#include <gtest/gtest.h> 2219656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov 2319656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov#include "../linker_allocator.h" 2419656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov 2519656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov#include <unistd.h> 2619656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov 2719656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanovnamespace { 2819656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov 2919656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov/* 3019656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov * this one has size below allocator cap which is 2*sizeof(void*) 3119656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov */ 3219656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanovstruct test_struct_small { 3319656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov char dummy_str[5]; 3419656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov}; 3519656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov 3619656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanovstruct test_struct_large { 3719656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov char dummy_str[1009]; 3819656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov}; 3919656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov 4019656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanovstruct test_struct_huge { 4119656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov char dummy_str[73939]; 4219656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov}; 4319656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov 4419656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanovstruct test_struct_512 { 4519656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov char dummy_str[503]; 4619656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov}; 4719656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov 4819656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov}; 4919656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov 5019656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanovstatic size_t kPageSize = sysconf(_SC_PAGE_SIZE); 5119656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov 5219656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy IvanovTEST(linker_memory, test_alloc_0) { 5319656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov LinkerMemoryAllocator allocator; 5419656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov void* ptr = allocator.alloc(0); 5519656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov ASSERT_TRUE(ptr != nullptr); 5619656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov free(ptr); 5719656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov} 5819656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov 5919656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy IvanovTEST(linker_memory, test_free_nullptr) { 6019656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov LinkerMemoryAllocator allocator; 6119656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov allocator.free(nullptr); 6219656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov} 6319656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov 6419656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy IvanovTEST(linker_memory, test_realloc) { 6519656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov LinkerMemoryAllocator allocator; 6619656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov uint32_t* array = reinterpret_cast<uint32_t*>(allocator.alloc(512)); 6719656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov const size_t array_size = 512 / sizeof(uint32_t); 6819656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov 6919656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov uint32_t model[1000]; 7019656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov 7119656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov model[0] = 1; 7219656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov model[1] = 1; 7319656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov 7419656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov for (size_t i = 2; i < 1000; ++i) { 7519656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov model[i] = model[i - 1] + model[i - 2]; 7619656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov } 7719656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov 7819656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov memcpy(array, model, array_size); 7919656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov 8019656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov uint32_t* reallocated_ptr = reinterpret_cast<uint32_t*>(allocator.realloc(array, 1024)); 8119656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov 8219656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov ASSERT_TRUE(reallocated_ptr != nullptr); 8319656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov ASSERT_TRUE(reallocated_ptr != array); 8419656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov 8519656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov ASSERT_TRUE(memcmp(reallocated_ptr, model, array_size) == 0); 8619656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov 8719656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov array = reallocated_ptr; 8819656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov 8919656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov memcpy(array, model, 2*array_size); 9019656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov 9119656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov reallocated_ptr = reinterpret_cast<uint32_t*>(allocator.realloc(array, 62)); 9219656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov 9319656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov ASSERT_TRUE(reallocated_ptr == array); 9419656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov 9519656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov reallocated_ptr = reinterpret_cast<uint32_t*>(allocator.realloc(array, 4000)); 9619656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov 9719656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov ASSERT_TRUE(reallocated_ptr != nullptr); 9819656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov ASSERT_TRUE(reallocated_ptr != array); 9919656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov 10019656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov ASSERT_TRUE(memcmp(reallocated_ptr, model, array_size * 2) == 0); 10119656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov 10219656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov array = reallocated_ptr; 10319656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov 10419656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov memcpy(array, model, 4000); 10519656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov 10619656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov reallocated_ptr = reinterpret_cast<uint32_t*>(allocator.realloc(array, 64000)); 10719656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov 10819656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov ASSERT_TRUE(reallocated_ptr != nullptr); 10919656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov ASSERT_TRUE(reallocated_ptr != array); 11019656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov 11119656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov ASSERT_TRUE(memcmp(reallocated_ptr, model, 4000) == 0); 11219656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov 11319656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov ASSERT_EQ(nullptr, realloc(reallocated_ptr, 0)); 11419656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov} 11519656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov 11619656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy IvanovTEST(linker_memory, test_small_smoke) { 11719656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov LinkerMemoryAllocator allocator; 11819656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov 11919656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov uint8_t zeros[16]; 12019656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov memset(zeros, 0, sizeof(zeros)); 12119656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov 12219656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov test_struct_small* ptr1 = 12319656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov reinterpret_cast<test_struct_small*>(allocator.alloc(sizeof(test_struct_small))); 12419656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov test_struct_small* ptr2 = 12519656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov reinterpret_cast<test_struct_small*>(allocator.alloc(sizeof(test_struct_small))); 12619656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov 12719656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov ASSERT_TRUE(ptr1 != nullptr); 12819656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov ASSERT_TRUE(ptr2 != nullptr); 12919656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov ASSERT_EQ(reinterpret_cast<uintptr_t>(ptr1)+16, reinterpret_cast<uintptr_t>(ptr2)); 13019656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov ASSERT_TRUE(memcmp(ptr1, zeros, 16) == 0); 13119656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov 13219656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov allocator.free(ptr1); 13319656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov allocator.free(ptr2); 13419656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov} 13519656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov 13619656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy IvanovTEST(linker_memory, test_huge_smoke) { 13719656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov LinkerMemoryAllocator allocator; 13819656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov 13919656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov // this should trigger proxy-to-mmap 14019656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov test_struct_huge* ptr1 = 14119656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov reinterpret_cast<test_struct_huge*>(allocator.alloc(sizeof(test_struct_huge))); 14219656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov test_struct_huge* ptr2 = 14319656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov reinterpret_cast<test_struct_huge*>(allocator.alloc(sizeof(test_struct_huge))); 14419656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov 14519656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov ASSERT_TRUE(ptr1 != nullptr); 14619656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov ASSERT_TRUE(ptr2 != nullptr); 14719656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov 14819656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov ASSERT_TRUE( 14919656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov reinterpret_cast<uintptr_t>(ptr1)/kPageSize != reinterpret_cast<uintptr_t>(ptr2)/kPageSize); 15019656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov allocator.free(ptr2); 15119656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov allocator.free(ptr1); 15219656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov} 15319656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov 15419656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy IvanovTEST(linker_memory, test_large) { 15519656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov LinkerMemoryAllocator allocator; 15619656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov 15719656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov test_struct_large* ptr1 = 15819656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov reinterpret_cast<test_struct_large*>(allocator.alloc(sizeof(test_struct_large))); 15919656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov test_struct_large* ptr2 = 16019656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov reinterpret_cast<test_struct_large*>(allocator.alloc(1024)); 16119656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov 16219656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov ASSERT_TRUE(ptr1 != nullptr); 16319656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov ASSERT_TRUE(ptr2 != nullptr); 16419656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov 16519656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov ASSERT_EQ(reinterpret_cast<uintptr_t>(ptr1) + 1024, reinterpret_cast<uintptr_t>(ptr2)); 16619656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov 16719656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov // let's allocate until we reach the next page. 16819656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov size_t n = kPageSize / sizeof(test_struct_large) + 1 - 2; 16919656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov test_struct_large* objects[n]; 17019656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov 17119656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov for (size_t i = 0; i < n; ++i) { 17219656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov test_struct_large* obj_ptr = 17319656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov reinterpret_cast<test_struct_large*>(allocator.alloc(sizeof(test_struct_large))); 17419656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov ASSERT_TRUE(obj_ptr != nullptr); 17519656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov objects[i] = obj_ptr; 17619656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov } 17719656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov 17819656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov test_struct_large* ptr_to_free = 17919656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov reinterpret_cast<test_struct_large*>(allocator.alloc(sizeof(test_struct_large))); 18019656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov 18119656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov ASSERT_TRUE(ptr_to_free != nullptr); 18219656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov 18319656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov allocator.free(ptr1); 18419656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov 18519656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov for (size_t i=0; i<n; ++i) { 18619656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov allocator.free(objects[i]); 18719656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov } 18819656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov 18919656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov allocator.free(ptr2); 19019656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov allocator.free(ptr_to_free); 19119656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov} 19219656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov 19319656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov 194