linker: Purge block allocator memory when possible
If all allocated memory from a block allocator is freed, it is a good opportunity to purge all the pages allocated to reduce lingering dirty pages. Memory saving varies with the platform and what processes are running. Measuring right after boot, this saves ~1.8MB on cuttelfish and ~1.3MB on a 32-bit ARM device. Bug: 112073665 Test: Boot and check memory usage with 'showmap'. Change-Id: I53769e0ec9699f0b3645cdf281a2c0bbffb98676
This commit is contained in:
parent
176d2fbcae
commit
fb78a4ac1b
|
@ -52,7 +52,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() {
|
||||
|
@ -73,6 +74,8 @@ void* LinkerBlockAllocator::alloc() {
|
|||
|
||||
memset(block_info, 0, block_size_);
|
||||
|
||||
++allocated_;
|
||||
|
||||
return block_info;
|
||||
}
|
||||
|
||||
|
@ -101,6 +104,11 @@ void LinkerBlockAllocator::free(void* block) {
|
|||
block_info->num_free_blocks = 1;
|
||||
|
||||
free_block_list_ = block_info;
|
||||
|
||||
--allocated_;
|
||||
if (allocated_ == 0) {
|
||||
free_all_pages();
|
||||
}
|
||||
}
|
||||
|
||||
void LinkerBlockAllocator::protect_all(int prot) {
|
||||
|
@ -151,3 +159,18 @@ LinkerBlockAllocatorPage* LinkerBlockAllocator::find_page(void* block) {
|
|||
|
||||
abort();
|
||||
}
|
||||
|
||||
void LinkerBlockAllocator::free_all_pages() {
|
||||
if (allocated_) {
|
||||
abort();
|
||||
}
|
||||
|
||||
LinkerBlockAllocatorPage* page = page_list_;
|
||||
while (page) {
|
||||
LinkerBlockAllocatorPage* next = page->next;
|
||||
munmap(page, PAGE_SIZE);
|
||||
page = next;
|
||||
}
|
||||
page_list_ = nullptr;
|
||||
free_block_list_ = nullptr;
|
||||
}
|
||||
|
|
|
@ -53,10 +53,12 @@ class LinkerBlockAllocator {
|
|||
private:
|
||||
void create_new_page();
|
||||
LinkerBlockAllocatorPage* find_page(void* block);
|
||||
void free_all_pages();
|
||||
|
||||
size_t block_size_;
|
||||
LinkerBlockAllocatorPage* page_list_;
|
||||
void* free_block_list_;
|
||||
size_t allocated_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(LinkerBlockAllocator);
|
||||
};
|
||||
|
@ -73,7 +75,8 @@ class LinkerBlockAllocator {
|
|||
* with size 513 this allocator will use 516 (520 for lp64) bytes of data
|
||||
* where generalized implementation is going to use 1024 sized blocks.
|
||||
*
|
||||
* 2. This allocator does not munmap allocated memory, where LinkerMemoryAllocator does.
|
||||
* 2. Unless all allocated memory is freed, this allocator does not munmap
|
||||
* allocated memory, where LinkerMemoryAllocator does.
|
||||
*
|
||||
* 3. This allocator provides mprotect services to the user, where LinkerMemoryAllocator
|
||||
* always treats it's memory as READ|WRITE.
|
||||
|
|
Loading…
Reference in New Issue