[pypy-dev] Locals clearing in RPython

Armin Rigo arigo at tunes.org
Thu Sep 6 21:25:26 CEST 2012


Hi Timothy,

On Thu, Sep 6, 2012 at 8:34 PM, Timothy Baldridge <tbaldridge at gmail.com> wrote:
> The question is: when is the GC
> free to free data passed into a function's arguments. Will that function
> hold on to all data passed in through arguments until the execution of the
> function terminates? If so is there a way to trigger garbage collection of
> unneeded argument data before the end of the function's execution?

RPython is not precisely defined for this question to have a definite
answer.  However, currently, with all our own GCs, keep-alive works
this way:

1. First, an RPython function keeps alive a variable "for as little
time as necessary".  Even if, as plain Python, the variable would be
kept alive until the function returns just because it's stored in a
local, it is not the case in RPython.

2. Across a call, *only* the variables that need to remain alive
*after* the call is done are pushed on the shadow stack.  In
particular, tail calls are really just goto's from the point of view
of the GC (even if they are not implemented as tail calls from the
point of view of the translation to C).

Using these general rules to figure out what occurs in your case:

> def wrapper_func(arg1, arg2):
>     return inner_func(arg2)
>
> def inner_func(x):
>    for y in range(x):
>       # do something here
>       pass
>    return -1
>
> wrapper_func(list(range(bigint)), bigint)

The list is passed as 'arg1' but not passed any further.  It is not
saved either across the call to wrapper_func() nor the call to
inner_func().  So it is dead.  If inner_func() triggers a GC cycle, it
will be collected.

If you need to prevent that (e.g. because 'arg1' is an object with a
__del__ and you don't want this __del__ to be called too early) then
you need to insert a call to
pypy.rlib.objectmodel.keepalive_until_here().


A bientôt,

Armin.


More information about the pypy-dev mailing list