aboutsummaryrefslogtreecommitdiff
path: root/src/bun.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/bun.js')
-rw-r--r--src/bun.js/webcore/encoding.zig43
1 files changed, 35 insertions, 8 deletions
diff --git a/src/bun.js/webcore/encoding.zig b/src/bun.js/webcore/encoding.zig
index 5d07fecfd..3172966ef 100644
--- a/src/bun.js/webcore/encoding.zig
+++ b/src/bun.js/webcore/encoding.zig
@@ -796,15 +796,42 @@ pub const Encoder = struct {
switch (comptime encoding) {
.ascii => {
var to = allocator.alloc(u8, len) catch return ZigString.init("Out of memory").toErrorInstance(global);
+ var complete = to;
+ var remain = input;
+
+ if (comptime bun.Environment.enableSIMD) {
+ const vector_size = 16;
+ // https://zig.godbolt.org/z/qezsY8T3W
+ var remain_in_u64 = remain[0 .. remain.len - (remain.len % vector_size)];
+ var to_in_u64 = to[0 .. to.len - (to.len % vector_size)];
+ var remain_as_u64 = std.mem.bytesAsSlice(u64, remain_in_u64);
+ var to_as_u64 = std.mem.bytesAsSlice(u64, to_in_u64);
+ const inner_vector_size = vector_size / 8;
+ const end_vector_len = @min(remain_as_u64.len, to_as_u64.len);
+ remain_as_u64 = remain_as_u64[0..end_vector_len];
+ to_as_u64 = to_as_u64[0..end_vector_len];
+ const end_ptr = remain_as_u64.ptr + remain_as_u64.len;
+ // using the pointer instead of the length is super important for the codegen
+ while (end_ptr != remain_as_u64.ptr) {
+ const buf = @as(@Vector(inner_vector_size, u64), remain_as_u64[0..inner_vector_size].*);
+ const mask = @splat(inner_vector_size, @as(u64, 0x7f7f7f7f7f7f7f7f));
+ to_as_u64[0..inner_vector_size].* = buf & mask;
+
+ remain_as_u64 = remain_as_u64[inner_vector_size..];
+ to_as_u64 = to_as_u64[inner_vector_size..];
+ }
+ remain = remain[remain_in_u64.len..];
+ to = to[to_in_u64.len..];
+ }
- @memcpy(to.ptr, input_ptr, to.len);
-
- // Hoping this gets auto vectorized
- for (to[0..to.len]) |c, i| {
- to[i] = @as(u8, @truncate(u7, c));
+ const end_ptr = to.ptr + to.len;
+ while (to.ptr != end_ptr) {
+ to[0] = @as(u8, @truncate(u7, remain[0]));
+ to = to[1..];
+ remain = remain[1..];
}
- return ZigString.init(to).toExternalValue(global);
+ return ZigString.init(complete).toExternalValue(global);
},
.latin1 => {
var to = allocator.alloc(u8, len) catch return ZigString.init("Out of memory").toErrorInstance(global);
@@ -919,7 +946,7 @@ pub const Encoder = struct {
if (slice.len == 0)
return 0;
- if (slice.len > 1 and strings.eqlComptime(slice[slice.len - 2 ..][0..2], "==")) {
+ if (strings.endsWithComptime(slice, "==")) {
slice = slice[0 .. slice.len - 2];
} else if (slice[slice.len - 1] == '=') {
slice = slice[0 .. slice.len - 1];
@@ -1094,7 +1121,7 @@ pub const Encoder = struct {
if (slice.len == 0)
return &[_]u8{};
- if (slice.len > 1 and strings.eqlComptime(slice[slice.len - 2 ..][0..2], "==")) {
+ if (strings.endsWithComptime(slice, "==")) {
slice = slice[0 .. slice.len - 2];
} else if (slice[slice.len - 1] == '=') {
slice = slice[0 .. slice.len - 1];