this repo has no description

Move static heap memory into space struct (#165)

Makes STATIC_HEAP a bit nicer -- can support multiple spaces, etc.

authored by bernsteinbear.com and committed by

GitHub 077608fa 6c1795ae

+56 -40
+8 -2
cli.c
··· 1 1 int main() { 2 - heap = make_heap(MEMORY_SIZE); 2 + #ifdef STATIC_HEAP 3 + char memory[MEMORY_SIZE] = {0}; 4 + struct space space = make_space(memory, MEMORY_SIZE); 5 + #else 6 + struct space space = make_space(MEMORY_SIZE); 7 + #endif 8 + init_heap(heap, space); 3 9 HANDLES(); 4 10 GC_HANDLE(struct object*, result, scrap_main()); 5 11 println(result); 6 - destroy_heap(heap); 12 + destroy_space(space); 7 13 return 0; 8 14 }
+8 -1
examples/11_platforms/web/web.c
··· 33 33 int main(int argc, const char * argv[]) 34 34 { 35 35 /* boot scrapscript */ 36 - heap = make_heap(MEMORY_SIZE); 36 + #ifdef STATIC_HEAP 37 + char memory[MEMORY_SIZE] = {0}; 38 + struct space space = make_space(memory, MEMORY_SIZE); 39 + #else 40 + struct space space = make_space(MEMORY_SIZE); 41 + #endif 42 + init_heap(heap, space); 37 43 HANDLES(); 38 44 GC_HANDLE(struct object*, handler, scrap_main()); 39 45 assert(is_closure(handler)); ··· 61 67 } 62 68 wby_stop(&server); 63 69 free(memory); 70 + destroy_space(space); 64 71 } 65 72
+37 -35
runtime.c
··· 21 21 22 22 struct gc_obj { 23 23 uintptr_t tag; // low bit is 0 if forwarding ptr 24 - uintptr_t payload[0]; 25 24 }; 26 25 27 26 // The low bit of the pointer is 1 if it's a heap object and 0 if it's an ··· 102 101 VisitFn visit); 103 102 void trace_roots(struct gc_heap* heap, VisitFn visit); 104 103 104 + struct space { 105 + uintptr_t start; 106 + uintptr_t size; 107 + }; 108 + 105 109 struct gc_heap { 106 110 uintptr_t hp; 107 111 uintptr_t limit; ··· 117 121 return align(size, sizeof(uintptr_t)); 118 122 } 119 123 120 - #ifndef MEMORY_SIZE 121 - #define MEMORY_SIZE 4096 122 - #endif 123 - 124 - #ifdef STATIC_HEAP 125 - static char heap_inited = 0; 126 - #endif 127 - 128 - static struct gc_heap* make_heap(size_t size) { 129 - size = align(size, kPageSize); 130 - struct gc_heap* heap = malloc(sizeof(struct gc_heap)); 131 124 #ifdef STATIC_HEAP 132 - static char mem[MEMORY_SIZE]; 133 - size_t aligned = align(MEMORY_SIZE, kPageSize); 134 - if (aligned != MEMORY_SIZE) { 135 - fprintf(stderr, "static heap size must be a multiple of %lu\n", kPageSize); 136 - abort(); 137 - } 138 - if (heap_inited) { 139 - fprintf(stderr, "heap already initialized\n"); 125 + #define make_space(mem, sz) \ 126 + (struct space) { .start = (uintptr_t)mem, .size = sz } 127 + void init_heap(struct gc_heap* heap, struct space space) { 128 + if (align(space.size, kPageSize) != space.size) { 129 + fprintf(stderr, "static heap size (%lu) must be a multiple of %lu\n", 130 + space.size, kPageSize); 140 131 abort(); 141 132 } 142 - heap_inited = 1; 133 + heap->size = space.size; 134 + heap->to_space = heap->hp = space.start; 135 + heap->from_space = heap->limit = heap->hp + space.size / 2; 136 + } 137 + void destroy_space(struct space space) {} 143 138 #else 139 + struct space make_space(uintptr_t size) { 140 + size = align(size, kPageSize); 144 141 void* mem = mmap(NULL, size, PROT_READ | PROT_WRITE, 145 142 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 146 - #endif 147 - heap->to_space = heap->hp = (uintptr_t)mem; 148 - heap->from_space = heap->limit = heap->hp + size / 2; 149 - heap->size = size; 150 - return heap; 143 + if (mem == MAP_FAILED) { 144 + fprintf(stderr, "mmap failed\n"); 145 + abort(); 146 + } 147 + return (struct space){(uintptr_t)mem, size}; 151 148 } 152 - 153 - void destroy_heap(struct gc_heap* heap) { 154 - #ifdef STATIC_HEAP 155 - heap_inited = 0; 156 - #else 157 - munmap((void*)heap->to_space, heap->size); 158 - #endif 159 - free(heap); 149 + void init_heap(struct gc_heap* heap, struct space space) { 150 + heap->size = space.size; 151 + heap->to_space = heap->hp = space.start; 152 + heap->from_space = heap->limit = heap->hp + space.size / 2; 160 153 } 154 + void destroy_space(struct space space) { 155 + munmap((void*)space.start, space.size); 156 + } 157 + #endif 161 158 162 159 struct gc_obj* copy(struct gc_heap* heap, struct gc_obj* obj) { 163 160 size_t size = heap_object_size(obj); ··· 607 604 } 608 605 } 609 606 610 - static struct gc_heap* heap = NULL; 607 + struct gc_heap heap_object; 608 + struct gc_heap* heap = &heap_object; 611 609 612 610 struct object* num_add(struct object* a, struct object* b) { 613 611 // NB: doesn't use pointers after allocating ··· 750 748 putchar('\n'); 751 749 return obj; 752 750 } 751 + 752 + #ifndef MEMORY_SIZE 753 + #define MEMORY_SIZE 4096 754 + #endif 753 755 754 756 // Put something in the const heap so that __start_const_heap and 755 757 // __stop_const_heap are defined by the linker.
+3 -2
scrapscript.py
··· 4641 4641 4642 4642 cc = env_get_split("CC", ["clang"]) 4643 4643 cflags = discover_cflags(cc, args.debug) 4644 - cflags += [f"-DMEMORY_SIZE={args.memory}"] 4644 + if args.memory: 4645 + cflags += [f"-DMEMORY_SIZE={args.memory}"] 4645 4646 ldflags = env_get_split("LDFLAGS") 4646 4647 subprocess.run([*cc, "-o", "a.out", *cflags, args.output, *ldflags], check=True) 4647 4648 ··· 4680 4681 comp.add_argument("-o", "--output", default="output.c") 4681 4682 comp.add_argument("--format", action="store_true") 4682 4683 comp.add_argument("--compile", action="store_true") 4683 - comp.add_argument("--memory", type=int, default=1024) 4684 + comp.add_argument("--memory", type=int) 4684 4685 comp.add_argument("--run", action="store_true") 4685 4686 comp.add_argument("--debug", action="store_true", default=False) 4686 4687 # The platform is in the same directory as this file