mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-29 23:04:49 +00:00
Switch builtins to use roc_alloc and friends
This commit is contained in:
parent
8cafabc0c9
commit
ab51582541
4 changed files with 299 additions and 297 deletions
|
@ -2,7 +2,6 @@ const std = @import("std");
|
|||
const testing = std.testing;
|
||||
const expectEqual = testing.expectEqual;
|
||||
const mem = std.mem;
|
||||
const Allocator = mem.Allocator;
|
||||
const assert = std.debug.assert;
|
||||
|
||||
const utils = @import("utils.zig");
|
||||
|
@ -94,20 +93,18 @@ const Alignment = packed enum(u8) {
|
|||
};
|
||||
|
||||
pub fn decref(
|
||||
allocator: *Allocator,
|
||||
alignment: Alignment,
|
||||
bytes_or_null: ?[*]u8,
|
||||
data_bytes: usize,
|
||||
) void {
|
||||
return utils.decref(allocator, alignment.toUsize(), bytes_or_null, data_bytes);
|
||||
return utils.decref(alignment.toUsize(), bytes_or_null, data_bytes);
|
||||
}
|
||||
|
||||
pub fn allocateWithRefcount(
|
||||
allocator: *Allocator,
|
||||
alignment: Alignment,
|
||||
data_bytes: usize,
|
||||
) [*]u8 {
|
||||
return utils.allocateWithRefcount(allocator, alignment.toUsize(), data_bytes);
|
||||
return utils.allocateWithRefcount(alignment.toUsize(), data_bytes);
|
||||
}
|
||||
|
||||
pub const RocDict = extern struct {
|
||||
|
@ -124,7 +121,6 @@ pub const RocDict = extern struct {
|
|||
}
|
||||
|
||||
pub fn allocate(
|
||||
allocator: *Allocator,
|
||||
number_of_levels: usize,
|
||||
number_of_entries: usize,
|
||||
alignment: Alignment,
|
||||
|
@ -136,7 +132,7 @@ pub const RocDict = extern struct {
|
|||
const data_bytes = number_of_slots * slot_size;
|
||||
|
||||
return RocDict{
|
||||
.dict_bytes = allocateWithRefcount(allocator, alignment, data_bytes),
|
||||
.dict_bytes = allocateWithRefcount(alignment, data_bytes),
|
||||
.number_of_levels = number_of_levels,
|
||||
.dict_entries_len = number_of_entries,
|
||||
};
|
||||
|
@ -144,7 +140,6 @@ pub const RocDict = extern struct {
|
|||
|
||||
pub fn reallocate(
|
||||
self: RocDict,
|
||||
allocator: *Allocator,
|
||||
alignment: Alignment,
|
||||
key_width: usize,
|
||||
value_width: usize,
|
||||
|
@ -157,7 +152,7 @@ pub const RocDict = extern struct {
|
|||
const delta_capacity = new_capacity - old_capacity;
|
||||
|
||||
const data_bytes = new_capacity * slot_size;
|
||||
const first_slot = allocateWithRefcount(allocator, alignment, data_bytes);
|
||||
const first_slot = allocateWithRefcount(alignment, data_bytes);
|
||||
|
||||
// transfer the memory
|
||||
|
||||
|
@ -204,7 +199,7 @@ pub const RocDict = extern struct {
|
|||
};
|
||||
|
||||
// NOTE we fuse an increment of all keys/values with a decrement of the input dict
|
||||
decref(allocator, alignment, self.dict_bytes, self.capacity() * slotSize(key_width, value_width));
|
||||
decref(alignment, self.dict_bytes, self.capacity() * slotSize(key_width, value_width));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -236,7 +231,7 @@ pub const RocDict = extern struct {
|
|||
return totalCapacityAtLevel(self.number_of_levels);
|
||||
}
|
||||
|
||||
pub fn makeUnique(self: RocDict, allocator: *Allocator, alignment: Alignment, key_width: usize, value_width: usize) RocDict {
|
||||
pub fn makeUnique(self: RocDict, alignment: Alignment, key_width: usize, value_width: usize) RocDict {
|
||||
if (self.isEmpty()) {
|
||||
return self;
|
||||
}
|
||||
|
@ -246,7 +241,7 @@ pub const RocDict = extern struct {
|
|||
}
|
||||
|
||||
// unfortunately, we have to clone
|
||||
var new_dict = RocDict.allocate(allocator, self.number_of_levels, self.dict_entries_len, alignment, key_width, value_width);
|
||||
var new_dict = RocDict.allocate(self.number_of_levels, self.dict_entries_len, alignment, key_width, value_width);
|
||||
|
||||
var old_bytes: [*]u8 = @ptrCast([*]u8, self.dict_bytes);
|
||||
var new_bytes: [*]u8 = @ptrCast([*]u8, new_dict.dict_bytes);
|
||||
|
@ -256,7 +251,7 @@ pub const RocDict = extern struct {
|
|||
|
||||
// NOTE we fuse an increment of all keys/values with a decrement of the input dict
|
||||
const data_bytes = self.capacity() * slotSize(key_width, value_width);
|
||||
decref(allocator, alignment, self.dict_bytes, data_bytes);
|
||||
decref(alignment, self.dict_bytes, data_bytes);
|
||||
|
||||
return new_dict;
|
||||
}
|
||||
|
@ -420,7 +415,7 @@ const Dec = fn (?[*]u8) callconv(.C) void;
|
|||
pub fn dictInsert(input: RocDict, alignment: Alignment, key: Opaque, key_width: usize, value: Opaque, value_width: usize, hash_fn: HashFn, is_eq: EqFn, dec_key: Dec, dec_value: Dec, output: *RocDict) callconv(.C) void {
|
||||
var seed: u64 = INITIAL_SEED;
|
||||
|
||||
var result = input.makeUnique(std.heap.c_allocator, alignment, key_width, value_width);
|
||||
var result = input.makeUnique(alignment, key_width, value_width);
|
||||
|
||||
var current_level: usize = 1;
|
||||
var current_level_size: usize = 8;
|
||||
|
@ -428,7 +423,7 @@ pub fn dictInsert(input: RocDict, alignment: Alignment, key: Opaque, key_width:
|
|||
|
||||
while (true) {
|
||||
if (current_level > result.number_of_levels) {
|
||||
result = result.reallocate(std.heap.c_allocator, alignment, key_width, value_width);
|
||||
result = result.reallocate(alignment, key_width, value_width);
|
||||
}
|
||||
|
||||
const hash = hash_fn(seed, key);
|
||||
|
@ -484,7 +479,7 @@ pub fn dictRemove(input: RocDict, alignment: Alignment, key: Opaque, key_width:
|
|||
return;
|
||||
},
|
||||
MaybeIndex.index => |index| {
|
||||
var dict = input.makeUnique(std.heap.c_allocator, alignment, key_width, value_width);
|
||||
var dict = input.makeUnique(alignment, key_width, value_width);
|
||||
|
||||
assert(index < dict.capacity());
|
||||
|
||||
|
@ -499,7 +494,7 @@ pub fn dictRemove(input: RocDict, alignment: Alignment, key: Opaque, key_width:
|
|||
// if the dict is now completely empty, free its allocation
|
||||
if (dict.dict_entries_len == 0) {
|
||||
const data_bytes = dict.capacity() * slotSize(key_width, value_width);
|
||||
decref(std.heap.c_allocator, alignment, dict.dict_bytes, data_bytes);
|
||||
decref(alignment, dict.dict_bytes, data_bytes);
|
||||
output.* = RocDict.empty();
|
||||
return;
|
||||
}
|
||||
|
@ -572,7 +567,7 @@ pub fn dictKeys(dict: RocDict, alignment: Alignment, key_width: usize, value_wid
|
|||
}
|
||||
|
||||
const data_bytes = length * key_width;
|
||||
var ptr = allocateWithRefcount(std.heap.c_allocator, alignment, data_bytes);
|
||||
var ptr = allocateWithRefcount(alignment, data_bytes);
|
||||
|
||||
var offset = blk: {
|
||||
if (alignment.keyFirst()) {
|
||||
|
@ -621,7 +616,7 @@ pub fn dictValues(dict: RocDict, alignment: Alignment, key_width: usize, value_w
|
|||
}
|
||||
|
||||
const data_bytes = length * value_width;
|
||||
var ptr = allocateWithRefcount(std.heap.c_allocator, alignment, data_bytes);
|
||||
var ptr = allocateWithRefcount(alignment, data_bytes);
|
||||
|
||||
var offset = blk: {
|
||||
if (alignment.keyFirst()) {
|
||||
|
@ -655,7 +650,7 @@ fn doNothing(ptr: Opaque) callconv(.C) void {
|
|||
}
|
||||
|
||||
pub fn dictUnion(dict1: RocDict, dict2: RocDict, alignment: Alignment, key_width: usize, value_width: usize, hash_fn: HashFn, is_eq: EqFn, inc_key: Inc, inc_value: Inc, output: *RocDict) callconv(.C) void {
|
||||
output.* = dict1.makeUnique(std.heap.c_allocator, alignment, key_width, value_width);
|
||||
output.* = dict1.makeUnique(alignment, key_width, value_width);
|
||||
|
||||
var i: usize = 0;
|
||||
while (i < dict2.capacity()) : (i += 1) {
|
||||
|
@ -690,7 +685,7 @@ pub fn dictUnion(dict1: RocDict, dict2: RocDict, alignment: Alignment, key_width
|
|||
}
|
||||
|
||||
pub fn dictIntersection(dict1: RocDict, dict2: RocDict, alignment: Alignment, key_width: usize, value_width: usize, hash_fn: HashFn, is_eq: EqFn, dec_key: Inc, dec_value: Inc, output: *RocDict) callconv(.C) void {
|
||||
output.* = dict1.makeUnique(std.heap.c_allocator, alignment, key_width, value_width);
|
||||
output.* = dict1.makeUnique(alignment, key_width, value_width);
|
||||
|
||||
var i: usize = 0;
|
||||
const size = dict1.capacity();
|
||||
|
@ -715,7 +710,7 @@ pub fn dictIntersection(dict1: RocDict, dict2: RocDict, alignment: Alignment, ke
|
|||
}
|
||||
|
||||
pub fn dictDifference(dict1: RocDict, dict2: RocDict, alignment: Alignment, key_width: usize, value_width: usize, hash_fn: HashFn, is_eq: EqFn, dec_key: Dec, dec_value: Dec, output: *RocDict) callconv(.C) void {
|
||||
output.* = dict1.makeUnique(std.heap.c_allocator, alignment, key_width, value_width);
|
||||
output.* = dict1.makeUnique(alignment, key_width, value_width);
|
||||
|
||||
var i: usize = 0;
|
||||
const size = dict1.capacity();
|
||||
|
@ -756,16 +751,17 @@ pub fn setFromList(list: RocList, alignment: Alignment, key_width: usize, value_
|
|||
|
||||
// NOTE: decref checks for the empty case
|
||||
const data_bytes = size * key_width;
|
||||
decref(std.heap.c_allocator, alignment, list.bytes, data_bytes);
|
||||
decref(alignment, list.bytes, data_bytes);
|
||||
}
|
||||
|
||||
const StepperCaller = fn (?[*]u8, ?[*]u8, ?[*]u8, ?[*]u8, ?[*]u8) callconv(.C) void;
|
||||
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 {
|
||||
const alignment_usize = alignment.toUsize();
|
||||
// allocate space to write the result of the stepper into
|
||||
// experimentally aliasing the accum and output pointers is not a good idea
|
||||
const alloc: [*]u8 = @ptrCast([*]u8, std.heap.c_allocator.alloc(u8, accum_width) catch unreachable);
|
||||
const bytes_ptr: [*]u8 = utils.alloc(alignment_usize, accum_width);
|
||||
var b1 = output orelse unreachable;
|
||||
var b2 = alloc;
|
||||
var b2 = bytes_ptr;
|
||||
|
||||
@memcpy(b2, accum orelse unreachable, accum_width);
|
||||
|
||||
|
@ -788,8 +784,8 @@ pub fn dictWalk(dict: RocDict, stepper: Opaque, stepper_caller: StepperCaller, a
|
|||
}
|
||||
|
||||
@memcpy(output orelse unreachable, b2, accum_width);
|
||||
std.heap.c_allocator.free(alloc[0..accum_width]);
|
||||
utils.dealloc(alignment_usize, bytes_ptr);
|
||||
|
||||
const data_bytes = dict.capacity() * slotSize(key_width, value_width);
|
||||
decref(std.heap.c_allocator, alignment, dict.dict_bytes, data_bytes);
|
||||
decref(alignment, dict.dict_bytes, data_bytes);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue