Author: Antonio Cuni <anto.c...@gmail.com> Branch: gc-hooks Changeset: r94193:ba293bc808ee Date: 2018-03-31 01:59 +0200 http://bitbucket.org/pypy/pypy/changeset/ba293bc808ee/
Log: start to add app-level gc hooks; the test pass, but we still need to polish stuff a bit diff --git a/pypy/module/gc/__init__.py b/pypy/module/gc/__init__.py --- a/pypy/module/gc/__init__.py +++ b/pypy/module/gc/__init__.py @@ -34,5 +34,10 @@ 'get_typeids_z': 'referents.get_typeids_z', 'get_typeids_list': 'referents.get_typeids_list', 'GcRef': 'referents.W_GcRef', + 'set_hooks': 'hook.set_hooks', }) MixedModule.__init__(self, space, w_name) + + def setup_after_space_initialization(self): + from pypy.module.gc.hook import gchooks + gchooks.setspace(self.space) diff --git a/pypy/module/gc/hook.py b/pypy/module/gc/hook.py new file mode 100644 --- /dev/null +++ b/pypy/module/gc/hook.py @@ -0,0 +1,54 @@ +from rpython.memory.gc.hook import GcHooks +from pypy.interpreter.baseobjspace import ObjSpace +from pypy.interpreter.gateway import interp2app, unwrap_spec +from pypy.interpreter.executioncontext import AsyncAction + +class LowLevelGcHooks(GcHooks): + + def setspace(self, space): + self.space = space + self.hooks = space.fromcache(AppLevelHooks) + + def on_gc_minor(self, total_memory_used, pinned_objects): + action = self.hooks.gc_minor + action.total_memory_used = total_memory_used + action.pinned_objects = pinned_objects + action.fire() + + def on_gc_collect_step(self, oldstate, newstate): + pass + + def on_gc_collect(self, count, arenas_count_before, arenas_count_after, + arenas_bytes, rawmalloc_bytes_before, + rawmalloc_bytes_after): + pass + + +gchooks = LowLevelGcHooks() + +class AppLevelHooks(object): + + def __init__(self, space): + self.space = space + self.gc_minor = GcMinorHookAction(space) + + def set_hooks(self, space, w_on_gc_minor): + # XXX: check for None and enable/disable accordingly + self.gc_minor.w_callable = w_on_gc_minor + + +class GcMinorHookAction(AsyncAction): + w_callable = None + total_memory_used = 0 + pinned_objects = 0 + + def perform(self, ec, frame): + self.space.call_function(self.w_callable, + self.space.wrap(self.total_memory_used), + self.space.wrap(self.pinned_objects)) + + + + +def set_hooks(space, w_on_gc_minor): + space.fromcache(AppLevelHooks).set_hooks(space, w_on_gc_minor) diff --git a/pypy/module/gc/test/test_hook.py b/pypy/module/gc/test/test_hook.py new file mode 100644 --- /dev/null +++ b/pypy/module/gc/test/test_hook.py @@ -0,0 +1,26 @@ +from pypy.module.gc.hook import gchooks +from pypy.interpreter.baseobjspace import ObjSpace +from pypy.interpreter.gateway import interp2app, unwrap_spec + +class AppTestGcHooks(object): + + def setup_class(cls): + space = cls.space + + @unwrap_spec(ObjSpace, int, int) + def fire_gc_minor(space, total_memory_used, pinned_objects): + gchooks.fire_gc_minor(total_memory_used, pinned_objects) + cls.w_fire_gc_minor = space.wrap(interp2app(fire_gc_minor)) + + def test_on_gc_minor(self): + import gc + lst = [] + def on_gc_minor(total_memory_used, pinned_objects): + lst.append((total_memory_used, pinned_objects)) + gc.set_hooks(on_gc_minor=on_gc_minor) + self.fire_gc_minor(10, 20) + self.fire_gc_minor(30, 40) + assert lst == [ + (10, 20), + (30, 40), + ] _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit