[Python-checkins] r77591 - in python/branches/release31-maint: Misc/NEWS Python/dtoa.c

mark.dickinson python-checkins at python.org
Sun Jan 17 22:06:28 CET 2010


Author: mark.dickinson
Date: Sun Jan 17 22:06:28 2010
New Revision: 77591

Log:
Merged revisions 77590 via svnmerge from 
svn+ssh://pythondev@svn.python.org/python/branches/py3k

................
  r77590 | mark.dickinson | 2010-01-17 21:02:55 +0000 (Sun, 17 Jan 2010) | 14 lines
  
  Merged revisions 77589 via svnmerge from 
  svn+ssh://pythondev@svn.python.org/python/trunk
  
  ........
    r77589 | mark.dickinson | 2010-01-17 20:57:56 +0000 (Sun, 17 Jan 2010) | 7 lines
    
    Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
    private memory allocation scheme in dtoa.c, along with a piece of code
    that caches powers of 5 for future use.  This makes it easier to
    detect dtoa.c memory leaks with Valgrind or similar tools.
    
    Patch by Stefan Krah.
  ........
................


Modified:
   python/branches/release31-maint/   (props changed)
   python/branches/release31-maint/Misc/NEWS
   python/branches/release31-maint/Python/dtoa.c

Modified: python/branches/release31-maint/Misc/NEWS
==============================================================================
--- python/branches/release31-maint/Misc/NEWS	(original)
+++ python/branches/release31-maint/Misc/NEWS	Sun Jan 17 22:06:28 2010
@@ -326,6 +326,10 @@
 Build
 -----
 
+- Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
+  private memory allocation scheme in dtoa.c and use PyMem_Malloc and
+  PyMem_Free instead.  Also disable caching of powers of 5.
+
 - Switch to OpenSSL 0.9.8l on Windows.
 
 - Issue #6603: Change READ_TIMESTAMP macro in ceval.c so that it

Modified: python/branches/release31-maint/Python/dtoa.c
==============================================================================
--- python/branches/release31-maint/Python/dtoa.c	(original)
+++ python/branches/release31-maint/Python/dtoa.c	Sun Jan 17 22:06:28 2010
@@ -308,6 +308,8 @@
 
 typedef struct Bigint Bigint;
 
+#ifndef Py_USING_MEMORY_DEBUGGER
+
 /* Memory management: memory is allocated from, and returned to, Kmax+1 pools
    of memory, where pool k (0 <= k <= Kmax) is for Bigints b with b->maxwds ==
    1 << k.  These pools are maintained as linked lists, with freelist[k]
@@ -375,6 +377,48 @@
     }
 }
 
+#else
+
+/* Alternative versions of Balloc and Bfree that use PyMem_Malloc and
+   PyMem_Free directly in place of the custom memory allocation scheme above.
+   These are provided for the benefit of memory debugging tools like
+   Valgrind. */
+
+/* Allocate space for a Bigint with up to 1<<k digits */
+
+static Bigint *
+Balloc(int k)
+{
+    int x;
+    Bigint *rv;
+    unsigned int len;
+
+    x = 1 << k;
+    len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1)
+        /sizeof(double);
+
+    rv = (Bigint*)MALLOC(len*sizeof(double));
+    if (rv == NULL)
+        return NULL;
+
+    rv->k = k;
+    rv->maxwds = x;
+    rv->sign = rv->wds = 0;
+    return rv;
+}
+
+/* Free a Bigint allocated with Balloc */
+
+static void
+Bfree(Bigint *v)
+{
+    if (v) {
+        FREE((void*)v);
+    }
+}
+
+#endif /* Py_USING_MEMORY_DEBUGGER */
+
 #define Bcopy(x,y) memcpy((char *)&x->sign, (char *)&y->sign,   \
                           y->wds*sizeof(Long) + 2*sizeof(int))
 
@@ -652,6 +696,8 @@
     return c;
 }
 
+#ifndef Py_USING_MEMORY_DEBUGGER
+
 /* p5s is a linked list of powers of 5 of the form 5**(2**i), i >= 2 */
 
 static Bigint *p5s;
@@ -711,6 +757,58 @@
     return b;
 }
 
+#else
+
+/* Version of pow5mult that doesn't cache powers of 5. Provided for
+   the benefit of memory debugging tools like Valgrind. */
+
+static Bigint *
+pow5mult(Bigint *b, int k)
+{
+    Bigint *b1, *p5, *p51;
+    int i;
+    static int p05[3] = { 5, 25, 125 };
+
+    if ((i = k & 3)) {
+        b = multadd(b, p05[i-1], 0);
+        if (b == NULL)
+            return NULL;
+    }
+
+    if (!(k >>= 2))
+        return b;
+    p5 = i2b(625);
+    if (p5 == NULL) {
+        Bfree(b);
+        return NULL;
+    }
+
+    for(;;) {
+        if (k & 1) {
+            b1 = mult(b, p5);
+            Bfree(b);
+            b = b1;
+            if (b == NULL) {
+                Bfree(p5);
+                return NULL;
+            }
+        }
+        if (!(k >>= 1))
+            break;
+        p51 = mult(p5, p5);
+        Bfree(p5);
+        p5 = p51;
+        if (p5 == NULL) {
+            Bfree(b);
+            return NULL;
+        }
+    }
+    Bfree(p5);
+    return b;
+}
+
+#endif /* Py_USING_MEMORY_DEBUGGER */
+
 /* shift a Bigint b left by k bits.  Return a pointer to the shifted result,
    or NULL on failure.  If the returned pointer is distinct from b then the
    original b will have been Bfree'd.   Ignores the sign of b. */


More information about the Python-checkins mailing list