Am 08. Januar diesen Jahres hat Mozilla den Firefox 18 veröffentlicht. Einer der wichtigsten Neuerungen ist ein neuer JIT-Compiler für JavaScript, welcher vor allem größere JavaScript-Anwendungen beschleunigen soll. Der Name des JIT-Compilers IonMonkey ist dabei eine Anlehnung an SpiderMonkey, der JavaScript-Engine von Mozilla im Firefox.
Am Freitag wurden wir erstmalig darauf aufmerksam gemacht, dass es im aktuellen Firefox 18 ein Problem geben könnte: Unsere Webanwendung (das Frontend ist mit Ext JS entwickelt; also sehr, sehr JavaScript-lastig) schmeißt unregelmäßige JavaScript-Fehler, welche nicht deterministisch reproduzierbar waren. (Hin und wieder wird auch vom Firefox vorgeblich Flash als Fehlerursache genannt, das ist aber nicht korrekt.)
Eine kurze Recherche ergab schnell, dass es beim Hersteller (Sencha) des Frameworks bereits einen Forenthread gibt. Andere Entwickler und auch die Sencha-Entwickler selbst hatten das Problem bereits seit Mittwoch (also unmittelbar nach Release-Start) bemerkt und ähnliche Fehlermeldungen erhalten. Netterweise hatte bereits jemand einen Testcase entwickelt, der über die gleichen Merkmale und das selbe Fehlerverhalten verfügt.
Als Ursache für das Problem ist jedoch weder ein Bug in unserer Anwendung oder ein Bug im Framework, sondern vielmehr ein Engine-Bug im neuen JIT-Compiler von Mozilla. Den dazugehörigen Bugzilla-Eintrag #818023 kann man aktuell verfolgen, wie der Bug (hoffentlich bald) behoben wird. Zum Zeitpunkt dieses Blogbeitrags sind Regression-Tests nach dem Patch fehlgeschlagen, was dazu führt, dass es noch kein Update geben kann (automatischer Pull).
Da die Regression-Tests nach den Nightly-Builds gesehen, gibt es aktuell ein Nightly-Build von Samstag morgen, welches den ursprünglichen Patch beinhaltet. Die Download-Links zur einer Firefox 21 Nightly finden sich als Antwort im o.g. Bugzilla-Eintrag.
Sobald der Bug behoben wird, ist voraussichtlich geplant, den Bugfix auch auf die Versionen 18-20 einzuspielen. Das würde ein baldiges Update auf 18.0.1 bedeuten.
Technischer Hintergrund
Bröselt man die Fehlermeldung d.caller is undefined auf, dann wird klar, dass der Fehler im internen Komponenten-Modell von Sencha auftritt. d ist ein function-Object, das JavaScript-Attribut caller fügt die Engine hinzu, damit man Zugriff auf die aufgerufene Funktion hat. Und genau dies macht der JIT-Compiler nicht (und bricht damit die Spezifikation der Engine).
Lösungsmöglichkeiten
Workaround #1: Verwendeten Code patchen
Zunächst sei nochmals darauf hingewiesen, dass dieser Fehler in der Engine zu finden ist. Daher ist ein Patch grundsätzlich von Seite der Engine-Verwender (wir verwenden als Entwickler ja die Engine) schwer möglich. Im oben erwähnten Forenthread bei Sencha haben Entwickler herausgefunden, dass ein Block mit einem (leeren) try/catch angeblich hilft, da der JIT-Compiler wohl Objekte (etwa ein function body) mit try/catch-Blöcke anders optimiert. Ob dieser Patch wirklich das Problem vollständig behebt, kann zu diesem Zeitpunkt nicht garantiert werden (in Erinnerung: es gibt fehlgeschlagene Regression-Tests). Außerdem sei darauf hingewiesen, dass auch andere Webanwendungen das Problem haben können.
Dieser Workaround bekämpft nur ein Symptom, aber nicht die Ursache.
Workaround #2: JIT-Compiler IonMonkey deaktivieren
Um grundsätzlich das Problem bei gleichzeitiger Verwendung von Firefox 18 zu lösen, empfiehlt sich das Deaktivieren des JIT-Compilers.
Dazu musst man folgende Schritte befolgen:
- In einem neuen Tab die interne URL about:config öffnen.
- Die Sicherheitswarnung bestätigen.
- Den Schlüssel javascript.options.ion.content suchen. Dort sollte der Wert auf true stehen, der sollte auf false geändert werden (ein Doppelklick auf die Zeile).
- Browser neustarten.
Man verliert dadurch keine sichtbaren Features, das Verhalten ist damit dann ähnlich wie im Firefox 17 und vorher.
Workaround #3: Downgrade des Firefox, Update von 18 verhindern
Falls man die Möglichkeit hat, sollte man das Update auf 18 hinauszögern. Allerdings ist das aus Gründen der Auto-Update-Funktionalität nicht leicht zu bewerkstelligen.
Workaround #4: Anderen Browser verwenden.
Falls man die Möglichkeit hat, sollte man Problemapplikationen kurzfristig mit einem anderen Browser nutzen.
Update 18. Januar 2012: Mittlerweile ist Firefox 18.0.1 mit einem Patch verfügbar.