| ... | @@ -283,7 +283,9 @@ pub const Decl = struct { | ... | @@ -283,7 +283,9 @@ pub const Decl = struct { |
| 283 | pub fn destroy(decl: *Decl, module: *Module) void { | 283 | pub fn destroy(decl: *Decl, module: *Module) void { |
| 284 | const gpa = module.gpa; | 284 | const gpa = module.gpa; |
| 285 | log.debug("destroy {*} ({s})", .{ decl, decl.name }); | 285 | log.debug("destroy {*} ({s})", .{ decl, decl.name }); |
| 286 | decl.clearName(gpa); | 286 | if (decl.deletion_flag) { |
| | 287 | module.deletion_set.swapRemoveAssertDiscard(decl); |
| | 288 | } |
| 287 | if (decl.has_tv) { | 289 | if (decl.has_tv) { |
| 288 | if (decl.getInnerNamespace()) |namespace| { | 290 | if (decl.getInnerNamespace()) |namespace| { |
| 289 | namespace.clearDecls(module); | 291 | namespace.clearDecls(module); |
| ... | @@ -292,6 +294,7 @@ pub const Decl = struct { | ... | @@ -292,6 +294,7 @@ pub const Decl = struct { |
| 292 | } | 294 | } |
| 293 | decl.dependants.deinit(gpa); | 295 | decl.dependants.deinit(gpa); |
| 294 | decl.dependencies.deinit(gpa); | 296 | decl.dependencies.deinit(gpa); |
| | 297 | decl.clearName(gpa); |
| 295 | if (module.emit_h != null) { | 298 | if (module.emit_h != null) { |
| 296 | const decl_plus_emit_h = @fieldParentPtr(DeclPlusEmitH, "decl", decl); | 299 | const decl_plus_emit_h = @fieldParentPtr(DeclPlusEmitH, "decl", decl); |
| 297 | decl_plus_emit_h.emit_h.fwd_decl.deinit(gpa); | 300 | decl_plus_emit_h.emit_h.fwd_decl.deinit(gpa); |
| ... | @@ -546,28 +549,6 @@ pub const Decl = struct { | ... | @@ -546,28 +549,6 @@ pub const Decl = struct { |
| 546 | fn removeDependency(decl: *Decl, other: *Decl) void { | 549 | fn removeDependency(decl: *Decl, other: *Decl) void { |
| 547 | decl.dependencies.removeAssertDiscard(other); | 550 | decl.dependencies.removeAssertDiscard(other); |
| 548 | } | 551 | } |
| 549 | | | |
| 550 | fn hasLinkAllocation(decl: Decl) bool { | | |
| 551 | return switch (decl.analysis) { | | |
| 552 | .unreferenced, | | |
| 553 | .in_progress, | | |
| 554 | .dependency_failure, | | |
| 555 | .file_failure, | | |
| 556 | .sema_failure, | | |
| 557 | .sema_failure_retryable, | | |
| 558 | .codegen_failure, | | |
| 559 | .codegen_failure_retryable, | | |
| 560 | => false, | | |
| 561 | | | |
| 562 | .complete, | | |
| 563 | .outdated, | | |
| 564 | => { | | |
| 565 | if (!decl.owns_tv) | | |
| 566 | return false; | | |
| 567 | return decl.ty.hasCodeGenBits(); | | |
| 568 | }, | | |
| 569 | }; | | |
| 570 | } | | |
| 571 | }; | 552 | }; |
| 572 | | 553 | |
| 573 | /// This state is attached to every Decl when Module emit_h is non-null. | 554 | /// This state is attached to every Decl when Module emit_h is non-null. |
| ... | @@ -929,6 +910,32 @@ pub const Scope = struct { | ... | @@ -929,6 +910,32 @@ pub const Scope = struct { |
| 929 | anon_decls.deinit(gpa); | 910 | anon_decls.deinit(gpa); |
| 930 | } | 911 | } |
| 931 | | 912 | |
| | 913 | pub fn deleteAllDecls( |
| | 914 | ns: *Namespace, |
| | 915 | mod: *Module, |
| | 916 | outdated_decls: ?*std.AutoArrayHashMap(*Decl, void), |
| | 917 | ) !void { |
| | 918 | const gpa = mod.gpa; |
| | 919 | |
| | 920 | log.debug("deleteAllDecls {*}", .{ns}); |
| | 921 | |
| | 922 | while (ns.decls.count() != 0) { |
| | 923 | const last_entry = ns.decls.entries.items[ns.decls.entries.items.len - 1]; |
| | 924 | const child_decl = last_entry.value; |
| | 925 | try mod.deleteDecl(child_decl, outdated_decls); |
| | 926 | } |
| | 927 | ns.decls.deinit(gpa); |
| | 928 | ns.decls = .{}; |
| | 929 | |
| | 930 | while (ns.anon_decls.count() != 0) { |
| | 931 | const last_entry = ns.anon_decls.entries.items[ns.anon_decls.entries.items.len - 1]; |
| | 932 | const child_decl = last_entry.key; |
| | 933 | try mod.deleteDecl(child_decl, outdated_decls); |
| | 934 | } |
| | 935 | ns.anon_decls.deinit(gpa); |
| | 936 | ns.anon_decls = .{}; |
| | 937 | } |
| | 938 | |
| 932 | pub fn removeDecl(ns: *Namespace, child: *Decl) void { | 939 | pub fn removeDecl(ns: *Namespace, child: *Decl) void { |
| 933 | if (child.zir_decl_index == 0) { | 940 | if (child.zir_decl_index == 0) { |
| 934 | _ = ns.anon_decls.swapRemove(child); | 941 | _ = ns.anon_decls.swapRemove(child); |
| ... | @@ -2646,7 +2653,7 @@ fn updateZirRefs(gpa: *Allocator, file: *Scope.File, old_zir: Zir) !void { | ... | @@ -2646,7 +2653,7 @@ fn updateZirRefs(gpa: *Allocator, file: *Scope.File, old_zir: Zir) !void { |
| 2646 | } | 2653 | } |
| 2647 | } | 2654 | } |
| 2648 | | 2655 | |
| 2649 | if (!decl.has_tv) continue; | 2656 | if (!decl.owns_tv) continue; |
| 2650 | | 2657 | |
| 2651 | if (decl.getStruct()) |struct_obj| { | 2658 | if (decl.getStruct()) |struct_obj| { |
| 2652 | struct_obj.zir_index = inst_map.get(struct_obj.zir_index) orelse { | 2659 | struct_obj.zir_index = inst_map.get(struct_obj.zir_index) orelse { |
| ... | @@ -3401,17 +3408,19 @@ pub fn deleteDecl( | ... | @@ -3401,17 +3408,19 @@ pub fn deleteDecl( |
| 3401 | mod: *Module, | 3408 | mod: *Module, |
| 3402 | decl: *Decl, | 3409 | decl: *Decl, |
| 3403 | outdated_decls: ?*std.AutoArrayHashMap(*Decl, void), | 3410 | outdated_decls: ?*std.AutoArrayHashMap(*Decl, void), |
| 3404 | ) !void { | 3411 | ) Allocator.Error!void { |
| 3405 | const tracy = trace(@src()); | 3412 | const tracy = trace(@src()); |
| 3406 | defer tracy.end(); | 3413 | defer tracy.end(); |
| 3407 | | 3414 | |
| 3408 | log.debug("deleting {*} ({s})", .{ decl, decl.name }); | 3415 | log.debug("deleting {*} ({s})", .{ decl, decl.name }); |
| 3409 | | 3416 | |
| | 3417 | const gpa = mod.gpa; |
| | 3418 | try mod.deletion_set.ensureUnusedCapacity(gpa, decl.dependencies.count()); |
| | 3419 | |
| 3410 | if (outdated_decls) |map| { | 3420 | if (outdated_decls) |map| { |
| 3411 | _ = map.swapRemove(decl); | 3421 | _ = map.swapRemove(decl); |
| 3412 | try map.ensureUnusedCapacity(decl.dependants.count()); | 3422 | try map.ensureUnusedCapacity(decl.dependants.count()); |
| 3413 | } | 3423 | } |
| 3414 | try mod.deletion_set.ensureUnusedCapacity(mod.gpa, decl.dependencies.count()); | | |
| 3415 | | 3424 | |
| 3416 | // Remove from the namespace it resides in. | 3425 | // Remove from the namespace it resides in. |
| 3417 | decl.namespace.removeDecl(decl); | 3426 | decl.namespace.removeDecl(decl); |
| ... | @@ -3443,18 +3452,23 @@ pub fn deleteDecl( | ... | @@ -3443,18 +3452,23 @@ pub fn deleteDecl( |
| 3443 | } | 3452 | } |
| 3444 | } | 3453 | } |
| 3445 | if (mod.failed_decls.swapRemove(decl)) |entry| { | 3454 | if (mod.failed_decls.swapRemove(decl)) |entry| { |
| 3446 | entry.value.destroy(mod.gpa); | 3455 | entry.value.destroy(gpa); |
| 3447 | } | 3456 | } |
| 3448 | if (mod.emit_h) |emit_h| { | 3457 | if (mod.emit_h) |emit_h| { |
| 3449 | if (emit_h.failed_decls.swapRemove(decl)) |entry| { | 3458 | if (emit_h.failed_decls.swapRemove(decl)) |entry| { |
| 3450 | entry.value.destroy(mod.gpa); | 3459 | entry.value.destroy(gpa); |
| 3451 | } | 3460 | } |
| 3452 | emit_h.decl_table.removeAssertDiscard(decl); | 3461 | emit_h.decl_table.removeAssertDiscard(decl); |
| 3453 | } | 3462 | } |
| 3454 | _ = mod.compile_log_decls.swapRemove(decl); | 3463 | _ = mod.compile_log_decls.swapRemove(decl); |
| 3455 | mod.deleteDeclExports(decl); | 3464 | mod.deleteDeclExports(decl); |
| 3456 | if (decl.hasLinkAllocation()) { | 3465 | mod.comp.bin_file.freeDecl(decl); |
| 3457 | mod.comp.bin_file.freeDecl(decl); | 3466 | |
| | 3467 | if (decl.has_tv) { |
| | 3468 | if (decl.getInnerNamespace()) |namespace| { |
| | 3469 | try namespace.deleteAllDecls(mod, outdated_decls); |
| | 3470 | } |
| | 3471 | decl.clearValues(gpa); |
| 3458 | } | 3472 | } |
| 3459 | | 3473 | |
| 3460 | decl.destroy(mod); | 3474 | decl.destroy(mod); |
| ... | @@ -3827,6 +3841,12 @@ pub fn constIntBig(mod: *Module, arena: *Allocator, src: LazySrcLoc, ty: Type, b | ... | @@ -3827,6 +3841,12 @@ pub fn constIntBig(mod: *Module, arena: *Allocator, src: LazySrcLoc, ty: Type, b |
| 3827 | } | 3841 | } |
| 3828 | } | 3842 | } |
| 3829 | | 3843 | |
| | 3844 | pub fn deleteAnonDecl(mod: *Module, scope: *Scope, decl: *Decl) void { |
| | 3845 | const scope_decl = scope.ownerDecl().?; |
| | 3846 | scope_decl.namespace.anon_decls.swapRemoveAssertDiscard(decl); |
| | 3847 | decl.destroy(mod); |
| | 3848 | } |
| | 3849 | |
| 3830 | /// Takes ownership of `name` even if it returns an error. | 3850 | /// Takes ownership of `name` even if it returns an error. |
| 3831 | pub fn createAnonymousDeclNamed( | 3851 | pub fn createAnonymousDeclNamed( |
| 3832 | mod: *Module, | 3852 | mod: *Module, |
| ... | @@ -4814,6 +4834,8 @@ pub fn processOutdatedAndDeletedDecls(mod: *Module) !void { | ... | @@ -4814,6 +4834,8 @@ pub fn processOutdatedAndDeletedDecls(mod: *Module) !void { |
| 4814 | for (file.outdated_decls.items) |decl| { | 4834 | for (file.outdated_decls.items) |decl| { |
| 4815 | outdated_decls.putAssumeCapacity(decl, {}); | 4835 | outdated_decls.putAssumeCapacity(decl, {}); |
| 4816 | } | 4836 | } |
| | 4837 | file.outdated_decls.clearRetainingCapacity(); |
| | 4838 | |
| 4817 | // Handle explicitly deleted decls from the source code. This is one of two | 4839 | // Handle explicitly deleted decls from the source code. This is one of two |
| 4818 | // places that Decl deletions happen. The other is in `Compilation`, after | 4840 | // places that Decl deletions happen. The other is in `Compilation`, after |
| 4819 | // `performAllTheWork`, where we iterate over `Module.deletion_set` and | 4841 | // `performAllTheWork`, where we iterate over `Module.deletion_set` and |
| ... | @@ -4824,12 +4846,9 @@ pub fn processOutdatedAndDeletedDecls(mod: *Module) !void { | ... | @@ -4824,12 +4846,9 @@ pub fn processOutdatedAndDeletedDecls(mod: *Module) !void { |
| 4824 | // deletion set at this time. | 4846 | // deletion set at this time. |
| 4825 | for (file.deleted_decls.items) |decl| { | 4847 | for (file.deleted_decls.items) |decl| { |
| 4826 | log.debug("deleted from source: {*} ({s})", .{ decl, decl.name }); | 4848 | log.debug("deleted from source: {*} ({s})", .{ decl, decl.name }); |
| 4827 | if (decl.deletion_flag) { | | |
| 4828 | log.debug("{*} ({s}) redundantly in deletion set; removing", .{ decl, decl.name }); | | |
| 4829 | mod.deletion_set.removeAssertDiscard(decl); | | |
| 4830 | } | | |
| 4831 | try mod.deleteDecl(decl, &outdated_decls); | 4849 | try mod.deleteDecl(decl, &outdated_decls); |
| 4832 | } | 4850 | } |
| | 4851 | file.deleted_decls.clearRetainingCapacity(); |
| 4833 | } | 4852 | } |
| 4834 | // Finally we can queue up re-analysis tasks after we have processed | 4853 | // Finally we can queue up re-analysis tasks after we have processed |
| 4835 | // the deleted decls. | 4854 | // the deleted decls. |