Skip to content

Commit c7e4333

Browse files
Move the Bigint freelist to _PyRuntimeState.
1 parent a0a961e commit c7e4333

File tree

4 files changed

+35
-15
lines changed

4 files changed

+35
-15
lines changed

Include/internal/pycore_dtoa.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#ifndef Py_INTERNAL_DTOA_H
2+
#define Py_INTERNAL_DTOA_H
13
#ifdef __cplusplus
24
extern "C" {
35
#endif
@@ -11,6 +13,21 @@ extern "C" {
1113

1214
#if _PY_SHORT_FLOAT_REPR == 1
1315

16+
typedef uint32_t ULong;
17+
18+
struct
19+
Bigint {
20+
struct Bigint *next;
21+
int k, maxwds, sign, wds;
22+
ULong x[1];
23+
};
24+
25+
#ifndef Py_USING_MEMORY_DEBUGGER
26+
/* The size of the Bigint freelist */
27+
# define Bigint_Kmax 7
28+
#endif
29+
30+
1431
/* These functions are used by modules compiled as C extension like math:
1532
they must be exported. */
1633

@@ -26,3 +43,4 @@ PyAPI_FUNC(double) _Py_dg_infinity(int sign);
2643
#ifdef __cplusplus
2744
}
2845
#endif
46+
#endif /* !Py_INTERNAL_DTOA_H */

Include/internal/pycore_runtime.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ extern "C" {
99
#endif
1010

1111
#include "pycore_atomic.h" /* _Py_atomic_address */
12+
#include "pycore_dtoa.h" // struct Bigint
1213
#include "pycore_gil.h" // struct _gil_runtime_state
1314
#include "pycore_global_objects.h" // struct _Py_global_objects
1415
#include "pycore_import.h" // struct _import_runtime_state
@@ -128,6 +129,11 @@ typedef struct pyruntimestate {
128129
struct {
129130
struct _PyTraceMalloc_Config config;
130131
} tracemalloc;
132+
struct {
133+
#ifndef Py_USING_MEMORY_DEBUGGER
134+
struct Bigint *freelist[Bigint_Kmax+1];
135+
#endif
136+
} dtoa;
131137

132138
PyPreConfig preconfig;
133139

Python/dtoa.c

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@
119119

120120
#include "Python.h"
121121
#include "pycore_dtoa.h" // _PY_SHORT_FLOAT_REPR
122+
#include "pycore_runtime.h" // _PyRuntime
122123
#include <stdlib.h> // exit()
123124

124125
/* if _PY_SHORT_FLOAT_REPR == 0, then don't even try to compile
@@ -156,7 +157,7 @@
156157
#endif
157158

158159

159-
typedef uint32_t ULong;
160+
// ULong is defined in pycore_dtoa.h.
160161
typedef int32_t Long;
161162
typedef uint64_t ULLong;
162163

@@ -298,8 +299,6 @@ BCinfo {
298299

299300
#define FFFFFFFF 0xffffffffUL
300301

301-
#define Kmax 7
302-
303302
/* struct Bigint is used to represent arbitrary-precision integers. These
304303
integers are stored in sign-magnitude format, with the magnitude stored as
305304
an array of base 2**32 digits. Bigints are always normalized: if x is a
@@ -322,13 +321,7 @@ BCinfo {
322321
significant (x[0]) to most significant (x[wds-1]).
323322
*/
324323

325-
struct
326-
Bigint {
327-
struct Bigint *next;
328-
int k, maxwds, sign, wds;
329-
ULong x[1];
330-
};
331-
324+
// struct Bigint is defined in pycore_dtoa.h.
332325
typedef struct Bigint Bigint;
333326

334327
#ifndef Py_USING_MEMORY_DEBUGGER
@@ -352,7 +345,7 @@ typedef struct Bigint Bigint;
352345
Bfree to PyMem_Free. Investigate whether this has any significant
353346
performance on impact. */
354347

355-
static Bigint *freelist[Kmax+1];
348+
#define freelist _PyRuntime.dtoa.freelist
356349

357350
/* Allocate space for a Bigint with up to 1<<k digits */
358351

@@ -363,13 +356,15 @@ Balloc(int k)
363356
Bigint *rv;
364357
unsigned int len;
365358

366-
if (k <= Kmax && (rv = freelist[k]))
359+
if (k <= Bigint_Kmax && (rv = freelist[k]))
367360
freelist[k] = rv->next;
368361
else {
369362
x = 1 << k;
370363
len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1)
371364
/sizeof(double);
372-
if (k <= Kmax && pmem_next - private_mem + len <= (Py_ssize_t)PRIVATE_mem) {
365+
if (k <= Bigint_Kmax &&
366+
pmem_next - private_mem + len <= (Py_ssize_t)PRIVATE_mem
367+
) {
373368
rv = (Bigint*)pmem_next;
374369
pmem_next += len;
375370
}
@@ -391,7 +386,7 @@ static void
391386
Bfree(Bigint *v)
392387
{
393388
if (v) {
394-
if (v->k > Kmax)
389+
if (v->k > Bigint_Kmax)
395390
FREE((void*)v);
396391
else {
397392
v->next = freelist[v->k];
@@ -400,6 +395,8 @@ Bfree(Bigint *v)
400395
}
401396
}
402397

398+
#undef freelist
399+
403400
#else
404401

405402
/* Alternative versions of Balloc and Bfree that use PyMem_Malloc and

Tools/c-analyzer/cpython/globals-to-fix.tsv

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,6 @@ Objects/unicodeobject.c - ucnhash_capi -
325325
# state
326326

327327
# pre-allocated memory
328-
Python/dtoa.c - freelist -
329328
Python/dtoa.c - private_mem -
330329

331330
# local buffer

0 commit comments

Comments
 (0)