Les sites modernes comme Google Docs et Gmail exécutent tellement de JavaScript que la vitesse du moteur avait deux goulots d'étranglement distincts. L'interpréteur de bytecode C++ de Firefox était lent et ne collectait aucune information de type, tandis que le JIT Baseline compilait chaque fonction en code machine ; sur les pages lourdes, cela signifiait compiler des milliers de fonctions, si bien que le temps passait en compilation plutôt qu'en exécution. Le JIT optimisant Ion ne devenait rapide qu'une fois que le JIT Baseline avait recueilli des données de type.
Les correctifs évidents coûtaient chacun quelque chose : accélérer l'interpréteur C++ et il ne fournit toujours aucune donnée de type à l'optimiseur ; retarder ou déplacer la compilation Baseline et les chemins froids ou les sorties de secours deviennent risqués ; reprendre les sorties de secours d'Ion au milieu du code JIT et chaque fonctionnalité exige des métadonnées supplémentaires et du code complexe pour les débogueurs et les exceptions. Mozilla a plutôt ajouté un nouveau niveau, l'interpréteur Baseline, situé entre l'interpréteur C++ et le JIT Baseline.
Ce qui a rendu cette approche peu coûteuse n'a pas été d'écrire un interpréteur à partir de zéro. Le JIT Baseline est un JIT à modèles : chaque instruction de bytecode correspond déjà à une séquence de code machine en grande partie fixe. Mozilla a généré ces mêmes séquences dans une boucle d'interpréteur à threads, en partageant un même générateur de code à modèles, la même disposition de cadre et une même structure JitScript contenant les caches en ligne et les données de profilage utilisées par les deux niveaux.
Comme l'interprétation recueillait désormais des informations de type, le seuil de préchauffage du JIT Baseline a pu passer de 10 à 100, réduisant fortement le nombre de fonctions compilées. Firefox Nightly a mesuré des chargements de pages 2 à 8 % plus rapides, des tests devtools 2 à 10 % plus rapides, des économies de mémoire et un code plus simple : les sorties de secours d'Ion reprenaient dans l'interpréteur, et une grande partie de la machinerie compliquée de débogage et de gestion des exceptions a été supprimée.
Générer le niveau peu coûteux à partir du même générateur de code que le niveau rapide, afin que les caches et les données de type restent partagés
Réutiliser le générateur de code du JIT signifie que le comportement de l'interpréteur et les caches en ligne correspondent au JIT par construction, sans seconde implémentation à maintenir en synchronisation.
L'interprétation recueille désormais les mêmes données de type que celles utilisées auparavant par le JIT, si bien que le niveau optimisant obtient son profil sans attendre la compilation.
Multiplier par dix le seuil de préchauffage du JIT a fortement réduit le nombre de fonctions compilées sur les pages riches en JS.
Les sorties de secours, la prise en charge du débogueur et la gestion des exceptions sont devenues plus simples parce qu'Ion reprend dans l'interpréteur plutôt qu'au milieu du code JIT, ce qui nécessite moins de métadonnées.
Entrer dans le niveau intermédiaire est peu coûteux : l'allocation de JitScript s'exécute au moins 10 fois plus vite que la compilation par le JIT Baseline.
Ne pas écrire à la main le niveau intermédiaire entre lent et rapide : le générer à partir des modèles du niveau rapide lui-même, et les caches, les cadres et le comportement restent identiques par construction
Suites
L'interpréteur Baseline est arrivé dans Firefox Nightly en juillet 2019 et était destiné à la version grand public de Firefox 70 en octobre de la même année. Les mesures de Mozilla montraient des chargements de pages 2 à 8 % plus rapides et des tests devtools 2 à 10 % plus rapides, avec en plus des économies de mémoire. Le nettoyage qu'il a permis a aussi accéléré la compilation par le JIT Baseline, et l'étape suivante annoncée par l'équipe était de déplacer cette compilation hors du thread principal.
VÉRIFIEZ LES SOURCES
Les sources
- The Baseline Interpreter: a faster JS interpreter in Firefox 70 Mozilla Hacks · hacks.mozilla.org ·
- Hacker News discussion: The Baseline Interpreter: a faster JS interpreter in Firefox 70 Hacker News · news.ycombinator.com ·