Abschied von asm.js
(spidermonkey.dev)- Ab Firefox 148 ist die asm.js-Optimierung von SpiderMonkey standardmäßig deaktiviert, und der zugehörige Code soll in künftigen Releases entfernt werden
- asm.js ist eine Teilmenge von JavaScript, daher funktionieren bestehende Websites weiterhin, laufen aber über den normalen JIT-Pfad, wodurch die Optimierungsvorteile entfallen
- Wenn asm.js-Inhalte zu WebAssembly neu kompiliert werden, sind schnellere Ausführung und kleinere Binärdateien möglich
- Gegenüber NaCl·PNaCl machte asm.js eine nahezu native Ausführung innerhalb von Web-Inhalten möglich, ganz ohne separate Sandbox oder alternative APIs
- OdinMonkey, eingeführt 2013 in Firefox 22, ermöglichte Web-Deployments von C/C++-Projekten wie Unity und Unreal und legte die Grundlage für WebAssembly
Deaktivierung der asm.js-Optimierung
- Seit Firefox 148 ist die asm.js-Optimierung von SpiderMonkey standardmäßig deaktiviert, und in einer kommenden Version soll der gesamte zugehörige Code entfernt werden
- Websites, die asm.js verwenden, funktionieren weiterhin
- asm.js ist eine Teilmenge von normalem JavaScript, daher wird bestehender Code wie andere Skripte über den normalen JIT-Pfad ausgeführt
- Allerdings entfallen die Vorteile der asm.js-spezifischen Optimierung
- Wenn weiterhin asm.js-Inhalte ausgeliefert werden, wird empfohlen, sie zu WebAssembly neu zu kompilieren
- Durch eine Neukompilierung zu WebAssembly sind schnellere Ausführung und kleinere Binärdateien möglich
- Die WebAssembly-Pipeline von SpiderMonkey ist deutlich weiter entwickelt als die asm.js-Pipeline
- Da WebAssembly erfolgreich ist und der Großteil der asm.js-Nutzung bereits migriert wurde, steigen die Kosten, beide Pfade parallel zu pflegen
- Es ist weiterhin Wartungsaufwand nötig
- Im VM bleibt zusätzliche Angriffsfläche bestehen
Die Rolle von asm.js und das Ende von OdinMonkey
- asm.js war Mozillas Antwort auf die von NaCl und PNaCl aufgeworfene Frage: „Kann Code im Web mit nativer Geschwindigkeit ausgeführt werden?“
- Dafür wurde eine strikte, statisch typisierte Teilmenge von JavaScript gewählt, die die Engine sofort erkennen und zu nativem Code kompilieren konnte
- So blieb alles innerhalb von Web-Inhalten, ohne separate Sandbox, IPC oder alternative APIs, und vorhandene Web-APIs konnten weiter genutzt werden
- asm.js wurde 2013 in Firefox 22 aufgenommen und ermöglichte Projekten wie Unity und Unreal, C/C++-Codebasen ausschließlich mit standardisierten Web-Technologien ins Web zu bringen
- Die Epic Citadel demo wurde in nur 4 Tagen ins Web portiert
- asm.js bewies, dass sich mit Web-Technologien allein Code mit nahezu nativer Geschwindigkeit ausführen lässt, und ebnete damit den Weg für WebAssembly
- WebAssembly wurde einige Jahre später in Firefox 52 aufgenommen; ohne asm.js hätte es WebAssembly wahrscheinlich nicht gegeben
- Der asm.js-Compiler hieß OdinMonkey, und seine Entfernung wird im Ragnarök-Bug unter dem Titel „Twilight of OdinMonkey“ verfolgt
- BaldrMonkey, hervorgegangen aus OdinMonkey, ist der optimierende Compiler für WebAssembly
- RabaldrMonkey ist der Baseline-Compiler für WebAssembly
- Nach 13 Jahren geht OdinMonkey nun seinem Ende entgegen
1 Kommentare
Hacker-News-Kommentare
asm.js war Mozillas Antwort auf die von NaCl und PNaCl aufgeworfene Frage: „Wie führt man Code im Web mit nativer Geschwindigkeit aus?“
Wenn das heute passieren würde, hätte Chrome NaCl und PNaCl wohl einfach durchgedrückt, und dann hätten sich alle darüber beschwert, warum Safari und Firefox den „Web“-Standards nicht folgen
Eine Zeit lang dachte ich ernsthaft, wir würden alles im Browser erledigen. In gewisser Weise entwickelt es sich auch in diese Richtung, aber das Gesamterlebnis fühlt sich schlechter an als je zuvor. Ich mag WASM und möchte es mögen, aber wie langsam das Ökosystem reift, ist kaum zu glauben.
Noch schlimmer ist, dass wir unzuverlässige AI-Tools und ihre Ausgaben genau in so einer Sandbox ausführen müssten, während Unternehmen stattdessen gehostete Sandboxes und gehostete JS-basierte VMs verkaufen.
Am Ende war es wohl immer dasselbe Problem. Mit clientseitigen Sandboxes ließ sich kein Geld verdienen
Intern war es nützlich, um den Flash-Player zu sandboxen, aber die Grenzen des LLVM-basierten Ansatzes wurden bald allen Beteiligten klar
Wenn ich mich richtig erinnere, war ein Hauptgrund für das Scheitern, dass NaCl eine zu „große“ Technologie und asm.js eine zu „kleine“ Technologie war, sodass asm.js trotz eines um mehrere Jahre späteren Starts zuerst produktionsreif wurde
Allerdings scheint Apple seit dem Beginn ernsthafter Regulierung in diesem Jahrzehnt die WebKit-Investitionen erhöht zu haben, daher könnte das Ergebnis heute anders ausfallen
Deshalb gab es damals weniger Beschwerden, und heute beschwert man sich über Dinge, die Safari nicht macht, weil sie dem App Store schaden würden. Zum Glück versucht die EU inzwischen, Apple in dieser Hinsicht etwas geradezurücken
Traurig, aber nachvollziehbar. Eine interessante Tatsache ist, dass Figma ursprünglich mit einer vollständigen C++-Codebasis gestartet ist und asm.js der Schlüsselbeweis dafür war, dass ein Design-Tool im Browser laufen kann.
Auf WebAssembly umgestellt hat man erst, nachdem es zahlende Kunden gab, und die Verbesserung der Ladezeiten war ziemlich groß. asm.js ist immer noch JS, daher ist das Bundle größer und der Code muss als AST geparst werden, bei WASM ist das nicht so
So ähnlich, wie traurig zu sein, weil die Unterstützung für i386-unknown-freebsd1 weggefallen ist
Ist jetzt also der Tod von asm.js gekommen? Wir entfernen uns von der prophetischen Zeitlinie.
https://www.destroyallsoftware.com/talks/the-birth-and-death...
Falls du es noch nicht gesehen hast: absolute Empfehlung. Je nachdem, wie man „das Beste“ definiert, könnte es der beste Tech-Vortrag aller Zeiten sein
Irgendwann, nach einer Zeit des Krieges und nachdem sich die psychologische Fixierung auf veraltete Programmierparadigmen gelöst hat, könnten wir zu fortschrittlicheren Ansätzen übergehen. Das heißt natürlich nicht, dass deine Bank in den nächsten mindestens 85 Jahren kein YavaScript mehr ausführen wird
Ich werde nie den Moment vergessen, als ich Gary Bernhardts JavaScript-Vortrag gesehen habe.[0] Damals habe ich zum ersten Mal von asm.js erfahren und bin in den Kaninchenbau des Kompilierens von Code zur Ausführung im Browser gefallen.
12 Jahre später erstaunt es mich, wie viel von seiner Fiktion Realität geworden ist.
[0] https://www.destroyallsoftware.com/talks/the-birth-and-death...
Als ich den Vortrag zum ersten Mal sah, war ich Praktikant, und mein Unternehmen baute Compiler, IDE und Debugger komplett selbst für kleine industrielle IO-Boxen. Der Compiler war in C geschrieben, wurde mit Emscripten in JS umgewandelt und dann zusammen mit IDE- und Debugger-Teilen in eine riesige HTML-Datei „kompiliert“ — eigentlich eher zusammengeklebt. Code-Upload und Debugging liefen über Ethernet, und alles wurde per Ajax hineingeschoben.
Das klingt nach einer verfluchten Architektur, aber die Kunden liebten es. Es war keine EXE und blieb daher nicht in den überzogenen Unternehmens-IT-Filtern der Kunden hängen. Deshalb sind wir nicht auf Electron umgestiegen. In gewisser Weise hatte es also primitive Elemente einer Thick App
Vor langer Zeit habe ich in einem WebGL-Buch ein kleines Kapitel über asm.js geschrieben.
https://webglinsights.github.io/
Es war spannend, den Aufstieg von asm.js zu beobachten, dem Vorläufer von WebAssembly. Unter den frühen Demos waren wirklich beeindruckende Dinge, etwa Unreal Engine, das im Browser lief. Es ist bittersüß, hier den Sonnenuntergang zu sehen, aber daraus ist viel Besseres entstanden
Vielleicht braucht es einen Transpiler von asm.js nach WASM.
Legacy-Code mit alten Emscripten-Versionen zu kompilieren ist ziemlich frustrierend. Manchmal ist es fast genauso schmerzhaft, den JS-Code an die über die Jahre aufgelaufenen ABI-Änderungen von Emscripten anzupassen
Zumindest wird asm.js-Code weiter funktionieren, selbst wenn asm.js-Optimierungen abgeschaltet sind, aber ein Konverter wäre schön
asm.js ist tot! Lang lebe WebAssembly!
Ich persönlich halte diese Entscheidung für einen Fehler. Wie groß die realen Auswirkungen sein werden, weiß ich allerdings nicht. Meines Wissens nutzen ohnehin nicht mehr viele Leute asm.js.
Aber wasm ist viel zu stark von JavaScript isoliert. Nachdem ich es nur begrenzt ausprobiert habe, dachte ich mir eher, ich sollte vielleicht lieber nach asm.js kompilieren.
Ich war mir nicht einmal sicher, ob Emscripten das noch vollständig unterstützt.
In wasm kann man die meisten Web-APIs nicht aufrufen.
Für das, was ich machen wollte, war noch wichtiger, dass man von JS aus keine Zero-Copy-Buffer an wasm übergeben kann.
Alles ist ein Kompromiss. Die Isolation ist ein Vorteil, aber eben auch ein Nachteil
Modernes wasm hat dagegen GC-Typen, und mit externref kann man auch JS-Werte festhalten.
Zero-Copy-Buffer gehen in asm.js wahrscheinlich ebenfalls nicht. Auf der wasm-Seite gibt es einen Vorschlag für Zero-Copy-Buffer: https://github.com/WebAssembly/memory-control/blob/main/prop...
Selbst in strengem asm.js kann man die meisten Web-APIs nicht direkt aufrufen. Es unterstützt nur Zahlen, keine JS-Strings oder -Objekte, und verwaltet den C-Heap wie WASM innerhalb eines ArrayBuffer-Objekts.
Bei Zero-Copy-Buffern ist es dasselbe Problem. Man muss aus asm.js in „echtes“ JavaScript herausspringen, um den Aufruf zu machen, und man kann einen anderen ArrayBuffer auch nicht direkt in den asm.js-Heap einblenden, daher ist Kopieren erforderlich. Die „JavaScript-FFI“ unterscheidet sich zwischen asm.js und WASM praktisch nicht stark
Ich erinnere mich, als Mozilla OdinMonkey veröffentlichte, das extrem stark auf asm.js-Code spezialisiert war. Das Chrome-/V8-Team konzentrierte sich stattdessen auf allgemeine JIT-Optimierungen, die normales JavaScript schneller machen und dabei auch asm.js helfen würden.
Der Geschwindigkeitsunterschied sprach mit dem Faktor 2 bis 4 für Firefox, und das wurde ziemlich offensiv beworben :D
Heutzutage haben sich die meisten JavaScript-VMs in Browsern auf sehr ähnliche Designs und Optimierungen angenähert, daher würde asm.js-Code wohl auch ohne Odin ohnehin ziemlich schnell laufen
Damit ist mein Plan dahin, zur Laufzeit JS-Code zu erzeugen, um Algorithmen schneller zu machen. Mit wasm dürfte das deutlich schwieriger sein
Für Tests gibt es eine kleine Bibliothek, die einen großen Teil davon übernimmt: https://searchfox.org/firefox-main/source/js/src/jit-test/li...
In JS wahrscheinlich https://www.npmjs.com/package/binaryen
https://www.assemblyscript.org/
Er wird nur nicht so schnell geparst oder ausgeführt wie mit einer asm.js-spezifischen Pipeline. Wenn es keine riesige Anwendung ist, wird man den Unterschied wahrscheinlich kaum bemerken