diff options
Diffstat (limited to 'src/bun.js')
-rw-r--r-- | src/bun.js/webcore/encoding.zig | 43 |
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]; |