]> gitweb.factorcode.org Git - factor.git/blob - vm/data_heap.h
Merge branch 'master' into experimental
[factor.git] / vm / data_heap.h
1 /* Set by the -securegc command line argument */
2 bool secure_gc;
3
4 /* generational copying GC divides memory into zones */
5 typedef struct {
6         /* allocation pointer is 'here'; its offset is hardcoded in the
7         compiler backends*/
8         CELL start;
9         CELL here;
10         CELL size;
11         CELL end;
12 } F_ZONE;
13
14 typedef struct {
15         F_SEGMENT *segment;
16
17         CELL young_size;
18         CELL aging_size;
19         CELL tenured_size;
20
21         CELL gen_count;
22
23         F_ZONE *generations;
24         F_ZONE* semispaces;
25
26         CELL *allot_markers;
27         CELL *allot_markers_end;
28
29         CELL *cards;
30         CELL *cards_end;
31
32         CELL *decks;
33         CELL *decks_end;
34 } F_DATA_HEAP;
35
36 F_DATA_HEAP *data_heap;
37
38 /* the 0th generation is where new objects are allocated. */
39 #define NURSERY 0
40 #define HAVE_NURSERY_P (data_heap->gen_count>1)
41 /* where objects hang around */
42 #define AGING (data_heap->gen_count-2)
43 #define HAVE_AGING_P (data_heap->gen_count>2)
44 /* the oldest generation */
45 #define TENURED (data_heap->gen_count-1)
46
47 #define MIN_GEN_COUNT 1
48 #define MAX_GEN_COUNT 3
49
50 /* new objects are allocated here */
51 DLLEXPORT F_ZONE nursery;
52
53 INLINE bool in_zone(F_ZONE *z, CELL pointer)
54 {
55         return pointer >= z->start && pointer < z->end;
56 }
57
58 CELL init_zone(F_ZONE *z, CELL size, CELL base);
59
60 void init_card_decks(void);
61
62 F_DATA_HEAP *grow_data_heap(F_DATA_HEAP *data_heap, CELL requested_bytes);
63
64 void dealloc_data_heap(F_DATA_HEAP *data_heap);
65
66 void clear_cards(CELL from, CELL to);
67 void clear_decks(CELL from, CELL to);
68 void clear_allot_markers(CELL from, CELL to);
69 void reset_generation(CELL i);
70 void reset_generations(CELL from, CELL to);
71
72 void set_data_heap(F_DATA_HEAP *data_heap_);
73
74 void init_data_heap(CELL gens,
75         CELL young_size,
76         CELL aging_size,
77         CELL tenured_size,
78         bool secure_gc_);
79
80 /* set up guard pages to check for under/overflow.
81 size must be a multiple of the page size */
82 F_SEGMENT *alloc_segment(CELL size);
83 void dealloc_segment(F_SEGMENT *block);
84
85 CELL untagged_object_size(CELL pointer);
86 CELL unaligned_object_size(CELL pointer);
87 CELL object_size(CELL pointer);
88 CELL binary_payload_start(CELL pointer);
89
90 void begin_scan(void);
91 CELL next_object(void);
92
93 void primitive_data_room(void);
94 void primitive_size(void);
95
96 void primitive_begin_scan(void);
97 void primitive_next_object(void);
98 void primitive_end_scan(void);
99
100 /* A heap walk allows useful things to be done, like finding all
101 references to an object for debugging purposes. */
102 CELL heap_scan_ptr;
103
104 /* GC is off during heap walking */
105 bool gc_off;
106
107 INLINE bool in_data_heap_p(CELL ptr)
108 {
109         return (ptr >= data_heap->segment->start
110                 && ptr <= data_heap->segment->end);
111 }
112
113 INLINE void *allot_zone(F_ZONE *z, CELL a)
114 {
115         CELL h = z->here;
116         z->here = h + align8(a);
117         return (void*)h;
118 }
119
120 CELL find_all_words(void);
121
122 /* Every object has a regular representation in the runtime, which makes GC
123 much simpler. Every slot of the object until binary_payload_start is a pointer
124 to some other object. */
125 INLINE void do_slots(CELL obj, void (* iter)(CELL *))
126 {
127         CELL scan = obj;
128         CELL payload_start = binary_payload_start(obj);
129         CELL end = obj + payload_start;
130
131         scan += CELLS;
132
133         while(scan < end)
134         {
135                 iter((CELL *)scan);
136                 scan += CELLS;
137         }
138 }