Откат оптимизации резидента: перенос данных банка в его страницу ломает картинку

Возврат к состоянию после звуковых правок (c6828c0).  Отменяются 3545826 и
9025573 целиком: --bank-data=SRC в sprinter-cc, его включение в PoP и
docs/resident_budget.md.

Что выяснено и почему откат, а не доводка.  Перенос писучих данных
банкового модуля в его 16-КБ страницу даёт цветной мусор блоками и уводит
DSS.  У pop_trob причина найдена: pop_trob_modif() возвращает указатель на
room_modif[24][30], и его разыменовывают банки 2/3/7 и резидент — то есть
пишут по 0xC000+ в СВОЮ страницу, поверх чужого кода.  Def/Ref-анализ такое
не ловит: снаружи ссылки на символ нет, есть ссылка на функцию, отдающую
его адрес.

Но и один pop_room, у которого явной утечки указателя найти не удалось,
ломается так же — значит механизм понят не до конца.  Пока не понят,
включать нельзя.  Нулевая инициализация при этом ни при чём: mkexe -p 0
проверен по образу (прогон нулей 14304 Б, самый длинный прогон 0xFF — 14).

Место в резиденте искать другими путями: malloc (287 Б, требует раздельных
cbl_open для APP и SILENCE) и код pop_tile (5972 Б).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-20 21:26:23 +03:00
parent 90255737c2
commit 63e426cc0d
3 changed files with 3 additions and 155 deletions
+1 -17
View File
@@ -35,23 +35,7 @@ MEMORY ?= huge # small-раскладка + банки кода в W
# ВАЖНО: любое сравнение занятости банков имеет смысл только при ОДНОМ и том
# же ALLOCS — иначе сравниваются не правки, а уровни оптимизации.
ALLOCS ?= 3000
# Писучие данные ЭТОГО банкового модуля живут в его же странице, а не в
# резиденте W1/W2 (−1620 Б базы). Список из одного файла — не лень, а
# результат проверки; ДВА условия, и второе стоило перезагрузки DSS:
#
# 1) ни один чужой модуль не ссылается на его глобалы (проверяется по
# .rel: символ Def только в своём объекте и нигде не Ref);
# 2) НИ ОДИН УКАЗАТЕЛЬ на его статику не уходит наружу. Def/Ref этого не
# видит. Так провалился pop_trob: pop_trob_modif() возвращает указатель
# на room_modif[24][30], и его разыменовывают банки 2/3/7 и резидент —
# то есть пишут по 0xC000+ в СВОЮ страницу, поверх чужого кода.
#
# У pop_room оба условия выполнены: _mobs не читает никто, bake_copy
# статическая, а atlas_load(&pop_env[i]) берёт адрес глобала из pop_tile.c
# (резидент), не своего. Подробности — ../docs/resident_budget.md.
BANK_DATA := --bank-data=pop_room.c
EXTRA_FLAGS ?= --gfx 256 -I $(CURDIR)/../poc/res/bg --max-allocs $(ALLOCS) --bank 2=pop_bg.c --bank 7=pop_room.c --bank 4=pop_cdraw.c --bank 4=pop_kdraw.c --bank 3=pop_map.c --bank 1=guards.c --bank 5=pop_ctrl.c --bank 6=pop_trob.c --bank 7=pop_redraw.c --bank 8=roomtest_cold.c --bank 8=pop_level_cold.c --bank 8=pop_kboot.c --bank 8=pop_guard_cold.c --bank 8=pop_shadow.c --bank 8=pop_sfx_cold.c $(BANK_DATA) $(PROF_FLAGS)
EXTRA_FLAGS ?= --gfx 256 -I $(CURDIR)/../poc/res/bg --max-allocs $(ALLOCS) --bank 2=pop_bg.c --bank 7=pop_room.c --bank 4=pop_cdraw.c --bank 4=pop_kdraw.c --bank 3=pop_map.c --bank 1=guards.c --bank 5=pop_ctrl.c --bank 6=pop_trob.c --bank 7=pop_redraw.c --bank 8=roomtest_cold.c --bank 8=pop_level_cold.c --bank 8=pop_kboot.c --bank 8=pop_guard_cold.c --bank 8=pop_shadow.c --bank 8=pop_sfx_cold.c $(PROF_FLAGS)
# Профилирование полосами бордюра (см. PROF() в roomtest.c) — ВКЛЮЧЕНО по
# умолчанию, пока идёт работа с производительностью; make PROF=0 выключает.
# Каждая фаза кадра красит бордюр в свой цвет, высота полосы на скриншоте