-
Notifications
You must be signed in to change notification settings - Fork 5
/
allocator.zig
executable file
·100 lines (84 loc) · 2.74 KB
/
allocator.zig
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
const std = @import("std");
const heap_start = @intToPtr([*]u8, 0x300000000);
const heap_length = 32 * 1024;
pub const allocator: std.mem.Allocator = .{
.ptr = @ptrCast(*Allocator, @alignCast(@alignOf(Allocator), heap_start)),
.vtable = &.{
.alloc = Allocator.allocFn,
.resize = Allocator.resizeFn,
.free = Allocator.freeFn,
},
};
const Allocator = struct {
end_index: usize,
fn isLastAllocation(self: Allocator, buf: []u8) bool {
return buf.ptr + buf.len == heap_start + self.end_index;
}
fn allocFn(
ctx: *anyopaque,
n: usize,
log2_ptr_align: u8,
return_address: usize,
) ?[*]u8 {
_ = return_address;
const self = @ptrCast(*Allocator, @alignCast(@alignOf(Allocator), ctx));
if (self.end_index == 0) {
self.end_index = comptime std.mem.alignPointerOffset(heap_start, @alignOf(Allocator)).? + @sizeOf(Allocator);
}
const ptr_align = @as(usize, 1) << @intCast(std.mem.Allocator.Log2Align, log2_ptr_align);
const offset = std.mem.alignPointerOffset(heap_start + self.end_index, ptr_align) orelse {
return null;
};
const adjusted_index = self.end_index + offset;
const new_end_index = adjusted_index + n;
if (new_end_index > heap_length) {
return null;
}
self.end_index = new_end_index;
return heap_start + adjusted_index;
}
fn resizeFn(
ctx: *anyopaque,
buf: []u8,
log2_buf_align: u8,
new_size: usize,
return_address: usize,
) bool {
_ = log2_buf_align;
_ = return_address;
const self = @ptrCast(*Allocator, @alignCast(@alignOf(Allocator), ctx));
if (self.end_index == 0) {
self.end_index = comptime std.mem.alignPointerOffset(heap_start, @alignOf(Allocator)).? + @sizeOf(Allocator);
}
if (!self.isLastAllocation(buf)) {
if (new_size > buf.len) {
return false;
}
return true;
}
if (new_size <= buf.len) {
const sub = buf.len - new_size;
self.end_index -= sub;
return true;
}
const add = new_size - buf.len;
if (add + self.end_index > heap_length) {
return false;
}
self.end_index += add;
return true;
}
fn freeFn(
ctx: *anyopaque,
buf: []u8,
log2_buf_align: u8,
return_address: usize,
) void {
_ = log2_buf_align;
_ = return_address;
const self = @ptrCast(*Allocator, @alignCast(@alignOf(Allocator), ctx));
if (self.isLastAllocation(buf)) {
self.end_index -= buf.len;
}
}
};