gh-100227: Move the dtoa State to PyInterpreterState (gh-102331)

https://github.com/python/cpython/issues/100227
This commit is contained in:
Eric Snow 2023-02-28 13:14:40 -07:00 committed by GitHub
parent b5ff382433
commit f300a1fa4c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 39 additions and 17 deletions

View file

@ -119,7 +119,7 @@
#include "Python.h"
#include "pycore_dtoa.h" // _PY_SHORT_FLOAT_REPR
#include "pycore_runtime.h" // _PyRuntime
#include "pycore_pystate.h" // _PyInterpreterState_GET()
#include <stdlib.h> // exit()
/* if _PY_SHORT_FLOAT_REPR == 0, then don't even try to compile
@ -339,9 +339,9 @@ typedef struct Bigint Bigint;
Bfree to PyMem_Free. Investigate whether this has any significant
performance on impact. */
#define freelist _PyRuntime.dtoa.freelist
#define private_mem _PyRuntime.dtoa.preallocated
#define pmem_next _PyRuntime.dtoa.preallocated_next
#define freelist interp->dtoa.freelist
#define private_mem interp->dtoa.preallocated
#define pmem_next interp->dtoa.preallocated_next
/* Allocate space for a Bigint with up to 1<<k digits */
@ -351,6 +351,7 @@ Balloc(int k)
int x;
Bigint *rv;
unsigned int len;
PyInterpreterState *interp = _PyInterpreterState_GET();
if (k <= Bigint_Kmax && (rv = freelist[k]))
freelist[k] = rv->next;
@ -385,6 +386,7 @@ Bfree(Bigint *v)
if (v->k > Bigint_Kmax)
FREE((void*)v);
else {
PyInterpreterState *interp = _PyInterpreterState_GET();
v->next = freelist[v->k];
freelist[v->k] = v;
}
@ -692,7 +694,8 @@ pow5mult(Bigint *b, int k)
if (!(k >>= 2))
return b;
p5 = _PyRuntime.dtoa.p5s;
PyInterpreterState *interp = _PyInterpreterState_GET();
p5 = interp->dtoa.p5s;
if (!p5) {
/* first time */
p5 = i2b(625);
@ -700,7 +703,7 @@ pow5mult(Bigint *b, int k)
Bfree(b);
return NULL;
}
_PyRuntime.dtoa.p5s = p5;
interp->dtoa.p5s = p5;
p5->next = 0;
}
for(;;) {

View file

@ -3,7 +3,8 @@
#include "Python.h"
#include "pycore_ceval.h"
#include "pycore_code.h" // stats
#include "pycore_code.h" // stats
#include "pycore_dtoa.h" // _dtoa_state_INIT()
#include "pycore_frame.h"
#include "pycore_initconfig.h"
#include "pycore_object.h" // _PyType_InitCache()
@ -618,6 +619,18 @@ free_interpreter(PyInterpreterState *interp)
e.g. by PyMem_RawCalloc() or memset(), or otherwise pre-initialized.
The runtime state is not manipulated. Instead it is assumed that
the interpreter is getting added to the runtime.
Note that the main interpreter was statically initialized as part
of the runtime and most state is already set properly. That leaves
a small number of fields to initialize dynamically, as well as some
that are initialized lazily.
For subinterpreters we memcpy() the main interpreter in
PyInterpreterState_New(), leaving it in the same mostly-initialized
state. The only difference is that the interpreter has some
self-referential state that is statically initializexd to the
main interpreter. We fix those fields here, in addition
to the other dynamically initialized fields.
*/
static void
@ -645,6 +658,11 @@ init_interpreter(PyInterpreterState *interp,
PyConfig_InitPythonConfig(&interp->config);
_PyType_InitCache(interp);
if (interp != &runtime->_main_interpreter) {
/* Fix the self-referential, statically initialized fields. */
interp->dtoa = (struct _dtoa_state)_dtoa_state_INIT(interp);
}
interp->_initialized = 1;
}