Publié le 29 janvier 2025
Collecte des ordures WebAssembly (WasmGC)
Il existe deux types de langages de programmation: les langages de programmation avec garbage collection et les langages de programmation qui nécessitent une gestion manuelle de la mémoire. Kotlin, PHP ou Java sont des exemples de langages de programmation de ce type. C, C++ ou Rust en sont des exemples. En règle générale, les langages de programmation de haut niveau sont plus susceptibles de proposer la récupération de mémoire comme fonctionnalité standard.
En termes simplifiés, la récupération de mémoire consiste à tenter de récupérer la mémoire allouée par le programme, mais qui n'est plus référencée. Cette mémoire est appelée "garbage". Il existe de nombreuses stratégies d'implémentation du garbage collection. L'une des méthodes les plus faciles à comprendre est le comptage des références, dont l'objectif est de compter le nombre de références aux objets en mémoire.
Vous pouvez avoir l'impression que c'est le début, mais les langages de programmation sont implémentés dans d'autres langages de programmation. Par exemple, l'environnement d'exécution PHP est principalement implémenté en C. Si les développeurs souhaitent compiler un langage comme PHP en Wasm, ils doivent généralement compiler toutes les parties, comme l'analyseur du langage, la prise en charge des bibliothèques, le garbage collection et d'autres composants essentiels.
Wasm s'exécute dans le navigateur dans le contexte du langage hôte JavaScript. Dans Chrome, JavaScript et Wasm sont exécutés dans V8, le moteur JavaScript Open Source de Google. De plus, V8 dispose déjà d'un ramasse-ordures. Cela signifie que les développeurs qui utilisent, par exemple, du code PHP compilé en Wasm, finissent par envoyer une implémentation du collecteur de déchets du langage porté (PHP) au navigateur qui dispose déjà d'un collecteur de déchets, ce qui est aussi inutile que cela puisse paraître. C'est là que WasmGC intervient.
Pour en savoir plus sur WasmGC, consultez l'article WebAssembly Garbage Collection (WasmGC) now enabled by default in Chrome (Le garbage collection WebAssembly (WasmGC) est désormais activé par défaut dans Chrome). Pour aller plus loin, consultez l'article de blog V8 A new way to bring garbage collected programming languages efficiently to WebAssembly (Une nouvelle façon d'intégrer efficacement des langages de programmation avec garbage collection à WebAssembly).
Optimisations des appels de fin de Wasm
Un appel est dit en position de fin s'il s'agit de la dernière instruction exécutée avant le retour de la fonction en cours. Les compilateurs peuvent optimiser ces appels en supprimant le frame de l'appelant et en remplaçant l'appel par un saut. Cela est particulièrement utile pour les fonctions récursives. Prenons l'exemple de cette fonction C qui additionne les éléments d'une liste chaînée:
int sum(List* list, int acc) {
if (list == nullptr) return acc;
return sum(list->next, acc + list->val);
}
Avec un appel régulier, cela consomme un espace de pile O(n) : chaque élément de la liste ajoute un nouveau frame à la pile d'appels. Avec une liste suffisamment longue, cela pourrait très rapidement déborder la pile. En remplaçant l'appel par un saut, l'optimisation des appels récursifs transforme efficacement cette fonction récursive en une boucle qui utilise un espace de pile O(1) :
int sum(List* list, int acc) {
while (list != nullptr) {
acc = acc + list->val;
list = list->next;
}
return acc;
}
Cette optimisation est particulièrement importante pour les langages fonctionnels. Ils s'appuient fortement sur les fonctions récursives, et les langages purs comme Haskell ne fournissent même pas de structures de contrôle de boucle. Tout type d'itération personnalisée utilise généralement la récursion d'une manière ou d'une autre. Sans l'optimisation des appels de queue, cela entraînerait très rapidement un débordement de pile pour tout programme non trivial, qui finirait par manquer d'espace de pile.
Initialement, WebAssembly n'autorisait pas de telles optimisations de rappels de fin, mais cela a changé avec la proposition d'extension des rappels de fin. Pour en savoir plus, consultez l'article Appels de fin WebAssembly sur le blog V8.
Conclusions
Désormais, WasmGC et les optimisations de la fonction tail call sont disponibles en tant que référence. Plus d'applications peuvent donc utiliser ces fonctionnalités pour améliorer leurs performances, comme l'a fait Google Sheets en portant le worker de calcul de Google Sheets vers WasmGC.