diff options
Diffstat (limited to 'src/Module.zig')
| -rw-r--r-- | src/Module.zig | 180 |
1 files changed, 14 insertions, 166 deletions
diff --git a/src/Module.zig b/src/Module.zig index 8ba856cf68..828ceb734a 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -132,10 +132,6 @@ failed_exports: std.AutoArrayHashMapUnmanaged(*Export, *ErrorMsg) = .{}, /// are stored here. cimport_errors: std.AutoArrayHashMapUnmanaged(Decl.Index, std.zig.ErrorBundle) = .{}, -/// Candidates for deletion. After a semantic analysis update completes, this list -/// contains Decls that need to be deleted if they end up having no references to them. -deletion_set: std.AutoArrayHashMapUnmanaged(Decl.Index, void) = .{}, - /// Key is the error name, index is the error tag value. Index 0 has a length-0 string. global_error_set: GlobalErrorSet = .{}, @@ -165,7 +161,7 @@ emit_h: ?*GlobalEmitH, test_functions: std.AutoArrayHashMapUnmanaged(Decl.Index, void) = .{}, -global_assembly: std.AutoHashMapUnmanaged(Decl.Index, []u8) = .{}, +global_assembly: std.AutoArrayHashMapUnmanaged(Decl.Index, []u8) = .{}, reference_table: std.AutoHashMapUnmanaged(Decl.Index, struct { referencer: Decl.Index, @@ -438,9 +434,6 @@ pub const Decl = struct { /// with it. That means when `Decl` is destroyed, the cleanup code should additionally /// check if the value owns a `Namespace`, and destroy that too. owns_tv: bool, - /// This flag is set when this Decl is added to `Module.deletion_set`, and cleared - /// when removed. - deletion_flag: bool, /// Whether the corresponding AST decl has a `pub` keyword. is_pub: bool, /// Whether the corresponding AST decl has a `export` keyword. @@ -873,47 +866,6 @@ pub const Namespace = struct { } }; - pub fn deinit(ns: *Namespace, mod: *Module) void { - ns.destroyDecls(mod); - ns.* = undefined; - } - - pub fn destroyDecls(ns: *Namespace, mod: *Module) void { - const gpa = mod.gpa; - - var decls = ns.decls; - ns.decls = .{}; - - for (decls.keys()) |decl_index| { - mod.destroyDecl(decl_index); - } - decls.deinit(gpa); - - ns.usingnamespace_set.deinit(gpa); - } - - pub fn deleteAllDecls( - ns: *Namespace, - mod: *Module, - outdated_decls: ?*std.AutoArrayHashMap(Decl.Index, void), - ) !void { - const gpa = mod.gpa; - - var decls = ns.decls; - ns.decls = .{}; - - // TODO rework this code to not panic on OOM. - // (might want to coordinate with the clearDecl function) - - for (decls.keys()) |child_decl| { - mod.clearDecl(child_decl, outdated_decls) catch @panic("out of memory"); - mod.destroyDecl(child_decl); - } - decls.deinit(gpa); - - ns.usingnamespace_set.deinit(gpa); - } - // This renders e.g. "std.fs.Dir.OpenOptions" pub fn renderFullyQualifiedName( ns: Namespace, @@ -2527,7 +2479,6 @@ pub fn deinit(mod: *Module) void { mod.embed_table.deinit(gpa); } - mod.deletion_set.deinit(gpa); mod.compile_log_text.deinit(gpa); mod.zig_cache_artifact_directory.handle.close(); @@ -2590,9 +2541,21 @@ pub fn deinit(mod: *Module) void { mod.test_functions.deinit(gpa); + for (mod.global_assembly.values()) |s| { + gpa.free(s); + } mod.global_assembly.deinit(gpa); + mod.reference_table.deinit(gpa); + { + var it = mod.intern_pool.allocated_namespaces.iterator(0); + while (it.next()) |namespace| { + namespace.decls.deinit(gpa); + namespace.usingnamespace_set.deinit(gpa); + } + } + mod.intern_pool.deinit(gpa); mod.tmp_hack_arena.deinit(); @@ -2606,20 +2569,10 @@ pub fn destroyDecl(mod: *Module, decl_index: Decl.Index) void { const ip = &mod.intern_pool; { - const decl = mod.declPtr(decl_index); _ = mod.test_functions.swapRemove(decl_index); - if (decl.deletion_flag) { - assert(mod.deletion_set.swapRemove(decl_index)); - } - if (mod.global_assembly.fetchRemove(decl_index)) |kv| { + if (mod.global_assembly.fetchSwapRemove(decl_index)) |kv| { gpa.free(kv.value); } - if (decl.has_tv) { - if (decl.getOwnedInnerNamespaceIndex(mod).unwrap()) |i| { - mod.namespacePtr(i).destroyDecls(mod); - mod.destroyNamespace(i); - } - } } ip.destroyDecl(gpa, decl_index); @@ -4422,56 +4375,6 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) Allocator.Err } } -/// Make it as if the semantic analysis for this Decl never happened. -pub fn clearDecl( - mod: *Module, - decl_index: Decl.Index, - outdated_decls: ?*std.AutoArrayHashMap(Decl.Index, void), -) Allocator.Error!void { - const tracy = trace(@src()); - defer tracy.end(); - - const decl = mod.declPtr(decl_index); - - const gpa = mod.gpa; - - if (outdated_decls) |map| { - _ = map.swapRemove(decl_index); - } - - if (mod.failed_decls.fetchSwapRemove(decl_index)) |kv| { - kv.value.destroy(gpa); - } - if (mod.cimport_errors.fetchSwapRemove(decl_index)) |kv| { - var errors = kv.value; - errors.deinit(gpa); - } - if (mod.emit_h) |emit_h| { - if (emit_h.failed_decls.fetchSwapRemove(decl_index)) |kv| { - kv.value.destroy(gpa); - } - assert(emit_h.decl_table.swapRemove(decl_index)); - } - _ = mod.compile_log_decls.swapRemove(decl_index); - try mod.deleteDeclExports(decl_index); - - if (decl.has_tv) { - if (decl.ty.isFnOrHasRuntimeBits(mod)) { - mod.comp.bin_file.freeDecl(decl_index); - } - if (decl.getOwnedInnerNamespace(mod)) |namespace| { - try namespace.deleteAllDecls(mod, outdated_decls); - } - } - - if (decl.deletion_flag) { - decl.deletion_flag = false; - assert(mod.deletion_set.swapRemove(decl_index)); - } - - decl.analysis = .unreferenced; -} - /// This function is exclusively called for anonymous decls. /// All resources referenced by anonymous decls are owned by InternPool /// so there is no cleanup to do here. @@ -4488,14 +4391,6 @@ pub fn deleteUnusedDecl(mod: *Module, decl_index: Decl.Index) void { } } -/// We don't perform a deletion here, because this Decl or another one -/// may end up referencing it before the update is complete. -fn markDeclForDeletion(mod: *Module, decl_index: Decl.Index) !void { - const decl = mod.declPtr(decl_index); - decl.deletion_flag = true; - try mod.deletion_set.put(mod.gpa, decl_index, {}); -} - /// Cancel the creation of an anon decl and delete any references to it. /// If other decls depend on this decl, they must be aborted first. pub fn abortAnonDecl(mod: *Module, decl_index: Decl.Index) void { @@ -4868,7 +4763,6 @@ pub fn allocateNewDecl( .@"linksection" = .none, .@"addrspace" = .generic, .analysis = .unreferenced, - .deletion_flag = false, .zir_decl_index = .none, .src_scope = src_scope, .generation = 0, @@ -5366,52 +5260,6 @@ pub fn optionsSrc(mod: *Module, decl: *Decl, base_src: LazySrcLoc, wanted: []con return base_src; } -/// Called from `performAllTheWork`, after all AstGen workers have finished, -/// and before the main semantic analysis loop begins. -pub fn processOutdatedAndDeletedDecls(mod: *Module) !void { - // Ultimately, the goal is to queue up `analyze_decl` tasks in the work queue - // for the outdated decls, but we cannot queue up the tasks until after - // we find out which ones have been deleted, otherwise there would be - // deleted Decl pointers in the work queue. - var outdated_decls = std.AutoArrayHashMap(Decl.Index, void).init(mod.gpa); - defer outdated_decls.deinit(); - for (mod.import_table.values()) |file| { - try outdated_decls.ensureUnusedCapacity(file.outdated_decls.items.len); - for (file.outdated_decls.items) |decl_index| { - outdated_decls.putAssumeCapacity(decl_index, {}); - } - file.outdated_decls.clearRetainingCapacity(); - - // Handle explicitly deleted decls from the source code. This is one of two - // places that Decl deletions happen. The other is in `Compilation`, after - // `performAllTheWork`, where we iterate over `Module.deletion_set` and - // delete Decls which are no longer referenced. - // If a Decl is explicitly deleted from source, and also no longer referenced, - // it may be both in this `deleted_decls` set, as well as in the - // `Module.deletion_set`. To avoid deleting it twice, we remove it from the - // deletion set at this time. - for (file.deleted_decls.items) |decl_index| { - const decl = mod.declPtr(decl_index); - - // Remove from the namespace it resides in, preserving declaration order. - assert(decl.zir_decl_index != .none); - _ = mod.namespacePtr(decl.src_namespace).decls.orderedRemoveAdapted( - decl.name, - DeclAdapter{ .mod = mod }, - ); - - try mod.clearDecl(decl_index, &outdated_decls); - mod.destroyDecl(decl_index); - } - file.deleted_decls.clearRetainingCapacity(); - } - // Finally we can queue up re-analysis tasks after we have processed - // the deleted decls. - for (outdated_decls.keys()) |key| { - try mod.markOutdatedDecl(key); - } -} - /// Called from `Compilation.update`, after everything is done, just before /// reporting compile errors. In this function we emit exported symbol collision /// errors and communicate exported symbols to the linker backend. |
