Deaktivieren von JIT in Safari 6 zur Umgehung schwerwiegender Javascript-JIT-Fehler

Wir haben ein schwerwiegendes Problem bei der Interpretation unseres Javascript-Codes festgestellt, das nur unter iOS 5 / Safari 6 (damals aktuelles iPad-Release) auftritt und unseres Erachtens auf einen kritischen Fehler im Just in Time JS-Compiler in Safari zurückzuführen ist. (SehenAktualisierung unten finden Sie weitere betroffene Versionen und Versionen, die anscheinend jetzt einen Fix enthalten).

Wir haben das Problem ursprünglich in unserem Online-Shop gefundenDemos unserer Bibliothek: Die Demos stürzen mehr oder weniger zufällig ab, dies geschieht jedoch erst zum zweiten Mal (oder sogar später), wenn derselbe Code ausgeführt wird. Das heißt Wenn Sie den Teil des Codes einmal ausführen, funktioniert alles in Ordnung, jedoch stürzen nachfolgende Ausführungen die Anwendung ab.

Interessanterweise wird das Problem nicht angezeigt, wenn derselbe Code in Chrome für iOS ausgeführt wird. Dies liegt unserer Ansicht nach an den fehlenden JIT-Funktionen von Webview, das in Chrome für iOS verwendet wird.

Nach einigem Hin und Her glauben wir endlich, dass wir mindestens ein problematisches Stück Code gefunden haben:

  var a = 0; // counter for index
  for (var b = this.getStart(); b !== null; b = b.getNext()) // iterate over all cells
    b.$f = a++; // assign index to cell and then increment 

Im Wesentlichen ist dies eine einfache for-Schleife, die jeder Zelle in einer verknüpften Listendatenstruktur ihren Index zuweist. Das Problem hierbei ist die Nachinkrementierungsoperation im Schleifenkörper. Die aktuelle Anzahl wird dem Feld zugewiesen und aktualisiert, nachdem der Ausdruck ausgewertet wurde. Dies entspricht im Grunde dem Zuweisen eines und anschließenden Inkrementieren um eins.

Dies funktioniert in allen Browsern, die wir das erste Mal getestet haben, und in Safari. Dann sieht es plötzlich so aus, als würde zuerst die Zählervariable a inkrementiert und dann das Ergebnis zugewiesen, wie bei einer Vorinkrementierungsoperation.

Ich habe eine Geige erstellt, die das Problem hier zeigt:http://jsfiddle.net/yGuy/L6t5G/

Wenn Sie das Beispiel auf einem iPad 2 mit iOS 6 und allen Updates ausführen, ist das Ergebnis für die ersten beiden Läufe in meinem Fall in Ordnung, und im dritten identischen Lauf wird dem letzten Element in der Liste plötzlich ein Wert zugewiesen, der um eins abweicht (die Ausgabe) Wenn Sie auf die Schaltfläche "Klick mich" klicken, ändert sich die Einstellung von "von 0 auf 500" in "von 0 auf 501".

Interessanterweise kann es passieren, dass beim Wechseln der Tabs oder wenn Sie etwas warten, die Ergebnisse für zwei oder mehr Läufe plötzlich korrekt sind! Es scheint, als ob Safari manchmal JIT-Caches zurücksetzt.

Da ich der Meinung bin, dass es sehr lange dauern kann, bis das Safari-Team diesen Fehler behebt (den ich noch nicht gemeldet habe), und es möglicherweise andere ähnliche Fehler wie diesen gibt, die in der JIT lauern und die ebenso schwer zu finden sind, würde ich gerne Sie müssen wissen, ob es eine Möglichkeit gibt, die JIT-Funktionalität in Safari zu deaktivieren. Dies würde natürlich unseren Code verlangsamen (der bereits sehr rechenintensiv ist), aber langsamer als Abstürze.

Aktualisieren: Es ist nicht überraschend, dass nicht nur der Post-Inkrement-Operator betroffen ist, sondern auch der Post-Dekrement-Operator. Weniger überraschend und besorgniserregender ist, dass es keinen Unterschied macht, ob der Wert zugewiesen wird. Daher reicht es nicht aus, nach einer Zuweisung in vorhandenem Code zu suchen. Z.B. das folgende der Codeb.$f = (a++ % 2 == 0) ? 1 : 2; Wenn der Variablenwert nicht zugewiesen, sondern nur für die ternäre Operatorbedingung verwendet wird, "schlägt" dies auch in dem Sinne fehl, dass manchmal der falsche Zweig ausgewählt wird. Derzeit sieht es so aus, als ob das Problem nur vermieden werden kann, wenn die Postoperatoren überhaupt nicht verwendet werden.

Aktualisieren: Das gleiche Problem tritt nicht nur bei iOS-Geräten auf, sondernauch unter Mac OSX in Safari 6 und der neuesten Version von Safari 5: Diese wurden getestet und sind vom Fehler betroffen: Mac OS 10.7.4, Safari 5.1.7, Mac OS X 10.8.2, WebKit Nightly r132968: Safari 6.0.1 (8536.26. 14, 537+). Interessanterweise tun diesnicht scheinen betroffen zu sein: iPad 2 (Mobile) Safari 5.1.7 und iPad 1 Mobile Safari 5.1. Ich habe Apple über diese Probleme informiert, aber noch keine Antwort erhalten.

Aktualisieren: Der Fehler wurde als Webkit-Fehler gemeldet109036. Apple hat immer noch nicht auf meinen Fehlerbericht geantwortet. Alle aktuellen (Februar 2013) Safari-Versionen unter iOS und MacOS sind weiterhin von dem Problem betroffen.

Update 27. Februar 2013: Es scheint der Fehler gewesen zu seinFest vom Webkit-TeamHier! Es war in der Tat ein Problem mit der GEG und den Postbetreibern! Die Kommentare deuten darauf hin, dass möglicherweise mehr Code von dem Fehler betroffen ist, sodass möglicherweise mysteriösere Heisenbugs behoben wurden!

Update Oktober 2013: Das Update hat es endlich in den Produktionscode geschafft: iOS 7.0.2 scheint zumindest auf iPad2 nicht mehr unter diesem Fehler zu leiden. Ich habe jedoch nicht alle Zwischenversionen überprüft, da wir das Problem vor langer Zeit behoben haben.

Antworten auf die Frage(3)

Ihre Antwort auf die Frage