blob: 4b9b9952631fd2f17558def572420b4c306e8d46 [file] [log] [blame]
Dmitriy Ivanovd597d262014-05-05 16:49:04 -07001/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Dmitriy Ivanov19656ce2015-03-10 17:48:27 -070017#ifndef __LINKER_BLOCK_ALLOCATOR_H
18#define __LINKER_BLOCK_ALLOCATOR_H
Dmitriy Ivanovd597d262014-05-05 16:49:04 -070019
20#include <stdlib.h>
21#include <limits.h>
22#include "private/bionic_macros.h"
23
Dmitriy Ivanov600bc3c2015-03-10 15:43:50 -070024struct LinkerBlockAllocatorPage;
Dmitriy Ivanovd597d262014-05-05 16:49:04 -070025
26/*
Dmitriy Ivanov19656ce2015-03-10 17:48:27 -070027 * This class is a non-template version of the LinkerTypeAllocator
Dmitriy Ivanovd597d262014-05-05 16:49:04 -070028 * It keeps code inside .cpp file by keeping the interface
29 * template-free.
30 *
Dmitriy Ivanov19656ce2015-03-10 17:48:27 -070031 * Please use LinkerTypeAllocator<type> where possible (everywhere).
Dmitriy Ivanovd597d262014-05-05 16:49:04 -070032 */
33class LinkerBlockAllocator {
34 public:
Dmitriy Ivanov4151ea72014-07-24 15:33:25 -070035 explicit LinkerBlockAllocator(size_t block_size);
Dmitriy Ivanovd597d262014-05-05 16:49:04 -070036
Dmitriy Ivanovd597d262014-05-05 16:49:04 -070037 void* alloc();
38 void free(void* block);
Dmitriy Ivanovd597d262014-05-05 16:49:04 -070039 void protect_all(int prot);
40
41 private:
42 void create_new_page();
Dmitriy Ivanov600bc3c2015-03-10 15:43:50 -070043 LinkerBlockAllocatorPage* find_page(void* block);
Dmitriy Ivanovd597d262014-05-05 16:49:04 -070044
45 size_t block_size_;
Dmitriy Ivanov600bc3c2015-03-10 15:43:50 -070046 LinkerBlockAllocatorPage* page_list_;
Dmitriy Ivanovd597d262014-05-05 16:49:04 -070047 void* free_block_list_;
48
49 DISALLOW_COPY_AND_ASSIGN(LinkerBlockAllocator);
50};
51
52/*
53 * A simple allocator for the dynamic linker. An allocator allocates instances
54 * of a single fixed-size type. Allocations are backed by page-sized private
55 * anonymous mmaps.
Dmitriy Ivanov19656ce2015-03-10 17:48:27 -070056 *
57 * The differences between this allocator and LinkerMemoryAllocator are:
58 * 1. This allocator manages space more efficiently. LinkerMemoryAllocator
59 * operates in power-of-two sized blocks up to 1k, when this implementation
60 * splits the page to aligned size of structure; For example for structures
61 * with size 513 this allocator will use 516 (520 for lp64) bytes of data
62 * where generalized implementation is going to use 1024 sized blocks.
63 *
64 * 2. This allocator does not munmap allocated memory, where LinkerMemoryAllocator does.
65 *
66 * 3. This allocator provides mprotect services to the user, where LinkerMemoryAllocator
67 * always treats it's memory as READ|WRITE.
Dmitriy Ivanovd597d262014-05-05 16:49:04 -070068 */
69template<typename T>
Dmitriy Ivanov600bc3c2015-03-10 15:43:50 -070070class LinkerTypeAllocator {
Dmitriy Ivanovd597d262014-05-05 16:49:04 -070071 public:
Dmitriy Ivanov600bc3c2015-03-10 15:43:50 -070072 LinkerTypeAllocator() : block_allocator_(sizeof(T)) {}
Dmitriy Ivanovd597d262014-05-05 16:49:04 -070073 T* alloc() { return reinterpret_cast<T*>(block_allocator_.alloc()); }
74 void free(T* t) { block_allocator_.free(t); }
Dmitriy Ivanovd597d262014-05-05 16:49:04 -070075 void protect_all(int prot) { block_allocator_.protect_all(prot); }
76 private:
77 LinkerBlockAllocator block_allocator_;
Dmitriy Ivanov600bc3c2015-03-10 15:43:50 -070078 DISALLOW_COPY_AND_ASSIGN(LinkerTypeAllocator);
Dmitriy Ivanovd597d262014-05-05 16:49:04 -070079};
Dmitriy Ivanov600bc3c2015-03-10 15:43:50 -070080
Dmitriy Ivanov19656ce2015-03-10 17:48:27 -070081#endif // __LINKER_BLOCK_ALLOCATOR_H