SDD 26 §3.bis: el diff contra Alpine dice que no es sólo PGO, y una de las diferencias es de seguridad

Pregunta del usuario: «¿firefox está sin pgo-lto-bolt? ¿eso es una desventaja frente a las otras
distros?». Sí, y para medirlo se trajeron el APKBUILD + mozconfig de community/firefox de aports y
el PKGBUILD de Arch, y se compararon línea a línea con el mozconfig de recipes/firefox.toml.

La comparación importa porque ALPINE ES NUESTRO PROPIO UPSTREAM: de ahí salen los once parches de
musl. No es una distro lejana sacándonos ventaja, es la que ya construye este mismo código con
`--enable-lto=cross` + `--enable-profile-use=cross` + jarlog. Arch hace lo mismo («Do 3-tier PGO»).

BOLT NO ES LA DESVENTAJA: cero menciones en los dos ficheros. Lo que nos separa es PGO+LTO.

Y el diff completo da más que velocidad:
- RLBOX APAGADO (`--without-wasm-sandboxed-libraries`) es una desventaja de SEGURIDAD y pesa más que
  el PGO: es la jaula wasm de graphite/ogg/expat/woff2, o sea el código que come entrada no
  confiable. Encenderlo pide wasi-sdk + wasi-compiler-rt en el corpus: receta, no flag.
- `--with-unsigned-addon-scopes=app,system` nos falta y ATUQ LO NECESITA para shipear sus propias
  extensiones ⇒ una capacidad de atuq que NO se resuelve en el overlay: exige tocar la base.
- Falta RELR; el linker es GNU ld y no lld.
- `--disable-jemalloc` NO es desviación nuestra: Alpine también lo pasa. Un fantasma menos que
  perseguir.
- Bundlear en vez de `--with-system-*` es diferencia a propósito: el corpus ES la fuente.

Corolario que ordena el plan: TODO ESO ENTRA EN UN SOLO REBUILD. Cada uno son cuatro horas y
re-sella la cola Gecko entera, así que la unidad 3 pasa a ser una pasada única y RLBox se separa
como 3.b.

Y dos muros del PGO que las distros no tienen, porque no persiguen lo que nosotros perseguimos:
- las dos corren el profileserver bajo `xvfb-run`, y NO TENEMOS X11 en el corpus (Wayland-only) ⇒ va
  bajo sway headless, que ya existe del frente wlr.
- el profdata NO ES DETERMINISTA (contadores dependientes del timing) ⇒ se genera una vez, se sella
  como artefacto propio y se consume por hash, o firefox deja de reproducir.

