Skip to content

Commit 8c74e75

Browse files
committed
fix: memory allocator align heap to eight bytes
1 parent b5a48bd commit 8c74e75

File tree

2 files changed

+23
-87
lines changed

2 files changed

+23
-87
lines changed

lib/std/header.ibu

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,7 @@ struct Vec {
1111
cap i32,
1212
}
1313

14-
struct BlockHeader {
15-
size i32,
16-
is_free bool,
17-
next *BlockHeader,
18-
}
19-
20-
func sbrk(increment i32) *u8;
2114
func alloc(size i32) *u8;
22-
func free(ptr *u8) u0;
2315
func strcmp(a *u8, b *u8) bool;
2416
func new_vec(cap i32) *Vec;
2517
func vec_realloc(vec *Vec) u0;

lib/std/std.ibu

Lines changed: 23 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -4,96 +4,42 @@
44

55
#define CHUNK_SIZE 16384 // 16KB
66

7-
let free_list *u8;
7+
#define HEAP_SIZE 2147483647
88

9-
func memset(ptr *u8, val u8, n i32) u0 {
10-
for let i i32 = 0; i < n; i++ {
11-
ptr[i] = val;
12-
}
13-
}
14-
15-
func sbrk(increment i32) *u8 {
16-
let old_break *u8 = brk(0);
17-
if old_break < 1 {
18-
return nil;
19-
}
20-
21-
let new_break *u8 = old_break + increment;
9+
let heap_head *u8;
10+
let heap_current *u8;
11+
let heap_tail *u8;
2212

23-
let result *u8 = brk(new_break);
24-
if result < 1 {
25-
return nil;
26-
}
27-
28-
return old_break;
29-
}
30-
31-
func find_free_block(size i32) *BlockHeader {
32-
let current *BlockHeader = free_list;
33-
while current != nil {
34-
if current.is_free && current.size >= size + typesize(BlockHeader) {
35-
return current;
36-
}
37-
current = current.next;
13+
func heap_init() u0 {
14+
heap_head = brk(0);
15+
heap_tail = brk(heap_head + HEAP_SIZE * 2);
16+
if (heap_head % 8) == 0 {
17+
heap_current = heap_head;
18+
} else {
19+
heap_current = heap_head + (8 - (heap_head % 8));
3820
}
39-
return nil;
4021
}
4122

42-
func request_space(size i32) *BlockHeader {
43-
let request_size i32 = size + typesize(BlockHeader);
44-
45-
let new_heap_head *BlockHeader = sbrk(request_size);
46-
if new_heap_head < 1 {
47-
return nil;
23+
func memset(ptr *u8, val u8, n i32) u0 {
24+
for let i i32 = 0; i < n; i++ {
25+
ptr[i] = val;
4826
}
49-
50-
memset(new_heap_head, 0, request_size);
51-
52-
new_heap_head.size = request_size;
53-
new_heap_head.is_free = false;
54-
new_heap_head.next = nil;
55-
56-
return new_heap_head;
5727
}
5828

5929
func alloc(size i32) *u8 {
60-
if size <= 0 {
61-
return nil;
62-
}
63-
64-
let aligned_size i32 = size;
65-
let block *BlockHeader = find_free_block(aligned_size);
66-
if block == nil {
67-
block = request_space(aligned_size);
68-
if block == nil {
69-
return nil;
70-
}
71-
} else {
72-
if block == free_list {
73-
free_list = block.next;
74-
} else {
75-
let prev *BlockHeader = free_list;
76-
while prev.next != block {
77-
prev = prev.next;
78-
}
79-
prev.next = block.next;
80-
}
81-
block.is_free = false;
82-
block.next = nil;
30+
if heap_current == nil {
31+
heap_init();
8332
}
8433

85-
return block + typesize(BlockHeader);
86-
}
87-
88-
func free(ptr *u8) u0 {
89-
if ptr == nil {
90-
return;
34+
if heap_current + size > heap_tail {
35+
eprintf("heap overflow\n");
36+
exit(1);
9137
}
92-
let block *BlockHeader = ptr - typesize(BlockHeader);
93-
block.is_free = true;
9438

95-
block.next = free_list;
96-
free_list = block;
39+
let result *u8 = heap_current;
40+
heap_current = heap_current + size;
41+
memset(result, 0, size);
42+
return result;
9743
}
9844

9945
func strcmp(a *u8, b *u8) bool {
@@ -186,8 +132,6 @@ func memmove(dest *u8, src *u8, n u32) u0 {
186132
*(p_dest + i) = *(tmp + i);
187133
}
188134
}
189-
190-
free(tmp);
191135
}
192136

193137
func byte_to_lower(c u8) u8 {

0 commit comments

Comments
 (0)