JavaScript runs at the reference browser's speed on 41 of our 42 measured workloads
The biggest JavaScript speed release so far. On the 42 workloads we measure against the reference browser's own engine, 41 now run at or near its speed (our measured score is 99.4 out of 100): function calls, recursion over trees, for-in loops, object fields, building objects and plain loops all got faster, often several times over. A long loop in a function that has only just become busy now switches to compiled code while it runs, objects take less memory, and several JavaScript rules now work exactly as in the reference browser.
Nearly everything at the reference browser's speed. We time 42 everyday JavaScript workloads in Floati and in the reference browser's engine on the same machine. 41 of them now run within twice the reference browser's time or faster, and across all 42 Floati averages 0.84 of the reference browser's time. The one left, a virtual DOM benchmark that builds and compares big trees of objects, is 4.4 times the reference browser's time and is what we are working on next.
JavaScript & JIT
Long loops speed up while they run. Floati compiles a function to machine code once it has run a few times, but a function that runs only a handful of times with one very long loop used to finish that loop slowly. Now a loop that keeps going switches to compiled code in the middle of the run (on-stack replacement): about 3.8 times faster on such loops.
Memory & reading
Recursive functions call themselves faster. A compiled function that calls itself now passes its arguments in machine registers instead of building a full call record in memory, borrows the caller's values instead of copying references, and answers simple base cases (like a leaf of a tree) right at the call site without making the call at all. Tree walkers run about a third faster on leaf-heavy trees.
JavaScript & JIT
for-in loops, object fields and global names are compiled. Listing an object's keys, checking a key is still there, reading a field at a known position, reading a global name, reading Math and building text with + all run as machine code now, where they used to go back to slower general code on every use.
Memory & reading
Objects are smaller and cheaper to build. An object's property names now live once in its shape (the layout shared by all objects built the same way) instead of in every object, and an object literal's values sit in the same piece of memory as the object itself: one allocation instead of two. Closures made inside loops no longer keep scopes they cannot see alive: peak memory on our closures benchmark went from 690 to 54 megabytes.
Memory & reading
Loops keep their variables in the processor. In a compiled function that makes no calls, local variables now stay in machine registers instead of memory between uses: such loops run 15 to 18 percent faster.
JavaScript & JIT
JavaScript rules that now match the reference browser. Assigning to an undeclared name in strict code throws; frozen and read only objects refuse writes in every tier; Object.assign runs getters and setters; undefined, NaN and Infinity can no longer be overwritten; a property that holds undefined hides the prototype's value; and a round of regular expression, Proxy, Reflect and Date details were corrected against the reference browser.