changeset 26032:a3d5da8b641e

reachableroots: bail if integer object cannot be allocated This patch also replaces Py_XDECREF() by Py_DECREF() because we known "val" and "p" are not NULL. BTW, we can eliminate some of these allocation and error handling of int objects if the internal "seen" array has more information. For example, enum { SEEN = 1, ROOT = 2, REACHABLE = 4 }; /* ... build ROOT mask from roots argument ... */ if (seen[revnum + 1] & ROOT) { /* instead of PySet_Contains(roots, val) */ >From my quick hack, it is 2x faster.
author Yuya Nishihara <yuya@tcha.org>
date Fri, 14 Aug 2015 12:31:56 +0900
parents 0b57b77f9b3e
children 9e7d805925c8
files mercurial/parsers.c
diffstat 1 files changed, 13 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/parsers.c	Sat Aug 01 05:43:39 2015 -0700
+++ b/mercurial/parsers.c	Fri Aug 14 12:31:56 2015 +0900
@@ -1185,14 +1185,16 @@
 		/* Add the node to reachable if it is a root*/
 		revnum = tovisit[k++];
 		val = PyInt_FromLong(revnum);
+		if (val == NULL)
+			goto bail;
 		if (PySet_Contains(roots, val) == 1) {
 			PySet_Add(reachable, val);
 			if (includepath == 0) {
-				Py_XDECREF(val);
+				Py_DECREF(val);
 				continue;
 			}
 		}
-		Py_XDECREF(val);
+		Py_DECREF(val);
 
 		/* Add its parents to the list of nodes to visit */
 		if (revnum != -1) {
@@ -1223,9 +1225,15 @@
 					goto bail;
 				for (k = 0; k < 2; k++) {
 					PyObject *p = PyInt_FromLong(parents[k]);
-					if (PySet_Contains(reachable, p) == 1)
-						PySet_Add(reachable, PyInt_FromLong(i));
-					Py_XDECREF(p);
+					if (p == NULL)
+						goto bail;
+					if (PySet_Contains(reachable, p) == 1) {
+						val = PyInt_FromLong(i);
+						if (val == NULL)
+							goto bail;
+						PySet_Add(reachable, val);
+					}
+					Py_DECREF(p);
 				}
 			}
 		}