[pypy-commit] pypy gc-hooks: add a hook interface to GC, which is implemented by a prebuilt object. Implement the hook for incminimark gc-minor

antocuni pypy.commits at gmail.com
Fri Mar 30 05:29:02 EDT 2018


Author: Antonio Cuni <anto.cuni at gmail.com>
Branch: gc-hooks
Changeset: r94182:7b2f669acfa4
Date: 2018-03-28 23:14 +0200
http://bitbucket.org/pypy/pypy/changeset/7b2f669acfa4/

Log:	add a hook interface to GC, which is implemented by a prebuilt
	object. Implement the hook for incminimark gc-minor

diff --git a/rpython/memory/gc/base.py b/rpython/memory/gc/base.py
--- a/rpython/memory/gc/base.py
+++ b/rpython/memory/gc/base.py
@@ -5,6 +5,7 @@
 from rpython.memory.support import DEFAULT_CHUNK_SIZE
 from rpython.memory.support import get_address_stack, get_address_deque
 from rpython.memory.support import AddressDict, null_address_dict
+from rpython.memory.gc.hook import GcHooks
 from rpython.rtyper.lltypesystem.llmemory import NULL, raw_malloc_usage
 from rpython.rtyper.annlowlevel import cast_adr_to_nongc_instance
 
@@ -25,7 +26,7 @@
     _totalroots_rpy = 0   # for inspector.py
 
     def __init__(self, config, chunk_size=DEFAULT_CHUNK_SIZE,
-                 translated_to_c=True):
+                 translated_to_c=True, hooks=None):
         self.gcheaderbuilder = GCHeaderBuilder(self.HDR)
         self.AddressStack = get_address_stack(chunk_size)
         self.AddressDeque = get_address_deque(chunk_size)
@@ -34,6 +35,9 @@
         self.config = config
         assert isinstance(translated_to_c, bool)
         self.translated_to_c = translated_to_c
+        if hooks is None:
+            hooks = GcHooks() # the default hooks are empty
+        self.hooks = hooks
 
     def setup(self):
         # all runtime mutable values' setup should happen here
diff --git a/rpython/memory/gc/hook.py b/rpython/memory/gc/hook.py
new file mode 100644
--- /dev/null
+++ b/rpython/memory/gc/hook.py
@@ -0,0 +1,6 @@
+class GcHooks(object):
+
+    def on_gc_minor(self, total_memory_used, pinned_objects):
+        """
+        Called after a minor collection
+        """
diff --git a/rpython/memory/gc/incminimark.py b/rpython/memory/gc/incminimark.py
--- a/rpython/memory/gc/incminimark.py
+++ b/rpython/memory/gc/incminimark.py
@@ -1828,8 +1828,8 @@
         # from the nursery that we just moved out.
         self.size_objects_made_old += r_uint(self.nursery_surviving_size)
         #
-        debug_print("minor collect, total memory used:",
-                    self.get_total_memory_used())
+        total_memory_used = self.get_total_memory_used()
+        debug_print("minor collect, total memory used:", total_memory_used)
         debug_print("number of pinned objects:",
                     self.pinned_objects_in_nursery)
         if self.DEBUG >= 2:
@@ -1838,6 +1838,8 @@
         self.root_walker.finished_minor_collection()
         #
         debug_stop("gc-minor")
+        self.hooks.on_gc_minor(total_memory_used=total_memory_used,
+                               pinned_objects=self.pinned_objects_in_nursery)
 
     def _reset_flag_old_objects_pointing_to_pinned(self, obj, ignore):
         ll_assert(self.header(obj).tid & GCFLAG_PINNED_OBJECT_PARENT_KNOWN != 0,
diff --git a/rpython/memory/gc/test/test_direct.py b/rpython/memory/gc/test/test_direct.py
--- a/rpython/memory/gc/test/test_direct.py
+++ b/rpython/memory/gc/test/test_direct.py
@@ -70,6 +70,9 @@
 class BaseDirectGCTest(object):
     GC_PARAMS = {}
 
+    def get_extra_gc_params(self):
+        return {}
+
     def setup_method(self, meth):
         from rpython.config.translationoption import get_combined_translation_config
         config = get_combined_translation_config(translating=True).translation
@@ -78,6 +81,7 @@
         if hasattr(meth, 'GC_PARAMS'):
             GC_PARAMS.update(meth.GC_PARAMS)
         GC_PARAMS['translated_to_c'] = False
+        GC_PARAMS.update(self.get_extra_gc_params())
         self.gc = self.GCClass(config, **GC_PARAMS)
         self.gc.DEBUG = True
         self.rootwalker = DirectRootWalker(self)
diff --git a/rpython/memory/gc/test/test_hook.py b/rpython/memory/gc/test/test_hook.py
new file mode 100644
--- /dev/null
+++ b/rpython/memory/gc/test/test_hook.py
@@ -0,0 +1,39 @@
+from rpython.rtyper.lltypesystem import lltype, llmemory
+from rpython.memory.gc.hook import GcHooks
+from rpython.memory.gc.test.test_direct import BaseDirectGCTest, S
+
+class MyGcHooks(GcHooks):
+
+    def __init__(self):
+        self.reset()
+
+    def reset(self):
+        self.minors = []
+
+    def on_gc_minor(self, **kwds):
+        self.minors.append(kwds)
+
+
+class TestIncMiniMarkHooks(BaseDirectGCTest):
+    from rpython.memory.gc.incminimark import IncrementalMiniMarkGC as GCClass
+
+    def get_extra_gc_params(self):
+        return {'hooks': MyGcHooks()}
+
+    def test_on_gc_minor(self):
+        self.malloc(S)
+        self.gc._minor_collection()
+        assert self.gc.hooks.minors == [
+            {'total_memory_used': 0, 'pinned_objects': 0}
+            ]
+        self.gc.hooks.reset()
+        #
+        # these objects survive, so the total_memory_used is > 0
+        self.stackroots.append(self.malloc(S))
+        self.stackroots.append(self.malloc(S))
+        size = llmemory.sizeof(S) + self.gc.gcheaderbuilder.size_gc_header
+        rawsize = llmemory.raw_malloc_usage(size)
+        self.gc._minor_collection()
+        assert self.gc.hooks.minors == [
+            {'total_memory_used': rawsize*2, 'pinned_objects': 0}
+            ]


More information about the pypy-commit mailing list