Dire adieu à asm.js
(spidermonkey.dev)- À partir de Firefox 148, l’optimisation asm.js de SpiderMonkey est désactivée par défaut, et le code associé sera supprimé dans une future version
- asm.js étant un sous-ensemble de JavaScript, les sites existants continueront de fonctionner, mais ils passeront par le chemin JIT général, sans les gains d’optimisation
- En recompilant le contenu asm.js en WebAssembly, on peut obtenir une exécution plus rapide et des binaires plus compacts
- Face à NaCl·PNaCl, asm.js a permis une exécution proche du natif dans le contenu web, sans sandbox distincte ni API alternative
- Intégré à Firefox 22 en 2013, OdinMonkey a permis le déploiement web de projets C/C++ comme Unity et Unreal, et a posé les bases de WebAssembly
Désactivation des optimisations asm.js
- À partir de Firefox 148, les optimisations asm.js de SpiderMonkey sont désactivées par défaut, et l’ensemble du code concerné sera supprimé dans une future version
- Les sites qui utilisent asm.js continueront de fonctionner
- asm.js est un sous-ensemble du JavaScript classique, donc le code existant sera exécuté comme les autres scripts via le chemin JIT général
- En revanche, les avantages des optimisations spécifiques à asm.js disparaissent
- Si vous distribuez encore du contenu asm.js, il est recommandé de le recompiler en WebAssembly
- Une recompilation vers WebAssembly permet d’obtenir une exécution plus rapide et des binaires plus compacts
- Le pipeline WebAssembly de SpiderMonkey est bien plus avancé que son pipeline asm.js
- Le succès de WebAssembly et la migration déjà effectuée par la majorité des usages d’asm.js rendent le coût de maintenance des deux voies de plus en plus élevé
- Cela demande toujours du temps de maintenance
- Cela laisse une surface d’attaque supplémentaire dans la VM
Le rôle d’asm.js et la fin d’OdinMonkey
- asm.js était la réponse de Mozilla à la question posée par NaCl et PNaCl : « Peut-on exécuter du code à vitesse native sur le web ? »
- Le principe consistait à choisir un sous-ensemble strict et statiquement typé de JavaScript, que le moteur pouvait reconnaître à la volée pour le compiler en code natif
- Cela permettait de rester dans le contenu web, d’utiliser les API web existantes, sans sandbox distincte, sans IPC ni API alternative
- asm.js a été intégré à Firefox 22 en 2013, permettant à des projets comme Unity et Unreal de déployer sur le web des bases de code C/C++ en utilisant uniquement des technologies web standard
- La démo Epic Citadel a été portée sur le web en 4 jours
- asm.js a démontré qu’il était possible, avec les seules technologies web, d’exécuter du code à une vitesse presque native, ouvrant ensuite la voie à WebAssembly
- Quelques années plus tard, WebAssembly a été intégré à Firefox 52, et il est fort possible que WebAssembly n’aurait pas existé sans asm.js
- Le compilateur asm.js s’appelait OdinMonkey, et sa suppression est suivie dans le bug Ragnarök sous le nom de « Twilight of OdinMonkey »
- BaldrMonkey, né d’OdinMonkey, est le compilateur d’optimisation WebAssembly
- RabaldrMonkey est le compilateur baseline WebAssembly
- Après 13 ans de service, OdinMonkey entre dans sa phase de retrait
1 commentaires
Réactions sur Hacker News
asm.js était la réponse de Mozilla à la question posée par NaCl et PNaCl : « comment exécuter du code à vitesse native sur le web ? »
Si cela se produisait aujourd’hui, Chrome aurait probablement simplement imposé NaCl et PNaCl, et tout le monde se serait plaint que Safari et Firefox n’arrivaient pas à suivre les standards du « web »
Pendant un temps, j’ai sérieusement cru qu’on ferait tout dans le navigateur. D’une certaine façon, on s’en rapproche de plus en plus, mais le ressenti global est pire que jamais. J’aime WASM et j’ai envie de l’aimer, mais la vitesse de maturation de l’écosystème est incroyablement mauvaise
Le pire, c’est qu’on a besoin d’outils d’IA peu fiables et qu’on doit exécuter directement leurs sorties dans ce genre de sandbox, alors que les entreprises vendent exactement l’inverse : des sandboxes hébergées et des VM JavaScript hébergées
Au final, on dirait que le problème a toujours été le même. Il n’y avait pas d’argent dans les sandboxes côté client
En interne, c’était utile pour sandboxer le lecteur Flash, mais les limites de l’approche basée sur LLVM sont vite devenues évidentes pour toutes les personnes impliquées
Si je me souviens bien, une grande partie de l’échec venait du fait que NaCl était une technologie trop « grosse » et asm.js trop « petite », si bien qu’asm.js, bien que lancé plusieurs années plus tard, est arrivé en production avant
Cela dit, Apple semble avoir accru ses investissements dans WebKit pendant cette décennie, après que les problèmes réglementaires sont devenus sérieux, donc aujourd’hui le résultat pourrait être différent
C’est pour ça qu’il y avait moins de plaintes à l’époque, et qu’aujourd’hui on se plaint des choses que Safari ne fait pas parce qu’elles nuisent à l’App Store. Heureusement, l’UE essaie maintenant de remettre un peu Apple dans le droit chemin
C’est triste, mais compréhensible. Fait amusant, Figma a démarré à l’origine avec une base de code entièrement en C++, et asm.js a été crucial pour prouver qu’on pouvait faire tourner un outil de design dans le navigateur
Le passage à WebAssembly n’est venu qu’après l’arrivée des clients payants, et le gain sur les temps de chargement a été assez important. asm.js reste du JS, donc les bundles sont plus volumineux et le code doit être parsé en AST, alors que WASM n’a pas ce problème
C’est un peu comme être triste parce qu’on abandonne le support de i386-unknown-freebsd1
Est-ce que la mort d’asm.js est arrivée ? On s’éloigne de la timeline prophétique
https://www.destroyallsoftware.com/talks/the-birth-and-death...
Fortement recommandé si vous ne l’avez jamais vu. Selon votre définition de « meilleur », c’est peut-être la meilleure conférence tech de tous les temps
Un jour, une fois la période de guerre passée et l’attachement psychologique aux vieux paradigmes de programmation dissipé, on passera à quelque chose de plus avancé. Bien sûr, cela n’empêchera pas votre banque de continuer à faire tourner YavaScript pendant au moins 85 ans
Je n’oublierai jamais le moment où j’ai vu la conférence de Gary Bernhardt sur JavaScript.[0] C’est là que j’ai découvert asm.js pour la première fois, et que je suis tombé dans le terrier du lapin de la compilation de code pour l’exécuter dans le navigateur
Douze ans plus tard, je suis frappé par le nombre d’éléments de sa fiction devenus réalité
[0] https://www.destroyallsoftware.com/talks/the-birth-and-death...
Quand j’ai vu cette conférence pour la première fois, j’étais stagiaire, et mon entreprise développait elle-même l’intégralité du compilateur, de l’IDE et du débogueur pour de petits boîtiers d’IO industriels. Le compilateur était écrit en C, converti en JS avec Emscripten, puis « compilé » avec la partie IDE et débogueur en un énorme fichier HTML — en réalité, surtout concaténé. L’upload du code et le débogage se faisaient via Ethernet, le tout poussé avec Ajax
Ça ressemble à une architecture maudite, mais les clients adoraient. Comme ce n’était pas un EXE, ça ne se faisait pas bloquer par les filtres IT d’entreprise excessifs chez les clients. C’est pour ça qu’on n’est pas passés à Electron. D’une certaine manière, on avait déjà des éléments primitifs de thick app
Il y a longtemps, j’ai écrit un petit chapitre sur asm.js dans un livre sur WebGL
https://webglinsights.github.io/
Voir l’essor d’asm.js, précurseur de WebAssembly, était enthousiasmant. Parmi les premières démos, il y avait des choses vraiment impressionnantes, comme Unreal Engine tournant dans le navigateur. C’est un peu amer de voir le soleil se coucher là-dessus, mais cela a conduit à quelque chose de bien meilleur
Il faudrait peut-être un transpileur d’asm.js vers WASM
Compiler du code legacy avec une vieille version d’Emscripten est assez frustrant. Parfois, c’est presque aussi pénible que de mettre à jour du code JS pour suivre l’accumulation des changements d’ABI d’Emscripten
Au moins, même si les optimisations asm.js sont désactivées, le code asm.js continuera de fonctionner, mais un convertisseur serait appréciable
asm.js est mort ! Vive WebAssembly !
Personnellement, je pense que cette décision est une erreur. Cela dit, je ne sais pas quel sera l’impact réel. À ma connaissance, il n’y a plus énormément de monde qui utilise asm.js
Mais wasm est trop isolé de JavaScript. Après l’avoir utilisé de façon limitée, je me suis dit que je ferais peut-être mieux de compiler vers asm.js
Je ne savais même pas si Emscripten le prenait encore totalement en charge
Avec wasm, on ne peut pas appeler directement la plupart des API web
Et, dans mon cas, plus important encore, on ne peut pas passer de buffer zéro copie de JS vers wasm
Tout est affaire de compromis. L’isolation est un avantage, mais aussi un inconvénient
Alors qu’aujourd’hui wasm a des types GC et peut même conserver des valeurs JS via
externrefasm.js ne permettrait probablement pas non plus les buffers zéro copie. Côté wasm, il existe une proposition à ce sujet : https://github.com/WebAssembly/memory-control/blob/main/prop...
Même en asm.js strict, on ne peut pas appeler directement la plupart des API web. Seuls les nombres sont supportés, pas les chaînes ou objets JS, et le tas C est géré dans un objet ArrayBuffer, comme avec WASM
Même problème pour les buffers zéro copie. Il faut sortir d’asm.js vers le « vrai » JavaScript pour appeler quoi que ce soit, et comme on ne peut pas mapper directement un autre ArrayBuffer dans le tas asm.js, il faut copier. La « JavaScript FFI » n’est en pratique pas très différente entre asm.js et WASM
Je me souviens du moment où Mozilla a dévoilé OdinMonkey, extrêmement spécialisé pour le code asm.js. L’équipe Chrome/V8, elle, s’est plutôt concentrée sur des optimisations JIT génériques capables d’accélérer le JavaScript ordinaire tout en bénéficiant aussi à asm.js
L’écart de performances donnait Firefox gagnant par un facteur de 2 à 4, et ils l’avaient largement mis en avant :D
Aujourd’hui, la plupart des VM JavaScript des navigateurs ont convergé vers des conceptions et optimisations très similaires, donc même sans Odin, le code asm.js s’exécuterait probablement assez vite de toute façon
Mon projet de générer du code JS à l’exécution pour accélérer des algorithmes est mort. Ça a l’air bien plus compliqué de faire ça avec wasm
Il existe une petite bibliothèque qui gère une bonne partie de ce travail pour les tests : https://searchfox.org/firefox-main/source/js/src/jit-test/li...
En JS, ce sera probablement https://www.npmjs.com/package/binaryen
https://www.assemblyscript.org/
Il ne sera simplement plus parsé ni exécuté aussi vite qu’avec un pipeline dédié à asm.js. Sauf pour une application vraiment énorme, je doute qu’on sente beaucoup la différence