diff options
author | Mark Dickinson <dickinsm@gmail.com> | 2010-01-17 21:06:28 (GMT) |
---|---|---|
committer | Mark Dickinson <dickinsm@gmail.com> | 2010-01-17 21:06:28 (GMT) |
commit | 173a1eedac69442362c8ed705ea7975c94ce3c93 (patch) | |
tree | f74f7df0b453dbf52c026770bfc0b6968696b02a /Python | |
parent | 93492334df7e664d1eb1cc02ac206b0bee686568 (diff) | |
download | cpython-173a1eedac69442362c8ed705ea7975c94ce3c93.zip cpython-173a1eedac69442362c8ed705ea7975c94ce3c93.tar.gz cpython-173a1eedac69442362c8ed705ea7975c94ce3c93.tar.bz2 |
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.
........
................
Diffstat (limited to 'Python')
-rw-r--r-- | Python/dtoa.c | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/Python/dtoa.c b/Python/dtoa.c index 24ce922..de3ca9e 100644 --- a/Python/dtoa.c +++ b/Python/dtoa.c @@ -308,6 +308,8 @@ Bigint { 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 @@ Bfree(Bigint *v) } } +#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 @@ mult(Bigint *a, Bigint *b) 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 @@ pow5mult(Bigint *b, int k) 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. */ |