]> 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 = 16;
5 static const cell block_size_increment = 32;
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         unordered_map<heap_block *, char *> forwarding;
17
18         explicit heap(bool secure_gc_, cell size, bool executable_p);
19
20         inline heap_block *next_block(heap_block *block)
21         {
22                 cell next = ((cell)block + block->size());
23                 if(next == seg->end)
24                         return NULL;
25                 else
26                         return (heap_block *)next;
27         }
28         
29         inline heap_block *first_block()
30         {
31                 return (heap_block *)seg->start;
32         }
33         
34         inline heap_block *last_block()
35         {
36                 return (heap_block *)seg->end;
37         }
38
39         void clear_free_list();
40         void new_heap(cell size);
41         void add_to_free_list(free_heap_block *block);
42         void build_free_list(cell size);
43         void assert_free_block(free_heap_block *block);
44         free_heap_block *find_free_block(cell size);
45         free_heap_block *split_free_block(free_heap_block *block, cell size);
46         heap_block *heap_allot(cell size, cell type);
47         void heap_free(heap_block *block);
48         void mark_block(heap_block *block);
49         void clear_mark_bits();
50         void heap_usage(cell *used, cell *total_free, cell *max_free);
51         cell heap_size();
52         void compact_heap();
53
54         heap_block *free_allocated(heap_block *prev, heap_block *scan);
55
56         /* After code GC, all referenced code blocks have status set to B_MARKED, so any
57         which are allocated and not marked can be reclaimed. */
58         template<typename Iterator> void free_unmarked(Iterator &iter)
59         {
60                 clear_free_list();
61         
62                 heap_block *prev = NULL;
63                 heap_block *scan = first_block();
64         
65                 while(scan)
66                 {
67                         if(scan->type() == FREE_BLOCK_TYPE)
68                         {
69                                 if(prev && prev->type() == FREE_BLOCK_TYPE)
70                                         prev->set_size(prev->size() + scan->size());
71                                 else
72                                         prev = scan;
73                         }
74                         else if(scan->marked_p())
75                         {
76                                 if(prev && prev->type() == FREE_BLOCK_TYPE)
77                                         add_to_free_list((free_heap_block *)prev);
78                                 scan->set_marked_p(false);
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 }