Added spec:commit task to commit changes to spec/ruby sources.
[rbx.git] / shotgun / lib / heap.c
blob0d70d8ce6e84cac12020d07add2fcf4e973fbb37
1 #include <stdlib.h>
2 #include <string.h>
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));
9 h->size = size;
10 heap_allocate_memory(h);
11 return h;
14 int heap_deallocate(rheap h) {
15 if(!heap_allocated_p(h)) {
16 return FALSE;
18 if(h->address) {
19 free((void*)(h->address));
21 h->size = 0;
22 h->address = 0;
23 h->current = 0;
24 /* Maybe free() here? */
25 return TRUE;
28 int heap_allocate_memory(rheap h) {
29 h->address = (address)calloc(1, h->size);
30 if(!h->address) {
31 return FALSE;
33 h->scan = h->address;
34 h->last = (void*)((uintptr_t)h->address + h->size - 1);
35 return heap_reset(h);
37 /* make current and scan position point to heap bottom */
38 int heap_reset(rheap h) {
39 h->current = h->address;
40 h->scan = h->current;
41 return TRUE;
44 /* heap allocation predicate */
45 int heap_allocated_p(rheap h) {
46 return h->address > 0;
49 #ifndef FAST_HEAP
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;
56 return TRUE;
59 address heap_allocate(rheap h, int size) {
60 address addr;
61 /* maybe raise exception here? */
62 assert(heap_enough_space_p(h, size));
63 addr = (address)h->current;
64 memset((void*)addr, 0, size);
65 h->current += size;
67 return addr;
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;
74 return TRUE;
77 #endif
79 /* whether number of fields fit the heap without calling for heap enlarge */
80 int heap_enough_fields_p(rheap h, int fields) {
81 int size;
83 size = SIZE_IN_BYTES_FIELDS(fields);
85 if((uintptr_t)h->current + size > (uintptr_t)h->last + 1) return FALSE;
86 return TRUE;
89 OBJECT heap_copy_object(rheap h, OBJECT obj) {
90 address out;
91 int size;
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);
97 if(!out) return 0;
98 memcpy((void*)out, (void*)obj, size);
99 return (OBJECT)out;
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) {
118 OBJECT obj;
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));
122 return obj;