Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 3fce883

Browse files
committed
Vladimir has restructured his code somewhat so that the blocks are now
represented by an explicit structure. (There are still too many casts in the code, but that may be unavoidable.) Also added code so that with -vv it is very chatty about what it does.
1 parent 4edf656 commit 3fce883

2 files changed

Lines changed: 97 additions & 51 deletions

File tree

Objects/floatobject.c

Lines changed: 50 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -94,24 +94,33 @@ double (*_Py_math_funcs_hack[])() = {
9494
#endif
9595

9696
/* Special free list -- see comments for same code in intobject.c. */
97-
static PyFloatObject *free_list = NULL;
98-
static PyFloatObject *block_list = NULL;
9997
#define BLOCK_SIZE 1000 /* 1K less typical malloc overhead */
100-
#define BHEAD_SIZE 8 /* Hope this is enough alignment */
98+
#define BHEAD_SIZE 8 /* Enough for a 64-bit pointer */
10199
#define N_FLOATOBJECTS ((BLOCK_SIZE - BHEAD_SIZE) / sizeof(PyFloatObject))
100+
102101
#define PyMem_MALLOC malloc
103102
#define PyMem_FREE free
104103

104+
struct _floatblock {
105+
struct _floatblock *next;
106+
PyFloatObject objects[N_FLOATOBJECTS];
107+
};
108+
109+
typedef struct _floatblock PyFloatBlock;
110+
111+
static PyFloatBlock *block_list = NULL;
112+
static PyFloatObject *free_list = NULL;
113+
105114
static PyFloatObject *
106115
fill_free_list()
107116
{
108117
PyFloatObject *p, *q;
109-
p = (PyFloatObject *)PyMem_MALLOC(BLOCK_SIZE);
118+
p = (PyFloatObject *)PyMem_MALLOC(sizeof(PyFloatBlock));
110119
if (p == NULL)
111120
return (PyFloatObject *)PyErr_NoMemory();
112-
*(PyFloatObject **)p = block_list;
113-
block_list = p;
114-
p = (PyFloatObject *)((char *)p + BHEAD_SIZE);
121+
((PyFloatBlock *)p)->next = block_list;
122+
block_list = (PyFloatBlock *)p;
123+
p = &((PyFloatBlock *)p)->objects[0];
115124
q = p + N_FLOATOBJECTS;
116125
while (--q > p)
117126
q->ob_type = (struct _typeobject *)(q-1);
@@ -611,7 +620,8 @@ PyTypeObject PyFloat_Type = {
611620
void
612621
PyFloat_Fini()
613622
{
614-
PyFloatObject *p, *list;
623+
PyFloatObject *p;
624+
PyFloatBlock *list, *next;
615625
int i;
616626
int bc, bf; /* block count, number of freed blocks */
617627
int frem, fsum; /* remaining unfreed floats per block, total */
@@ -622,36 +632,51 @@ PyFloat_Fini()
622632
list = block_list;
623633
block_list = NULL;
624634
while (list != NULL) {
625-
p = list;
626-
p = (PyFloatObject *)((char *)p + BHEAD_SIZE);
635+
p = &list->objects[0];
627636
bc++;
628637
frem = 0;
629638
for (i = 0; i < N_FLOATOBJECTS; i++, p++) {
630639
if (PyFloat_Check(p) && p->ob_refcnt != 0)
631640
frem++;
632641
}
633-
p = list;
634-
list = *(PyFloatObject **)p;
642+
next = list->next;
635643
if (frem) {
636-
*(PyFloatObject **)p = block_list;
637-
block_list = p;
644+
list->next = block_list;
645+
block_list = list;
638646
}
639647
else {
640-
PyMem_FREE(p);
648+
PyMem_FREE(list);
641649
bf++;
642650
}
643651
fsum += frem;
652+
list = next;
644653
}
645-
if (Py_VerboseFlag) {
646-
fprintf(stderr, "# cleanup floats");
647-
if (!fsum) {
648-
fprintf(stderr, "\n");
649-
}
650-
else {
651-
fprintf(stderr,
652-
": %d unfreed float%s in %d out of %d block%s\n",
653-
fsum, fsum == 1 ? "" : "s",
654-
bc - bf, bc, bc == 1 ? "" : "s");
654+
if (!Py_VerboseFlag)
655+
return;
656+
fprintf(stderr, "# cleanup floats");
657+
if (!fsum) {
658+
fprintf(stderr, "\n");
659+
}
660+
else {
661+
fprintf(stderr,
662+
": %d unfreed float%s in %d out of %d block%s\n",
663+
fsum, fsum == 1 ? "" : "s",
664+
bc - bf, bc, bc == 1 ? "" : "s");
665+
}
666+
if (Py_VerboseFlag > 1) {
667+
list = block_list;
668+
while (list != NULL) {
669+
p = &list->objects[0];
670+
for (i = 0; i < N_FLOATOBJECTS; i++, p++) {
671+
if (PyFloat_Check(p) && p->ob_refcnt != 0) {
672+
char buf[100];
673+
PyFloat_AsString(buf, p);
674+
fprintf(stderr,
675+
"# <float object at %lx, refcnt=%d, val=%s>\n",
676+
p, p->ob_refcnt, buf);
677+
}
678+
}
679+
list = list->next;
655680
}
656681
}
657682
}

Objects/intobject.c

Lines changed: 47 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -90,31 +90,39 @@ err_ovf(msg)
9090
*/
9191

9292
#define BLOCK_SIZE 1000 /* 1K less typical malloc overhead */
93-
#define N_INTOBJECTS ((BLOCK_SIZE - sizeof(PyIntObject *)) / \
94-
sizeof(PyIntObject))
93+
#define BHEAD_SIZE 8 /* Enough for a 64-bit pointer */
94+
#define N_INTOBJECTS ((BLOCK_SIZE - BHEAD_SIZE) / sizeof(PyIntObject))
9595

9696
#define PyMem_MALLOC malloc
9797
#define PyMem_FREE free
98-
static PyIntObject *block_list = NULL;
98+
99+
struct _intblock {
100+
struct _intblock *next;
101+
PyIntObject objects[N_INTOBJECTS];
102+
};
103+
104+
typedef struct _intblock PyIntBlock;
105+
106+
static PyIntBlock *block_list = NULL;
107+
static PyIntObject *free_list = NULL;
99108

100109
static PyIntObject *
101110
fill_free_list()
102111
{
103112
PyIntObject *p, *q;
104-
p = (PyIntObject *)PyMem_MALLOC(BLOCK_SIZE);
113+
p = (PyIntObject *)PyMem_MALLOC(sizeof(PyIntBlock));
105114
if (p == NULL)
106115
return (PyIntObject *)PyErr_NoMemory();
107-
*(PyIntObject **)p = block_list;
108-
block_list = p;
109-
p = (PyIntObject *)((char *)p + sizeof(PyIntObject *));
116+
((PyIntBlock *)p)->next = block_list;
117+
block_list = (PyIntBlock *)p;
118+
p = &((PyIntBlock *)p)->objects[0];
110119
q = p + N_INTOBJECTS;
111120
while (--q > p)
112121
q->ob_type = (struct _typeobject *)(q-1);
113122
q->ob_type = NULL;
114123
return p + N_INTOBJECTS - 1;
115124
}
116125

117-
static PyIntObject *free_list = NULL;
118126
#ifndef NSMALLPOSINTS
119127
#define NSMALLPOSINTS 100
120128
#endif
@@ -802,7 +810,8 @@ PyTypeObject PyInt_Type = {
802810
void
803811
PyInt_Fini()
804812
{
805-
PyIntObject *p, *list;
813+
PyIntObject *p;
814+
PyIntBlock *list, *next;
806815
int i;
807816
int bc, bf; /* block count, number of freed blocks */
808817
int irem, isum; /* remaining unfreed ints per block, total */
@@ -823,36 +832,48 @@ PyInt_Fini()
823832
list = block_list;
824833
block_list = NULL;
825834
while (list != NULL) {
826-
p = list;
827-
p = (PyIntObject *)((char *)p + sizeof(PyIntObject *));
835+
p = &list->objects[0];
828836
bc++;
829837
irem = 0;
830838
for (i = 0; i < N_INTOBJECTS; i++, p++) {
831839
if (PyInt_Check(p) && p->ob_refcnt != 0)
832840
irem++;
833841
}
834-
p = list;
835-
list = *(PyIntObject **)p;
842+
next = list->next;
836843
if (irem) {
837-
*(PyIntObject **)p = block_list;
838-
block_list = p;
844+
list->next = block_list;
845+
block_list = list;
839846
}
840847
else {
841-
PyMem_FREE(p);
848+
PyMem_FREE(list);
842849
bf++;
843850
}
844851
isum += irem;
852+
list = next;
845853
}
846-
if (Py_VerboseFlag) {
847-
fprintf(stderr, "# cleanup ints");
848-
if (!isum) {
849-
fprintf(stderr, "\n");
850-
}
851-
else {
852-
fprintf(stderr,
853-
": %d unfreed int%s in %d out of %d block%s\n",
854-
isum, isum == 1 ? "" : "s",
855-
bc - bf, bc, bc == 1 ? "" : "s");
854+
if (!Py_VerboseFlag)
855+
return;
856+
fprintf(stderr, "# cleanup ints");
857+
if (!isum) {
858+
fprintf(stderr, "\n");
859+
}
860+
else {
861+
fprintf(stderr,
862+
": %d unfreed int%s in %d out of %d block%s\n",
863+
isum, isum == 1 ? "" : "s",
864+
bc - bf, bc, bc == 1 ? "" : "s");
865+
}
866+
if (Py_VerboseFlag > 1) {
867+
list = block_list;
868+
while (list != NULL) {
869+
p = &list->objects[0];
870+
for (i = 0; i < N_INTOBJECTS; i++, p++) {
871+
if (PyInt_Check(p) && p->ob_refcnt != 0)
872+
fprintf(stderr,
873+
"# <int object at %lx, refcnt=%d, val=%ld>\n",
874+
p, p->ob_refcnt, p->ob_ival);
875+
}
876+
list = list->next;
856877
}
857878
}
858879
}

0 commit comments

Comments
 (0)