alloc.om (1790B)
1 struct page { 2 ptr: *byte; 3 fill: int; 4 size: int; 5 } 6 7 struct alloc { 8 page: *page; 9 } 10 11 func setup_alloc(c: *alloc) { 12 c.page = nil; 13 } 14 15 func assert_zero(b: *byte, size: int) { 16 var i: int; 17 i = 0; 18 loop { 19 if i == size { 20 break; 21 } 22 if b[i] { 23 fxxd(nil, b, size); 24 die("HEAP CORRUPTION"); 25 } 26 i = i + 1; 27 } 28 } 29 30 func alloc(c: *alloc, size: int): *byte { 31 var page: *page; 32 var mret: int; 33 var ret: *byte; 34 var psize: int; 35 36 if (size < 0) { 37 die("invalid alloc"); 38 } 39 40 if size == 0 { 41 return nil; 42 } 43 44 if (size >= 2048) { 45 size = size + 4095; 46 size = size & ~4095; 47 mret = mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); 48 if (mret == -1) { 49 die("out of memory"); 50 } 51 ret = mret as *byte; 52 assert_zero(ret, size); 53 return ret; 54 } 55 56 page = c.page; 57 if (page) { 58 if (size <= page.size - page.fill) { 59 mret = page.ptr as int + page.fill; 60 page.fill = page.fill + size; 61 ret = mret as *byte; 62 assert_zero(ret, size); 63 return ret; 64 } 65 } 66 67 psize = 64 * 1024; 68 69 mret = mmap(0, psize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); 70 if (mret == -1) { 71 die("out of memory"); 72 } 73 74 page = mret as *page; 75 page.ptr = (&page[1]) as *byte; 76 ret = page.ptr; 77 page.size = psize - sizeof(*page); 78 page.fill = size; 79 80 c.page = page; 81 82 assert_zero(ret, size); 83 return ret; 84 } 85 86 func free(a: *alloc, p: *byte): void { 87 } 88 89 func ensure_arr(a: *alloc, arr: **void, cap: *int, need: int, elen: int) { 90 var new_arr: *byte; 91 var new_cap: int; 92 93 need = need * elen; 94 95 new_cap = *cap; 96 if need < new_cap { 97 return; 98 } 99 100 loop { 101 if need <= new_cap { 102 break; 103 } 104 new_cap = new_cap * 2 + 16; 105 } 106 107 new_arr = alloc(a, new_cap); 108 109 if *cap { 110 memcpy(new_arr, (*arr) as *byte, *cap); 111 free(a, (*arr) as *byte); 112 } 113 114 *arr = new_arr as *void; 115 *cap = new_cap; 116 }