In my continuing research for my bare-metal operating system and language, I have been looking at polyFORTH. This is a system language designed for use on the massively-parallel processor chips produced by GreenArrays, obviously from the same heritage as the Problem Oriented Language philosophy from Charles Moore’s 1970 document.
One interesting thing about the polyFORTH reference manual is that it goes into detail about memory sizes and how the various parts of the system are mapped to physical memory. Each process gets its own data and return stacks, as well as an area for variables, per-process register storage and so on; processes with user input also get an input buffer and a dictionary to hold new words as they are defined.
This is reasonable enough, but there is an extra trick, the process dictionaries all link back to a central default dictionary, which is immutable once the separate processes are running, and shared between all running processes. This helps make the individual process memory as lightweight as possible, while still transparently providing rich shared functionality.
My current plan for ELIUS is to use a string pool, to hold constant text for more powerful string handling, and it seems to make sense to do the same trick of splitting the pool into a shared fixed part and an extendable part in each process. For this to make sense, it does mean a change to the way I have structured the pool in memory, though.
At the moment, the pool has variable length entries, each consisting of a length (32 bits) and a collection of bytes of data. To skip forward from one entry to another involves rounding up the length to the next multiple of 4 bytes. This simple enough, but does assume that the pool memory is contiguous.
To support split pools, the location of the next entry needs to be explicit rather than implicit. I am now proposing that each entry on the pool have both a length (vital for efficient comparisons) and the address of the next entry. With this simple change, the pool can now be split into arbitrary chunks, and arranged in any order in memory without breaking any code.
As an extra benefit, this should also allow the nano-kernel part of the system (the minimum needed so that other words can be defined to extend the system) to be co-located in memory. This both makes it simpler to define in a source file when the system is being built, and means that for target systems such as micro-controllers with segregated memory the immutable parts of the system can be placed in ROM or FLASH, saving precious RAM for things which might actually vary.