aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/bun.zig72
-rw-r--r--src/c.zig1
2 files changed, 7 insertions, 66 deletions
diff --git a/src/bun.zig b/src/bun.zig
index 17a234d5d..148244df5 100644
--- a/src/bun.zig
+++ b/src/bun.zig
@@ -391,74 +391,14 @@ pub fn copy(comptime Type: type, dest: []Type, src: []const Type) void {
var input: []const u8 = std.mem.sliceAsBytes(src);
var output: []u8 = std.mem.sliceAsBytes(dest);
- if (@ptrToInt(output.ptr) < @ptrToInt(input.ptr)) {
- const output_end = output.ptr + input.len;
-
- // |--- dest ---|
- // |--- src ---|
- if (@ptrToInt(input.ptr) < @ptrToInt(output_end)) brk: {
- while (input.len >= strings.ascii_vector_size) {
- const vec = @as(@Vector(strings.ascii_vector_size, u8), input[0..strings.ascii_vector_size].*);
- output[0..strings.ascii_vector_size].* = vec;
- input = input[strings.ascii_vector_size..];
- output = output[strings.ascii_vector_size..];
- if (@ptrToInt(input.ptr) >= @ptrToInt(output_end)) break :brk;
- }
-
- while (input.len >= @sizeOf(usize)) {
- output[0..@sizeOf(usize)].* = input[0..@sizeOf(usize)].*;
- input = input[@sizeOf(usize)..];
- output = output[@sizeOf(usize)..];
- if (@ptrToInt(input.ptr) >= @ptrToInt(output_end)) break :brk;
- }
+ // if input.len overlaps with output.len, we need to copy backwards
+ const overlaps = isSliceInBuffer(input, output) or isSliceInBuffer(output, input);
- while (input.len > 0) {
- output[0] = input[0];
- input = input[1..];
- output = output[1..];
- if (@ptrToInt(input.ptr) >= @ptrToInt(output_end)) break :brk;
- }
- }
+ if (!overlaps) {
+ @memcpy(output.ptr, input.ptr, input.len);
} else {
- var input_end = input.ptr + input.len;
-
- // |--- src ---|
- // |--- dest ---|
- if (@ptrToInt(output.ptr) < @ptrToInt(input_end)) brk: {
- while (input.len >= strings.ascii_vector_size) {
- const input_start = input.len - strings.ascii_vector_size;
- const output_start = output.len - strings.ascii_vector_size;
- const vec = @as(@Vector(strings.ascii_vector_size, u8), input[input_start..][0..strings.ascii_vector_size].*);
- output[output_start..][0..strings.ascii_vector_size].* = vec;
- input = input[0..input_start];
- output = output[0..output_start];
- input_end -= strings.ascii_vector_size;
- if (@ptrToInt(output.ptr) >= @ptrToInt(input_end)) break :brk;
- }
-
- while (input.len >= @sizeOf(usize)) {
- const input_start = input.len - @sizeOf(usize);
- const output_start = output.len - @sizeOf(usize);
- output[output_start..][0..@sizeOf(usize)].* = input[input_start..][0..@sizeOf(usize)].*;
- input = input[0..input_start];
- output = output[0..output_start];
- input_end -= @sizeOf(usize);
- if (@ptrToInt(output.ptr) >= @ptrToInt(input_end)) break :brk;
- }
-
- while (input.len >= @sizeOf(usize)) {
- const input_start = input.len - 1;
- const output_start = output.len - 1;
- output[output_start] = input[input_start];
- input = input[0..input_start];
- output = output[0..output_start];
- input_end -= 1;
- if (@ptrToInt(output.ptr) >= @ptrToInt(input_end)) break :brk;
- }
- }
+ C.memmove(output.ptr, input.ptr, input.len);
}
-
- @memcpy(output.ptr, input.ptr, input.len);
}
pub const hasCloneFn = std.meta.trait.multiTrait(.{ std.meta.trait.isContainer, std.meta.trait.hasFn("clone") });
@@ -642,7 +582,7 @@ pub fn isHeapMemory(memory: anytype) bool {
pub const Mimalloc = @import("./allocators/mimalloc.zig");
-pub fn isSliceInBuffer(slice: []const u8, buffer: []const u8) bool {
+pub inline fn isSliceInBuffer(slice: []const u8, buffer: []const u8) bool {
return slice.len > 0 and @ptrToInt(buffer.ptr) <= @ptrToInt(slice.ptr) and ((@ptrToInt(slice.ptr) + slice.len) <= (@ptrToInt(buffer.ptr) + buffer.len));
}
diff --git a/src/c.zig b/src/c.zig
index 695ee6b34..d6417bad2 100644
--- a/src/c.zig
+++ b/src/c.zig
@@ -443,3 +443,4 @@ pub extern fn get_process_priority(pid: c_uint) i32;
pub extern fn set_process_priority(pid: c_uint, priority: c_int) i32;
pub extern fn strncasecmp(s1: [*]const u8, s2: [*]const u8, n: usize) i32;
+pub extern fn memmove(dest: [*]u8, src: [*]const u8, n: usize) void;