]> gitweb.factorcode.org Git - factor.git/blob - vm/heap.hpp
Merge branch 'master' of git://factorcode.org/git/factor
[factor.git] / vm / heap.hpp
1 namespace factor
2 {
3
4 static const cell free_list_count = 32;
5 static const cell block_size_increment = 16;
6
7 struct heap_free_list {
8         free_heap_block *small_blocks[free_list_count];
9         free_heap_block *large_blocks;
10 };
11
12 struct heap {
13         bool secure_gc;
14         segment *seg;
15         heap_free_list free;
16         mark_bits<heap_block,block_size_increment> *state;
17         unordered_map<heap_block *, char *> forwarding;
18
19         explicit heap(bool secure_gc_, cell size, bool executable_p);
20         ~heap();
21
22         inline heap_block *next_block(heap_block *block)
23         {
24                 cell next = ((cell)block + block->size());
25                 if(next == seg->end)
26                         return NULL;
27                 else
28                         return (heap_block *)next;
29         }
30         
31         inline heap_block *first_block()
32         {
33                 return (heap_block *)seg->start;
34         }
35         
36         inline heap_block *last_block()
37         {
38                 return (heap_block *)seg->end;
39         }
40
41         void clear_free_list();
42         void new_heap(cell size);
43         void add_to_free_list(free_heap_block *block);
44         void build_free_list(cell size);
45         void assert_free_block(free_heap_block *block);
46         free_heap_block *find_free_block(cell size);
47         free_heap_block *split_free_block(free_heap_block *block, cell size);
48         heap_block *heap_allot(cell size, cell type);
49         void heap_free(heap_block *block);
50         void mark_block(heap_block *block);
51         void heap_usage(cell *used, cell *total_free, cell *max_free);
52         cell heap_size();
53         void compact_heap();
54
55         heap_block *free_allocated(heap_block *prev, heap_block *scan);
56
57         /* After code GC, all referenced code blocks have status set to B_MARKED, so any
58         which are allocated and not marked can be reclaimed. */
59         template<typename Iterator> void free_unmarked(Iterator &iter)
60         {
61                 clear_free_list();
62         
63                 heap_block *prev = NULL;
64                 heap_block *scan = first_block();
65         
66                 while(scan)
67                 {
68                         if(scan->type() == FREE_BLOCK_TYPE)
69                         {
70                                 if(prev && prev->type() == FREE_BLOCK_TYPE)
71                                         prev->set_size(prev->size() + scan->size());
72                                 else
73                                         prev = scan;
74                         }
75                         else if(state->is_marked_p(scan))
76                         {
77                                 if(prev && prev->type() == FREE_BLOCK_TYPE)
78                                         add_to_free_list((free_heap_block *)prev);
79                                 prev = scan;
80                                 iter(scan);
81                         }
82                         else
83                                 prev = free_allocated(prev,scan);
84
85                         scan = next_block(scan);
86                 }
87
88                 if(prev && prev->type() == FREE_BLOCK_TYPE)
89                         add_to_free_list((free_heap_block *)prev);
90         }
91 };
92
93 }