[pypy-commit] pypy gc-hooks: call the hooks through helpers which are marked as @rgc.no_collect, to ensure that we cannot allocate anything from within

antocuni pypy.commits at gmail.com
Fri Mar 30 09:00:42 EDT 2018


Author: Antonio Cuni <anto.cuni at gmail.com>
Branch: gc-hooks
Changeset: r94188:3d2b6d04026f
Date: 2018-03-30 14:22 +0200
http://bitbucket.org/pypy/pypy/changeset/3d2b6d04026f/

Log:	call the hooks through helpers which are marked as @rgc.no_collect,
	to ensure that we cannot allocate anything from within

diff --git a/rpython/memory/gc/hook.py b/rpython/memory/gc/hook.py
--- a/rpython/memory/gc/hook.py
+++ b/rpython/memory/gc/hook.py
@@ -1,10 +1,21 @@
+from rpython.rlib import rgc
+
 class GcHooks(object):
+    """
+    Base class to write your own GC hooks.
+
+    Subclasses are expected to override the on_* methods. Note that such
+    methods can do only simple stuff such as updating statistics and/or
+    setting a flag: in particular, they cannot do anything which can possibly
+    trigger a GC collection.
+    """
 
     def __init__(self):
         self.gc_minor_enabled = False
         self.gc_collect_step_enabled = False
         self.gc_collect_enabled = False
 
+
     def on_gc_minor(self, total_memory_used, pinned_objects):
         """
         Called after a minor collection
@@ -20,9 +31,29 @@
         incminimark.GC_STATES.
         """
 
+
     def on_gc_collect(self, count, arenas_count_before, arenas_count_after,
                       arenas_bytes, rawmalloc_bytes_before,
                       rawmalloc_bytes_after):
         """
         Called after a major collection is fully done
         """
+
+    # the fire_* methods are meant to be called from the GC are should NOT be
+    # overridden
+
+    @rgc.no_collect
+    def fire_gc_minor(self, total_memory_used, pinned_objects):
+        self.on_gc_minor(total_memory_used, pinned_objects)
+
+    @rgc.no_collect
+    def fire_gc_collect_step(self, oldstate, newstate):
+        self.on_gc_collect_step(oldstate, newstate)
+
+    @rgc.no_collect
+    def fire_gc_collect(self, count, arenas_count_before, arenas_count_after,
+                        arenas_bytes, rawmalloc_bytes_before,
+                        rawmalloc_bytes_after):
+        self.on_gc_collect(count, arenas_count_before, arenas_count_after,
+                           arenas_bytes, rawmalloc_bytes_before,
+                           rawmalloc_bytes_after)
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
@@ -1839,7 +1839,7 @@
         #
         debug_stop("gc-minor")
         if self.hooks.gc_minor_enabled:
-            self.hooks.on_gc_minor(total_memory_used=total_memory_used,
+            self.hooks.fire_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):
@@ -2425,7 +2425,7 @@
                             self.rawmalloced_total_size)
                 debug_stop("gc-collect-done")
                 if self.hooks.gc_collect_enabled:
-                    self.hooks.on_gc_collect(
+                    self.hooks.fire_gc_collect(
                         count=self.num_major_collects,
                         arenas_count_before=self.stat_ac_arenas_count,
                         arenas_count_after=self.ac.arenas_count,
@@ -2484,7 +2484,7 @@
         debug_print("stopping, now in gc state: ", GC_STATES[self.gc_state])
         debug_stop("gc-collect-step")
         if self.hooks.gc_collect_step_enabled:
-            self.hooks.on_gc_collect_step(oldstate=oldstate,
+            self.hooks.fire_gc_collect_step(oldstate=oldstate,
                                           newstate=self.gc_state)
 
     def _sweep_old_objects_pointing_to_pinned(self, obj, new_list):


More information about the pypy-commit mailing list