Disabling JIT in Safari 6 to workaround severe Javascript JIT bugs

后端 未结 3 1620
既然无缘
既然无缘 2021-02-05 06:56

We found a severe problem with the interpretation of our Javascript code that only occurs on iOS 5/Safari 6 (then current iPad release) that we think is due to critical bug in t

相关标签:
3条回答
  • 2021-02-05 07:10

    Actually, the FOR loop bug is still present in Safari on iOS 7.0.4 in iPhone 4 and iPad 2. The loop failing can be significantly simpler than the illustration above, and it rakes several passes through the code to hit. Changing to a WHILE loop allows proper execution.

    Failing code:

    function zf(num,digs) 
    { 
    var out = ""; 
    var n = Math.abs(num); 
    for (digs;  digs>0||n>0; digs--)
    { 
        out = n%10 + out; 
        n = Math.floor(n/10); 
    }  
    return num<0?"-"+out:out; 
    } 
    

    Successful code:

    function zf(num,digs) 
    { 
    var out = ""; 
    var n = Math.abs(num); 
    do 
    { 
        out = n%10 + out; 
        n = Math.floor(n/10); 
    } 
    while (--digs>0||n>0) 
    return num<0?"-"+out:out; 
    } 
    
    0 讨论(0)
  • 2021-02-05 07:16

    Try-catch blocks seem to disable the JIT compiler on Safari 6 on Lion for the part directly inside the try block (this code worked for me on Safari 6.0.1 7536.26.14 and OS X Lion).

    // test function
    utility.test = function(){
        try {
            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
        }
        catch (e) { throw e }
        this.$f5 = !1; // random code
    };
    

    This is at least a documented behavior of the current version of Google's V8 (see the Google I/O presentation on V8), but I don't know for Safari.

    If you want to disable it for the whole script, one solution would be to compile your JS to wrap every function's content inside a try-catch with a tool such as burrito.

    Good job on making this reproducible!

    0 讨论(0)
  • 2021-02-05 07:16

    IMO, the correct solution is to report the bug to Apple, then workaround it in your code (surely using a separate a = a + 1; statement will work, unless the JIT is even worse than you thought!). It does indeed suck, though. Here's a list of common things you can also try throwing in to the function to make it de-optimise and not use JIT:

    • Exceptions
    • 'with' statement
    • using arguments object, e.g. arguments.callee
    • eval()

    The problem with those is if the Javascript engine is optimised to JIT them before they fix that bug, in which case you're back to crashing. So, report and workaround!

    0 讨论(0)
提交回复
热议问题