4 ms·
It's not low-hanging fruit at all. First, making it fast is extremely difficult. JavaScript compilers are under extreme pressure to compile code quickly, unlik
by ootachi 15y ago
It's not low-hanging fruit at all.
First, making it fast is extremely difficult. JavaScript compilers are under extreme pressure to compile code quickly, unlike any other type-inferring compiler, because JS compilation keeps the user from seeing the page.
Second, in order to be useful, type inference for JavaScript has to be speculative. JS's semantics require that ints overflow into doubles, for example, meaning that a conservative type inference engine would have to assume every number can potentially be a double. This is too imprecise to be useful, so the inference engine speculates. If the engine guesses wrong, the compiler must not only recompile the function under the new assumptions but also (since this is a global analysis) potentially update every other function that the function called.
Finally, the presence of eval() and the like mean that almost no inference can be totally sound, requiring even more dynamic checks.
There's a reason that (despite what some others are saying in this thread) V8 and Chakra haven't done this yet: it takes a long time to get right.
- masklinn 15y agoOn the other hand, most of the dynamic checks (type assertion barriers) will be there anyway as the JIT-generated code needs them (for type-specialized traces). Static type inference may even allow for doing away with some, if it's possible to statically prove types are fully known at compile time for a code section.
- seanalltogether 15y agoYeah the biggest problem is that there are millions of pre-existing codebases all over the web that mozilla needs to make sure don't break. Since it is a speculative engine, the possibility of breaking even a small percentage of those codebases becomes very likely, so it's really not an easy thing to do. I'll be curious if it's good enough to enable by default, or if the developer needs to flag the engine somehow to enable the feature.
- rpearl 15y agoSince this type inference is speculative and dynamic, if the speculative type optimizations fail you can fall back to less optimized code, or interpreted JS, that handles the badly-typed code. Nothing will break.
- ori_b 15y ago> JavaScript compilers are under extreme pressure to compile code quickly, unlike any other type-inferring compiler, because JS compilation keeps the user from seeing the page You only run type inference after you detect the hot loops. Same with other expensive optimizations. This is something that all JITs out there do -- you start with simple interpretation (or extremely cheap compilation, in the case of V8), and then when you detect that you're spending a whole lot of time in one section of code, you replace it with a highly optimized version. Type inference is not that expensive compared to several more interesting optimizations done on several JITs that are in production systems. In some long running JITs, the compilation of some hot loops takes far longer than static compilations, running in a low priority thread in the background (while the less optimized code keeps going in the foreground). Finally, if anything, JITs allow more time to run heavy optimizations because they can leave those running in the background without affecting the use of the program or hurting developer productivity. > JS's semantics require that ints overflow into doubles, for example On recent x86 processors, you would just use doubles in most cases. It turns out that they're on par with integers for speed, although I believe there were some differences on latency. I'd have to look back at the Intel opt manual to confirm, though. However, if you really want to solve the issue (say, on ARM where integer/float performance actually matters -- especially since lots of architectures are still on softfloat), then you'd use a combination of guards, versioning, and VRP to solve the issue, not type inference. > Finally, the presence of eval() and the like mean that almost no inference can be totally sound, requiring even more dynamic checks. Yep, eval is a terrible language feature if you care about making things fast. Regardless of whether you have type inference or not.
- azakai 15y ago> You only run type inference after you detect the hot loops. That is the traditional approach, yes. But it will only get you so far. If you just analyze the current piece of code, you will miss out on a lot of potential optimizations. For example, the types of the variables in the current function may be always of the same type, but without analyzing all the callers you wouldn't notice that - which means you would need to check the type each time you enter. With a more global analysis you could detect that once and be much faster. There are a lot of other optimizations of that sort, like global variables - you can prove statically the type of many of them, just by looking in the whole program. What is cool about this new Type Inference engine is that it is a hybrid approach. It does both local and global, and both static and dynamic analyses. You are very correct that local/dynamic type inference is a known thing, and JITs like TraceMonkey have done a form of it for a long time. But this new engine is something much better.