summaryrefslogtreecommitdiff
path: root/linker/linker_block_allocator.cpp
diff options
context:
space:
mode:
authorVic Yang <victoryang@google.com>2019-01-29 20:23:16 -0800
committerVic Yang <victoryang@google.com>2019-01-30 22:13:13 -0800
commitbb7e1236f3676baffd5953061154e9a3552317d7 (patch)
treea1ddb820db657e34a56e66dd81a0b04a46922673 /linker/linker_block_allocator.cpp
parent58dd1cbd7f2a0b8a779f2f43c45447cdccc09c3e (diff)
Purge linker block allocators before leaving linker
This is the second attempt to purge linker block allocators. Unlike the previously reverted change which purge allocators whenever all objects are freed, we only purge right before control leaves the linker. This limits the performance impact to one munmap() call per dlopen(), in most cases. Bug: 112073665 Test: Boot and check memory usage with 'showmap'. Test: Run camear cold start performance test. Change-Id: I02c7c44935f768e065fbe7ff0389a84bd44713f0
Diffstat (limited to 'linker/linker_block_allocator.cpp')
-rw-r--r--linker/linker_block_allocator.cpp22
1 files changed, 21 insertions, 1 deletions
diff --git a/linker/linker_block_allocator.cpp b/linker/linker_block_allocator.cpp
index d72cad3d6..fdb4c8563 100644
--- a/linker/linker_block_allocator.cpp
+++ b/linker/linker_block_allocator.cpp
@@ -55,7 +55,8 @@ LinkerBlockAllocator::LinkerBlockAllocator(size_t block_size)
: block_size_(
round_up(block_size < sizeof(FreeBlockInfo) ? sizeof(FreeBlockInfo) : block_size, 16)),
page_list_(nullptr),
- free_block_list_(nullptr)
+ free_block_list_(nullptr),
+ allocated_(0)
{}
void* LinkerBlockAllocator::alloc() {
@@ -76,6 +77,8 @@ void* LinkerBlockAllocator::alloc() {
memset(block_info, 0, block_size_);
+ ++allocated_;
+
return block_info;
}
@@ -104,6 +107,8 @@ void LinkerBlockAllocator::free(void* block) {
block_info->num_free_blocks = 1;
free_block_list_ = block_info;
+
+ --allocated_;
}
void LinkerBlockAllocator::protect_all(int prot) {
@@ -154,3 +159,18 @@ LinkerBlockAllocatorPage* LinkerBlockAllocator::find_page(void* block) {
abort();
}
+
+void LinkerBlockAllocator::purge() {
+ if (allocated_) {
+ return;
+ }
+
+ LinkerBlockAllocatorPage* page = page_list_;
+ while (page) {
+ LinkerBlockAllocatorPage* next = page->next;
+ munmap(page, kAllocateSize);
+ page = next;
+ }
+ page_list_ = nullptr;
+ free_block_list_ = nullptr;
+}