Bonus para el §2: el jarlog del PGO ordena el omni.ja para el arranque. Re-empacarlo a lo bruto tira
esa optimización a la basura sin que nadie lo note.
This commit is contained in:
Sergio
2026-09-05 03:03:23 +00:00
parent 1fcad3f6de
commit 42404bc692
+57 -1
View File
@@ -57,6 +57,8 @@ Pero nosotros no distribuimos un binario: sellamos artefactos. Entonces `atuq` e
- **`omni.ja` es un zip ⇒ hay que re-empacarlo determinista** (mtimes fijos, orden estable) o el
artefacto deja de reproducir bit a bit. Es la misma disciplina que ya exige la imagen del lab.
- **El `jarlog` del PGO ordena el `omni.ja` para el arranque** (§3.bis). Re-empacarlo a lo bruto
tira esa optimización a la basura sin que nadie lo note. El re-empaque preserva el orden.
- **Hay que invalidar el startup cache** tras tocarlo (fichero `.purgecaches` junto al binario, o
bump del BuildID). Si no, los cambios no se ven y **parece que el overlay no agarró**: un falso
negativo de los caros, de la misma familia que el cache-hit que congela regresiones.
@@ -103,6 +105,59 @@ palanca por unidad de trabajo que hay en este frente**, y por eso encabeza el pl
de página y JS. **Hoy estamos ATRÁS de Zen en este eje, no adelante** — Zen hereda la
configuración de Mozilla tal cual. Esto no es una ventaja nuestra: es una deuda que se salda.
### 3.bis El diff contra Alpine — y no es sólo PGO
Medido el 2026-09-05 trayendo el `APKBUILD` y el `mozconfig` de `community/firefox` de aports y el
`PKGBUILD` de Arch, y comparándolos línea a línea con el mozconfig de `recipes/firefox.toml`.
**Alpine es nuestro propio upstream** —de ahí salen los once parches de musl— así que la comparación
no es contra una distro lejana: es contra la que ya construye este mismo código.
| | `recipes/firefox.toml` | Alpine `community/firefox` |
|---|---|---|
| LTO | **no** | `--enable-lto=cross` |
| PGO | **no** | `--enable-profile-use=cross` + `merged.profdata` + `jarlog` |
| Linker | GNU ld (via gcc) | `--enable-linker=lld` (lld 22) |
| RELR | **no** | `--enable-packed-relative-relocs` |
| Sandbox RLBox | **APAGADO** (`--without-wasm-sandboxed-libraries`) | `--with-wasi-sysroot` |
| Extensiones sin firmar | **no declarado** | `--with-unsigned-addon-scopes=app,system` |
| Allocator | `--disable-jemalloc` | `--disable-jemalloc`**igual, no es desviación nuestra** |
| Librerías | todo bundleado | `--with-system-{icu,nss,nspr,av1,vpx,webp,png,jpeg,zlib,ffi,libevent,pixman,pipewire}` |
Arch hace lo mismo en el eje de velocidad («Do 3-tier PGO», `--enable-lto=cross`,
`--enable-profile-use=cross`). **Ni Alpine ni Arch usan BOLT** (cero menciones en los dos ficheros)
⇒ BOLT no es la desventaja, es el extra. Lo que nos separa del resto del mundo es **PGO + LTO**, del
orden de 10-20% en carga de página y JS.
**Tres lecturas que hay que sacar de esa tabla:**
1. **RLBox apagado es una desventaja de SEGURIDAD, no de velocidad, y probablemente pesa más que el
PGO.** Es la jaula wasm alrededor de los parsers de fuentes y medios —graphite, ogg, expat,
woff2—, o sea exactamente el código que come entrada no confiable. Encenderlo pide `wasi-sdk` +
`wasi-compiler-rt` en el corpus: receta propia, no un flag.
2. **`--with-unsigned-addon-scopes=app,system` nos falta y `atuq` lo NECESITA** para shipear sus
propias extensiones desde `distribution/extensions/` (§6.1, §7). Es un flag de `configure`
**una capacidad de `atuq` que no se resuelve en el overlay: exige tocar la base.**
3. **Las librerías del sistema son diferencia a propósito, no deuda.** Alpine usa las suyas; nuestro
corpus *es* la fuente y bundlear es lo que mantiene la clausura cerrada.
**Corolario que ordena el plan: todo esto entra en UN SOLO rebuild de `firefox`.** Cada rebuild son
cuatro horas y re-sella la cola Gecko entera (waterfox incluido), así que LTO, PGO, RELR, lld, RLBox
y el scope de addons se juntan en una sola pasada, no en seis.
### 3.ter Los dos muros del PGO que las distros no tienen
**El perfil se junta corriendo el navegador, y las dos distros lo hacen bajo `xvfb-run`** (Alpine:
`xvfb-run -a -s "-screen 0 1920x1080x24" ./mach python build/pgo/profileserver.py`; Arch, idéntico).
**Nosotros no tenemos X11 en el corpus** —es la decisión Wayland-only de toda la distro— así que ese
camino no existe acá. La salida hammer-nativa es correrlo bajo un **sway headless**
(`WLR_BACKENDS=headless`), que ya tenemos del frente wlr/sway y arranca en segundos.
**Y el perfil no es determinista.** Los contadores dependen del timing de la corrida, así que dos
generaciones del profdata no dan los mismos bytes — a las distros no les importa porque no persiguen
bit-repro; a nosotros nos rompe el invariante. La salida: **generar el perfil UNA vez y sellarlo como
artefacto propio, consumido por hash** desde `firefox`. El build optimizado vuelve a ser determinista
aunque su insumo no lo sea, y el perfil se regenera a propósito, no por accidente.
## 4. Lo que `atuq` NO promete
Esta sección existe antes que la lista de features a propósito, con el mismo criterio que el modelo
@@ -211,7 +266,8 @@ siguiente.
|---|---|---|---|
| 1 | `waterfox` sella | valida la tesis del reúso | build en curso |
| 2 | **`llvm-toolchain`** (clang+lld+libc++ musl) | LTO, PGO, BOLT **y** el muro 3 | — |
| 3 | `firefox` con LTO+PGO (perfil en `hash_inputs`) | el eje de velocidad | 2 |
| 3 | **`firefox` en UNA pasada**: LTO, PGO (perfil sellado aparte), lld, RELR, `--with-unsigned-addon-scopes` | el eje de velocidad **y** las extensiones de `atuq` | 2 |
| 3.b | `wasi-sdk` + `wasi-compiler-rt` ⇒ RLBox encendido | cierra el hueco de seguridad del §3.bis | 2 |
| 4 | **`atuq`: receta derivada + overlay de chrome** | el andamio de todo lo demás | 1 |
| 5 | Host de native messaging (tawasuyu) | los verbos del §6 | 4 |
| 6 | `sct` v1 (extensión + testigo) | el diferenciador que nadie tiene | 5 |