perf(size): 移除多余的 dynamic_cast 并省掉 56KB 的 C++ 名字反修饰器

两处独立收益:

1. Toolbar::BuildBoxes 里唯一的 dynamic_cast 是**多余强转**(Button::widget 本来就是
   UiButtonWidget*),却让全项目必须开 RTTI。改为直接遍历 m_buttons(与控件树同源)。
   最小复现程序实测:39,936 B -> 115,200 B(+75,264 B)。
2. RTTI 关掉后 cp-demangle.o 仍然在链接里 —— 真凶是 libstdc++ 的 vterminate.o
   (引用 __cxa_demangle)。本文件自行定义 __gnu_cxx::__verbose_terminate_handler(),
   让它不再被拉入(本应用启动后会换成自己的 terminate 处理,行为等效)。

Makefile 新增 NO_RTTI=1(默认开启)-> CXXFLAGS += -fno-rtti。

实测:Release 890,880 -> 829,440 B(-61,440);.text 753,136 -> 703,616(-49,520);
.rdata 36,936 -> 26,616(-10,320);Debug 1,801,617 -> 1,734,578(-67,039)。
release/debug 全量重建零警告。
This commit is contained in:
DeepSeek-V4.1-Flash committed 2026-11-04 02:48:59 +08:00
1 parent 86ff0291ba
commit 5de3763e72
3 files changed
+73 -16

No files matched your search

+9
View File
@@ -192,6 +192,15 @@ ifeq ($(strip $(NO_EXCEPTIONS)), 1)
CXXFLAGS += -fno-exceptions
endif
# ---- RTTI:全项目不使用 `dynamic_cast` / `typeid` ----
# 2026-11-04 审查:唯一的 `dynamic_cast`(Toolbar::BuildBoxes)是多余的强转,
# 已改为直接使用已有的 `UiButtonWidget*`。RTTI 会链入 `cp-demangle.o`
# (Release map 实测 56,320 B)+ `type_info` 表,最小复现程序实测 +75,264 B。
NO_RTTI = 1
ifeq ($(strip $(NO_RTTI)), 1)
CXXFLAGS += -fno-rtti
endif
# 丢弃未被引用的函数/数据(非 LTO 时还需要配合 -ffunction-sections 才有粒度)。
GC_SECTIONS = -Wl,--gc-sections