Skip to content

Commit 5bd1059

Browse files
authored
bpo-40521: Make dtoa bigint free list per-interpreter (GH-24821)
1 parent d0a4454 commit 5bd1059

File tree

3 files changed

+39
-17
lines changed

3 files changed

+39
-17
lines changed

Include/internal/pycore_dtoa.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
#ifndef PY_NO_SHORT_FLOAT_REPR
2+
#ifndef Py_INTERNAL_DTOA_H
3+
#define Py_INTERNAL_DTOA_H
24
#ifdef __cplusplus
35
extern "C" {
46
#endif
@@ -17,7 +19,21 @@ PyAPI_FUNC(void) _Py_dg_freedtoa(char *s);
1719
PyAPI_FUNC(double) _Py_dg_stdnan(int sign);
1820
PyAPI_FUNC(double) _Py_dg_infinity(int sign);
1921

22+
#define _PyDtoa_Kmax 7
23+
24+
typedef uint32_t _PyDtoa_ULong;
25+
typedef int32_t _PyDtoa_Long;
26+
typedef uint64_t _PyDtoa_ULLong;
27+
28+
struct
29+
_PyDtoa_Bigint {
30+
struct _PyDtoa_Bigint *next;
31+
int k, maxwds, sign, wds;
32+
_PyDtoa_ULong x[1];
33+
};
34+
2035
#ifdef __cplusplus
2136
}
2237
#endif
38+
#endif /* !Py_INTERNAL_DTOA_H */
2339
#endif /* !PY_NO_SHORT_FLOAT_REPR */

Include/internal/pycore_interp.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ extern "C" {
1313
#include "pycore_gil.h" // struct _gil_runtime_state
1414
#include "pycore_gc.h" // struct _gc_runtime_state
1515
#include "pycore_warnings.h" // struct _warnings_runtime_state
16+
#include "pycore_dtoa.h"
1617

1718
struct _pending_calls {
1819
PyThread_type_lock lock;
@@ -321,6 +322,9 @@ struct _is {
321322

322323
struct ast_state ast;
323324
struct type_cache type_cache;
325+
#ifndef PY_NO_SHORT_FLOAT_REPR
326+
struct _PyDtoa_Bigint *dtoa_freelist[_PyDtoa_Kmax + 1];
327+
#endif
324328
};
325329

326330
extern void _PyInterpreterState_ClearModules(PyInterpreterState *interp);

Python/dtoa.c

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,16 @@
119119

120120
#include "Python.h"
121121
#include "pycore_dtoa.h"
122+
#include "pycore_interp.h"
123+
#include "pycore_pystate.h"
124+
125+
#define ULong _PyDtoa_ULong
126+
#define Long _PyDtoa_Long
127+
#define ULLong _PyDtoa_ULLong
128+
#define Kmax _PyDtoa_Kmax
129+
130+
typedef struct _PyDtoa_Bigint Bigint;
131+
122132

123133
/* if PY_NO_SHORT_FLOAT_REPR is defined, then don't even try to compile
124134
the following code */
@@ -154,11 +164,6 @@
154164
#error "doubles and ints have incompatible endianness"
155165
#endif
156166

157-
158-
typedef uint32_t ULong;
159-
typedef int32_t Long;
160-
typedef uint64_t ULLong;
161-
162167
#undef DEBUG
163168
#ifdef Py_DEBUG
164169
#define DEBUG
@@ -297,8 +302,6 @@ BCinfo {
297302

298303
#define FFFFFFFF 0xffffffffUL
299304

300-
#define Kmax 7
301-
302305
/* struct Bigint is used to represent arbitrary-precision integers. These
303306
integers are stored in sign-magnitude format, with the magnitude stored as
304307
an array of base 2**32 digits. Bigints are always normalized: if x is a
@@ -321,14 +324,6 @@ BCinfo {
321324
significant (x[0]) to most significant (x[wds-1]).
322325
*/
323326

324-
struct
325-
Bigint {
326-
struct Bigint *next;
327-
int k, maxwds, sign, wds;
328-
ULong x[1];
329-
};
330-
331-
typedef struct Bigint Bigint;
332327

333328
#ifndef Py_USING_MEMORY_DEBUGGER
334329

@@ -351,7 +346,13 @@ typedef struct Bigint Bigint;
351346
Bfree to PyMem_Free. Investigate whether this has any significant
352347
performance on impact. */
353348

354-
static Bigint *freelist[Kmax+1];
349+
350+
/* Get Bigint freelist from interpreter */
351+
static Bigint **
352+
get_freelist(void) {
353+
PyInterpreterState *interp = _PyInterpreterState_GET();
354+
return interp->dtoa_freelist;
355+
}
355356

356357
/* Allocate space for a Bigint with up to 1<<k digits */
357358

@@ -361,7 +362,7 @@ Balloc(int k)
361362
int x;
362363
Bigint *rv;
363364
unsigned int len;
364-
365+
Bigint **freelist = get_freelist();
365366
if (k <= Kmax && (rv = freelist[k]))
366367
freelist[k] = rv->next;
367368
else {
@@ -393,6 +394,7 @@ Bfree(Bigint *v)
393394
if (v->k > Kmax)
394395
FREE((void*)v);
395396
else {
397+
Bigint **freelist = get_freelist();
396398
v->next = freelist[v->k];
397399
freelist[v->k] = v;
398400
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy