authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-03-19 09:45:05+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-03-19 09:45:05+01:00
logf026939a40b3567f1a798547391b398dc40db49a
tree699f7b7b6c1af84f878a787260e8b598f20b8e26
parent6f15eedff1bd32085808ab58f095ab549b493745

macho: enable hot update state only when on compatible host


1 files changed, 27 insertions(+), 12 deletions(-)

src/link/MachO.zig+27-12
...@@ -221,8 +221,13 @@ lazy_bindings: BindingTable = .{},...@@ -221,8 +221,13 @@ lazy_bindings: BindingTable = .{},
221/// Table of tracked Decls.221/// Table of tracked Decls.
222decls: std.AutoArrayHashMapUnmanaged(Module.Decl.Index, DeclMetadata) = .{},222decls: std.AutoArrayHashMapUnmanaged(Module.Decl.Index, DeclMetadata) = .{},
223223
224/// Mach task used when the compiler is in hot-code swapping mode.224/// Hot-code swapping state.
225mach_task: ?std.os.darwin.MachTask = null,225hot_state: if (is_hot_update_compatible) HotUpdateState else struct {} = .{},
226
227const is_hot_update_compatible = switch (builtin.target.os.tag) {
228 .macos => true,
229 else => false,
230};
226231
227const DeclMetadata = struct {232const DeclMetadata = struct {
228 atom: Atom.Index,233 atom: Atom.Index,
...@@ -303,6 +308,10 @@ pub const SymbolWithLoc = struct {...@@ -303,6 +308,10 @@ pub const SymbolWithLoc = struct {
303 }308 }
304};309};
305310
311const HotUpdateState = struct {
312 mach_task: ?std.os.darwin.MachTask = null,
313};
314
306/// When allocating, the ideal_capacity is calculated by315/// When allocating, the ideal_capacity is calculated by
307/// actual_capacity + (actual_capacity / ideal_factor)316/// actual_capacity + (actual_capacity / ideal_factor)
308const ideal_factor = 3;317const ideal_factor = 3;
...@@ -1085,14 +1094,16 @@ pub fn writeAtom(self: *MachO, atom_index: Atom.Index, code: []u8) !void {...@@ -1085,14 +1094,16 @@ pub fn writeAtom(self: *MachO, atom_index: Atom.Index, code: []u8) !void {
1085 try Atom.resolveRelocations(self, atom_index, relocs.items, code);1094 try Atom.resolveRelocations(self, atom_index, relocs.items, code);
1086 }1095 }
10871096
1088 if (self.base.child_pid) |pid| blk: {1097 if (is_hot_update_compatible) {
1089 const task = self.mach_task orelse {1098 if (self.base.child_pid) |pid| blk: {
1090 log.warn("cannot hot swap: no Mach task acquired for child process with pid {d}", .{pid});1099 const task = self.hot_state.mach_task orelse {
1091 break :blk;1100 log.warn("cannot hot swap: no Mach task acquired for child process with pid {d}", .{pid});
1092 };1101 break :blk;
1093 self.updateAtomInMemory(task, section.segment_index, sym.n_value, code) catch |err| {1102 };
1094 log.warn("cannot hot swap: writing to memory failed: {s}", .{@errorName(err)});1103 self.updateAtomInMemory(task, section.segment_index, sym.n_value, code) catch |err| {
1095 };1104 log.warn("cannot hot swap: writing to memory failed: {s}", .{@errorName(err)});
1105 };
1106 }
1096 }1107 }
10971108
1098 try self.base.file.?.pwriteAll(code, file_offset);1109 try self.base.file.?.pwriteAll(code, file_offset);
...@@ -3812,9 +3823,11 @@ pub fn allocatedVirtualSize(self: *MachO, start: u64) u64 {...@@ -3812,9 +3823,11 @@ pub fn allocatedVirtualSize(self: *MachO, start: u64) u64 {
3812}3823}
38133824
3814pub fn ptraceAttach(self: *MachO, pid: std.os.pid_t) !void {3825pub fn ptraceAttach(self: *MachO, pid: std.os.pid_t) !void {
3826 if (!is_hot_update_compatible) return;
3827
3815 const mach_task = try std.os.darwin.machTaskForPid(pid);3828 const mach_task = try std.os.darwin.machTaskForPid(pid);
3816 log.debug("Mach task for pid {d}: {any}", .{ pid, mach_task });3829 log.debug("Mach task for pid {d}: {any}", .{ pid, mach_task });
3817 self.mach_task = mach_task;3830 self.hot_state.mach_task = mach_task;
38183831
3819 // TODO start exception handler in another thread3832 // TODO start exception handler in another thread
38203833
...@@ -3823,6 +3836,8 @@ pub fn ptraceAttach(self: *MachO, pid: std.os.pid_t) !void {...@@ -3823,6 +3836,8 @@ pub fn ptraceAttach(self: *MachO, pid: std.os.pid_t) !void {
3823}3836}
38243837
3825pub fn ptraceDetach(self: *MachO, pid: std.os.pid_t) !void {3838pub fn ptraceDetach(self: *MachO, pid: std.os.pid_t) !void {
3839 if (!is_hot_update_compatible) return;
3840
3826 _ = pid;3841 _ = pid;
38273842
3828 // TODO stop exception handler3843 // TODO stop exception handler
...@@ -3830,7 +3845,7 @@ pub fn ptraceDetach(self: *MachO, pid: std.os.pid_t) !void {...@@ -3830,7 +3845,7 @@ pub fn ptraceDetach(self: *MachO, pid: std.os.pid_t) !void {
3830 // TODO see comment in ptraceAttach3845 // TODO see comment in ptraceAttach
3831 // try std.os.ptrace(std.os.darwin.PT.DETACH, pid, 0, 0);3846 // try std.os.ptrace(std.os.darwin.PT.DETACH, pid, 0, 0);
38323847
3833 self.mach_task = null;3848 self.hot_state.mach_task = null;
3834}3849}
38353850
3836pub fn makeStaticString(bytes: []const u8) [16]u8 {3851pub fn makeStaticString(bytes: []const u8) [16]u8 {