For now, this GC is non-generational, and much slower than the old
version. It tracks objects by a fixed object ID rather than changeable
memory address. Small object (eight bytes or less) are stored directly
in the array, indexed by object ID, while larger object are allocated
with malloc() (for now) and stored in the array as a pointer. Object
IDs are stored as 32-bit integers, even on 64-bit platforms.
Advantages:
- Simpler design
- Requires less memory on 64-bit platforms
- Object IDs don't change when running the GC
- No need to store a random "hash" value in vectors/strings/structs
- Can hash pairs by identity, not just value
- Can move objects individually, without fixing up all references
- Can determine object type from value, without another memory access
Disadvantages:
- Lower initial performance (non-generational, relies on malloc())
- 32-bit values place a (high) limit on total number of objects
- Must explicitly free unreachable object IDs after GC
Each transient identifies the value of the corresponding previous bytecode.
This change (a) frees up many bytecodes formerly used by the conditional
expression (if c t f); (b) regularizes the bytecode by always placing opcodes
before operands; and (c) causes the bytecode to conform to the Single Static
Assignment (SSA) form preferred by e.g. LLVM.
Includes updates to the hand-assembled files (*.rla) and the bytecode compiler.
Add special variables for keyword arguments & values.
Add support for keyword arguments to (simplify-apply).
Implement full string parsing in src/reader.rls.
TODO: Support keywords in (simplify-lambda) and writer.
Add support for (fix=), (list), (and), (or), (cond), (when), and (unless).
Fix a mapper bug which could assign the same frame var to separate variables.
Update make-struct primitive for new structure type layout.
Change primitives to use #% as prefix instead of just %.
Add primitive operations for comparing byte-strings.
This is to separate the three 'call' parameters (target, argv, ctx) from
the 'return to' parameter (k). The old order made it look as if the dynamic
context was in some way related to the continuation, which is not the case.
Fix tree_replace() to handle recursive data structures.
Fix some other minor bugs in the reader and interpreter.
Implement comment-escapes in the string parser, for more readable input.
Allow input program files (*.rla) to be invoked directly, with arguments.
Add a simple string->number converter as a builtin function.