4 #include "shotgun/lib/shotgun.h"
5 #include "shotgun/lib/heap.h"
7 rheap
heap_new(size_t size
) {
8 rheap h
= (rheap
)calloc(1, sizeof(struct heap
));
10 heap_allocate_memory(h
);
14 int heap_deallocate(rheap h
) {
15 if(!heap_allocated_p(h
)) {
19 free((void*)(h
->address
));
24 /* Maybe free() here? */
28 int heap_allocate_memory(rheap h
) {
29 h
->address
= (address
)calloc(1, h
->size
);
34 h
->last
= (void*)((uintptr_t)h
->address
+ h
->size
- 1);
37 /* make current and scan position point to heap bottom */
38 int heap_reset(rheap h
) {
39 h
->current
= h
->address
;
44 /* heap allocation predicate */
45 int heap_allocated_p(rheap h
) {
46 return h
->address
> 0;
51 /* whether given address is between heap bottom and heap top */
52 int heap_contains_p(rheap h
, address addr
) {
54 if(addr
< h
->address
) return FALSE
;
55 if(addr
>= h
->address
+ h
->size
) return FALSE
;
59 address
heap_allocate(rheap h
, int size
) {
61 /* maybe raise exception here? */
62 assert(heap_enough_space_p(h
, size
));
63 addr
= (address
)h
->current
;
64 memset((void*)addr
, 0, size
);
70 /* whether SIZE bytes fit the heap without calling for heap enlarge */
71 int heap_enough_space_p(rheap h
, int size
) {
72 if (size
< 0) abort();
73 if(h
->current
+ size
> h
->last
+ 1) return FALSE
;
79 /* whether number of fields fit the heap without calling for heap enlarge */
80 int heap_enough_fields_p(rheap h
, int fields
) {
83 size
= SIZE_IN_BYTES_FIELDS(fields
);
85 if((uintptr_t)h
->current
+ size
> (uintptr_t)h
->last
+ 1) return FALSE
;
89 OBJECT
heap_copy_object(rheap h
, OBJECT obj
) {
92 /* avoid copying what's already on the heap */
93 if(heap_contains_p(h
, obj
)) return obj
;
94 size
= SIZE_IN_BYTES(obj
);
96 out
= heap_allocate(h
, size
);
98 memcpy((void*)out
, (void*)obj
, size
);
103 * Shotgun uses very slight variation Cheney's algorithm for young generation.
105 * See http://en.wikipedia.org/wiki/Cheney_algorithm
108 OBJECT
heap_next_object(rheap h
) {
109 return (OBJECT
)(h
->current
);
112 int heap_fully_scanned_p(rheap h
) {
113 return h
->scan
== h
->current
;
116 /* makes scan point to next object location */
117 OBJECT
heap_next_unscanned(rheap h
) {
119 if(heap_fully_scanned_p(h
)) return 0;
120 obj
= (OBJECT
)(h
->scan
);
121 h
->scan
= (void*)((uintptr_t)h
->scan
+ SIZE_IN_BYTES(obj
));