merged.profdata: 501.521 funciones, 3.734.991 bloques, 5.885.254.799 ejecuciones registradas. Recogido corriendo firefox-instrumentado sobre el corpus de entrenamiento de Mozilla (build/pgo: blueprint para maquetación, js-input y sunspider para el motor JS), 35 de 36 páginas servidas. VIVE COMO FUENTE PINEADA, NO COMO RECETA QUE LO GENERA. El perfil NO es determinista —los contadores dependen del timing—, así que una receta que lo produjera tendría un ArtifactHash estable sobre bytes cambiantes: firefox consumiría cosas distintas en la misma dirección y dejaría de reproducir sin que nada lo dijera. Es el modo de fallo del lab fuera de hash_inputs, fabricado a propósito. Sellarlo una vez y pinearlo por sha256 hace que el insumo sea no determinista y el build vuelva a serlo. El blob (17.426.112 bytes, xz) está publicado en hammer/fuentes/<sha256>.tar del Storage Box y verificado bajándolo de vuelta por el mismo camino que usa hammer. La URL upstream no resuelve por DNS a propósito: es el patrón que el ADR 0013 ya prueba, y como la URL nunca estuvo en hash_inputs, mover el objeto de origen no re-hashea nada. Dos cosas que costaron y quedan escritas: · strip_components = 0. hammer recorta un componente al extraer (los releases GNU traen un proyecto-version/ de más) y este tarball lleva el fichero en la raíz, así que el default se llevaba lo único que había. El error era «cp: cannot stat merged.profdata» y no menciona el recorte por ningún lado. · SIN --with-pgo-jarlog, y es una mitad que falta, no un olvido. Alpine pasa además un jarlog que reordena omni.ja para acelerar el ARRANQUE; lo emite el profileserver.py de Mozilla con su extensión Quitter, que la corrida headless no tiene. Hoy se gana la disposición de CÓDIGO y no el orden del omni.ja. Y VIAJA UN ARREGLO QUE NO ES DE PGO, porque firefox se reconstruye igual: EL ARTEFACTO NO ARRANCABA. Medido sobre el sellado: `firefox --version` moría con «Error loading shared library libnspr4.so / Couldn't load XPCOM». mach install deja /usr/bin/firefox como symlink pelado, el binario no trae RUNPATH y el cierre no publica ld-musl-x86_64.path, así que las librerías que viven junto al binario no las encuentra nadie. atuq andaba sólo porque su receta añade este mismo lanzador; firefox, que va en las CUATRO imágenes de escritorio, no lo tenía. Es el NEEDED colgante un escalón más allá —no falta la librería, falta el modo de encontrarla— y por eso vigia-sonames.py no puede verlo: las librerías SÍ están en el artefacto y las cuenta como propias. firefox: b3:8116bdec -> b3:1d730334.
74 lines
4.4 KiB
TOML
74 lines
4.4 KiB
TOML
# firefox-pgo-profile — el perfil de ejecución que optimiza a firefox. UNA MEDICIÓN CONGELADA.
|
|
#
|
|
# ══ QUÉ ES ═════════════════════════════════════════════════════════════════════════════════════
|
|
# `merged.profdata`: 501.521 funciones, 3.734.991 bloques y 5.885.254.799 ejecuciones registradas,
|
|
# recogidas corriendo el `firefox-instrumentado` sobre el corpus de entrenamiento de Mozilla
|
|
# (`build/pgo`: las 4 páginas de maquetación de blueprint y los benchmarks JS de js-input/sunspider).
|
|
# `firefox` lo consume con `--enable-profile-use=cross`.
|
|
#
|
|
# ══ POR QUÉ ES UNA FUENTE PINEADA Y NO UNA RECETA QUE LO GENERA ════════════════════════════════
|
|
# **El perfil NO ES DETERMINISTA**: los contadores dependen del timing de la corrida, así que dos
|
|
# generaciones no dan los mismos bytes. Si esto fuera una receta que lo produce, su ArtifactHash
|
|
# —input-addressed— no se movería entre generaciones, y firefox consumiría bytes distintos en la
|
|
# misma dirección: el build optimizado dejaría de reproducir sin que nada lo dijera. Es el mismo
|
|
# modo de fallo que el lab fuera de `hash_inputs`, fabricado a propósito.
|
|
#
|
|
# La salida es la que el SDD 26 §3.ter ya elegía: **generar el perfil UNA vez y sellarlo**, aquí como
|
|
# fuente pineada por sha256. Así el insumo es no determinista pero el build vuelve a serlo, que es
|
|
# exactamente lo que se quiere. Regenerarlo es una decisión explícita —subir un blob nuevo y cambiar
|
|
# el sha256—, nunca un accidente.
|
|
#
|
|
# ⚠ NO TIENE UPSTREAM, Y LA URL LO DICE. El blob es nuestro: sale de nuestra corrida sobre nuestro
|
|
# binario. La URL `.invalid` no resuelve por DNS a propósito (es el patrón que el ADR 0013 ya usa y
|
|
# prueba); los bytes vienen del mirror de fuentes, que sirve por sha256. Como la URL nunca estuvo en
|
|
# `hash_inputs` (ADR 0013), mover el objeto de origen no re-hashea nada.
|
|
#
|
|
# Publicado el 2026-09-07 en `hammer/fuentes/<sha256>.tar` del Storage Box
|
|
# (`scripts/fuentes/mirror-env.sh` trae `HAMMER_MIRROR` y su clave).
|
|
# Verificado bajándolo de vuelta por el mismo camino que usa hammer: 17.426.112 bytes, sha256 ok.
|
|
#
|
|
# ⚠ SI SE RECONSTRUYE `firefox-instrumentado`, ESTE PERFIL NO CADUCA SOLO. Un perfil recogido de un
|
|
# binario que ya no se parece al que se optimiza sigue siendo válido para clang —los contadores se
|
|
# aplican por nombre de función— pero vale menos: las funciones que ya no existen se ignoran y las
|
|
# nuevas quedan sin datos. Regenerarlo es su propia unidad de trabajo, no un efecto secundario.
|
|
name = "firefox-pgo-profile"
|
|
version = "2026.09.07"
|
|
license = "MPL-2.0"
|
|
|
|
[source]
|
|
tarball = "https://no-hay-upstream.invalid/hammer/firefox-pgo-2026-09-07.tar.xz"
|
|
sha256 = "92edb9c56c87c0b489e61ed722d97b7fe5d6dc37ce48ffa3f3cf7523cc4d2dbf"
|
|
# ⚠ `0` Y NO EL DEFAULT. hammer recorta UN componente al extraer, porque los releases GNU vienen
|
|
# con un `proyecto-version/` de más. Este tarball es nuestro y lleva el fichero en la raíz, así que
|
|
# con el default se recortaba lo único que hay y el install moría en `cp: cannot stat
|
|
# merged.profdata`. El error no menciona el recorte por ningún lado.
|
|
strip_components = 0
|
|
|
|
[build]
|
|
compiler = "clang"
|
|
|
|
[build.phases]
|
|
configure = "true"
|
|
compile = "true"
|
|
install = '''
|
|
set -e
|
|
mkdir -p /out/usr/share/firefox-pgo
|
|
cp merged.profdata /out/usr/share/firefox-pgo/merged.profdata
|
|
|
|
P=/out/usr/share/firefox-pgo/merged.profdata
|
|
|
|
# ── GUARDIÁN: QUE SEA UN PERFIL, NO UN FICHERO GRANDE ────────────────────────────────────────
|
|
# «Existe» no es «sirve», y acá el modo de fallo es especialmente callado: `--enable-profile-use`
|
|
# con un profdata vacío o de otra versión no rompe el build de firefox — lo hace más lento y ya.
|
|
# O sea que un perfil malo sella en verde, reproduce, y lo único que se pierde es justo lo que se
|
|
# fue a buscar. Se le pregunta a `llvm-profdata` cuántas funciones trae.
|
|
n=$(llvm-profdata show "$P" 2>/dev/null | sed -n 's/^Total functions: //p')
|
|
case "${n:-0}" in ''|*[!0-9]*) n=0 ;; esac
|
|
test "$n" -gt 100000 || {
|
|
echo "!! el profdata declara $n funciones (esperaba >100000): perfil vacío o ilegible" >&2
|
|
llvm-profdata show "$P" 2>&1 | head -5 >&2
|
|
exit 1
|
|
}
|
|
echo "guardián: perfil válido — $n funciones, $(stat -c%s "$P") bytes"
|
|
'''
|