Patchwork [2,of,6,V2] dirstate: use the 'nogc' decorator

login
register
mail settings
Submitter Pierre-Yves David
Date Dec. 4, 2014, 3:16 p.m.
Message ID <a57059d6ce3c918719db.1417706175@marginatus.alto.octopoid.net>
Download mbox | patch
Permalink /patch/6997/
State Accepted
Headers show

Comments

Pierre-Yves David - Dec. 4, 2014, 3:16 p.m.
# HG changeset patch
# User Pierre-Yves David <pierre-yves.david@fb.com>
# Date 1417700595 28800
#      Thu Dec 04 05:43:15 2014 -0800
# Node ID a57059d6ce3c918719db5c383c95c8f62179bb80
# Parent  52fbb116345b349dbd2bd3fbbe49bc7e09227365
dirstate: use the 'nogc' decorator

Now that we have a generic way to disable the gc, we use it. however, we have too
use it in a baroque way. See inline comment for details.

Patch

diff --git a/mercurial/dirstate.py b/mercurial/dirstate.py
--- a/mercurial/dirstate.py
+++ b/mercurial/dirstate.py
@@ -6,11 +6,11 @@ 
 # GNU General Public License version 2 or any later version.
 
 from node import nullid
 from i18n import _
 import scmutil, util, ignore, osutil, parsers, encoding, pathutil
-import os, stat, errno, gc
+import os, stat, errno
 
 propertycache = util.propertycache
 filecache = scmutil.filecache
 _rangemask = 0x7fffffff
 
@@ -315,17 +315,14 @@  class dirstate(object):
         # effect on when GCs are triggered, only on what objects the GC looks
         # into. This means that O(number of files) GCs are unavoidable.
         # Depending on when in the process's lifetime the dirstate is parsed,
         # this can get very expensive. As a workaround, disable GC while
         # parsing the dirstate.
-        gcenabled = gc.isenabled()
-        gc.disable()
-        try:
-            p = parsers.parse_dirstate(self._map, self._copymap, st)
-        finally:
-            if gcenabled:
-                gc.enable()
+        #
+        # (we cannot decorate the function directly since it is in a C module)
+        parse_dirstate = util.nogc(parsers.parse_dirstate)
+        p = parse_dirstate(self._map, self._copymap, st)
         if not self._dirtypl:
             self._pl = p
 
     def invalidate(self):
         for a in ("_map", "_copymap", "_foldmap", "_branch", "_pl", "_dirs",