diff --git a/docs/26-atuq-envoltorio-gecko.md b/docs/26-atuq-envoltorio-gecko.md index a876b485..946bdba1 100644 --- a/docs/26-atuq-envoltorio-gecko.md +++ b/docs/26-atuq-envoltorio-gecko.md @@ -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 |