mirror of https://github.com/python/cpython
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. ........ ................
This commit is contained in:
parent
93492334df
commit
173a1eedac
|
@ -326,6 +326,10 @@ C-API
|
||||||
Build
|
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.
|
- Switch to OpenSSL 0.9.8l on Windows.
|
||||||
|
|
||||||
- Issue #6603: Change READ_TIMESTAMP macro in ceval.c so that it
|
- Issue #6603: Change READ_TIMESTAMP macro in ceval.c so that it
|
||||||
|
|
|
@ -308,6 +308,8 @@ Bigint {
|
||||||
|
|
||||||
typedef struct Bigint Bigint;
|
typedef struct Bigint Bigint;
|
||||||
|
|
||||||
|
#ifndef Py_USING_MEMORY_DEBUGGER
|
||||||
|
|
||||||
/* Memory management: memory is allocated from, and returned to, Kmax+1 pools
|
/* 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 ==
|
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]
|
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, \
|
#define Bcopy(x,y) memcpy((char *)&x->sign, (char *)&y->sign, \
|
||||||
y->wds*sizeof(Long) + 2*sizeof(int))
|
y->wds*sizeof(Long) + 2*sizeof(int))
|
||||||
|
|
||||||
|
@ -652,6 +696,8 @@ mult(Bigint *a, Bigint *b)
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef Py_USING_MEMORY_DEBUGGER
|
||||||
|
|
||||||
/* p5s is a linked list of powers of 5 of the form 5**(2**i), i >= 2 */
|
/* p5s is a linked list of powers of 5 of the form 5**(2**i), i >= 2 */
|
||||||
|
|
||||||
static Bigint *p5s;
|
static Bigint *p5s;
|
||||||
|
@ -711,6 +757,58 @@ pow5mult(Bigint *b, int k)
|
||||||
return b;
|
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,
|
/* 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
|
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. */
|
original b will have been Bfree'd. Ignores the sign of b. */
|
||||||
|
|
Loading…
Reference in New Issue