Skip to content

Commit 17aa518

Browse files
committed
renamed 'auto_heap' to 'gc'
1 parent 72e24ee commit 17aa518

File tree

8 files changed

+136
-97
lines changed

8 files changed

+136
-97
lines changed

.githooks/pre-commit

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
#!/bin/sh
22

3-
! grep -Rns nocheckin compiler interpretter runtime
3+
! grep -Rns nocheckin compiler interpretter runtime core

CHANGELOG

-3
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,6 @@ Additions:
3434
* many math functions.
3535
* basics of reading environment variables
3636
* Relative file inclusion using "./" at the start of the path
37-
* Basics of "notes" in the code. Basically special comments that allow you to easily search in the code.
38-
Currently this is not something very useful in the language, but I wanted a way to write searchable
39-
notes without having to parse comments. The syntax is "@Note".
4037

4138
Removals:
4239
* the "proc" keyword.

core/alloc.onyx

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ package core.alloc
66
#load "./alloc/ring"
77
#load "./alloc/pool"
88
#load "./alloc/logging"
9-
#load "./alloc/auto_heap"
9+
#load "./alloc/gc"
1010

1111
as_allocator :: #match {
1212
macro (a: Allocator) => a

core/alloc/auto_heap.onyx

-85
This file was deleted.

core/alloc/gc.onyx

+114
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
package core.alloc.gc
2+
3+
GCState :: struct {
4+
backing_allocator: Allocator;
5+
first: ^GCLink;
6+
}
7+
8+
#local
9+
GCLink :: struct {
10+
prev: ^GCLink;
11+
next: ^GCLink;
12+
magic_number: u32;
13+
}
14+
15+
make :: (backing := context.allocator) -> GCState {
16+
hs: GCState;
17+
hs.backing_allocator = backing;
18+
return hs;
19+
}
20+
21+
clear :: (hs: ^GCState) {
22+
while l := hs.first; l != null {
23+
n := l.next;
24+
raw_free(hs.backing_allocator, l);
25+
l = n;
26+
}
27+
28+
hs.first = null;
29+
}
30+
31+
#match core.alloc.as_allocator make_allocator
32+
make_allocator :: (hs: ^GCState) -> Allocator {
33+
return Allocator.{
34+
func = gc_alloc_proc,
35+
data = hs
36+
};
37+
}
38+
39+
auto :: #match {
40+
macro () {
41+
use core.alloc {gc}
42+
43+
gcs := gc.make();
44+
old_allocator := context.allocator;
45+
context.allocator = core.alloc.as_allocator(^gcs);
46+
defer {
47+
gc.clear(^gcs);
48+
context.allocator = old_allocator;
49+
}
50+
},
51+
52+
macro (body: Code) -> i32 {
53+
auto :: auto
54+
55+
#context_scope {
56+
auto();
57+
#unquote body;
58+
}
59+
60+
return 0;
61+
}
62+
}
63+
64+
65+
#local
66+
GC_Link_Magic_Number :: 0x1337face
67+
68+
#local gc_alloc_proc :: (data: ^GCState, aa: AllocationAction, size: u32, align: u32, oldptr: rawptr) -> rawptr {
69+
70+
old: ^GCLink;
71+
72+
if oldptr != null {
73+
old = (cast(^GCLink) oldptr) - 1;
74+
75+
//
76+
// If this allocated space was not from an gc allocator,
77+
// just try to free it using the backing allocator.
78+
if old.magic_number != GC_Link_Magic_Number {
79+
return data.backing_allocator.func(
80+
data.backing_allocator.data, aa, size, align, oldptr
81+
);
82+
}
83+
}
84+
85+
if aa == .Resize || aa == .Free {
86+
if data.first == old {
87+
data.first = data.first.next;
88+
89+
} else {
90+
old.prev.next = old.next;
91+
old.next.prev = old.prev;
92+
}
93+
}
94+
95+
newptr: ^GCLink = data.backing_allocator.func(
96+
data.backing_allocator.data, aa,
97+
size + sizeof GCLink, align, old);
98+
99+
if aa == .Alloc || aa == .Resize {
100+
if newptr != null {
101+
newptr.magic_number = GC_Link_Magic_Number;
102+
newptr.next = data.first;
103+
newptr.prev = null;
104+
105+
if data.first != null {
106+
data.first.prev = newptr;
107+
}
108+
109+
data.first = newptr;
110+
}
111+
}
112+
113+
return newptr + 1;
114+
}

core/alloc/heap.onyx

+18-5
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ package core.alloc.heap
44
// that may happen on the heap, with the added overhead of checking that
55
// on every alloc/resize/free.
66
Enable_Debug :: #defined( runtime.vars.Enable_Heap_Debug )
7+
Enable_Clear_Freed_Memory :: #defined(runtime.vars.Enable_Heap_Clear_Freed_Memory)
78

