119656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov/*
219656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov * Copyright (C) 2013 The Android Open Source Project
3bcc4da9b752f0def46d63ed7b31f3f49cc2435adDimitry Ivanov * All rights reserved.
419656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov *
5bcc4da9b752f0def46d63ed7b31f3f49cc2435adDimitry Ivanov * Redistribution and use in source and binary forms, with or without
6bcc4da9b752f0def46d63ed7b31f3f49cc2435adDimitry Ivanov * modification, are permitted provided that the following conditions
7bcc4da9b752f0def46d63ed7b31f3f49cc2435adDimitry Ivanov * are met:
8bcc4da9b752f0def46d63ed7b31f3f49cc2435adDimitry Ivanov *  * Redistributions of source code must retain the above copyright
9bcc4da9b752f0def46d63ed7b31f3f49cc2435adDimitry Ivanov *    notice, this list of conditions and the following disclaimer.
10bcc4da9b752f0def46d63ed7b31f3f49cc2435adDimitry Ivanov *  * Redistributions in binary form must reproduce the above copyright
11bcc4da9b752f0def46d63ed7b31f3f49cc2435adDimitry Ivanov *    notice, this list of conditions and the following disclaimer in
12bcc4da9b752f0def46d63ed7b31f3f49cc2435adDimitry Ivanov *    the documentation and/or other materials provided with the
13bcc4da9b752f0def46d63ed7b31f3f49cc2435adDimitry Ivanov *    distribution.
1419656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov *
15bcc4da9b752f0def46d63ed7b31f3f49cc2435adDimitry Ivanov * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16bcc4da9b752f0def46d63ed7b31f3f49cc2435adDimitry Ivanov * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17bcc4da9b752f0def46d63ed7b31f3f49cc2435adDimitry Ivanov * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
18bcc4da9b752f0def46d63ed7b31f3f49cc2435adDimitry Ivanov * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19bcc4da9b752f0def46d63ed7b31f3f49cc2435adDimitry Ivanov * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20bcc4da9b752f0def46d63ed7b31f3f49cc2435adDimitry Ivanov * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21bcc4da9b752f0def46d63ed7b31f3f49cc2435adDimitry Ivanov * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22bcc4da9b752f0def46d63ed7b31f3f49cc2435adDimitry Ivanov * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23bcc4da9b752f0def46d63ed7b31f3f49cc2435adDimitry Ivanov * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24bcc4da9b752f0def46d63ed7b31f3f49cc2435adDimitry Ivanov * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25bcc4da9b752f0def46d63ed7b31f3f49cc2435adDimitry Ivanov * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26bcc4da9b752f0def46d63ed7b31f3f49cc2435adDimitry Ivanov * SUCH DAMAGE.
2719656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov */
2819656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov
2919656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov#include <stdlib.h>
3019656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov#include <string.h>
3119656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov#include <sys/mman.h>
3219656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov
3319656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov#include <gtest/gtest.h>
3419656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov
3519656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov#include "../linker_allocator.h"
3619656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov
3719656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov#include <unistd.h>
3819656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov
3919656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanovnamespace {
4019656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov
4119656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov/*
4219656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov * this one has size below allocator cap which is 2*sizeof(void*)
4319656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov */
4419656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanovstruct test_struct_small {
4519656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  char dummy_str[5];
4619656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov};
4719656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov
4819656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanovstruct test_struct_large {
4919656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  char dummy_str[1009];
5019656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov};
5119656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov
5219656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanovstruct test_struct_huge {
5319656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  char dummy_str[73939];
5419656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov};
5519656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov
5619656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanovstruct test_struct_512 {
5719656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  char dummy_str[503];
5819656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov};
5919656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov
6019656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov};
6119656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov
6219656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanovstatic size_t kPageSize = sysconf(_SC_PAGE_SIZE);
6319656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov
6419656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy IvanovTEST(linker_memory, test_alloc_0) {
6519656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  LinkerMemoryAllocator allocator;
6619656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  void* ptr = allocator.alloc(0);
6719656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  ASSERT_TRUE(ptr != nullptr);
68a0f187bec77cee6db1ecc12ff7e39ccabb66c078Dmitriy Ivanov  allocator.free(ptr);
6919656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov}
7019656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov
7119656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy IvanovTEST(linker_memory, test_free_nullptr) {
7219656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  LinkerMemoryAllocator allocator;
7319656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  allocator.free(nullptr);
7419656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov}
7519656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov
7619656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy IvanovTEST(linker_memory, test_realloc) {
7719656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  LinkerMemoryAllocator allocator;
7819656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  uint32_t* array = reinterpret_cast<uint32_t*>(allocator.alloc(512));
7919656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  const size_t array_size = 512 / sizeof(uint32_t);
8019656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov
8119656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  uint32_t model[1000];
8219656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov
8319656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  model[0] = 1;
8419656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  model[1] = 1;
8519656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov
8619656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  for (size_t i = 2; i < 1000; ++i) {
8719656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov    model[i] = model[i - 1] + model[i - 2];
8819656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  }
8919656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov
9019656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  memcpy(array, model, array_size);
9119656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov
9219656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  uint32_t* reallocated_ptr = reinterpret_cast<uint32_t*>(allocator.realloc(array, 1024));
9319656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov
9419656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  ASSERT_TRUE(reallocated_ptr != nullptr);
9519656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  ASSERT_TRUE(reallocated_ptr != array);
9619656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov
9719656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  ASSERT_TRUE(memcmp(reallocated_ptr, model, array_size) == 0);
9819656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov
9919656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  array = reallocated_ptr;
10019656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov
10119656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  memcpy(array, model, 2*array_size);
10219656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov
10319656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  reallocated_ptr = reinterpret_cast<uint32_t*>(allocator.realloc(array, 62));
10419656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov
10519656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  ASSERT_TRUE(reallocated_ptr == array);
10619656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov
10719656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  reallocated_ptr = reinterpret_cast<uint32_t*>(allocator.realloc(array, 4000));
10819656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov
10919656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  ASSERT_TRUE(reallocated_ptr != nullptr);
11019656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  ASSERT_TRUE(reallocated_ptr != array);
1113edc5c41bbee7cf608a781e7056599f32ca1949cDimitry Ivanov  ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(reallocated_ptr) % 16);
11219656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov
11319656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  ASSERT_TRUE(memcmp(reallocated_ptr, model, array_size * 2) == 0);
11419656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov
11519656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  array = reallocated_ptr;
11619656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov
11719656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  memcpy(array, model, 4000);
11819656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov
11919656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  reallocated_ptr = reinterpret_cast<uint32_t*>(allocator.realloc(array, 64000));
12019656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov
12119656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  ASSERT_TRUE(reallocated_ptr != nullptr);
12219656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  ASSERT_TRUE(reallocated_ptr != array);
1233edc5c41bbee7cf608a781e7056599f32ca1949cDimitry Ivanov  ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(reallocated_ptr) % 16);
12419656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov
12519656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  ASSERT_TRUE(memcmp(reallocated_ptr, model, 4000) == 0);
12619656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov
127a0f187bec77cee6db1ecc12ff7e39ccabb66c078Dmitriy Ivanov  ASSERT_EQ(nullptr, allocator.realloc(reallocated_ptr, 0));
12819656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov}
12919656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov
13019656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy IvanovTEST(linker_memory, test_small_smoke) {
13119656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  LinkerMemoryAllocator allocator;
13219656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov
13319656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  uint8_t zeros[16];
13419656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  memset(zeros, 0, sizeof(zeros));
13519656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov
13619656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  test_struct_small* ptr1 =
13719656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov      reinterpret_cast<test_struct_small*>(allocator.alloc(sizeof(test_struct_small)));
13819656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  test_struct_small* ptr2 =
13919656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov      reinterpret_cast<test_struct_small*>(allocator.alloc(sizeof(test_struct_small)));
14019656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov
14119656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  ASSERT_TRUE(ptr1 != nullptr);
1423edc5c41bbee7cf608a781e7056599f32ca1949cDimitry Ivanov  ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(ptr1) % 16);
14319656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  ASSERT_TRUE(ptr2 != nullptr);
1443edc5c41bbee7cf608a781e7056599f32ca1949cDimitry Ivanov  ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(ptr2) % 16);
1453edc5c41bbee7cf608a781e7056599f32ca1949cDimitry Ivanov
14619656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  ASSERT_EQ(reinterpret_cast<uintptr_t>(ptr1)+16, reinterpret_cast<uintptr_t>(ptr2));
14719656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  ASSERT_TRUE(memcmp(ptr1, zeros, 16) == 0);
14819656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov
14919656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  allocator.free(ptr1);
15019656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  allocator.free(ptr2);
15119656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov}
15219656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov
15319656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy IvanovTEST(linker_memory, test_huge_smoke) {
15419656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  LinkerMemoryAllocator allocator;
15519656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov
15619656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  // this should trigger proxy-to-mmap
15719656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  test_struct_huge* ptr1 =
15819656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov      reinterpret_cast<test_struct_huge*>(allocator.alloc(sizeof(test_struct_huge)));
15919656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  test_struct_huge* ptr2 =
16019656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov      reinterpret_cast<test_struct_huge*>(allocator.alloc(sizeof(test_struct_huge)));
16119656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov
16219656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  ASSERT_TRUE(ptr1 != nullptr);
1633edc5c41bbee7cf608a781e7056599f32ca1949cDimitry Ivanov  ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(ptr1) % 16);
16419656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  ASSERT_TRUE(ptr2 != nullptr);
1653edc5c41bbee7cf608a781e7056599f32ca1949cDimitry Ivanov  ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(ptr2) % 16);
16619656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov
16719656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  ASSERT_TRUE(
16819656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov      reinterpret_cast<uintptr_t>(ptr1)/kPageSize != reinterpret_cast<uintptr_t>(ptr2)/kPageSize);
16919656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  allocator.free(ptr2);
17019656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  allocator.free(ptr1);
17119656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov}
17219656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov
17319656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy IvanovTEST(linker_memory, test_large) {
17419656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  LinkerMemoryAllocator allocator;
17519656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov
17619656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  test_struct_large* ptr1 =
17719656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov      reinterpret_cast<test_struct_large*>(allocator.alloc(sizeof(test_struct_large)));
17819656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  test_struct_large* ptr2 =
17919656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov      reinterpret_cast<test_struct_large*>(allocator.alloc(1024));
18019656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov
18119656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  ASSERT_TRUE(ptr1 != nullptr);
1823edc5c41bbee7cf608a781e7056599f32ca1949cDimitry Ivanov  ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(ptr1) % 16);
18319656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  ASSERT_TRUE(ptr2 != nullptr);
1843edc5c41bbee7cf608a781e7056599f32ca1949cDimitry Ivanov  ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(ptr2) % 16);
18519656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov
18619656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  ASSERT_EQ(reinterpret_cast<uintptr_t>(ptr1) + 1024, reinterpret_cast<uintptr_t>(ptr2));
18719656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov
18819656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  // let's allocate until we reach the next page.
18919656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  size_t n = kPageSize / sizeof(test_struct_large) + 1 - 2;
19019656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  test_struct_large* objects[n];
19119656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov
19219656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  for (size_t i = 0; i < n; ++i) {
19319656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov    test_struct_large* obj_ptr =
19419656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov        reinterpret_cast<test_struct_large*>(allocator.alloc(sizeof(test_struct_large)));
19519656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov    ASSERT_TRUE(obj_ptr != nullptr);
19619656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov    objects[i] = obj_ptr;
19719656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  }
19819656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov
19919656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  test_struct_large* ptr_to_free =
20019656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov      reinterpret_cast<test_struct_large*>(allocator.alloc(sizeof(test_struct_large)));
20119656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov
20219656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  ASSERT_TRUE(ptr_to_free != nullptr);
2033edc5c41bbee7cf608a781e7056599f32ca1949cDimitry Ivanov  ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(ptr_to_free) % 16);
20419656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov
20519656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  allocator.free(ptr1);
20619656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov
20719656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  for (size_t i=0; i<n; ++i) {
20819656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov    allocator.free(objects[i]);
20919656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  }
21019656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov
21119656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  allocator.free(ptr2);
21219656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov  allocator.free(ptr_to_free);
21319656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov}
21419656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov
21519656ce5376c95ce0deebc4d0c6af1bb8d740934Dmitriy Ivanov
216