From bcc32291e8db6de9efd49d02c6616cc0b9f0ef98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Lindqvist?= Date: Tue, 12 Apr 2016 01:47:40 +0200 Subject: [PATCH] VM: merge of free_list_allocator.hpp into free_list.hpp It's better if all the free list stuff is in a single header. --- GNUmakefile | 1 - vm/free_list.hpp | 180 ++++++++++++++++++++++++++++++++++++ vm/free_list_allocator.hpp | 184 ------------------------------------- vm/master.hpp | 3 +- 4 files changed, 181 insertions(+), 187 deletions(-) delete mode 100644 vm/free_list_allocator.hpp diff --git a/GNUmakefile b/GNUmakefile index f1433f530e..753fb05c10 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -92,7 +92,6 @@ ifdef CONFIG vm/mark_bits.hpp \ vm/free_list.hpp \ vm/fixup.hpp \ - vm/free_list_allocator.hpp \ vm/write_barrier.hpp \ vm/object_start_map.hpp \ vm/aging_space.hpp \ diff --git a/vm/free_list.hpp b/vm/free_list.hpp index d30570c5e5..ab7c17e119 100644 --- a/vm/free_list.hpp +++ b/vm/free_list.hpp @@ -43,4 +43,184 @@ struct free_list { cell largest_free_block(); }; +struct allocator_room { + cell size; + cell occupied_space; + cell total_free; + cell contiguous_free; + cell free_block_count; +}; + +template struct free_list_allocator { + cell size; + cell start; + cell end; + free_list free_blocks; + mark_bits state; + + free_list_allocator(cell size, cell start); + void initial_free_list(cell occupied); + bool contains_p(Block* block); + bool can_allot_p(cell size); + Block* allot(cell size); + void free(Block* block); + cell occupied_space(); + cell free_space(); + cell largest_free_block(); + cell free_block_count(); + void sweep(); + template void sweep(Iterator& iter); + template + void compact(Iterator& iter, Fixup fixup, const Block** finger); + template + void iterate(Iterator& iter, Fixup fixup); + template void iterate(Iterator& iter); + allocator_room as_allocator_room(); +}; + +template +free_list_allocator::free_list_allocator(cell size, cell start) + : size(size), + start(start), + end(start + size), + state(mark_bits(size, start)) { + initial_free_list(0); +} + +template +void free_list_allocator::initial_free_list(cell occupied) { + free_blocks.initial_free_list(start, end, occupied); +} + +template +bool free_list_allocator::contains_p(Block* block) { + return ((cell)block - start) < size; +} + +template +bool free_list_allocator::can_allot_p(cell size) { + return free_blocks.can_allot_p(size); +} + +template Block* free_list_allocator::allot(cell size) { + size = align(size, data_alignment); + + free_heap_block* block = free_blocks.find_free_block(size); + if (block) { + block = free_blocks.split_free_block(block, size); + return (Block*)block; + } else + return NULL; +} + +template void free_list_allocator::free(Block* block) { + free_heap_block* free_block = (free_heap_block*)block; + free_block->make_free(block->size()); + free_blocks.add_to_free_list(free_block); +} + +template cell free_list_allocator::free_space() { + return free_blocks.free_space; +} + +template cell free_list_allocator::occupied_space() { + return size - free_blocks.free_space; +} + +template +cell free_list_allocator::largest_free_block() { + return free_blocks.largest_free_block(); +} + +template cell free_list_allocator::free_block_count() { + return free_blocks.free_block_count; +} + +template +template +void free_list_allocator::sweep(Iterator& iter) { + free_blocks.clear_free_list(); + + cell start = this->start; + cell end = this->end; + + while (start != end) { + /* find next unmarked block */ + start = state.next_unmarked_block_after(start); + + if (start != end) { + /* find size */ + cell size = state.unmarked_block_size(start); + FACTOR_ASSERT(size > 0); + + free_heap_block* free_block = (free_heap_block*)start; + free_block->make_free(size); + free_blocks.add_to_free_list(free_block); + iter((Block*)start, size); + + start = start + size; + } + } +} + +template void free_list_allocator::sweep() { + auto null_sweep = [](Block* free_block, cell size) { }; + sweep(null_sweep); +} + +/* The forwarding map must be computed first by calling + state.compute_forwarding(). */ +template +template +void free_list_allocator::compact(Iterator& iter, Fixup fixup, + const Block** finger) { + cell dest_addr = start; + auto compact_block_func = [&](Block* block, cell size) { + cell block_addr = (cell)block; + if (!state.marked_p(block_addr)) + return; + *finger = (Block*)(block_addr + size); + memmove((Block*)dest_addr, block, size); + iter(block, (Block*)dest_addr, size); + dest_addr += size; + }; + iterate(compact_block_func, fixup); + + /* Now update the free list; there will be a single free block at + the end */ + free_blocks.initial_free_list(start, end, dest_addr - start); +} + +/* During compaction we have to be careful and measure object sizes + differently */ +template +template +void free_list_allocator::iterate(Iterator& iter, Fixup fixup) { + cell scan = this->start; + while (scan != this->end) { + Block* block = (Block*)scan; + cell size = fixup.size(block); + if (!block->free_p()) + iter(block, size); + scan += size; + } +} + +template +template +void free_list_allocator::iterate(Iterator& iter) { + iterate(iter, no_fixup()); +} + +template +allocator_room free_list_allocator::as_allocator_room() { + allocator_room room; + room.size = size; + room.occupied_space = occupied_space(); + room.total_free = free_space(); + room.contiguous_free = largest_free_block(); + room.free_block_count = free_block_count(); + return room; +} + } diff --git a/vm/free_list_allocator.hpp b/vm/free_list_allocator.hpp deleted file mode 100644 index 65e6851d9e..0000000000 --- a/vm/free_list_allocator.hpp +++ /dev/null @@ -1,184 +0,0 @@ -namespace factor { - -struct allocator_room { - cell size; - cell occupied_space; - cell total_free; - cell contiguous_free; - cell free_block_count; -}; - -template struct free_list_allocator { - cell size; - cell start; - cell end; - free_list free_blocks; - mark_bits state; - - free_list_allocator(cell size, cell start); - void initial_free_list(cell occupied); - bool contains_p(Block* block); - bool can_allot_p(cell size); - Block* allot(cell size); - void free(Block* block); - cell occupied_space(); - cell free_space(); - cell largest_free_block(); - cell free_block_count(); - void sweep(); - template void sweep(Iterator& iter); - template - void compact(Iterator& iter, Fixup fixup, const Block** finger); - template - void iterate(Iterator& iter, Fixup fixup); - template void iterate(Iterator& iter); - allocator_room as_allocator_room(); -}; - -template -free_list_allocator::free_list_allocator(cell size, cell start) - : size(size), - start(start), - end(start + size), - state(mark_bits(size, start)) { - initial_free_list(0); -} - -template -void free_list_allocator::initial_free_list(cell occupied) { - free_blocks.initial_free_list(start, end, occupied); -} - -template -bool free_list_allocator::contains_p(Block* block) { - return ((cell)block - start) < size; -} - -template -bool free_list_allocator::can_allot_p(cell size) { - return free_blocks.can_allot_p(size); -} - -template Block* free_list_allocator::allot(cell size) { - size = align(size, data_alignment); - - free_heap_block* block = free_blocks.find_free_block(size); - if (block) { - block = free_blocks.split_free_block(block, size); - return (Block*)block; - } else - return NULL; -} - -template void free_list_allocator::free(Block* block) { - free_heap_block* free_block = (free_heap_block*)block; - free_block->make_free(block->size()); - free_blocks.add_to_free_list(free_block); -} - -template cell free_list_allocator::free_space() { - return free_blocks.free_space; -} - -template cell free_list_allocator::occupied_space() { - return size - free_blocks.free_space; -} - -template -cell free_list_allocator::largest_free_block() { - return free_blocks.largest_free_block(); -} - -template cell free_list_allocator::free_block_count() { - return free_blocks.free_block_count; -} - -template -template -void free_list_allocator::sweep(Iterator& iter) { - free_blocks.clear_free_list(); - - cell start = this->start; - cell end = this->end; - - while (start != end) { - /* find next unmarked block */ - start = state.next_unmarked_block_after(start); - - if (start != end) { - /* find size */ - cell size = state.unmarked_block_size(start); - FACTOR_ASSERT(size > 0); - - free_heap_block* free_block = (free_heap_block*)start; - free_block->make_free(size); - free_blocks.add_to_free_list(free_block); - iter((Block*)start, size); - - start = start + size; - } - } -} - -template void free_list_allocator::sweep() { - auto null_sweep = [](Block* free_block, cell size) { }; - sweep(null_sweep); -} - -/* The forwarding map must be computed first by calling - state.compute_forwarding(). */ -template -template -void free_list_allocator::compact(Iterator& iter, Fixup fixup, - const Block** finger) { - cell dest_addr = start; - auto compact_block_func = [&](Block* block, cell size) { - cell block_addr = (cell)block; - if (!state.marked_p(block_addr)) - return; - *finger = (Block*)(block_addr + size); - memmove((Block*)dest_addr, block, size); - iter(block, (Block*)dest_addr, size); - dest_addr += size; - }; - iterate(compact_block_func, fixup); - - /* Now update the free list; there will be a single free block at - the end */ - free_blocks.initial_free_list(start, end, dest_addr - start); -} - -/* During compaction we have to be careful and measure object sizes - differently */ -template -template -void free_list_allocator::iterate(Iterator& iter, Fixup fixup) { - cell scan = this->start; - while (scan != this->end) { - Block* block = (Block*)scan; - cell size = fixup.size(block); - if (!block->free_p()) - iter(block, size); - scan += size; - } -} - -template -template -void free_list_allocator::iterate(Iterator& iter) { - iterate(iter, no_fixup()); -} - -template -allocator_room free_list_allocator::as_allocator_room() { - allocator_room room; - - room.size = size; - room.occupied_space = occupied_space(); - room.total_free = free_space(); - room.contiguous_free = largest_free_block(); - room.free_block_count = free_block_count(); - return room; -} - -} diff --git a/vm/master.hpp b/vm/master.hpp index ede79126a5..5331a31e3d 100644 --- a/vm/master.hpp +++ b/vm/master.hpp @@ -108,9 +108,8 @@ namespace factor { struct factor_vm; } #include "bump_allocator.hpp" #include "bitwise_hacks.hpp" #include "mark_bits.hpp" -#include "free_list.hpp" #include "fixup.hpp" -#include "free_list_allocator.hpp" +#include "free_list.hpp" #include "write_barrier.hpp" #include "object_start_map.hpp" #include "aging_space.hpp"