89
// This is the implementation for the general purpose heap allocator.
910
// It is a simple bump allocator, with a free list. It is not very good
@@ -63,11 +64,11 @@ get_freed_size :: () => {
6364

6465
heap_block :: struct {
6566
size : u32;
67+
magic_number : u32;
6668
}
6769

6870
heap_freed_block :: struct {
6971
use base: heap_block;
70-
magic_number : u32;
7172
next : ^heap_freed_block;
7273
prev : ^heap_freed_block;
7374
}
@@ -76,9 +77,10 @@ get_freed_size :: () => {
7677
use base: heap_block;
7778
}
7879

79-
Allocated_Flag :: 0x1
80-
Free_Block_Magic_Number :: 0xdeadbeef
81-
Block_Split_Size :: 256
80+
Allocated_Flag :: 0x1
81+
Free_Block_Magic_Number :: 0xdeadbeef
82+
Alloc_Block_Magic_Number :: 0xbabecafe
83+
Block_Split_Size :: 256
8284

8385
// FIX: This does not respect the choice of alignment
8486
heap_alloc :: (size_: u32, align: u32) -> rawptr {
@@ -137,13 +139,15 @@ get_freed_size :: () => {
137139
best.prev = null;
138140
best.magic_number = 0;
139141
best.size |= Allocated_Flag;
142+
best.magic_number = Alloc_Block_Magic_Number;
140143
return cast(rawptr) (cast(uintptr) best + sizeof heap_allocated_block);
141144
}
142145

143146
if size < heap_state.remaining_space {
144147
ret := cast(^heap_allocated_block) heap_state.next_alloc;
145148
ret.size = size;
146149
ret.size |= Allocated_Flag;
150+
ret.magic_number = Alloc_Block_Magic_Number;
147151

148152
heap_state.next_alloc = cast(rawptr) (cast(uintptr) heap_state.next_alloc + size);
149153
heap_state.remaining_space -= size;
@@ -161,6 +165,7 @@ get_freed_size :: () => {
161165
ret := cast(^heap_allocated_block) heap_state.next_alloc;
162166
ret.size = size;
163167
ret.size |= Allocated_Flag;
168+
ret.magic_number = Alloc_Block_Magic_Number;
164169

165170
heap_state.next_alloc = cast(rawptr) (cast(uintptr) heap_state.next_alloc + size);
166171
heap_state.remaining_space -= size;
@@ -185,12 +190,19 @@ get_freed_size :: () => {
185190
log("INVALID DOUBLE FREE");
186191
return;
187192
}
193+
194+
if hb_ptr.magic_number != Alloc_Block_Magic_Number {
195+
log("FREEING INVALID BLOCK");
196+
return;
197+
}
188198
}
189199

190200
hb_ptr.size &= ~Allocated_Flag;
191201
orig_size := hb_ptr.size - sizeof heap_allocated_block;
192202

193-
#if Enable_Debug do memory_fill(ptr, ~~0xcc, orig_size);
203+
#if Enable_Debug && Enable_Clear_Freed_Memory {
204+
memory_fill(ptr, ~~0xcc, orig_size);
205+
}
194206

195207
if cast(uintptr) hb_ptr + hb_ptr.size < cast(uintptr) heap_state.next_alloc {
196208
next_block := cast(^heap_freed_block) (cast(uintptr) hb_ptr + hb_ptr.size);
@@ -275,6 +287,7 @@ get_freed_size :: () => {
275287

276288
hb_ptr.size = new_size;
277289
hb_ptr.size |= Allocated_Flag;
290+
hb_ptr.magic_number = Alloc_Block_Magic_Number;
278291
heap_state.next_alloc = cast(rawptr) (cast(uintptr) heap_state.next_alloc + needed_size);
279292
heap_state.remaining_space -= needed_size;
280293
return ptr;

core/container/iter.onyx

+1-1
Original file line numberDiff line numberDiff line change
@@ -709,7 +709,7 @@ comp :: macro (i: $I/Iterable, value: Code) => {
709709

710710
close :: (use c: ^Context($T)) {
711711
sync.mutex_destroy(^c.mutex);
712-
cfree(c);
712+
delete(c);
713713
}
714714

715715
// This iterator's context is allocated from the heap because

scripts/run_tests.onyx

+1-1
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ main :: (args) => {
130130

131131
proc_reader := io.reader_make(^proc);
132132
output := io.read_all(^proc_reader);
133-
defer memory.free_slice(^output);
133+
defer delete(^output);
134134

135135
if exit := os.process_wait(^proc); exit != .Success {
136136
// Error running the test case

0 commit comments

Comments
 (0)