reachableroots: bail if integer object cannot be allocated
authorYuya Nishihara <yuya@tcha.org>
Fri, 14 Aug 2015 12:31:56 +0900
changeset 26032 a3d5da8b641e
parent 26031 0b57b77f9b3e
child 26033 9e7d805925c8
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.
mercurial/parsers.c
--- 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);
 				}
 			}
 		}