| ... | @@ -3671,74 +3671,13 @@ pub fn astGenFile(mod: *Module, file: *File) !void { | ... | @@ -3671,74 +3671,13 @@ pub fn astGenFile(mod: *Module, file: *File) !void { |
| 3671 | file.sub_file_path, header.instructions_len, | 3671 | file.sub_file_path, header.instructions_len, |
| 3672 | }); | 3672 | }); |
| 3673 | | 3673 | |
| 3674 | var instructions: std.MultiArrayList(Zir.Inst) = .{}; | 3674 | file.zir = loadZirCacheBody(gpa, header, cache_file) catch |err| switch (err) { |
| 3675 | defer instructions.deinit(gpa); | 3675 | error.UnexpectedFileSize => { |
| 3676 | | 3676 | log.warn("unexpected EOF reading cached ZIR for {s}", .{file.sub_file_path}); |
| 3677 | try instructions.setCapacity(gpa, header.instructions_len); | 3677 | break :update; |
| 3678 | instructions.len = header.instructions_len; | | |
| 3679 | | | |
| 3680 | var zir: Zir = .{ | | |
| 3681 | .instructions = instructions.toOwnedSlice(), | | |
| 3682 | .string_bytes = &.{}, | | |
| 3683 | .extra = &.{}, | | |
| 3684 | }; | | |
| 3685 | var keep_zir = false; | | |
| 3686 | defer if (!keep_zir) zir.deinit(gpa); | | |
| 3687 | | | |
| 3688 | zir.string_bytes = try gpa.alloc(u8, header.string_bytes_len); | | |
| 3689 | zir.extra = try gpa.alloc(u32, header.extra_len); | | |
| 3690 | | | |
| 3691 | const safety_buffer = if (data_has_safety_tag) | | |
| 3692 | try gpa.alloc([8]u8, header.instructions_len) | | |
| 3693 | else | | |
| 3694 | undefined; | | |
| 3695 | defer if (data_has_safety_tag) gpa.free(safety_buffer); | | |
| 3696 | | | |
| 3697 | const data_ptr = if (data_has_safety_tag) | | |
| 3698 | @ptrCast([*]u8, safety_buffer.ptr) | | |
| 3699 | else | | |
| 3700 | @ptrCast([*]u8, zir.instructions.items(.data).ptr); | | |
| 3701 | | | |
| 3702 | var iovecs = [_]std.os.iovec{ | | |
| 3703 | .{ | | |
| 3704 | .iov_base = @ptrCast([*]u8, zir.instructions.items(.tag).ptr), | | |
| 3705 | .iov_len = header.instructions_len, | | |
| 3706 | }, | | |
| 3707 | .{ | | |
| 3708 | .iov_base = data_ptr, | | |
| 3709 | .iov_len = header.instructions_len * 8, | | |
| 3710 | }, | | |
| 3711 | .{ | | |
| 3712 | .iov_base = zir.string_bytes.ptr, | | |
| 3713 | .iov_len = header.string_bytes_len, | | |
| 3714 | }, | | |
| 3715 | .{ | | |
| 3716 | .iov_base = @ptrCast([*]u8, zir.extra.ptr), | | |
| 3717 | .iov_len = header.extra_len * 4, | | |
| 3718 | }, | 3678 | }, |
| | 3679 | else => |e| return e, |
| 3719 | }; | 3680 | }; |
| 3720 | const amt_read = try cache_file.readvAll(&iovecs); | | |
| 3721 | const amt_expected = zir.instructions.len * 9 + | | |
| 3722 | zir.string_bytes.len + | | |
| 3723 | zir.extra.len * 4; | | |
| 3724 | if (amt_read != amt_expected) { | | |
| 3725 | log.warn("unexpected EOF reading cached ZIR for {s}", .{file.sub_file_path}); | | |
| 3726 | break :update; | | |
| 3727 | } | | |
| 3728 | if (data_has_safety_tag) { | | |
| 3729 | const tags = zir.instructions.items(.tag); | | |
| 3730 | for (zir.instructions.items(.data), 0..) |*data, i| { | | |
| 3731 | const union_tag = Zir.Inst.Tag.data_tags[@enumToInt(tags[i])]; | | |
| 3732 | const as_struct = @ptrCast(*HackDataLayout, data); | | |
| 3733 | as_struct.* = .{ | | |
| 3734 | .safety_tag = @enumToInt(union_tag), | | |
| 3735 | .data = safety_buffer[i], | | |
| 3736 | }; | | |
| 3737 | } | | |
| 3738 | } | | |
| 3739 | | | |
| 3740 | keep_zir = true; | | |
| 3741 | file.zir = zir; | | |
| 3742 | file.zir_loaded = true; | 3681 | file.zir_loaded = true; |
| 3743 | file.stat = .{ | 3682 | file.stat = .{ |
| 3744 | .size = header.stat_size, | 3683 | .size = header.stat_size, |
| ... | @@ -3916,6 +3855,76 @@ pub fn astGenFile(mod: *Module, file: *File) !void { | ... | @@ -3916,6 +3855,76 @@ pub fn astGenFile(mod: *Module, file: *File) !void { |
| 3916 | } | 3855 | } |
| 3917 | } | 3856 | } |
| 3918 | | 3857 | |
| | 3858 | pub fn loadZirCache(gpa: Allocator, cache_file: std.fs.File) !Zir { |
| | 3859 | return loadZirCacheBody(gpa, try cache_file.reader().readStruct(Zir.Header), cache_file); |
| | 3860 | } |
| | 3861 | |
| | 3862 | fn loadZirCacheBody(gpa: Allocator, header: Zir.Header, cache_file: std.fs.File) !Zir { |
| | 3863 | var instructions: std.MultiArrayList(Zir.Inst) = .{}; |
| | 3864 | errdefer instructions.deinit(gpa); |
| | 3865 | |
| | 3866 | try instructions.setCapacity(gpa, header.instructions_len); |
| | 3867 | instructions.len = header.instructions_len; |
| | 3868 | |
| | 3869 | var zir: Zir = .{ |
| | 3870 | .instructions = instructions.toOwnedSlice(), |
| | 3871 | .string_bytes = &.{}, |
| | 3872 | .extra = &.{}, |
| | 3873 | }; |
| | 3874 | errdefer zir.deinit(gpa); |
| | 3875 | |
| | 3876 | zir.string_bytes = try gpa.alloc(u8, header.string_bytes_len); |
| | 3877 | zir.extra = try gpa.alloc(u32, header.extra_len); |
| | 3878 | |
| | 3879 | const safety_buffer = if (data_has_safety_tag) |
| | 3880 | try gpa.alloc([8]u8, header.instructions_len) |
| | 3881 | else |
| | 3882 | undefined; |
| | 3883 | defer if (data_has_safety_tag) gpa.free(safety_buffer); |
| | 3884 | |
| | 3885 | const data_ptr = if (data_has_safety_tag) |
| | 3886 | @ptrCast([*]u8, safety_buffer.ptr) |
| | 3887 | else |
| | 3888 | @ptrCast([*]u8, zir.instructions.items(.data).ptr); |
| | 3889 | |
| | 3890 | var iovecs = [_]std.os.iovec{ |
| | 3891 | .{ |
| | 3892 | .iov_base = @ptrCast([*]u8, zir.instructions.items(.tag).ptr), |
| | 3893 | .iov_len = header.instructions_len, |
| | 3894 | }, |
| | 3895 | .{ |
| | 3896 | .iov_base = data_ptr, |
| | 3897 | .iov_len = header.instructions_len * 8, |
| | 3898 | }, |
| | 3899 | .{ |
| | 3900 | .iov_base = zir.string_bytes.ptr, |
| | 3901 | .iov_len = header.string_bytes_len, |
| | 3902 | }, |
| | 3903 | .{ |
| | 3904 | .iov_base = @ptrCast([*]u8, zir.extra.ptr), |
| | 3905 | .iov_len = header.extra_len * 4, |
| | 3906 | }, |
| | 3907 | }; |
| | 3908 | const amt_read = try cache_file.readvAll(&iovecs); |
| | 3909 | const amt_expected = zir.instructions.len * 9 + |
| | 3910 | zir.string_bytes.len + |
| | 3911 | zir.extra.len * 4; |
| | 3912 | if (amt_read != amt_expected) return error.UnexpectedFileSize; |
| | 3913 | if (data_has_safety_tag) { |
| | 3914 | const tags = zir.instructions.items(.tag); |
| | 3915 | for (zir.instructions.items(.data), 0..) |*data, i| { |
| | 3916 | const union_tag = Zir.Inst.Tag.data_tags[@enumToInt(tags[i])]; |
| | 3917 | const as_struct = @ptrCast(*HackDataLayout, data); |
| | 3918 | as_struct.* = .{ |
| | 3919 | .safety_tag = @enumToInt(union_tag), |
| | 3920 | .data = safety_buffer[i], |
| | 3921 | }; |
| | 3922 | } |
| | 3923 | } |
| | 3924 | |
| | 3925 | return zir; |
| | 3926 | } |
| | 3927 | |
| 3919 | /// Patch ups: | 3928 | /// Patch ups: |
| 3920 | /// * Struct.zir_index | 3929 | /// * Struct.zir_index |
| 3921 | /// * Decl.zir_index | 3930 | /// * Decl.zir_index |