mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-27 13:59:08 +00:00
parent
858f19f5f5
commit
044f653fda
4 changed files with 6 additions and 163 deletions
|
@ -4,8 +4,8 @@ const mem = std.mem;
|
|||
const Builder = std.build.Builder;
|
||||
|
||||
pub fn build(b: *Builder) void {
|
||||
b.setPreferredReleaseMode(builtin.Mode.Debug);
|
||||
// b.setPreferredReleaseMode(builtin.Mode.ReleaseFast);
|
||||
// b.setPreferredReleaseMode(builtin.Mode.Debug);
|
||||
b.setPreferredReleaseMode(builtin.Mode.ReleaseFast);
|
||||
const mode = b.standardReleaseOptions();
|
||||
|
||||
// Options
|
||||
|
|
|
@ -763,8 +763,9 @@ const StepperCaller = fn (?[*]u8, ?[*]u8, ?[*]u8, ?[*]u8, ?[*]u8) callconv(.C) v
|
|||
pub fn dictWalk(dict: RocDict, stepper: Opaque, stepper_caller: StepperCaller, accum: Opaque, alignment: Alignment, key_width: usize, value_width: usize, accum_width: usize, inc_key: Inc, inc_value: Inc, output: Opaque) callconv(.C) void {
|
||||
// allocate space to write the result of the stepper into
|
||||
// experimentally aliasing the accum and output pointers is not a good idea
|
||||
const threshold: comptime usize = 512;
|
||||
const buffer_allocator = &utils.stackFallback(threshold, std.heap.c_allocator).allocator;
|
||||
const threshold: comptime usize = 64;
|
||||
var buffer: [threshold]u8 = undefined;
|
||||
const buffer_allocator = &std.heap.FixedBufferAllocator.init(&buffer).allocator;
|
||||
|
||||
const alloc: [*]u8 = @ptrCast([*]u8, buffer_allocator.alloc(u8, accum_width) catch unreachable);
|
||||
var b1 = output orelse unreachable;
|
||||
|
|
|
@ -163,161 +163,3 @@ pub const Ordering = packed enum(u8) {
|
|||
GT = 1,
|
||||
LT = 2,
|
||||
};
|
||||
|
||||
// including this code because of fixes introduced in https://github.com/ziglang/zig/commit/d73f46b57c1c407bacd0daed8c69c4f14d14a06a
|
||||
// Are we using a version of zig bigger than 0.7.1? Then shoud be removed and we can use the version from std.heap!
|
||||
|
||||
const mem = std.mem;
|
||||
const assert = debug.assert;
|
||||
const debug = std.debug;
|
||||
|
||||
fn sliceContainsPtr(container: []u8, ptr: [*]u8) bool {
|
||||
return @ptrToInt(ptr) >= @ptrToInt(container.ptr) and
|
||||
@ptrToInt(ptr) < (@ptrToInt(container.ptr) + container.len);
|
||||
}
|
||||
|
||||
fn sliceContainsSlice(container: []u8, slice: []u8) bool {
|
||||
return @ptrToInt(slice.ptr) >= @ptrToInt(container.ptr) and
|
||||
(@ptrToInt(slice.ptr) + slice.len) <= (@ptrToInt(container.ptr) + container.len);
|
||||
}
|
||||
|
||||
pub fn stackFallback(comptime size: usize, fallback_allocator: *Allocator) StackFallbackAllocator(size) {
|
||||
return StackFallbackAllocator(size){
|
||||
.buffer = undefined,
|
||||
.fallback_allocator = fallback_allocator,
|
||||
.fixed_buffer_allocator = undefined,
|
||||
.allocator = Allocator{
|
||||
.allocFn = StackFallbackAllocator(size).alloc,
|
||||
.resizeFn = StackFallbackAllocator(size).resize,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
pub fn StackFallbackAllocator(comptime size: usize) type {
|
||||
return struct {
|
||||
const Self = @This();
|
||||
|
||||
buffer: [size]u8,
|
||||
allocator: Allocator,
|
||||
fallback_allocator: *Allocator,
|
||||
fixed_buffer_allocator: FixedBufferAllocator,
|
||||
|
||||
pub fn get(self: *Self) *Allocator {
|
||||
self.fixed_buffer_allocator = FixedBufferAllocator.init(self.buffer[0..]);
|
||||
return &self.allocator;
|
||||
}
|
||||
|
||||
fn alloc(
|
||||
allocator: *Allocator,
|
||||
len: usize,
|
||||
ptr_align: u29,
|
||||
len_align: u29,
|
||||
return_address: usize,
|
||||
) error{OutOfMemory}![]u8 {
|
||||
const self = @fieldParentPtr(Self, "allocator", allocator);
|
||||
return FixedBufferAllocator.alloc(&self.fixed_buffer_allocator.allocator, len, ptr_align, len_align, return_address) catch
|
||||
return self.fallback_allocator.allocFn(self.fallback_allocator, len, ptr_align, len_align, return_address);
|
||||
}
|
||||
|
||||
fn resize(
|
||||
allocator: *Allocator,
|
||||
buf: []u8,
|
||||
buf_align: u29,
|
||||
new_len: usize,
|
||||
len_align: u29,
|
||||
return_address: usize,
|
||||
) error{OutOfMemory}!usize {
|
||||
const self = @fieldParentPtr(Self, "allocator", allocator);
|
||||
if (self.fixed_buffer_allocator.ownsPtr(buf.ptr)) {
|
||||
return FixedBufferAllocator.resize(&self.fixed_buffer_allocator.allocator, buf, buf_align, new_len, len_align, return_address);
|
||||
} else {
|
||||
return self.fallback_allocator.resizeFn(self.fallback_allocator, buf, buf_align, new_len, len_align, return_address);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub const FixedBufferAllocator = struct {
|
||||
allocator: Allocator,
|
||||
end_index: usize,
|
||||
buffer: []u8,
|
||||
|
||||
pub fn init(buffer: []u8) FixedBufferAllocator {
|
||||
return FixedBufferAllocator{
|
||||
.allocator = Allocator{
|
||||
.allocFn = alloc,
|
||||
.resizeFn = resize,
|
||||
},
|
||||
.buffer = buffer,
|
||||
.end_index = 0,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn ownsPtr(self: *FixedBufferAllocator, ptr: [*]u8) bool {
|
||||
return sliceContainsPtr(self.buffer, ptr);
|
||||
}
|
||||
|
||||
pub fn ownsSlice(self: *FixedBufferAllocator, slice: []u8) bool {
|
||||
return sliceContainsSlice(self.buffer, slice);
|
||||
}
|
||||
|
||||
/// NOTE: this will not work in all cases, if the last allocation had an adjusted_index
|
||||
/// then we won't be able to determine what the last allocation was. This is because
|
||||
/// the alignForward operation done in alloc is not reverisible.
|
||||
pub fn isLastAllocation(self: *FixedBufferAllocator, buf: []u8) bool {
|
||||
return buf.ptr + buf.len == self.buffer.ptr + self.end_index;
|
||||
}
|
||||
|
||||
fn alloc(allocator: *Allocator, n: usize, ptr_align: u29, len_align: u29, ra: usize) ![]u8 {
|
||||
const self = @fieldParentPtr(FixedBufferAllocator, "allocator", allocator);
|
||||
|
||||
const stdout = std.io.getStdOut().writer();
|
||||
stdout.print("Hello, {d} {d}!\n", .{ @ptrToInt(self.buffer.ptr), self.end_index }) catch unreachable;
|
||||
|
||||
const aligned_addr = mem.alignForward(@ptrToInt(self.buffer.ptr) + self.end_index, ptr_align);
|
||||
const adjusted_index = aligned_addr - @ptrToInt(self.buffer.ptr);
|
||||
const new_end_index = adjusted_index + n;
|
||||
if (new_end_index > self.buffer.len) {
|
||||
return error.OutOfMemory;
|
||||
}
|
||||
const result = self.buffer[adjusted_index..new_end_index];
|
||||
self.end_index = new_end_index;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
fn resize(
|
||||
allocator: *Allocator,
|
||||
buf: []u8,
|
||||
buf_align: u29,
|
||||
new_size: usize,
|
||||
len_align: u29,
|
||||
return_address: usize,
|
||||
) Allocator.Error!usize {
|
||||
const self = @fieldParentPtr(FixedBufferAllocator, "allocator", allocator);
|
||||
assert(self.ownsSlice(buf)); // sanity check
|
||||
|
||||
if (!self.isLastAllocation(buf)) {
|
||||
if (new_size > buf.len)
|
||||
return error.OutOfMemory;
|
||||
return if (new_size == 0) 0 else mem.alignAllocLen(buf.len, new_size, len_align);
|
||||
}
|
||||
|
||||
if (new_size <= buf.len) {
|
||||
const sub = buf.len - new_size;
|
||||
self.end_index -= sub;
|
||||
return if (new_size == 0) 0 else mem.alignAllocLen(buf.len - sub, new_size, len_align);
|
||||
}
|
||||
|
||||
const add = new_size - buf.len;
|
||||
if (add + self.end_index > self.buffer.len) {
|
||||
return error.OutOfMemory;
|
||||
}
|
||||
self.end_index += add;
|
||||
return new_size;
|
||||
}
|
||||
|
||||
pub fn reset(self: *FixedBufferAllocator) void {
|
||||
self.end_index = 0;
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue