From 2e4069b89af28e4e0c48b83958951a6e60efde1f Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Tue, 19 May 2026 12:31:16 -0700 Subject: [PATCH] debug stats for /OPT:REF --- src/linker/lnk.c | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/src/linker/lnk.c b/src/linker/lnk.c index 6fa2636b..13fb8d1a 100644 --- a/src/linker/lnk.c +++ b/src/linker/lnk.c @@ -2676,9 +2676,9 @@ THREAD_POOL_TASK_FUNC(lnk_walk_relocs_and_mark_ref_sections_task) if (task_id == 0) { ProfBegin("Remove Unreachable Sections"); - U64 discard_vsize = 0; - U64 discard_fsize = 0; - U64 discard_count = 0; + typedef struct { U64 vsize; U64 fsize; U64 section_count; } Stat; + enum { Stat_Null, Stat_Code, Stat_Data, Stat_Debug, Stat_Count }; + Stat stats[Stat_Count] = {0}; for EachNode(obj_n, LNK_ObjNode, objs.first) { LNK_Obj *obj = &obj_n->data; @@ -2690,18 +2690,35 @@ THREAD_POOL_TASK_FUNC(lnk_walk_relocs_and_mark_ref_sections_task) COFF_SectionHeader *section_header = lnk_coff_section_header_from_section_number(obj, section_number); section_header->flags |= COFF_SectionFlag_LnkRemove; + U64 stat_kind = Stat_Null; + if (section_header->flags & LNK_SECTION_FLAG_DEBUG) { stat_kind = Stat_Debug; } + else if (section_header->flags & COFF_SectionFlag_CntCode) { stat_kind = Stat_Code; } + else { stat_kind = Stat_Data; } + if (section_header->flags & COFF_SectionFlag_CntUninitializedData) { - discard_vsize += section_header->vsize; + stats[stat_kind].vsize += section_header->vsize; } else { - discard_fsize += section_header->fsize; + stats[stat_kind].fsize += section_header->fsize; } - discard_count += 1; + stats[stat_kind].section_count += 1; } } - lnk_log(LNK_Log_Debug, "/OPT:REF total virt size discard: %M", (unsigned long long)discard_vsize); - lnk_log(LNK_Log_Debug, "/OPT:REF total file size discard: %M", (unsigned long long)discard_fsize); - lnk_log(LNK_Log_Debug, "/OPT:REF total section discard : %llu", (unsigned long long)discard_count); + if (lnk_get_log_status(LNK_Log_Debug)) { + U64 total_vsize = 0, total_fsize = 0, total_section_count = 0; + for EachElement(i, stats) { + total_vsize += stats[i].vsize; + total_fsize += stats[i].fsize; + total_section_count += stats[i].section_count; + } + String8List stat_list = {0}; + str8_list_pushf(scratch.arena, &stat_list, "Code : vsize: %M, fsize: %M, section count %llu", stats[Stat_Code].vsize, stats[Stat_Code].fsize, (unsigned long long)stats[Stat_Code].section_count ); + str8_list_pushf(scratch.arena, &stat_list, "Data : vsize: %M, fsize: %M, section count %llu", stats[Stat_Data].vsize, stats[Stat_Data].fsize, (unsigned long long)stats[Stat_Data].section_count ); + str8_list_pushf(scratch.arena, &stat_list, "Debug: vsize: %M, fsize: %M, section count %llu", stats[Stat_Debug].vsize, stats[Stat_Debug].fsize, (unsigned long long)stats[Stat_Debug].section_count); + str8_list_pushf(scratch.arena, &stat_list, "Total: vsize: %M, fsize: %M, section count %llu", total_vsize, total_fsize, total_section_count); + String8 stat_str = str8_list_join(scratch.arena, &stat_list, &(StringJoin){.pre = str8_lit(" "), .sep = str8_lit("\n ")}); + lnk_log(LNK_Log_Debug, "/OPT:REF Stats:\n%S", stat_str); + } ProfEnd(); }