MultiArrayList: use @memcpy as a workaround

Reverts bf642204b3 and uses a different
workaround, suggested by @LemonBoy.

There is either a compiler bug or a design flaw somewhere around here.
It does not have to block this branch, but I need to understand exactly
what's going on here and make it so that nobody ever has to run into
this problem again.
This commit is contained in:
Andrew Kelley 2021-02-24 12:49:12 -07:00
parent 52c45bf44d
commit 38441b5eab
2 changed files with 14 additions and 14 deletions

View File

@ -407,6 +407,7 @@ set(ZIG_STAGE2_SOURCES
"${CMAKE_SOURCE_DIR}/lib/std/meta.zig" "${CMAKE_SOURCE_DIR}/lib/std/meta.zig"
"${CMAKE_SOURCE_DIR}/lib/std/meta/trailer_flags.zig" "${CMAKE_SOURCE_DIR}/lib/std/meta/trailer_flags.zig"
"${CMAKE_SOURCE_DIR}/lib/std/meta/trait.zig" "${CMAKE_SOURCE_DIR}/lib/std/meta/trait.zig"
"${CMAKE_SOURCE_DIR}/lib/std/multi_array_list.zig"
"${CMAKE_SOURCE_DIR}/lib/std/os.zig" "${CMAKE_SOURCE_DIR}/lib/std/os.zig"
"${CMAKE_SOURCE_DIR}/lib/std/os/bits.zig" "${CMAKE_SOURCE_DIR}/lib/std/os/bits.zig"
"${CMAKE_SOURCE_DIR}/lib/std/os/bits/linux.zig" "${CMAKE_SOURCE_DIR}/lib/std/os/bits/linux.zig"

View File

@ -203,7 +203,11 @@ pub fn MultiArrayList(comptime S: type) type {
const other_slice = other.slice(); const other_slice = other.slice();
inline for (fields) |field_info, i| { inline for (fields) |field_info, i| {
const field = @intToEnum(Field, i); const field = @intToEnum(Field, i);
mem.copy(field_info.field_type, other_slice.items(field), self_slice.items(field)); // TODO we should be able to use std.mem.copy here but it causes a
// test failure on aarch64 with -OReleaseFast
const src_slice = mem.sliceAsBytes(self_slice.items(field));
const dst_slice = mem.sliceAsBytes(other_slice.items(field));
@memcpy(dst_slice.ptr, src_slice.ptr, src_slice.len);
} }
gpa.free(self.allocatedBytes()); gpa.free(self.allocatedBytes());
self.* = other; self.* = other;
@ -256,25 +260,20 @@ pub fn MultiArrayList(comptime S: type) type {
const other_slice = other.slice(); const other_slice = other.slice();
inline for (fields) |field_info, i| { inline for (fields) |field_info, i| {
const field = @intToEnum(Field, i); const field = @intToEnum(Field, i);
mem.copy(field_info.field_type, other_slice.items(field), self_slice.items(field)); // TODO we should be able to use std.mem.copy here but it causes a
// test failure on aarch64 with -OReleaseFast
const src_slice = mem.sliceAsBytes(self_slice.items(field));
const dst_slice = mem.sliceAsBytes(other_slice.items(field));
@memcpy(dst_slice.ptr, src_slice.ptr, src_slice.len);
} }
gpa.free(self.allocatedBytes()); gpa.free(self.allocatedBytes());
self.* = other; self.* = other;
} }
fn capacityInBytes(capacity: usize) usize { fn capacityInBytes(capacity: usize) usize {
// TODO move this workaround of LLVM SIMD bugs into the Zig frontend. const sizes_vector: std.meta.Vector(sizes.bytes.len, usize) = sizes.bytes;
if (std.Target.current.cpu.arch == .aarch64) { const capacity_vector = @splat(sizes.bytes.len, capacity);
var sum: usize = 0; return @reduce(.Add, capacity_vector * sizes_vector);
for (sizes.bytes) |size| {
sum += capacity * size;
}
return sum;
} else {
const sizes_vector: std.meta.Vector(sizes.bytes.len, usize) = sizes.bytes;
const capacity_vector = @splat(sizes.bytes.len, capacity);
return @reduce(.Add, capacity_vector * sizes_vector);
}
} }
fn allocatedBytes(self: Self) []align(@alignOf(S)) u8 { fn allocatedBytes(self: Self) []align(@alignOf(S)) u8 {