summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2018-04-24 20:40:31 -0700
committerKaz Kylheku <kaz@kylheku.com>2018-04-24 20:40:31 -0700
commit8b7d03c3e8d1c936ecc8329f5993e46a4a65b945 (patch)
tree4955d1d3e628c748e550426a52a0a1b141fd7b74
parent3281d6ace7839140c1b241b5ddc129882ce08f85 (diff)
downloadtxr-8b7d03c3e8d1c936ecc8329f5993e46a4a65b945.tar.gz
txr-8b7d03c3e8d1c936ecc8329f5993e46a4a65b945.tar.bz2
txr-8b7d03c3e8d1c936ecc8329f5993e46a4a65b945.zip
vm: destroy t-reg values used as call args.
Whe the compiler uses t-regs as function call arguments, they are t-regs that have no next use and can be nulled out. We do this to prevent false retention. * vm.c (vm_getz): New function. (vm_call, vm_apply, vm_gcall, vm_gapply): Use vm_getz for fetching arguments.
-rw-r--r--vm.c42
1 files changed, 25 insertions, 17 deletions
diff --git a/vm.c b/vm.c
index ed22cebb..b615e31d 100644
--- a/vm.c
+++ b/vm.c
@@ -311,6 +311,14 @@ INLINE val vm_get(struct vm_env *dspl, unsigned ref)
return dspl[vm_lev(ref)].mem[vm_idx(ref)];
}
+INLINE val vm_getz(struct vm_env *dspl, unsigned ref)
+{
+ unsigned lev = vm_lev(ref);
+ if (lev == 0)
+ return z(dspl[0].mem[vm_idx(ref)]);
+ return dspl[lev].mem[vm_idx(ref)];
+}
+
INLINE val vm_sm_get(struct vm_env *dspl, unsigned ref)
{
return dspl[vm_sm_lev(ref)].mem[vm_sm_idx(ref)];
@@ -419,17 +427,17 @@ static void vm_call(struct vm *vm, vm_word_t insn)
while (nargs >= 2) {
nargs -= 2;
argw = vm->code[vm->ip++];
- args_add(args, vm_get(vm->dspl, vm_arg_operand_lo(argw)));
- args_add(args, vm_get(vm->dspl, vm_arg_operand_hi(argw)));
+ args_add(args, vm_getz(vm->dspl, vm_arg_operand_lo(argw)));
+ args_add(args, vm_getz(vm->dspl, vm_arg_operand_hi(argw)));
}
if (nargs) {
argw = vm->code[vm->ip++];
- args_add(args, vm_get(vm->dspl, vm_arg_operand_lo(argw)));
+ args_add(args, vm_getz(vm->dspl, vm_arg_operand_lo(argw)));
}
}
- result = generic_funcall(vm_get(vm->dspl, fun), args);
+ result = generic_funcall(vm_getz(vm->dspl, fun), args);
vm_set(vm->dspl, dest, result);
}
@@ -443,22 +451,22 @@ static void vm_apply(struct vm *vm, vm_word_t insn)
args_decl (args, nargs < ARGS_MIN ? ARGS_MIN : nargs);
if (nargs--) {
- args_add(args, vm_get(vm->dspl, vm_arg_operand_hi(argw)));
+ args_add(args, vm_getz(vm->dspl, vm_arg_operand_hi(argw)));
while (nargs >= 2) {
nargs -= 2;
argw = vm->code[vm->ip++];
- args_add(args, vm_get(vm->dspl, vm_arg_operand_lo(argw)));
- args_add(args, vm_get(vm->dspl, vm_arg_operand_hi(argw)));
+ args_add(args, vm_getz(vm->dspl, vm_arg_operand_lo(argw)));
+ args_add(args, vm_getz(vm->dspl, vm_arg_operand_hi(argw)));
}
if (nargs) {
argw = vm->code[vm->ip++];
- args_add(args, vm_get(vm->dspl, vm_arg_operand_lo(argw)));
+ args_add(args, vm_getz(vm->dspl, vm_arg_operand_lo(argw)));
}
}
- result = applyv(vm_get(vm->dspl, fun), args);
+ result = applyv(vm_getz(vm->dspl, fun), args);
vm_set(vm->dspl, dest, result);
}
@@ -489,18 +497,18 @@ static void vm_gcall(struct vm *vm, vm_word_t insn)
args_decl (args, nargs < ARGS_MIN ? ARGS_MIN : nargs);
if (nargs--) {
- args_add(args, vm_get(vm->dspl, vm_arg_operand_hi(argw)));
+ args_add(args, vm_getz(vm->dspl, vm_arg_operand_hi(argw)));
while (nargs >= 2) {
nargs -= 2;
argw = vm->code[vm->ip++];
- args_add(args, vm_get(vm->dspl, vm_arg_operand_lo(argw)));
- args_add(args, vm_get(vm->dspl, vm_arg_operand_hi(argw)));
+ args_add(args, vm_getz(vm->dspl, vm_arg_operand_lo(argw)));
+ args_add(args, vm_getz(vm->dspl, vm_arg_operand_hi(argw)));
}
if (nargs) {
argw = vm->code[vm->ip++];
- args_add(args, vm_get(vm->dspl, vm_arg_operand_lo(argw)));
+ args_add(args, vm_getz(vm->dspl, vm_arg_operand_lo(argw)));
}
}
@@ -518,18 +526,18 @@ static void vm_gapply(struct vm *vm, vm_word_t insn)
args_decl (args, nargs < ARGS_MIN ? ARGS_MIN : nargs);
if (nargs--) {
- args_add(args, vm_get(vm->dspl, vm_arg_operand_hi(argw)));
+ args_add(args, vm_getz(vm->dspl, vm_arg_operand_hi(argw)));
while (nargs >= 2) {
nargs -= 2;
argw = vm->code[vm->ip++];
- args_add(args, vm_get(vm->dspl, vm_arg_operand_lo(argw)));
- args_add(args, vm_get(vm->dspl, vm_arg_operand_hi(argw)));
+ args_add(args, vm_getz(vm->dspl, vm_arg_operand_lo(argw)));
+ args_add(args, vm_getz(vm->dspl, vm_arg_operand_hi(argw)));
}
if (nargs) {
argw = vm->code[vm->ip++];
- args_add(args, vm_get(vm->dspl, vm_arg_operand_lo(argw)));
+ args_add(args, vm_getz(vm->dspl, vm_arg_operand_lo(argw)));
}
}