diff --git a/_posts/2014-09-12-register-allocation-reviewed.md b/_posts/2014-09-12-register-allocation-reviewed.md new file mode 100644 index 0000000..23b9a4a --- /dev/null +++ b/_posts/2014-09-12-register-allocation-reviewed.md @@ -0,0 +1,88 @@ +--- +layout: news +author: Torsten +--- + +The time of introspection is coming to an end and i am finally producing executables again. (hurrah) + +### Block and exception + +Even neither ruby blocks or exceptions are implemented i have figured out how to do it, which is sort of good news. +I'll see off course when the day comes, but a plan is made and it is this: + +No information lives on the machine stack. + +Maybe it's easier to understand this way: All objects live in memory primarily. Whatever get's moved onto the machine +stack is just a copy and, for purposes of the gc, does not need to be considered. + +### 4 Objects, 4 registers + +As far as i have determined the vm needs internal access to exactly four objects. These are: + +- Message: the currently received one, ie the one that in a method led to the method being called +- Self: this is an instance variable of the message +- Frame: local and temporary variables of the method. Also part of the message. +- NewMessage: where the next call is prepared + +And, as stated above, all these objects live in memory. + +### Single Set Instruction + +Self and frame are duplicated information, because then it is easier to transfer. After inital trying, i settle on a +single Instruction to move data around in the vm, Set. It can move instance variables from any of the objects to any +other of the 4 objects. + +The implementation of Set ensures that any move to the self slot in Message gets duplicated into the Self register. Same +for the frame, but both are once per method occurances, and both are read only afterwards, so don't need updating later. + +Set, like other instructions may use any other variables at any time. Those registers (r4 and up) are scratch. + +### Simple call + +This makes calling relatively simple and thus easy to understand. To make a call we must be in a method, ie Message, +Self and Frame have been set up. + +The method then produces values for the call. This involves operations and the result of that is stored in a variable +(tmp/local/arg). When all values have been calculated a NewMessage is created and all data moved there (see Set) + +A Call is then quite simple: because of the duplication of Self and Frame, we only need to push the Message to the +machine stack. Then we move the NewMessage to Message, unroll (copy) the Self into it's register and assign a new +Frame. + +Returning is also not overly complicated: Remembering that the return value is an instance variable in the +Message object. So when the method is done, the value is there, not for example in a dedicated register. +So we need to undo the above: move the current Message to NewMessage, pop the previously pushed message from the +machine stack and unroll the Self and Frame copies. + +The caller then continues and can pick up the return from it's NewMessage if it is used for further calculation. +It's like it did everything to built the (New)Message and immediately the return value was filled in. + +As I said, often we need to calculate the values for the call, so we need to make calls. This happens in exacly the same +way, and the result is shuffled to a Frame slot (local or temporary variable). + +### Message creation + +Well, i hear, that sounds good and almost too easy. But .... (always one isn't there) what about the Message and Frame +objects, where do you get those from ? + +And this is true: in c the Message does not exist, it's just data in registers and the Frame is created on the stack if +needed. + +And unfortunately we can't really make a call to get/create these objects as that would create an endless loop. Hmm + +We need a very fast way to create and reuse these objects: a bit like a stack. So let's just use a Stack :-) + +Off course not the machine stack, but a Stack object. An array to which we append and take from. +It must be global off course, or rather accessible from compiling code. And fast may be that we use assembler, or +if things work out well, we can use the same code as what makes builtin arrays tick. + +Still, this is a different problem and the full solution will need a bit time. But clearly it is solvable and does +not impact above register usage convention. + +### The fineprint + +Just for the sake of completeness: The assumtion i made a the beginning of the Simple Call section, can off course not +possibly be always true. + +To boot the vm, we must create the first message by "magic" and place it and the Self (Kernel module reference). +As it can be an empty Message for now, this is not difficult, just one of those little gotachs. diff --git a/ideas.html b/ideas.html index c707812..ba2a135 100755 --- a/ideas.html +++ b/ideas.html @@ -80,7 +80,7 @@ sub-title: Salama hopes make the the mysterious more accessible, shed light in t But to mention a few things that have crossed my mind (and that i will most certainly not implement)