summaryrefslogtreecommitdiffstats
path: root/parser.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2021-02-11 06:52:46 -0800
committerKaz Kylheku <kaz@kylheku.com>2021-02-11 06:52:46 -0800
commitd662a6c925b959b0b521c2954c87863e46478897 (patch)
tree73958b54600b93e340cb8ac88fe98d88e1f7ed7f /parser.c
parent512fa869e31d3fde5eb9422a5ed46e3fec58c94a (diff)
downloadtxr-d662a6c925b959b0b521c2954c87863e46478897.tar.gz
txr-d662a6c925b959b0b521c2954c87863e46478897.tar.bz2
txr-d662a6c925b959b0b521c2954c87863e46478897.zip
compiler/vm: more compact frame size for closures.
Closures do not share t-registers with surrounding code; they do not store a value into such a register that code outside the closure would read and vice versa. When compiling closures, we can can temporarily reset the compiler's t-register allocator machinery to get low t-register values. Then, when executing the closure, we reserve space just for the registers it needs, not based off the containing vm description. Here we make a backwards-incompatible change. The VM close instruction needs an extra parameter indicating the number of t-regisers. This is stored into the closure and used for allocating the frame when it is dispatched. * parser.c (read_file_common): We read nothing but version 6 tlo files now. * share/txr/stdlib/asm.tl (op-close asm): Parse new ntreg argument from close syntax, and put it out as an extra word. Here is where we pay for this improvement in extra code size. (op-close dis): Extract the new argument from the machine code and add it to the disassembled format. * share/txr/stdlib/compiler.tl (compile-in-toplevel): Save and restore the t-reg discards list also. Don't bother with a gensym for the compiler; the argument is always a symbol, which we can use unhygienically like in with-var-spy. (compile-with-fresh-tregs): New macro based on compile-in-toplevel: almost the same but doesn't reset the level. (comp-lambda-impl): Use compile-with-fresh-tregs to compile the entire closure with a minimized register set. Place the treg-cntr into the closure instruction to indicate the number of registers the closure requires. * vm.c (struct vm): New member, nreg. (vm_make_closure): New parameter, nreg, stored into the closure. (vm_close): Extract a third opcode word, and pull the nreg value from the bottom half. Pass this to vm_make_closure. (vm_execute_closure, vm_funcall_common): Calculate frame size based on the closur's nreg rather than the VM description's. * txr.1: Document that the upcoming version 252 produces version 6.0 object files and only loads version 6.
Diffstat (limited to 'parser.c')
-rw-r--r--parser.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/parser.c b/parser.c
index 5282b75f..77797b19 100644
--- a/parser.c
+++ b/parser.c
@@ -741,7 +741,7 @@ static val read_file_common(val self, val stream, val error_stream, val compiled
if (compiled && first) {
val major = car(form);
- if (lt(major, one) || gt(major, num_fast(6)))
+ if (neq(major, num_fast(6)))
uw_throwf(error_s,
lit("cannot load ~s: version number mismatch"),
stream, nao);