> > Actually, I _was_ saying we shouldn't do caller-save (except > > possibly for a small number of registers designated for the > > purpose). > > Remember that the caller only has to save the stuff that is important > to it, after all, anything that might be of importance to *its* > callers will already have been saved. If the callee saves then it's > going to be doing belt and braces save/restores on registers that may > be completely irrelevant.
I'm not familiar with current literature on the subject, so it's possible that the ideas I'm about to suggest haven't been previously suggested for a very good reason. Hopefully no one will mind. :) In each function, store a list of the registers it uses as a bistring. Should be four integers per function for the four register sets. We store four integers in the interpter, consisting of what has been used in the call stack up until this point. When we call function A, we AND it's used bits with the call stack used bits. Then we go through them, pushing only those values onto the stack for which the corresponding bits are on. Might cause worse performance in some situations, but would be pushing/popping less overall. Not sure if the time spent iterating through the bits would screw up any speed benefit, however. Another idea is to store a list of register frames, which don't get GC'ed out from under us. Every time a function is called, instead of memcpy'ing the current register frame, we merely adjust the pointer farther down the list. Upon returning from a function, we move the pointer back up to the previous register frame. Not sure how this will interact with the GC system, such that a highly-recursive function doesn't cause a bunch of memory to get stuck hanging around, while not freeing memory as soon as we return from a function (since it's very useful for the next time we enter any function) It makes function calls as simple as a couple pointer updates (unless we have to create a register frame, a one-time expense), at the expense of possibly hurting cache coherency. Tail-recursion calls would just leave the current register frame on the stack. Not sure how it would interact with continuations. Just some random, hopefully helpful, ideas. Mike Lambert