As the title says, the goal of this PR is to be able to use @specialize.memo()
on the callbacks which are passed to gc.trace
, and in particular on the callback
argument which is passed when using rgc.register_custom_trace_hook
.
This branch is needed for hpy; in particular for the branch hpy-0.0.4-hpyfields
: in that branch, we need to call the user-supplied tp_traverse
inside our custom GC tracer: to do so, we generate a tp-traverse-compatible callback for each gc.trace
callback that we receive, using @specialize.memo()
.
The problem is that before this branch, some of the callbacks were functions and some were instance methods, and it's not possible to @specialize.memo()
on instance methods.
To achieve the final goal, this branch does:
- add an
assert_callback_is_function()
insidegc.trace
in order to catch early all the places in which you pass a method - add a second argument to the callback
- fix all places which were passing methods
I have run extensive benchmarks to ensure that this branch does not introduce performance regressions. In particular I benchmarked:
-
default
(rev8eb1cf456a46
) vsgc-custom-trace-memo-on-default
, with and without JIT -
py3.9
(reva528f674f2d1
) vsgc-custom-trace-memo
, with and without JIT -
targetgcbench.py
(on default vs this branch)
The results of (1) and (2) are visible at https://speed.pypy.org/comparison/ if you select the relevant binaries (permalink is not working unfortunately). In that comparison we see that some benchmarks are slightly faster and some are slightly slower; to be extra sure, I re-ran the slower benchmarks manually on bencher7 and could not see any noticeable difference, so probably the difference that we see in the charts are just random variations.
(3) is an RPython benchmark which exercises the GC which I ran manually on bencher7, and it doesn't show any performance regression.
--HG-- branch : gc-custom-trace-memo-on-default