Las optimizaciones de llamada de cola de WasmGC y Wasm ahora están disponibles como versión preliminar

Fecha de publicación: 29 de enero de 2025

Recolección de elementos no utilizados de WebAssembly (WasmGC)

Existen dos tipos de lenguajes de programación: lenguajes de programación con recolección de basura y lenguajes de programación que requieren administración manual de la memoria. Entre los ejemplos de los primeros, se encuentran Kotlin, PHP o Java. Algunos ejemplos de los últimos son C, C++ o Rust. Como regla general, los lenguajes de programación de nivel superior tienen más probabilidades de tener la recolección de basura como una función estándar.

En términos simplificados, la recolección de elementos no utilizados es el intento de recuperar la memoria que asignó el programa, pero a la que ya no se hace referencia. Esa memoria se denomina basura. Existen muchas estrategias para implementar la recolección de basura. Uno de los más fáciles de entender es el recuento de referencias, en el que el objetivo es contar la cantidad de referencias a objetos en la memoria.

Puede parecer el principio, pero los lenguajes de programación se implementan en otros lenguajes de programación. Por ejemplo, el entorno de ejecución de PHP se implementa principalmente en C. Si los desarrolladores quieren compilar un lenguaje como PHP a Wasm, suelen tener que compilar todas las partes, como el analizador del lenguaje, la compatibilidad con bibliotecas, la recolección de basura y otros componentes fundamentales.

Wasm se ejecuta en el navegador en el contexto del lenguaje host JavaScript. En Chrome, JavaScript y Wasm se ejecutan en V8, el motor de JavaScript de código abierto de Google. Además, V8 ya tiene un recolector de basura. Esto significa que los desarrolladores que usan, por ejemplo, PHP compilado a Wasm, terminan enviando una implementación del recolector de elementos no usados del lenguaje portabilizado (PHP) al navegador que ya tiene un recolector de elementos no usados, lo que es tan ineficiente como suena. Aquí es donde entra en juego WasmGC.

Para obtener más información sobre WasmGC, lee WebAssembly Garbage Collection (WasmGC) now enabled by default in Chrome y, si quieres profundizar, consulta la entrada de blog de V8 A new way to bring garbage collected programming languages efficiently to WebAssembly

Optimizaciones de llamada de cola de Wasm

Se dice que una llamada está en posición de cola si es la última instrucción que se ejecuta antes de regresar de la función actual. Los compiladores pueden optimizar esas llamadas descartando la trama del llamador y reemplazando la llamada por un salto. Esto es particularmente útil para las funciones recursivas. Por ejemplo, toma esta función de C que suma los elementos de una lista vinculada:

int sum(List* list, int acc) {
  if (list == nullptr) return acc;
  return sum(list->next, acc + list->val);
}

Con una llamada normal, esto consume espacio de pila O(n): cada elemento de la lista agrega un marco nuevo a la pila de llamadas. Con una lista lo suficientemente larga, esto podría desbordar la pila muy rápidamente. Cuando se reemplaza la llamada por un salto, la optimización de la llamada al final convierte de manera eficaz esta función recursiva en un bucle que usa espacio de pila O(1):

int sum(List* list, int acc) {
  while (list != nullptr) {
    acc = acc + list->val;
    list = list->next;
  }
  return acc;
}

Esta optimización es particularmente importante para los lenguajes funcionales. Dependen en gran medida de las funciones recursivas, y las puras, como Haskell, ni siquiera proporcionan estructuras de control de bucles. Cualquier tipo de iteración personalizada suele usar la recursividad de una forma u otra. Sin la optimización de la llamada al final, esto se encontraría muy rápidamente con un desbordamiento de pila para cualquier programa no trivial, que de otro modo se quedaría sin espacio de pila rápidamente.

Inicialmente, WebAssembly no permitía tales optimizaciones de llamada al final, pero esto cambió con la propuesta de extensión de llamada al final. Para obtener más información, lee el artículo Llamadas de cola de WebAssembly en el blog de V8.

Conclusiones

Ahora que WasmGC y las optimizaciones de llamada de cola están disponibles como Baseline, más apps pueden usar estas funciones para mejorar el rendimiento, como lo hizo Hojas de cálculo de Google cuando transfirió el trabajador de cálculo de Hojas de cálculo de Google a WasmGC.