Author: Antonio Cuni <[email protected]>
Branch: gc-disable
Changeset: r94635:5635dcf404cf
Date: 2018-05-19 11:37 +0200
http://bitbucket.org/pypy/pypy/changeset/5635dcf404cf/

Log:    make sure that gc.collect() works even when the GC is disabled

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
@@ -760,7 +760,7 @@
         if gen < 0:
             self._minor_collection()   # dangerous! no major GC cycle progress
         elif gen <= 1:
-            self.minor_collection_with_major_progress()
+            self.minor_collection_with_major_progress(force_enabled=True)
             if gen == 1 and self.gc_state == STATE_SCANNING:
                 self.major_collection_step()
         else:
@@ -768,14 +768,15 @@
         self.rrc_invoke_callback()
 
 
-    def minor_collection_with_major_progress(self, extrasize=0):
+    def minor_collection_with_major_progress(self, extrasize=0,
+                                             force_enabled=False):
         """Do a minor collection.  Then, if the GC is enabled and there
         is already a major GC in progress, run at least one major collection
         step.  If there is no major GC but the threshold is reached, start a
         major GC.
         """
         self._minor_collection()
-        if not self.enabled:
+        if not self.enabled and not force_enabled:
             return
 
         # If the gc_state is STATE_SCANNING, we're not in the middle
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
@@ -790,3 +790,28 @@
         self.gc.enable()
         summary = large_malloc()
         assert sorted(summary.keys()) == ['gc-collect-step', 'gc-minor']
+
+    def test_call_collect_when_disabled(self, debuglog):
+        # malloc an object and put it the old generation
+        s = self.malloc(S)
+        s.x = 42
+        self.stackroots.append(s)
+        self.gc.collect()
+        s = self.stackroots.pop()
+        #
+        self.gc.disable()
+        self.gc.collect(1) # start a major collect
+        assert sorted(debuglog.summary()) == ['gc-collect-step', 'gc-minor']
+        assert s.x == 42 # s is not freed yet
+        #
+        debuglog.reset()
+        self.gc.collect(1) # run one more step
+        assert sorted(debuglog.summary()) == ['gc-collect-step', 'gc-minor']
+        assert s.x == 42 # s is not freed yet
+        #
+        debuglog.reset()
+        self.gc.collect() # finish the major collection
+        summary = debuglog.summary()
+        assert sorted(debuglog.summary()) == ['gc-collect-step', 'gc-minor']
+        # s is freed
+        py.test.raises(RuntimeError, 's.x')
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to