summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTaylan Kammer <taylan.kammer@gmail.com>2025-03-19 08:49:52 +0100
committerTaylan Kammer <taylan.kammer@gmail.com>2025-03-19 08:49:52 +0100
commitd1e0c8f3a928247d9e2576fddd8143f5d6cf4646 (patch)
tree50d5fdc71c992433da4b6572f2c5a09eaca7737e
parent7b67144bc3bda3b92b5ba599e5198d16c0cf4d1f (diff)
Code cleanup & use SMP Allocator.
-rw-r--r--src/libzisp.zig27
-rw-r--r--src/libzisp/gc.zig40
-rw-r--r--src/libzisp/io/unparser.zig10
-rw-r--r--src/libzisp/value.zig6
-rw-r--r--src/libzisp/value/istr.zig9
-rw-r--r--src/libzisp/value/ptr.zig20
-rw-r--r--src/libzisp/value/seq.zig5
7 files changed, 63 insertions, 54 deletions
diff --git a/src/libzisp.zig b/src/libzisp.zig
index 3a217fd..90508be 100644
--- a/src/libzisp.zig
+++ b/src/libzisp.zig
@@ -1,17 +1,17 @@
-//! By convention, root.zig is the root source file when making a library. If
-//! you are making an executable, the convention is to delete this file and
-//! start with main.zig instead.
-const std = @import("std");
const builtin = @import("builtin");
+const std = @import("std");
+
const testing = std.testing;
+pub const gc = @import("libzisp/gc.zig");
pub const io = @import("libzisp/io.zig");
pub const lib = @import("libzisp/lib.zig");
pub const value = @import("libzisp/value.zig");
+pub const Hval = gc.Hval;
+
pub const ShortString = value.ShortString;
pub const Value = value.Value;
-pub const Hval = value.Hval;
test "double" {
const d1: f64 = 0.123456789;
@@ -46,7 +46,7 @@ test "fixnum" {
test "ptr" {
const ptr = value.ptr;
- const val: [*]Hval = @ptrFromInt(256);
+ const val: *Hval = @ptrFromInt(256);
const tag = ptr.Tag.pair;
const p = ptr.pack(val, tag);
@@ -310,12 +310,15 @@ test "parse3" {
const car = value.pair.car;
const cdr = value.pair.cdr;
- // const e1 = car(val);
+ const e1 = car(val);
const e2 = car(cdr(val));
- // const e3 = car(cdr(cdr(val)));
- // const e4 = car(cdr(cdr(cdr(val))));
+ const e3 = car(cdr(cdr(val)));
+ const e4 = car(cdr(cdr(cdr(val))));
+ try std.testing.expect(value.sstr.check(e1));
try std.testing.expect(value.rune.check(e2));
+ try std.testing.expect(value.pair.check(e3));
+ try std.testing.expect(value.pair.check(e4));
}
test "parse4" {
@@ -329,11 +332,7 @@ test "parse4" {
}
fn parseBench(path: []const u8) !void {
- const iters = switch (@import("builtin").mode) {
- .Debug, .ReleaseSmall => 1000,
- .ReleaseSafe => 10_000,
- .ReleaseFast => 100_000,
- };
+ const iters = 1000;
var buf: [8196]u8 = undefined;
const file = try std.fs.cwd().openFile(path, .{});
diff --git a/src/libzisp/gc.zig b/src/libzisp/gc.zig
index 46ac091..059be74 100644
--- a/src/libzisp/gc.zig
+++ b/src/libzisp/gc.zig
@@ -1,16 +1,30 @@
+const builtin = @import("builtin");
const std = @import("std");
const value = @import("value.zig");
+const seq = value.seq;
+
const Value = value.Value;
-const Hval = value.Hval;
-var _gpa = std.heap.GeneralPurposeAllocator(.{}).init;
-const gpa = _gpa.allocator();
+/// A "heap value" that could be a Value or object header.
+pub const Hval = union {
+ value: Value,
+ seq_header: seq.Header,
+};
+
+var _debugAlloc = switch (builtin.mode) {
+ .Debug => std.heap.DebugAllocator(.{}).init,
+ else => undefined,
+};
+const alloc = switch (builtin.mode) {
+ .Debug => _debugAlloc.allocator(),
+ else => std.heap.smp_allocator,
+};
// Cons cells
-var cons_pool = std.heap.MemoryPool([2]Value).init(gpa);
+var cons_pool = std.heap.MemoryPool([2]Value).init(alloc);
pub fn cons(v1: Value, v2: Value) *[2]Value {
const mem = cons_pool.create() catch @panic("OOM");
@@ -21,22 +35,20 @@ pub fn cons(v1: Value, v2: Value) *[2]Value {
// Interned strings
-var istr_pool = std.hash_map.StringHashMap(void).init(gpa);
+var istr_pool = std.hash_map.StringHashMap(void).init(alloc);
-pub fn intern(header: value.seq.Header, str: []const u8) [*]Hval {
- comptime {
- std.debug.assert(@sizeOf(value.seq.Header) == 8);
- }
- const size = str.len + 8;
- const copy = gpa.alloc(u8, size) catch @panic("OOM");
+pub fn intern(header: seq.Header, str: []const u8) *seq.Header {
+ const hs = @sizeOf(seq.Header);
+ const size = str.len + hs;
+ const copy = alloc.alloc(u8, size) catch @panic("OOM");
const header_bytes: [8]u8 = @bitCast(header);
- @memcpy(copy[0..8], &header_bytes);
- @memcpy(copy[8..size], str);
+ @memcpy(copy[0..hs], &header_bytes);
+ @memcpy(copy[hs..size], str);
const entry = istr_pool.getOrPutValue(copy, {}) catch @panic("OOM");
return @ptrCast(entry.key_ptr);
}
-pub fn istrHeader(ptr: [*]Hval) *value.seq.Header {
+pub fn istrHeader(ptr: *Hval) *seq.Header {
const entry_key: *[]u8 = @ptrCast(ptr);
return @alignCast(@ptrCast(entry_key.ptr));
}
diff --git a/src/libzisp/io/unparser.zig b/src/libzisp/io/unparser.zig
index dd48364..d65ffb0 100644
--- a/src/libzisp/io/unparser.zig
+++ b/src/libzisp/io/unparser.zig
@@ -5,7 +5,6 @@ const value = @import("../value.zig");
const ShortString = value.ShortString;
const OtherTag = value.OtherTag;
const Value = value.Value;
-const Hval = value.Hval;
pub fn unparse(w: anytype, v: Value) anyerror!void {
try if (value.double.check(v))
@@ -33,7 +32,7 @@ fn unparseFixnum(w: anytype, v: Value) !void {
fn unparseHeap(w: anytype, v: Value) !void {
const p, const t = value.ptr.unpack(v);
try switch (t) {
- .pair => unparsePair(w, p),
+ .pair => unparsePair(w, @ptrCast(p)),
else => @panic("not implemented"),
};
}
@@ -82,11 +81,10 @@ fn unparseMisc(w: anytype, v: Value) !void {
};
}
-fn unparsePair(w: anytype, p: [*]Hval) !void {
- const vs: *[2]Value = @ptrCast(p);
+fn unparsePair(w: anytype, p: *[2]Value) !void {
try w.writeByte('(');
- try unparse(w, vs[0]);
- var cdr = vs[1];
+ try unparse(w, p[0]);
+ var cdr = p[1];
while (value.pair.check(cdr)) : (cdr = value.pair.cdr(cdr)) {
try w.writeByte(' ');
try unparse(w, value.pair.car(cdr));
diff --git a/src/libzisp/value.zig b/src/libzisp/value.zig
index aefca14..2561ca7 100644
--- a/src/libzisp/value.zig
+++ b/src/libzisp/value.zig
@@ -319,9 +319,3 @@ pub const Value = packed union {
return v.isOther() and v.other.tag == tag;
}
};
-
-/// A "heap value" that could be a Value or object header.
-pub const Hval = packed union {
- value: Value,
- seq_header: seq.Header,
-};
diff --git a/src/libzisp/value/istr.zig b/src/libzisp/value/istr.zig
index 8056d98..9834716 100644
--- a/src/libzisp/value/istr.zig
+++ b/src/libzisp/value/istr.zig
@@ -6,6 +6,8 @@ const gc = @import("../gc.zig");
const ptr = @import("ptr.zig");
const seq = @import("seq.zig");
+const Hval = gc.Hval;
+
const Value = value.Value;
// Zig API
@@ -34,13 +36,14 @@ pub fn intern(str: []const u8, quoted: bool) Value {
} },
.size = @intCast(str.len),
};
- const bytes_ptr = gc.intern(header, str);
- return ptr.pack(bytes_ptr, .seq);
+ const header_ptr = gc.intern(header, str);
+ return ptr.pack(@ptrCast(header_ptr), .seq);
}
pub fn getHeader(v: Value) *seq.Header {
assert(v);
- return gc.istrHeader(ptr.unpack(v).@"0");
+ const header_ptr, _ = ptr.unpack(v);
+ return gc.istrHeader(header_ptr);
}
// Zisp API
diff --git a/src/libzisp/value/ptr.zig b/src/libzisp/value/ptr.zig
index b07acc4..2ed3765 100644
--- a/src/libzisp/value/ptr.zig
+++ b/src/libzisp/value/ptr.zig
@@ -1,9 +1,11 @@
const std = @import("std");
-const value = @import("../value.zig");
+
const gc = @import("../gc.zig");
+const value = @import("../value.zig");
+
+const Hval = gc.Hval;
const Value = value.Value;
-const Hval = value.Hval;
// Zig API
@@ -86,23 +88,23 @@ pub fn assertStrong(v: Value) void {
}
}
-pub fn packZisp(ptr: [*]Hval, tag: Tag, is_weak: bool) Value {
+pub fn packZisp(ptr: *Hval, tag: Tag, is_weak: bool) Value {
return .{ .zptr = .{
.tagged_value = tagPtr(ptr, tag),
.is_weak = is_weak,
} };
}
-pub fn pack(ptr: [*]Hval, tag: Tag) Value {
+pub fn pack(ptr: *Hval, tag: Tag) Value {
return packZisp(ptr, tag, false);
}
-pub fn packWeak(ptr: [*]Hval, tag: Tag) Value {
+pub fn packWeak(ptr: *Hval, tag: Tag) Value {
return packZisp(ptr, tag, true);
}
// Unpacks weak as well; no need for a separate fn.
-pub fn unpack(v: Value) struct { [*]Hval, Tag } {
+pub fn unpack(v: Value) struct { *Hval, Tag } {
assertZisp(v);
return untagPtr(v.zptr.tagged_value);
}
@@ -117,15 +119,15 @@ pub fn isWeakNull(v: Value) bool {
return v.zptr.tagged_value == 0;
}
-fn tagPtr(ptr: [*]Hval, tag: Tag) u48 {
+fn tagPtr(ptr: *Hval, tag: Tag) u48 {
const int: usize = @intFromPtr(ptr);
const untagged: u48 = @intCast(int);
return untagged | @intFromEnum(tag);
}
-fn untagPtr(tagged: u48) struct { [*]Hval, Tag } {
+fn untagPtr(tagged: u48) struct { *Hval, Tag } {
const untagged: u48 = tagged & 0xfffffffffff8;
- const ptr: [*]Hval = @ptrFromInt(untagged);
+ const ptr: *Hval = @ptrFromInt(untagged);
const int: u3 = @truncate(tagged);
const tag: Tag = @enumFromInt(int);
return .{ ptr, tag };
diff --git a/src/libzisp/value/seq.zig b/src/libzisp/value/seq.zig
index 5382a7e..3418a5a 100644
--- a/src/libzisp/value/seq.zig
+++ b/src/libzisp/value/seq.zig
@@ -49,8 +49,9 @@ pub const Header = packed struct(u64) {
size: u48,
pub fn bytes(self: *Header) []u8 {
+ const hs = @sizeOf(Header);
const ptr: [*]u8 = @ptrCast(self);
- const end = 8 + self.size;
- return ptr[8..end];
+ const end = hs + self.size;
+ return ptr[hs..end];
}
};