Luc,
I just realised I was making a dreadful assumption in my
closure freelisting stuff. Namely:
If you're making a closure of procedure that you've closed
before, then you'll also be closing the same number of
arguments as before.
This is wrong of course. A closure should only be free-listed with
repect to the number of closed arguments. I didn't know it was
possible to find out that information, but dredging through the
documentation reveals that -datalength- will do the trick:
datalength(identfn(% 1, 2 %)) =>
** 2
So a rewrite of my code is
define lconstant pdr_table =
newproperty([], 8, [], "tmpboth")
enddefine;
define make_closure(n) -> clos;
lvars n, i, args, free, clos, pdr,
;
conslist(n) -> args; ;;; get the rest of the stuff
() -> pdr; ;;; from the stack
pdr_table(n) -> free; ;;; index the table with the number
;;; of frozvals
if free == [] then
;;; just like before
partapply(pdr, args) -> clos;
else
destpair(free) -> pdr_table(n) -> clos;
1 -> n;
for i in args do
i -> frozval(n, clos);
n + 1 -> n;
endfor;
pdr -> pdpart(clos); ;;; need to assign the new base
;;; procedure to the closure
endif;
sys_grbg_list(args);
enddefine;
define free_closure(clos);
lvars clos, n = datalength(clos),
;
clos :: pdr_table(n) -> pdr_table(n);
enddefine;
Some extra code will be needed if the closures have updaters.
axs@cs.bham.ac.uk (Aaron Sloman) writes:
> for Poplog V13.6)). Steve Knight has been arguing for ages that the
> mechanism should be generalised, and he is right. On the other hand
> you are right that users *can* do it themselves to reduce garbage
> collections, if they know enough. (Sometimes I think that if they
> need to be told how to do it then they don't know enough to do it
> safely!!!)
Ok guv, it's a fair cop :)
Ian.
|