Skip to content

Commit de50800

Browse files
committed
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 python#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. ........
1 parent 2ff627a commit de50800

2 files changed

Lines changed: 102 additions & 0 deletions

File tree

Misc/NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -613,6 +613,10 @@ Extension Modules
613613
Build
614614
-----
615615

616+
- Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
617+
private memory allocation scheme in dtoa.c and use PyMem_Malloc and
618+
PyMem_Free instead. Also disable caching of powers of 5.
619+
616620
- Issue #6491: Allow --with-dbmliborder to specify that no dbms will be built.
617621

618622
- Issue #6943: Use pkg-config to find the libffi headers when the

Python/dtoa.c

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,8 @@ Bigint {
308308

309309
typedef struct Bigint Bigint;
310310

311+
#ifndef Py_USING_MEMORY_DEBUGGER
312+
311313
/* Memory management: memory is allocated from, and returned to, Kmax+1 pools
312314
of memory, where pool k (0 <= k <= Kmax) is for Bigints b with b->maxwds ==
313315
1 << k. These pools are maintained as linked lists, with freelist[k]
@@ -375,6 +377,48 @@ Bfree(Bigint *v)
375377
}
376378
}
377379

380+
#else
381+
382+
/* Alternative versions of Balloc and Bfree that use PyMem_Malloc and
383+
PyMem_Free directly in place of the custom memory allocation scheme above.
384+
These are provided for the benefit of memory debugging tools like
385+
Valgrind. */
386+
387+
/* Allocate space for a Bigint with up to 1<<k digits */
388+
389+
static Bigint *
390+
Balloc(int k)
391+
{
392+
int x;
393+
Bigint *rv;
394+
unsigned int len;
395+
396+
x = 1 << k;
397+
len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1)
398+
/sizeof(double);
399+
400+
rv = (Bigint*)MALLOC(len*sizeof(double));
401+
if (rv == NULL)
402+
return NULL;
403+
404+
rv->k = k;
405+
rv->maxwds = x;
406+
rv->sign = rv->wds = 0;
407+
return rv;
408+
}
409+
410+
/* Free a Bigint allocated with Balloc */
411+
412+
static void
413+
Bfree(Bigint *v)
414+
{
415+
if (v) {
416+
FREE((void*)v);
417+
}
418+
}
419+
420+
#endif /* Py_USING_MEMORY_DEBUGGER */
421+
378422
#define Bcopy(x,y) memcpy((char *)&x->sign, (char *)&y->sign, \
379423
y->wds*sizeof(Long) + 2*sizeof(int))
380424

@@ -652,6 +696,8 @@ mult(Bigint *a, Bigint *b)
652696
return c;
653697
}
654698

699+
#ifndef Py_USING_MEMORY_DEBUGGER
700+
655701
/* p5s is a linked list of powers of 5 of the form 5**(2**i), i >= 2 */
656702

657703
static Bigint *p5s;
@@ -711,6 +757,58 @@ pow5mult(Bigint *b, int k)
711757
return b;
712758
}
713759

760+
#else
761+
762+
/* Version of pow5mult that doesn't cache powers of 5. Provided for
763+
the benefit of memory debugging tools like Valgrind. */
764+
765+
static Bigint *
766+
pow5mult(Bigint *b, int k)
767+
{
768+
Bigint *b1, *p5, *p51;
769+
int i;
770+
static int p05[3] = { 5, 25, 125 };
771+
772+
if ((i = k & 3)) {
773+
b = multadd(b, p05[i-1], 0);
774+
if (b == NULL)
775+
return NULL;
776+
}
777+
778+
if (!(k >>= 2))
779+
return b;
780+
p5 = i2b(625);
781+
if (p5 == NULL) {
782+
Bfree(b);
783+
return NULL;
784+
}
785+
786+
for(;;) {
787+
if (k & 1) {
788+
b1 = mult(b, p5);
789+
Bfree(b);
790+
b = b1;
791+
if (b == NULL) {
792+
Bfree(p5);
793+
return NULL;
794+
}
795+
}
796+
if (!(k >>= 1))
797+
break;
798+
p51 = mult(p5, p5);
799+
Bfree(p5);
800+
p5 = p51;
801+
if (p5 == NULL) {
802+
Bfree(b);
803+
return NULL;
804+
}
805+
}
806+
Bfree(p5);
807+
return b;
808+
}
809+
810+
#endif /* Py_USING_MEMORY_DEBUGGER */
811+
714812
/* shift a Bigint b left by k bits. Return a pointer to the shifted result,
715813
or NULL on failure. If the returned pointer is distinct from b then the
716814
original b will have been Bfree'd. Ignores the sign of b. */

0 commit comments

Comments
 (0)