Le 11-05-15 23:36 , Marc Feeley a écrit :
This weekend I improved my prototype compiler which compiles JS to x86, using the global property jump optimization. The compiler is rather minimal and handles just enough to compile fib and similar simple code.
This prototype is mainly useful to explore various implementation approaches quickly, without the burden of the complete Tachyon compiler.
I would be interested in using it too, is it in scheme? Could you put it in our private repository?
The results are very good. On fib(40), proto2 generate faster code than V8 (1.5x) and SpiderMonkey (2.3x), and Tachyon (18x). There is a 1.2x difference between proto1 and proto2 (in other words, there is a 20% overhead to setup and check argument counts). Here are the detailed running times:
relative time to proto2
Tachyon 29.613 (18.3) SM 3.700 ( 2.3) V8 2.397 ( 1.5) proto1 2.000 ( 1.2) proto2 1.614 ( 1.0)
Those are great news, how does that compare to gcc?
If you have any questions please let me know.
You did not show how to handle closures. We would need to store the function object pointer in addition to the entry point of the code at the call site. It should only need a little modification of the patching code.
Also, what if the code or the function object is moved by the GC? Should we invalidate all the call site caches or should we patch them with the new addresses?
I could see a similar mecanism used to lazily compile functions. The function could be stored in an AST, HIR or string representation. When jumping to the function the first time, the compiler would first compile the function and then replace the entry point in the function object by the compiled code. This would be complimentary to the global call optimization by delaying the global function call site patching until the entry point of the compiled code is known.
Here's a question for Maxime and Erick... can you estimate the work needed to get Tachyon to generate similar x86 code?
Marc
To follow your current design, we could introduce a global function call instruction in the IR that would take a string property, a this object and the arguments (instead of the function object, the this object and the arguments for a regular CallInstr). This part should be simple.
Additionnally, we would need to modify the global object layout to have a pointer to the call site list in addition to the value of a property. Again, that should be simple with the layout system.
The tricky part, I think, is how to implement the different handlers. I would try to separate the implementation of those such that: 1. The layout of the call sites is known only to the backend 2. The patching code is done by the backend, including the list traversal to invalidate the call sites 3. The global object layout and property lookup is implemented using the layout and primitive system
I would guess it could be done in a couple of days.
Erick