moved code_gc functions to vm
parent
062c56f94b
commit
fdabc9a5d8
|
@ -3,15 +3,20 @@
|
||||||
namespace factor
|
namespace factor
|
||||||
{
|
{
|
||||||
|
|
||||||
static void clear_free_list(heap *heap)
|
void factorvm::clear_free_list(heap *heap)
|
||||||
{
|
{
|
||||||
memset(&heap->free,0,sizeof(heap_free_list));
|
memset(&heap->free,0,sizeof(heap_free_list));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void clear_free_list(heap *heap)
|
||||||
|
{
|
||||||
|
return vm->clear_free_list(heap);
|
||||||
|
}
|
||||||
|
|
||||||
/* This malloc-style heap code is reasonably generic. Maybe in the future, it
|
/* This malloc-style heap code is reasonably generic. Maybe in the future, it
|
||||||
will be used for the data heap too, if we ever get incremental
|
will be used for the data heap too, if we ever get incremental
|
||||||
mark/sweep/compact GC. */
|
mark/sweep/compact GC. */
|
||||||
void new_heap(heap *heap, cell size)
|
void factorvm::new_heap(heap *heap, cell size)
|
||||||
{
|
{
|
||||||
heap->seg = alloc_segment(align_page(size));
|
heap->seg = alloc_segment(align_page(size));
|
||||||
if(!heap->seg)
|
if(!heap->seg)
|
||||||
|
@ -20,7 +25,12 @@ void new_heap(heap *heap, cell size)
|
||||||
clear_free_list(heap);
|
clear_free_list(heap);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void add_to_free_list(heap *heap, free_heap_block *block)
|
void new_heap(heap *heap, cell size)
|
||||||
|
{
|
||||||
|
return vm->new_heap(heap,size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void factorvm::add_to_free_list(heap *heap, free_heap_block *block)
|
||||||
{
|
{
|
||||||
if(block->size < free_list_count * block_size_increment)
|
if(block->size < free_list_count * block_size_increment)
|
||||||
{
|
{
|
||||||
|
@ -35,11 +45,16 @@ static void add_to_free_list(heap *heap, free_heap_block *block)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void add_to_free_list(heap *heap, free_heap_block *block)
|
||||||
|
{
|
||||||
|
return vm->add_to_free_list(heap,block);
|
||||||
|
}
|
||||||
|
|
||||||
/* Called after reading the code heap from the image file, and after code GC.
|
/* Called after reading the code heap from the image file, and after code GC.
|
||||||
|
|
||||||
In the former case, we must add a large free block from compiling.base + size to
|
In the former case, we must add a large free block from compiling.base + size to
|
||||||
compiling.limit. */
|
compiling.limit. */
|
||||||
void build_free_list(heap *heap, cell size)
|
void factorvm::build_free_list(heap *heap, cell size)
|
||||||
{
|
{
|
||||||
heap_block *prev = NULL;
|
heap_block *prev = NULL;
|
||||||
|
|
||||||
|
@ -91,13 +106,23 @@ void build_free_list(heap *heap, cell size)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void assert_free_block(free_heap_block *block)
|
void build_free_list(heap *heap, cell size)
|
||||||
|
{
|
||||||
|
return vm->build_free_list(heap,size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void factorvm::assert_free_block(free_heap_block *block)
|
||||||
{
|
{
|
||||||
if(block->status != B_FREE)
|
if(block->status != B_FREE)
|
||||||
critical_error("Invalid block in free list",(cell)block);
|
critical_error("Invalid block in free list",(cell)block);
|
||||||
}
|
}
|
||||||
|
|
||||||
static free_heap_block *find_free_block(heap *heap, cell size)
|
void assert_free_block(free_heap_block *block)
|
||||||
|
{
|
||||||
|
return vm->assert_free_block(block);
|
||||||
|
}
|
||||||
|
|
||||||
|
free_heap_block *factorvm::find_free_block(heap *heap, cell size)
|
||||||
{
|
{
|
||||||
cell attempt = size;
|
cell attempt = size;
|
||||||
|
|
||||||
|
@ -137,7 +162,12 @@ static free_heap_block *find_free_block(heap *heap, cell size)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static free_heap_block *split_free_block(heap *heap, free_heap_block *block, cell size)
|
free_heap_block *find_free_block(heap *heap, cell size)
|
||||||
|
{
|
||||||
|
return vm->find_free_block(heap,size);
|
||||||
|
}
|
||||||
|
|
||||||
|
free_heap_block *factorvm::split_free_block(heap *heap, free_heap_block *block, cell size)
|
||||||
{
|
{
|
||||||
if(block->size != size )
|
if(block->size != size )
|
||||||
{
|
{
|
||||||
|
@ -153,8 +183,13 @@ static free_heap_block *split_free_block(heap *heap, free_heap_block *block, cel
|
||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free_heap_block *split_free_block(heap *heap, free_heap_block *block, cell size)
|
||||||
|
{
|
||||||
|
return vm->split_free_block(heap,block,size);
|
||||||
|
}
|
||||||
|
|
||||||
/* Allocate a block of memory from the mark and sweep GC heap */
|
/* Allocate a block of memory from the mark and sweep GC heap */
|
||||||
heap_block *heap_allot(heap *heap, cell size)
|
heap_block *factorvm::heap_allot(heap *heap, cell size)
|
||||||
{
|
{
|
||||||
size = (size + block_size_increment - 1) & ~(block_size_increment - 1);
|
size = (size + block_size_increment - 1) & ~(block_size_increment - 1);
|
||||||
|
|
||||||
|
@ -170,14 +205,24 @@ heap_block *heap_allot(heap *heap, cell size)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
heap_block *heap_allot(heap *heap, cell size)
|
||||||
|
{
|
||||||
|
return vm->heap_allot(heap,size);
|
||||||
|
}
|
||||||
|
|
||||||
/* Deallocates a block manually */
|
/* Deallocates a block manually */
|
||||||
void heap_free(heap *heap, heap_block *block)
|
void factorvm::heap_free(heap *heap, heap_block *block)
|
||||||
{
|
{
|
||||||
block->status = B_FREE;
|
block->status = B_FREE;
|
||||||
add_to_free_list(heap,(free_heap_block *)block);
|
add_to_free_list(heap,(free_heap_block *)block);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mark_block(heap_block *block)
|
void heap_free(heap *heap, heap_block *block)
|
||||||
|
{
|
||||||
|
return vm->heap_free(heap,block);
|
||||||
|
}
|
||||||
|
|
||||||
|
void factorvm::mark_block(heap_block *block)
|
||||||
{
|
{
|
||||||
/* If already marked, do nothing */
|
/* If already marked, do nothing */
|
||||||
switch(block->status)
|
switch(block->status)
|
||||||
|
@ -193,9 +238,14 @@ void mark_block(heap_block *block)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void mark_block(heap_block *block)
|
||||||
|
{
|
||||||
|
return vm->mark_block(block);
|
||||||
|
}
|
||||||
|
|
||||||
/* If in the middle of code GC, we have to grow the heap, data GC restarts from
|
/* If in the middle of code GC, we have to grow the heap, data GC restarts from
|
||||||
scratch, so we have to unmark any marked blocks. */
|
scratch, so we have to unmark any marked blocks. */
|
||||||
void unmark_marked(heap *heap)
|
void factorvm::unmark_marked(heap *heap)
|
||||||
{
|
{
|
||||||
heap_block *scan = first_block(heap);
|
heap_block *scan = first_block(heap);
|
||||||
|
|
||||||
|
@ -208,9 +258,14 @@ void unmark_marked(heap *heap)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void unmark_marked(heap *heap)
|
||||||
|
{
|
||||||
|
return vm->unmark_marked(heap);
|
||||||
|
}
|
||||||
|
|
||||||
/* After code GC, all referenced code blocks have status set to B_MARKED, so any
|
/* After code GC, all referenced code blocks have status set to B_MARKED, so any
|
||||||
which are allocated and not marked can be reclaimed. */
|
which are allocated and not marked can be reclaimed. */
|
||||||
void free_unmarked(heap *heap, heap_iterator iter)
|
void factorvm::free_unmarked(heap *heap, heap_iterator iter)
|
||||||
{
|
{
|
||||||
clear_free_list(heap);
|
clear_free_list(heap);
|
||||||
|
|
||||||
|
@ -257,8 +312,13 @@ void free_unmarked(heap *heap, heap_iterator iter)
|
||||||
add_to_free_list(heap,(free_heap_block *)prev);
|
add_to_free_list(heap,(free_heap_block *)prev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void free_unmarked(heap *heap, heap_iterator iter)
|
||||||
|
{
|
||||||
|
return vm->free_unmarked(heap,iter);
|
||||||
|
}
|
||||||
|
|
||||||
/* Compute total sum of sizes of free blocks, and size of largest free block */
|
/* Compute total sum of sizes of free blocks, and size of largest free block */
|
||||||
void heap_usage(heap *heap, cell *used, cell *total_free, cell *max_free)
|
void factorvm::heap_usage(heap *heap, cell *used, cell *total_free, cell *max_free)
|
||||||
{
|
{
|
||||||
*used = 0;
|
*used = 0;
|
||||||
*total_free = 0;
|
*total_free = 0;
|
||||||
|
@ -286,8 +346,13 @@ void heap_usage(heap *heap, cell *used, cell *total_free, cell *max_free)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void heap_usage(heap *heap, cell *used, cell *total_free, cell *max_free)
|
||||||
|
{
|
||||||
|
return vm->heap_usage(heap,used,total_free,max_free);
|
||||||
|
}
|
||||||
|
|
||||||
/* The size of the heap, not including the last block if it's free */
|
/* The size of the heap, not including the last block if it's free */
|
||||||
cell heap_size(heap *heap)
|
cell factorvm::heap_size(heap *heap)
|
||||||
{
|
{
|
||||||
heap_block *scan = first_block(heap);
|
heap_block *scan = first_block(heap);
|
||||||
|
|
||||||
|
@ -302,8 +367,13 @@ cell heap_size(heap *heap)
|
||||||
return heap->seg->size;
|
return heap->seg->size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cell heap_size(heap *heap)
|
||||||
|
{
|
||||||
|
return vm->heap_size(heap);
|
||||||
|
}
|
||||||
|
|
||||||
/* Compute where each block is going to go, after compaction */
|
/* Compute where each block is going to go, after compaction */
|
||||||
cell compute_heap_forwarding(heap *heap, unordered_map<heap_block *,char *> &forwarding)
|
cell factorvm::compute_heap_forwarding(heap *heap, unordered_map<heap_block *,char *> &forwarding)
|
||||||
{
|
{
|
||||||
heap_block *scan = first_block(heap);
|
heap_block *scan = first_block(heap);
|
||||||
char *address = (char *)first_block(heap);
|
char *address = (char *)first_block(heap);
|
||||||
|
@ -324,7 +394,12 @@ cell compute_heap_forwarding(heap *heap, unordered_map<heap_block *,char *> &for
|
||||||
return (cell)address - heap->seg->start;
|
return (cell)address - heap->seg->start;
|
||||||
}
|
}
|
||||||
|
|
||||||
void compact_heap(heap *heap, unordered_map<heap_block *,char *> &forwarding)
|
cell compute_heap_forwarding(heap *heap, unordered_map<heap_block *,char *> &forwarding)
|
||||||
|
{
|
||||||
|
return vm->compute_heap_forwarding(heap,forwarding);
|
||||||
|
}
|
||||||
|
|
||||||
|
void factorvm::compact_heap(heap *heap, unordered_map<heap_block *,char *> &forwarding)
|
||||||
{
|
{
|
||||||
heap_block *scan = first_block(heap);
|
heap_block *scan = first_block(heap);
|
||||||
|
|
||||||
|
@ -338,4 +413,9 @@ void compact_heap(heap *heap, unordered_map<heap_block *,char *> &forwarding)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void compact_heap(heap *heap, unordered_map<heap_block *,char *> &forwarding)
|
||||||
|
{
|
||||||
|
return vm->compact_heap(heap,forwarding);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
18
vm/vm.hpp
18
vm/vm.hpp
|
@ -330,6 +330,24 @@ struct factorvm {
|
||||||
inline void vmprim_fclose();
|
inline void vmprim_fclose();
|
||||||
int err_no();
|
int err_no();
|
||||||
void clear_err_no();
|
void clear_err_no();
|
||||||
|
|
||||||
|
//code_gc
|
||||||
|
void clear_free_list(heap *heap);
|
||||||
|
void new_heap(heap *heap, cell size);
|
||||||
|
void add_to_free_list(heap *heap, free_heap_block *block);
|
||||||
|
void build_free_list(heap *heap, cell size);
|
||||||
|
void assert_free_block(free_heap_block *block);
|
||||||
|
free_heap_block *find_free_block(heap *heap, cell size);
|
||||||
|
free_heap_block *split_free_block(heap *heap, free_heap_block *block, cell size);
|
||||||
|
heap_block *heap_allot(heap *heap, cell size);
|
||||||
|
void heap_free(heap *heap, heap_block *block);
|
||||||
|
void mark_block(heap_block *block);
|
||||||
|
void unmark_marked(heap *heap);
|
||||||
|
void free_unmarked(heap *heap, heap_iterator iter);
|
||||||
|
void heap_usage(heap *heap, cell *used, cell *total_free, cell *max_free);
|
||||||
|
cell heap_size(heap *heap);
|
||||||
|
cell compute_heap_forwarding(heap *heap, unordered_map<heap_block *,char *> &forwarding);
|
||||||
|
void compact_heap(heap *heap, unordered_map<heap_block *,char *> &forwarding);
|
||||||
// next method here:
|
// next method here:
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue