mirror of
https://github.com/ziglang/zig.git
synced 2024-11-15 08:33:06 +00:00
stage2: link.C: use pwritev
This commit is contained in:
parent
7b8cede61f
commit
e1811f72eb
@ -459,6 +459,7 @@ pub const File = struct {
|
||||
return index;
|
||||
}
|
||||
|
||||
/// See https://github.com/ziglang/zig/issues/7699
|
||||
pub fn readv(self: File, iovecs: []const os.iovec) ReadError!usize {
|
||||
if (is_windows) {
|
||||
// TODO improve this to use ReadFileScatter
|
||||
@ -479,6 +480,7 @@ pub const File = struct {
|
||||
/// is not an error condition.
|
||||
/// The `iovecs` parameter is mutable because this function needs to mutate the fields in
|
||||
/// order to handle partial reads from the underlying OS layer.
|
||||
/// See https://github.com/ziglang/zig/issues/7699
|
||||
pub fn readvAll(self: File, iovecs: []os.iovec) ReadError!usize {
|
||||
if (iovecs.len == 0) return;
|
||||
|
||||
@ -500,6 +502,7 @@ pub const File = struct {
|
||||
}
|
||||
}
|
||||
|
||||
/// See https://github.com/ziglang/zig/issues/7699
|
||||
pub fn preadv(self: File, iovecs: []const os.iovec, offset: u64) PReadError!usize {
|
||||
if (is_windows) {
|
||||
// TODO improve this to use ReadFileScatter
|
||||
@ -520,6 +523,7 @@ pub const File = struct {
|
||||
/// is not an error condition.
|
||||
/// The `iovecs` parameter is mutable because this function needs to mutate the fields in
|
||||
/// order to handle partial reads from the underlying OS layer.
|
||||
/// See https://github.com/ziglang/zig/issues/7699
|
||||
pub fn preadvAll(self: File, iovecs: []const os.iovec, offset: u64) PReadError!void {
|
||||
if (iovecs.len == 0) return;
|
||||
|
||||
@ -582,6 +586,7 @@ pub const File = struct {
|
||||
}
|
||||
}
|
||||
|
||||
/// See https://github.com/ziglang/zig/issues/7699
|
||||
pub fn writev(self: File, iovecs: []const os.iovec_const) WriteError!usize {
|
||||
if (is_windows) {
|
||||
// TODO improve this to use WriteFileScatter
|
||||
@ -599,6 +604,7 @@ pub const File = struct {
|
||||
|
||||
/// The `iovecs` parameter is mutable because this function needs to mutate the fields in
|
||||
/// order to handle partial writes from the underlying OS layer.
|
||||
/// See https://github.com/ziglang/zig/issues/7699
|
||||
pub fn writevAll(self: File, iovecs: []os.iovec_const) WriteError!void {
|
||||
if (iovecs.len == 0) return;
|
||||
|
||||
@ -615,6 +621,7 @@ pub const File = struct {
|
||||
}
|
||||
}
|
||||
|
||||
/// See https://github.com/ziglang/zig/issues/7699
|
||||
pub fn pwritev(self: File, iovecs: []os.iovec_const, offset: u64) PWriteError!usize {
|
||||
if (is_windows) {
|
||||
// TODO improve this to use WriteFileScatter
|
||||
@ -632,6 +639,7 @@ pub const File = struct {
|
||||
|
||||
/// The `iovecs` parameter is mutable because this function needs to mutate the fields in
|
||||
/// order to handle partial writes from the underlying OS layer.
|
||||
/// See https://github.com/ziglang/zig/issues/7699
|
||||
pub fn pwritevAll(self: File, iovecs: []os.iovec_const, offset: u64) PWriteError!void {
|
||||
if (iovecs.len == 0) return;
|
||||
|
||||
|
@ -41,13 +41,12 @@ pub fn openPath(allocator: *Allocator, sub_path: []const u8, options: link.Optio
|
||||
if (options.use_lld) return error.LLDHasNoCBackend;
|
||||
|
||||
const file = try options.emit.?.directory.handle.createFile(sub_path, .{
|
||||
.truncate = true,
|
||||
// Truncation is done on `flush`.
|
||||
.truncate = false,
|
||||
.mode = link.determineMode(options),
|
||||
});
|
||||
errdefer file.close();
|
||||
|
||||
try file.writeAll(zig_h);
|
||||
|
||||
var c_file = try allocator.create(C);
|
||||
errdefer allocator.destroy(c_file);
|
||||
|
||||
@ -133,40 +132,61 @@ pub fn flushModule(self: *C, comp: *Compilation) !void {
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
const file = self.base.file.?;
|
||||
const module = self.base.options.module orelse
|
||||
return error.LinkingWithoutZigSourceUnimplemented;
|
||||
|
||||
// The header is written upon opening; here we truncate and seek to after the header.
|
||||
// TODO: use writev
|
||||
try file.seekTo(zig_h.len);
|
||||
try file.setEndPos(zig_h.len);
|
||||
// We collect a list of buffers to write, and write them all at once with pwritev 😎
|
||||
var all_buffers = std.ArrayList(std.os.iovec_const).init(comp.gpa);
|
||||
defer all_buffers.deinit();
|
||||
|
||||
var buffered_writer = std.io.bufferedWriter(file.writer());
|
||||
const writer = buffered_writer.writer();
|
||||
// This is at least enough until we get to the function bodies without error handling.
|
||||
try all_buffers.ensureCapacity(module.decl_table.count() + 1);
|
||||
|
||||
const module = self.base.options.module orelse return error.LinkingWithoutZigSourceUnimplemented;
|
||||
var file_size: u64 = zig_h.len;
|
||||
all_buffers.appendAssumeCapacity(.{
|
||||
.iov_base = zig_h,
|
||||
.iov_len = zig_h.len,
|
||||
});
|
||||
|
||||
var fn_count: usize = 0;
|
||||
|
||||
// Forward decls and non-functions first.
|
||||
// TODO: use writev
|
||||
for (module.decl_table.items()) |kv| {
|
||||
const decl = kv.value;
|
||||
const decl_tv = decl.typed_value.most_recent.typed_value;
|
||||
if (decl_tv.val.castTag(.function)) |_| {
|
||||
try writer.writeAll(decl.fn_link.c.fwd_decl.items);
|
||||
} else {
|
||||
try writer.writeAll(decl.link.c.code.items);
|
||||
}
|
||||
const buf = buf: {
|
||||
if (decl_tv.val.castTag(.function)) |_| {
|
||||
fn_count += 1;
|
||||
break :buf decl.fn_link.c.fwd_decl.items;
|
||||
} else {
|
||||
break :buf decl.link.c.code.items;
|
||||
}
|
||||
};
|
||||
all_buffers.appendAssumeCapacity(.{
|
||||
.iov_base = buf.ptr,
|
||||
.iov_len = buf.len,
|
||||
});
|
||||
file_size += buf.len;
|
||||
}
|
||||
|
||||
// Now the function bodies.
|
||||
try all_buffers.ensureCapacity(all_buffers.items.len + fn_count);
|
||||
for (module.decl_table.items()) |kv| {
|
||||
const decl = kv.value;
|
||||
const decl_tv = decl.typed_value.most_recent.typed_value;
|
||||
if (decl_tv.val.castTag(.function)) |_| {
|
||||
try writer.writeAll(decl.link.c.code.items);
|
||||
const buf = decl.link.c.code.items;
|
||||
all_buffers.appendAssumeCapacity(.{
|
||||
.iov_base = buf.ptr,
|
||||
.iov_len = buf.len,
|
||||
});
|
||||
file_size += buf.len;
|
||||
}
|
||||
}
|
||||
|
||||
try buffered_writer.flush();
|
||||
const file = self.base.file.?;
|
||||
try file.setEndPos(file_size);
|
||||
try file.pwritevAll(all_buffers.items, 0);
|
||||
}
|
||||
|
||||
pub fn updateDeclExports(
|
||||
|
Loading…
Reference in New Issue
Block a user