It's a very simple idea really. Where your bytecode would previously look like pushTemp: 1 pushTemp: 2 add now it looks like: add 1, 2, 3 where 3 is the start of your original stack, for example. So rather than pushing and popping etc, you just abstractly interpret the bytecodes and figure out the stack locations where they would be pushed. And then you use this number as arguments to a copy bytecode, rather than calling "push". This avoids having to maintain a stack where you up front already know what the target index will be. You know this up front since your code is static by itself. The advantage is that you don't need to do stack-tricks to keep data around, since all the operation are simple things such as copy, loadFromOuterScope, storeInOuterScope, loadFromField, storeInField, ... So conversely to what you might have thought beforehand, you don't have "real registers" around, you just consider a stackframe to be a set of registers. And you operate on them with easy bytecodes. The advantage, in addition to it being less work and thus slightly faster by itself, is that it will later on also map better on the real hardware. The operations already look like what normal assembler operations would look like. cheers, Toon On 03/22/2011 07:00 PM, Stéphane Ducasse wrote:
Can you explain rapidly register-case byte code?
Stef
On Mar 22, 2011, at 4:02 PM, Toon Verwaest wrote:
On 03/22/2011 04:52 PM, Alexandre Bergel wrote:
I am not saying that this is feasible with the current VM. But I am doubtful that the bytecode verification can only be done in the VM. If something get wrong, why not to raise a primitiveFailed, as 1/0 will do?
Because checking all these things at runtime will make interpretation slow. But could not it be at compile time?
I am not expert in VM. But something that I learnt from all over these years, is that if we copy what other people do, then we will just have a pale copy. Innovation begins by doing what other think it is impossible to do. Smalltalk has classes as object, whereas Java and C++ took a different stance. Smalltalk has the debugger and the profiler in the image; again, java people have a different opinion. Now, if someone say that bytecode verification can only be done in the VM, I am skeptic. Ok, I very much understand this point of view. That's exactly why I started Pinocchio.
I'm currently building my 4rd iteration. I started building a Smalltalk by having AST evaluation (actually I started out with self-evaluating AST objects that got evaluated by sending message... :D) . Then moved on to stack-based bytecodes. Then moved on to registered-based bytecodes (where I am now). All of my progress has been made by careful scrutinizing of the problems at hand. I did reevaluate and question all steps; and I'm a bit sad that I ended up doing it this way... But then I guess there is some inevitability in it.
For example the register-based bytecodes, I had no idea that what I was doing were register-based bytecodes until I read the Lua VM description and noticed that it was exactly the same.
However I do think that I learned a lot by doing it. I made the trade-offs myself and understand them a lot better than I did before. What I'm defending in this discussion isn't based on estimates but experience from building it from the ground up.
And this is where I welcome everyone to do the same! It took me 2 years to get to where I am now, but maybe it goes faster for you ;) It is definitely a very worthwhile exercise. And I think because of it I'm finally at the point where I can contribute something...
cheers, Toon