diff options
Diffstat (limited to 'doc/0')
| -rw-r--r-- | doc/0/0-value.md | 41 |
1 files changed, 24 insertions, 17 deletions
diff --git a/doc/0/0-value.md b/doc/0/0-value.md index f30735e..b84a528 100644 --- a/doc/0/0-value.md +++ b/doc/0/0-value.md @@ -105,9 +105,9 @@ highest bits, providing a payload value of 48 bits for each. 011 :: Immediate short string - 100 :: Immediate small rational (sign bit 0) + 100 :: Immediate small rational - 101 :: Immediate small rational (sign bit 1) + 101 :: Undefined 110 :: Undefined @@ -126,11 +126,14 @@ highest bits, providing a payload value of 48 bits for each. Forbidden Pattern #3, Positive cqNaN, is avoided thanks to the fact that some bits of a list pointer are always set; see below. -Zisp splits the native program heap provided by the platform into three regions -of virtual memory: The list heap of 32 GiB, addressed in 64-bit (8-byte) units; -the main heap of 32 GiB, also addressed in 64-bit units; and the 4 GiB heap for -`istr` objects (interned strings) which is addressed in bytes. Each region can -thus be addressed via 32-bit indices instead of larger direct pointers. +Zisp divides platform-provided heap memory into regions that are addressed via +32-bit indexes rather than direct pointers. Different pointer types may refer +to different regions. For instance, a list pointer and a regular heap pointer +may have the same index value, which does not mean that they point to the same +real memory address. They may also be addressing their respective region with +different unit sizes. For instance, `istr` (interned string) pointers may use +byte-addressing, meaning the 32-bit index limits the `istr` heap to 4 GiB only, +while list pointers use 64-bit (8-byte) addressing, allowing for a 32 GiB heap. ### List pointers @@ -138,13 +141,13 @@ In Zisp, a list is a contiguous array of a fixed number of Values. To improve memory density and cache locality, especially for the interpreter, lists of up to 255 elements are allocated in tight blocks with little or no padding and no metadata headers on the heap. Their length is therefore encoded directly with -an 8-bit metadata field within the NaN-packed pointer. +an 8-bit metadata field within the NaN-packed pointer itself. The exact layout of the 48-bit payload is as follows: The low 32 bits are an index into the list heap, while the higher 16 bits are -divided into 8 high bits for the length, and 8 low bits for garbage collector -or other internal metadata. +divided into 8 high bits for the length, and 8 low bits for internal metadata +such as for garbage collection. The length bits cannot be zero. The empty list is represented by a different bit pattern to provide a minor benefit during garbage collection: Zero-length @@ -157,17 +160,20 @@ and the generic list API hides the difference. ### Heap pointers -Regular heap objects are represented by this index type, which uses a 32-bit +Regular heap objects are represented by this pointer type, which uses a 32-bit index into the main heap, in the lower portion of the 48-bit payload. Of the 16 high bits of the payload, the upper 8 are used to immediately encode -the type of the heap object, and the remaining 8 are used for garbage collector -metadata. +the type of the heap object, and the remaining 8 are used for internal metadata +such as for garbage collection. This means our 64-bit Values can be checked against heap types by comparing the 24 high bits to a combined constant: the 16 high bits that indicate it's a main heap index, plus 8 more bits encoding a specific heap type. +Some heap types may actually reside in their own separate heap, meaning the +32-bit index may refer to yet another memory region rather than the main heap. + ### String pointers An `istr` is a string of up to 255 arbitrary bytes, that is typically interned, @@ -207,8 +213,9 @@ depend on the endianness of the platform. ### Small rationals -We use a 49-bit space for small rational numbers, with a signed 25-bit two's -complement integer numerator, and 24-bit unsigned integer denominator. +We use a 48-bit space for small rational numbers, with a 32-bit signed two's +complement integer numerator in the low 32 bits, and a 16-bit unsigned integer +denominator in the high 16 bits of the payload. ### Runes & others @@ -251,7 +258,7 @@ almost purely in-place mutations of the original source code tree. 010 :: Pointer to istr as constant - 011 :: Short string as constant + 011 :: Immediate short string as constant 100 :: Pointer to opcodes in list heap @@ -295,7 +302,7 @@ only of the above listed Value types. Function arguments, and locally declared variables, reside in a "stack frame" allocated for each call. Since a Value has a uniform 64-bit representation, -the stack frame is simply an array. +stack frames are simply Value arrays. The low 16 bits of the payload are an index into the stack array; the other 32 bits are reserved for other purposes. |
