| ... | @@ -794,6 +794,28 @@ pub const File = struct { | ... | @@ -794,6 +794,28 @@ pub const File = struct { |
| 794 | } | 794 | } |
| 795 | } | 795 | } |
| 796 | | 796 | |
| | 797 | /// When there is a ZCU, this is called exactly once per update, to indicate that all per-file |
| | 798 | /// state (e.g. `Zcu.alive_files`) has been populated by the frontend, so can now be safely |
| | 799 | /// accessed by the linker. |
| | 800 | /// |
| | 801 | /// This call occurs before any call to any of these functions: |
| | 802 | /// * `updateNav` |
| | 803 | /// * `updateFunc` |
| | 804 | /// * `updateContainerType` |
| | 805 | /// * `updateLineNumber` |
| | 806 | /// |
| | 807 | /// Asserts that the ZCU is not using the LLVM backend. |
| | 808 | fn zcuFilesReady(base: *File) Error!void { |
| | 809 | assert(base.comp.zcu.?.llvm_object == null); |
| | 810 | switch (base.tag) { |
| | 811 | else => {}, |
| | 812 | inline .elf2 => |tag| { |
| | 813 | dev.check(tag.devFeature()); |
| | 814 | return @as(*tag.Type(), @fieldParentPtr("base", base)).zcuFilesReady(); |
| | 815 | }, |
| | 816 | } |
| | 817 | } |
| | 818 | |
| 797 | /// Asserts that the ZCU is not using the LLVM backend. | 819 | /// Asserts that the ZCU is not using the LLVM backend. |
| 798 | fn updateNav(base: *File, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) Error!void { | 820 | fn updateNav(base: *File, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) Error!void { |
| 799 | assert(base.comp.zcu.?.llvm_object == null); | 821 | assert(base.comp.zcu.?.llvm_object == null); |
| ... | @@ -823,19 +845,6 @@ pub const File = struct { | ... | @@ -823,19 +845,6 @@ pub const File = struct { |
| 823 | } | 845 | } |
| 824 | } | 846 | } |
| 825 | | 847 | |
| 826 | /// Never called when LLVM is codegenning the ZCU. | | |
| 827 | fn clearContainerType(base: *File, pt: Zcu.PerThread, ty: InternPool.Index) Error!void { | | |
| 828 | assert(base.comp.zcu.?.llvm_object == null); | | |
| 829 | switch (base.tag) { | | |
| 830 | .lld => unreachable, | | |
| 831 | else => {}, | | |
| 832 | inline .elf => |tag| { | | |
| 833 | dev.check(tag.devFeature()); | | |
| 834 | return @as(*tag.Type(), @fieldParentPtr("base", base)).clearContainerType(pt, ty); | | |
| 835 | }, | | |
| 836 | } | | |
| 837 | } | | |
| 838 | | | |
| 839 | /// The active tag of `mir` is determined by the backend used for the module this function is in. | 848 | /// The active tag of `mir` is determined by the backend used for the module this function is in. |
| 840 | /// Never called when LLVM is codegenning the ZCU. | 849 | /// Never called when LLVM is codegenning the ZCU. |
| 841 | fn updateFunc( | 850 | fn updateFunc( |
| ... | @@ -1417,6 +1426,9 @@ pub const PrelinkTask = union(enum) { | ... | @@ -1417,6 +1426,9 @@ pub const PrelinkTask = union(enum) { |
| 1417 | load_dso: Path, | 1426 | load_dso: Path, |
| 1418 | }; | 1427 | }; |
| 1419 | pub const ZcuTask = union(enum) { | 1428 | pub const ZcuTask = union(enum) { |
| | 1429 | /// Sent once per update, as the very first `ZcuTask` in the update. Indicates that all per-file |
| | 1430 | /// state (e.g. `Zcu.alive_files`) is populated so can now be safely accessed by the linker. |
| | 1431 | files_ready, |
| 1420 | /// Write the constant value for a Decl to the output file. | 1432 | /// Write the constant value for a Decl to the output file. |
| 1421 | link_nav: InternPool.Nav.Index, | 1433 | link_nav: InternPool.Nav.Index, |
| 1422 | /// Write the machine code for a function to the output file. | 1434 | /// Write the machine code for a function to the output file. |
| ... | @@ -1620,6 +1632,16 @@ pub fn doZcuTask(comp: *Compilation, tid: Zcu.PerThread.Id, task: ZcuTask) void | ... | @@ -1620,6 +1632,16 @@ pub fn doZcuTask(comp: *Compilation, tid: Zcu.PerThread.Id, task: ZcuTask) void |
| 1620 | var timer = comp.startTimer(); | 1632 | var timer = comp.startTimer(); |
| 1621 | | 1633 | |
| 1622 | const maybe_nav: ?InternPool.Nav.Index = switch (task) { | 1634 | const maybe_nav: ?InternPool.Nav.Index = switch (task) { |
| | 1635 | .files_ready => { |
| | 1636 | if (zcu.llvm_object != null) return; |
| | 1637 | const lf = comp.bin_file orelse return; |
| | 1638 | lf.zcuFilesReady() catch |err| switch (err) { |
| | 1639 | error.Canceled => io.recancel(), |
| | 1640 | error.AlreadyReported => return, |
| | 1641 | error.OutOfMemory => return diags.setAllocFailure(), |
| | 1642 | }; |
| | 1643 | return; |
| | 1644 | }, |
| 1623 | .link_nav => |nav_index| nav: { | 1645 | .link_nav => |nav_index| nav: { |
| 1624 | const fqn_slice = ip.getNav(nav_index).fqn.toSlice(ip); | 1646 | const fqn_slice = ip.getNav(nav_index).fqn.toSlice(ip); |
| 1625 | const nav_prog_node = comp.link_prog_node.start(fqn_slice, 0); | 1647 | const nav_prog_node = comp.link_prog_node.start(fqn_slice, 0); |