mirror of https://github.com/python/cpython
bpo-38858: Allocate small integers on the heap (GH-17301)
Allocate small Python integers (small_ints of longobject.c) on the heap, rather than using static objects.
This commit is contained in:
parent
d67279147a
commit
5dcc06f6e0
|
@ -40,7 +40,7 @@ PyObject *_PyLong_One = NULL;
|
||||||
The integers that are preallocated are those in the range
|
The integers that are preallocated are those in the range
|
||||||
-NSMALLNEGINTS (inclusive) to NSMALLPOSINTS (not inclusive).
|
-NSMALLNEGINTS (inclusive) to NSMALLPOSINTS (not inclusive).
|
||||||
*/
|
*/
|
||||||
static PyLongObject small_ints[NSMALLNEGINTS + NSMALLPOSINTS];
|
static PyLongObject* small_ints[NSMALLNEGINTS + NSMALLPOSINTS] = {0};
|
||||||
|
|
||||||
#define IS_SMALL_INT(ival) (-NSMALLNEGINTS <= (ival) && (ival) < NSMALLPOSINTS)
|
#define IS_SMALL_INT(ival) (-NSMALLNEGINTS <= (ival) && (ival) < NSMALLPOSINTS)
|
||||||
#define IS_SMALL_UINT(ival) ((ival) < NSMALLPOSINTS)
|
#define IS_SMALL_UINT(ival) ((ival) < NSMALLPOSINTS)
|
||||||
|
@ -52,9 +52,8 @@ Py_ssize_t _Py_quick_int_allocs, _Py_quick_neg_int_allocs;
|
||||||
static PyObject *
|
static PyObject *
|
||||||
get_small_int(sdigit ival)
|
get_small_int(sdigit ival)
|
||||||
{
|
{
|
||||||
PyObject *v;
|
|
||||||
assert(IS_SMALL_INT(ival));
|
assert(IS_SMALL_INT(ival));
|
||||||
v = (PyObject *)&small_ints[ival + NSMALLNEGINTS];
|
PyObject *v = (PyObject*)small_ints[ival + NSMALLNEGINTS];
|
||||||
Py_INCREF(v);
|
Py_INCREF(v);
|
||||||
#ifdef COUNT_ALLOCS
|
#ifdef COUNT_ALLOCS
|
||||||
if (ival >= 0)
|
if (ival >= 0)
|
||||||
|
@ -5784,40 +5783,30 @@ int
|
||||||
_PyLong_Init(void)
|
_PyLong_Init(void)
|
||||||
{
|
{
|
||||||
#if NSMALLNEGINTS + NSMALLPOSINTS > 0
|
#if NSMALLNEGINTS + NSMALLPOSINTS > 0
|
||||||
int ival, size;
|
for (Py_ssize_t i=0; i < NSMALLNEGINTS + NSMALLPOSINTS; i++) {
|
||||||
PyLongObject *v = small_ints;
|
sdigit ival = (sdigit)i - NSMALLNEGINTS;
|
||||||
|
int size = (ival < 0) ? -1 : ((ival == 0) ? 0 : 1);
|
||||||
|
|
||||||
for (ival = -NSMALLNEGINTS; ival < NSMALLPOSINTS; ival++, v++) {
|
PyLongObject *v = _PyLong_New(1);
|
||||||
size = (ival < 0) ? -1 : ((ival == 0) ? 0 : 1);
|
if (!v) {
|
||||||
if (Py_TYPE(v) == &PyLong_Type) {
|
return -1;
|
||||||
/* The element is already initialized, most likely
|
}
|
||||||
* the Python interpreter was initialized before.
|
|
||||||
*/
|
|
||||||
Py_ssize_t refcnt;
|
|
||||||
PyObject* op = (PyObject*)v;
|
|
||||||
|
|
||||||
refcnt = Py_REFCNT(op) < 0 ? 0 : Py_REFCNT(op);
|
|
||||||
_Py_NewReference(op);
|
|
||||||
/* _Py_NewReference sets the ref count to 1 but
|
|
||||||
* the ref count might be larger. Set the refcnt
|
|
||||||
* to the original refcnt + 1 */
|
|
||||||
Py_REFCNT(op) = refcnt + 1;
|
|
||||||
assert(Py_SIZE(op) == size);
|
|
||||||
assert(v->ob_digit[0] == (digit)abs(ival));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
(void)PyObject_INIT(v, &PyLong_Type);
|
|
||||||
}
|
|
||||||
Py_SIZE(v) = size;
|
Py_SIZE(v) = size;
|
||||||
v->ob_digit[0] = (digit)abs(ival);
|
v->ob_digit[0] = (digit)abs(ival);
|
||||||
|
|
||||||
|
small_ints[i] = v;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
_PyLong_Zero = PyLong_FromLong(0);
|
_PyLong_Zero = PyLong_FromLong(0);
|
||||||
if (_PyLong_Zero == NULL)
|
if (_PyLong_Zero == NULL) {
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
_PyLong_One = PyLong_FromLong(1);
|
_PyLong_One = PyLong_FromLong(1);
|
||||||
if (_PyLong_One == NULL)
|
if (_PyLong_One == NULL) {
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* initialize int_info */
|
/* initialize int_info */
|
||||||
if (Int_InfoType.tp_name == NULL) {
|
if (Int_InfoType.tp_name == NULL) {
|
||||||
|
@ -5832,17 +5821,11 @@ _PyLong_Init(void)
|
||||||
void
|
void
|
||||||
_PyLong_Fini(void)
|
_PyLong_Fini(void)
|
||||||
{
|
{
|
||||||
/* Integers are currently statically allocated. Py_DECREF is not
|
|
||||||
needed, but Python must forget about the reference or multiple
|
|
||||||
reinitializations will fail. */
|
|
||||||
Py_CLEAR(_PyLong_One);
|
Py_CLEAR(_PyLong_One);
|
||||||
Py_CLEAR(_PyLong_Zero);
|
Py_CLEAR(_PyLong_Zero);
|
||||||
#if NSMALLNEGINTS + NSMALLPOSINTS > 0
|
#if NSMALLNEGINTS + NSMALLPOSINTS > 0
|
||||||
int i;
|
for (Py_ssize_t i = 0; i < NSMALLNEGINTS + NSMALLPOSINTS; i++) {
|
||||||
PyLongObject *v = small_ints;
|
Py_CLEAR(small_ints[i]);
|
||||||
for (i = 0; i < NSMALLNEGINTS + NSMALLPOSINTS; i++, v++) {
|
|
||||||
_Py_DEC_REFTOTAL;
|
|
||||||
_Py_ForgetReference((PyObject*)v);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue