gioser

sergio/takana

> Una distribución Linux construida con un laboratorio funcional y hermético en el > sótano, y una terminal mutable, clásica y anárquica en el piso de arriba — diseñada > desde el suelo para que una IA programadora entienda, modifique y co…

TOML 1572Shell 203Rust 109Markdown 993728 Sutichaykuna

⎇ main recipes/firefox-pgo-profile.toml TOML · 107 siq'ikuna · 6.8 KB Ñawpa willay ch'uya

takana etapa 5a: los comentarios de las 741 recetas e852f4849 · Sergio ·

1# firefox-pgo-profile — el perfil de ejecución que optimiza a firefox. UNA MEDICIÓN CONGELADA.
2#
3# ══ QUÉ ES ═════════════════════════════════════════════════════════════════════════════════════
4# `merged.profdata`: 501.521 funciones, 3.734.991 bloques y **38.498.366.335 ejecuciones**
5# registradas sobre un corpus de **46 páginas**: las 36 de Mozilla (`build/pgo`) MÁS las 10 de
6# maquetación propias de `scripts/pgo-corpus/`.
7#
8# ⚠ EL CORPUS SE AMPLIÓ POR UNA MEDICIÓN, NO POR CORAZONADA. Con sólo las 36 de Mozilla la ganancia
9# medida fue **−9,4 %** en una página de DOM/maquetación y **−1,0 %** en `3d-raytrace`. La razón es
10# que un benchmark JIT-bound es casi CIEGO al PGO —el bucle caliente lo ejecuta código que el JIT
11# emite en runtime, y el PGO optimiza el intérprete, el GC y el propio JIT, no lo que el JIT
12# produce—, y el corpus de Mozilla está dominado en número de páginas por SunSpider. O sea que
13# entrenaba mucho justo donde el PGO menos rinde. Las 10 nuevas van al camino que sí es C++ de punta
14# a punta: flexbox, grid, tablas, texto en columnas, selectores, pintado, transforms, SVG, scroll
15# pegajoso y layout thrashing. Efecto medido en el propio perfil: las ejecuciones registradas pasan
16# de 5.885.254.799 a 38.498.366.335 (**6,5×**).
17# `firefox` lo consume con `--enable-profile-use=cross`.
18#
19# ══ POR QUÉ ES UNA FUENTE PINEADA Y NO UNA RECETA QUE LO GENERA ════════════════════════════════
20# **El perfil NO ES DETERMINISTA**: los contadores dependen del timing de la corrida, así que dos
21# generaciones no dan los mismos bytes. Si esto fuera una receta que lo produce, su ArtifactHash
22# —input-addressed— no se movería entre generaciones, y firefox consumiría bytes distintos en la
23# misma dirección: el build optimizado dejaría de reproducir sin que nada lo dijera. Es el mismo
24# modo de fallo que el lab fuera de `hash_inputs`, fabricado a propósito.
25#
26# La salida es la que el SDD 26 §3.ter ya elegía: **generar el perfil UNA vez y sellarlo**, aquí como
27# fuente pineada por sha256. Así el insumo es no determinista pero el build vuelve a serlo, que es
28# exactamente lo que se quiere. Regenerarlo es una decisión explícita —subir un blob nuevo y cambiar
29# el sha256—, nunca un accidente.
30#
31# ⚠ NO TIENE UPSTREAM, Y LA URL LO DICE. El blob es nuestro: sale de nuestra corrida sobre nuestro
32# binario. La URL `.invalid` no resuelve por DNS a propósito (es el patrón que el ADR 0013 ya usa y
33# prueba); los bytes vienen del mirror de fuentes, que sirve por sha256. Como la URL nunca estuvo en
34# `hash_inputs` (ADR 0013), mover el objeto de origen no re-hashea nada.
35#
36#   Publicado el 2026-09-07 en `takana/fuentes/<sha256>.tar` del Storage Box
37#   (`scripts/fuentes/mirror-env.sh` trae `TAKANA_MIRROR` y su clave).
38#   Verificado bajándolo de vuelta por el mismo camino que usa takana: 17.426.112 bytes, sha256 ok.
39#
40# ⚠ SI SE RECONSTRUYE `firefox-instrumentado`, ESTE PERFIL NO CADUCA SOLO. Un perfil recogido de un
41# binario que ya no se parece al que se optimiza sigue siendo válido para clang —los contadores se
42# aplican por nombre de función— pero vale menos: las funciones que ya no existen se ignoran y las
43# nuevas quedan sin datos. Regenerarlo es su propia unidad de trabajo, no un efecto secundario.
44# ⚠ EL JARLOG SE PROBÓ, FUNCIONA, Y ESTÁ APARCADO CON LA EVIDENCIA MEDIDA (2026-09-08).
45# Se generó (`MOZ_JAR_LOG_FILE` en el entorno; NO hace falta la extensión `Quitter` de Mozilla, que
46# el SDD daba por bloqueante), entró en el build, y se verificó del lado del artefacto: el `libxul`
47# quedó IDÉNTICO byte a byte y sólo cambió el `omni.ja`. O sea que la función existe.
48#
49# Pero **convierte el `omni.ja` al formato «jar optimizado» de Mozilla**, que mueve el directorio
50# central al principio:
51#
52#     sin jarlog:  PK\003\004    ZIP estándar — `zipfile` lo abre, 5306 entradas
53#     con jarlog:  \376\204#\0   `zipfile` lo rechaza: BadZipFile
54#
55# Y eso ROMPE `atuq`, que reempaqueta el `omni.ja` con `zipfile` para su branding:
56# `zipfile.BadZipFile: Bad magic number for central directory` en `rebrand.py`.
57#
58# La cuenta es asimétrica y por eso se aparca: el COSTE está MEDIDO —el navegador propio de la
59# distro no se puede construir— y el BENEFICIO no. El banco corre con caché de página caliente, que
60# es donde reordenar el `omni.ja` no ahorra ninguna lectura, y dio −0,1 %: por debajo del suelo de
61# ruido del propio banco (~1 % entre corridas de días distintos). Cambiar algo que funciona por una
62# ganancia que no se pudo medir, rompiendo algo que sí funcionaba, es mal negocio.
63#
64# Se retoma cuando (1) se mida el arranque EN FRÍO, que es su terreno, y (2) `rebrand.py` sepa leer
65# el jar optimizado o des-optimizarlo antes. **El blob `92497cdd…` del mirror YA TRAE el jarlog**,
66# así que retomarlo no exige volver a perfilar: es cambiar una línea y re-pinear el sha256.
67#
68name    = "firefox-pgo-profile"
69version = "2026.09.08"
70license = "MPL-2.0"
71
72[source]
73tarball = "https://no-hay-upstream.invalid/hammer/firefox-pgo-2026-09-08.tar.xz"
74sha256  = "95472411ba252e14c4d57de7193d53e4ba35fbccf4819ba95ceff1ca843e4a7a"
75# ⚠ `0` Y NO EL DEFAULT. takana recorta UN componente al extraer, porque los releases GNU vienen
76# con un `proyecto-version/` de más. Este tarball es nuestro y lleva el fichero en la raíz, así que
77# con el default se recortaba lo único que hay y el install moría en `cp: cannot stat
78# merged.profdata`. El error no menciona el recorte por ningún lado.
79strip_components = 0
80
81[build]
82compiler = "clang"
83
84[build.phases]
85configure = "true"
86compile   = "true"
87install = '''
88set -e
89mkdir -p /out/usr/share/firefox-pgo
90cp merged.profdata /out/usr/share/firefox-pgo/merged.profdata
91
92P=/out/usr/share/firefox-pgo/merged.profdata
93
94# ── GUARDIÁN: QUE SEA UN PERFIL, NO UN FICHERO GRANDE ────────────────────────────────────────
95# «Existe» no es «sirve», y acá el modo de fallo es especialmente callado: `--enable-profile-use`
96# con un profdata vacío o de otra versión no rompe el build de firefox — lo hace más lento y ya.
97# O sea que un perfil malo sella en verde, reproduce, y lo único que se pierde es justo lo que se
98# fue a buscar. Se le pregunta a `llvm-profdata` cuántas funciones trae.
99n=$(llvm-profdata show "$P" 2>/dev/null | sed -n 's/^Total functions: //p')
100case "${n:-0}" in ''|*[!0-9]*) n=0 ;; esac
101test "$n" -gt 100000 || {
102  echo "!! el profdata declara $n funciones (esperaba >100000): perfil vacío o ilegible" >&2
103  llvm-profdata show "$P" 2>&1 | head -5 >&2
104  exit 1
105}
106echo "guardián: perfil válido — $n funciones, $(stat -c%s "$P") bytes"
107'''