Estaba en un scratchpad y se perdía; ahora vive en el repo con el porqué de cada
guarda, porque las tres se pagaron durante la primera corrida:
1. --unshare-pid en el bwrap. Sin él los hijos SOBREVIVEN al sandbox: un
http.server quedó vivo 19 HORAS, retuvo el puerto y envenenó las corridas
siguientes con «Address in use».
2. Puerto aleatorio por corrida. Elimina la colisión de raíz en vez de
detectarla: si otro proceso tiene un puerto, este arranque usa otro.
3. Marcador único por corrida, servido desde una copia ESCRIBIBLE del corpus.
La versión anterior horneaba el marcador como constante del script, y eso
rompía justo lo que el chequeo existe para probar: el servidor huérfano
servía el MISMO fichero de marca y el chequeo lo daba por bueno. Verificaba
«alguien sirve este contenido», no «este servidor es el mío». Con el marcador
por corrida, un servidor ajeno devuelve otra cosa y se aborta.
Y queda escrito por qué los sandboxes de Firefox van apagados en el
entrenamiento: con ellos los hijos mueren con signal 11, el proceso que renderiza
no nace, el servidor registra 0 GET y el único .profraw es el del padre
arrancando — un perfil de nada, con todo en verde. Es lo que hace el
profileserver.py de Mozilla. Sólo aplica al entrenamiento.
La espera al servidor va con reintento y no con un sleep fijo: 2 s concluían
«no responde» sobre uno que sí iba a responder.
Medida la ganancia del PGO ayer: -9,4% en una página de DOM/maquetación y -1,0%
en 3d-raytrace de SunSpider. La razón de la diferencia es que un benchmark
JIT-bound es casi CIEGO al PGO: el bucle caliente no lo ejecuta el C++ de
SpiderMonkey sino el código máquina que el JIT emite en runtime, y el PGO
optimiza el intérprete, el GC y el propio JIT — no lo que el JIT produce.
El corpus de Mozilla está dominado en número de páginas por SunSpider, o sea que
entrenaba mucho justo donde el PGO menos rinde. Estas diez ejercitan el camino
que sí es C++ de punta a punta:
flex flexbox anidado, wrap, alineaciones
rejilla CSS Grid: pistas, áreas nombradas, auto-fit
tablas tablas grandes con table-layout FIJO y AUTO (dos algoritmos)
texto columnas, shaping, reflujo por cambio de ancho
selectores DOM profundo contra 600 reglas, muchas que NO casan
pintado degradados, sombras, opacidad, mix-blend-mode
transformar transforms y contextos de apilamiento
svg paths, degradados, clip
desbordes overflow anidado, position:sticky, scroll programático
reflujo layout thrashing: leer y escribir geometría alternadamente
Reglas que cumplen todas, y no son de estilo:
· DETERMINISTAS (LCG propio, ni Math.random ni Date ni red) — dos corridas hacen
lo mismo, así que dos perfiles difieren por el timing de los contadores y no
por haber visitado caminos distintos.
· AUTOCONTENIDAS — el perfilado corre sin red.
· NUESTRAS — nada de páginas ajenas capturadas, que traerían licencia y
fragilidad.
· ACOTADAS — 16 a 32 s cada una; el perfilado arranca un navegador POR PÁGINA.
Validadas las diez contra el firefox sellado: todas renderizan y producen
captura. `flex` hubo que acortarla de 40 a 12 cajas raíz: con 40 la página medía
68.241 px de alto y la captura moría con «Failed to allocate a surface due to
invalid size». El layout ocurría igual, pero sin captura no se ejercita el
pintado, que es justo la mitad que se venía a entrenar.