static intptr_t alloc_cache_free_all_pages(AllocCacheBlock *blockfree) { int i; intptr_t freed = 0; alloc_cache_collapse_pages(blockfree); for (i = 0; i < BLOCKFREE_CACHE_SIZE; i++) { if (blockfree[i].start) { os_free_pages(blockfree[i].start, blockfree[i].len); freed -= blockfree[i].len; blockfree[i].start = NULL; blockfree[i].len = 0; } } return freed; }
static void alloc_cache_return_mem(VM *vm, char *p, size_t len, int zeroed) { int i; FreeBlock *blockfree = vm->freeblocks; /* Round up to nearest page: */ if (len & (page_size - 1)) len += page_size - (len & (page_size - 1)); /* Try to free pages in larger blocks, since the OS may be slow. */ for (i = 0; i < BLOCKFREE_CACHE_SIZE; i++) if(blockfree[i].start && (blockfree[i].len < (1024 * 1024))) { if (p == blockfree[i].start + blockfree[i].len) { blockfree[i].len += len; if (!zeroed) blockfree[i].zeroed = 0; return; } if (p + len == blockfree[i].start) { blockfree[i].start = p; blockfree[i].len += len; if (!zeroed) blockfree[i].zeroed = 0; return; } } for (i = 0; i < BLOCKFREE_CACHE_SIZE; i++) { if (!blockfree[i].start) { blockfree[i].start = p; blockfree[i].len = len; blockfree[i].age = 0; blockfree[i].zeroed = zeroed; return; } } /* Might help next time around: */ alloc_cache_collapse_pages(blockfree); os_vm_free_pages(p, len); vm_memory_allocated_dec(vm, len); }
static void vm_flush_freed_pages(VM *vm) { int i; FreeBlock *blockfree = vm->freeblocks; alloc_cache_collapse_pages(blockfree); for (i = 0; i < BLOCKFREE_CACHE_SIZE; i++) { if (blockfree[i].start) { if (blockfree[i].age == BLOCKFREE_UNMAP_AGE) { os_vm_free_pages(blockfree[i].start, blockfree[i].len); vm_memory_allocated_dec(vm, blockfree[i].len); blockfree[i].start = NULL; blockfree[i].len = 0; } else blockfree[i].age++; } } }
static intptr_t alloc_cache_free_page(AllocCacheBlock *blockfree, char *p, size_t len, int dirty, int originated_here) { int i; /* Try to free pages in larger blocks, since the OS may be slow. */ for (i = 0; i < BLOCKFREE_CACHE_SIZE; i++) if(blockfree[i].start && (blockfree[i].len < (1024 * 1024))) { if (p == blockfree[i].start + blockfree[i].len) { blockfree[i].len += len; if (dirty) blockfree[i].zeroed = 0; return (originated_here ? 0 : len); } if (p + len == blockfree[i].start) { blockfree[i].start = p; blockfree[i].len += len; if (dirty) blockfree[i].zeroed = 0; return (originated_here ? 0 : len); } } for (i = 0; i < BLOCKFREE_CACHE_SIZE; i++) { if (!blockfree[i].start) { blockfree[i].start = p; blockfree[i].len = len; blockfree[i].age = 0; blockfree[i].zeroed = !dirty; return (originated_here ? 0 : len); } } /* Might help next time around: */ alloc_cache_collapse_pages(blockfree); os_free_pages(p, len); return (originated_here ? -len : 0); }