Author: Antonio Cuni <[email protected]>
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
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit