- What is the code before the "entry" label doing? It seems to be
testing that nbargs=2, and if nbargs<2 it fills in %edx and %ebx with the undefined value... but the function (as seen in the LIR) expects 0 arguments. So if nbargs>0 there is a simple adjustment to do to the stack (pop ra; sp+=nbargs*4; push ra). Note that the implicit parameter "this" does not count as an argument (it is always passed in the calling convention).
- The "ret $0" (3 bytes) is equivalent to "ret" (1 byte).
I guess you should bring this up at the meeting Wednesday. The return issue should be trivial to implement. The arguments one I don't know.
- The code will be more compact, and perhaps just as fast, if the
undefined value is stored in the context. That way the "movl $25,%eax" (5 bytes) can be replaced with "movl undef_offs(%ecx),%eax" (3 bytes). This trick can be used for other frequent constants (such as "true", "false", "null", 0, 1, 2). But there are better suggestions below...
Isn't moving data from the context to a register loading something from memory? How can that be faster than loading it directly from the (hopefully precached) code stream?
- Another trick which can reduce the code size and possibly improve speed
is to encode the special values ("true", "false", "null", "undefined", ...) using only the 8 low bits of a word (and with the two lowest bits equal to 01). The more significant bits, above the low 8 bits, can be any bit pattern because they ares never used in a test. So instead of "movl $25,%eax" (5 bytes) it would be sufficient to do "movb $25,%al" (2 bytes).
That should be feasible. As I keep saying, we need to keep a big TODO list of all the improvements we want to make after the bootstrap, and some kind of order of priority.
I have a list of improvements I want to make to the IR/front-end myself.
- Maxime