We're getting to the point where we need to pick tag bits for boxed values in order to implement our system.
I've looked at our previous notes and wrote down the following tentative scheme:
Tags needed: - immediate int X----X000 0 - object X----X111 7 - function obj X----X110 6 - array obj X----X101 5 - float X----X100 4 - string X----X011 3 - constants X----X010 2 - bool/null/undef - other X----X001 1 - (getter-setter, hash table, etc.)
All tags are 3 bits wide, which has the advantage of making it easy to extract the tag, always using the same mask operation (val & MASK).
I have picked the tags 7, 6 and 5 for objects, functions and arrays, because those 3 can all have properties stored on them, and so might share a similar memory layout (eg; might have a prototype pointer, a hash table pointer, etc, at the same offset, they are all objects). This makes it possible to test if something is "an object" by doing (val & MASK >= 5).
This scheme has 8 possible tags. The last one, "other", is for all the things that may exist in our heap but won't necessarily have a reserved tag. These include getter-setter objects, hash tables, and other possible runtime objects that may end up in the garbage-collected part of the heap.
Some question worth considering are:
1) Could we do away with some of these tags?
2) Are there other things worth tagging that are not included in there? Do we need more tags?
3) Would it be worthwhile to pick a different/more complex encoding scheme, so as to gain 1 or 2 extra bits for immediate integers, or have a simpler (one-bit?) check for "is an object"?
- Maxime