On 2011-02-19, at 12:03 PM, chevalma@iro.umontreal.ca wrote:
- 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?
The slots in the context that are accessed frequently should be in the L1 cache (and the probability of this being true will increase if we put all of the frequently accessed ones close together so they fall into the same cache line). The allocation pointer (if not in a register), the argument count (if not in a register), the stack limit pointer, the global object, are probably the most frequently accessed and should be close together. So wether the value is taken from the cached code stream, or the cached context will not matter much for the actual data transfer. However, if the code is more compact it will increase the likelihood that all of the hot parts of the code will be in a cache close to the CPU. But when I say it is "perhaps just as fast", I concede that it will have to be tested to see how the different factors impact the performance.
- 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.
Well... "after the bootstrap" is going to be in a few days right? ;-)
Marc