Skip to content

Commit c91ed40

Browse files
committed
SF #561244, Micro optimizations
Initialize the small integers and __builtins__ in startup. This removes some if conditions. Change XDECREF to DECREF for values which shouldn't be NULL.
1 parent 83f898c commit c91ed40

File tree

5 files changed

+44
-19
lines changed

5 files changed

+44
-19
lines changed

Include/intobject.h

+1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ PyAPI_DATA(PyTypeObject) PyInt_Type;
3030
#define PyInt_Check(op) PyObject_TypeCheck(op, &PyInt_Type)
3131
#define PyInt_CheckExact(op) ((op)->ob_type == &PyInt_Type)
3232

33+
PyAPI_FUNC(int) PyInt_Init(void);
3334
PyAPI_FUNC(PyObject *) PyInt_FromString(char*, char**, int);
3435
#ifdef Py_USING_UNICODE
3536
PyAPI_FUNC(PyObject *) PyInt_FromUnicode(Py_UNICODE*, int, int);

Include/pythonrun.h

+1
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ PyAPI_FUNC(PyObject *) _PySys_Init(void);
100100
PyAPI_FUNC(void) _PyImport_Init(void);
101101
PyAPI_FUNC(void) _PyExc_Init(void);
102102
PyAPI_FUNC(void) _PyImportHooks_Init(void);
103+
PyAPI_FUNC(int) PyFrame_Init(void);
103104

104105
/* Various internal finalizers */
105106
PyAPI_FUNC(void) _PyExc_Fini(void);

Objects/frameobject.c

+13-9
Original file line numberDiff line numberDiff line change
@@ -401,9 +401,9 @@ frame_dealloc(PyFrameObject *f)
401401
}
402402

403403
Py_XDECREF(f->f_back);
404-
Py_XDECREF(f->f_code);
405-
Py_XDECREF(f->f_builtins);
406-
Py_XDECREF(f->f_globals);
404+
Py_DECREF(f->f_code);
405+
Py_DECREF(f->f_builtins);
406+
Py_DECREF(f->f_globals);
407407
Py_XDECREF(f->f_locals);
408408
Py_XDECREF(f->f_trace);
409409
Py_XDECREF(f->f_exc_type);
@@ -525,21 +525,23 @@ PyTypeObject PyFrame_Type = {
525525
0, /* tp_dict */
526526
};
527527

528+
static PyObject *builtin_object;
529+
530+
int PyFrame_Init()
531+
{
532+
builtin_object = PyString_InternFromString("__builtins__");
533+
return (builtin_object != NULL);
534+
}
535+
528536
PyFrameObject *
529537
PyFrame_New(PyThreadState *tstate, PyCodeObject *code, PyObject *globals,
530538
PyObject *locals)
531539
{
532540
PyFrameObject *back = tstate->frame;
533-
static PyObject *builtin_object;
534541
PyFrameObject *f;
535542
PyObject *builtins;
536543
int extras, ncells, nfrees;
537544

538-
if (builtin_object == NULL) {
539-
builtin_object = PyString_InternFromString("__builtins__");
540-
if (builtin_object == NULL)
541-
return NULL;
542-
}
543545
#ifdef Py_DEBUG
544546
if (code == NULL || globals == NULL || !PyDict_Check(globals) ||
545547
(locals != NULL && !PyDict_Check(locals))) {
@@ -802,4 +804,6 @@ PyFrame_Fini(void)
802804
--numfree;
803805
}
804806
assert(numfree == 0);
807+
Py_XDECREF(builtin_object);
808+
builtin_object = NULL;
805809
}

Objects/intobject.c

+23-10
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ fill_free_list(void)
7878
#define NSMALLPOSINTS 100
7979
#endif
8080
#ifndef NSMALLNEGINTS
81-
#define NSMALLNEGINTS 1
81+
#define NSMALLNEGINTS 5
8282
#endif
8383
#if NSMALLNEGINTS + NSMALLPOSINTS > 0
8484
/* References to small integers are saved in this array so that they
@@ -97,8 +97,8 @@ PyInt_FromLong(long ival)
9797
{
9898
register PyIntObject *v;
9999
#if NSMALLNEGINTS + NSMALLPOSINTS > 0
100-
if (-NSMALLNEGINTS <= ival && ival < NSMALLPOSINTS &&
101-
(v = small_ints[ival + NSMALLNEGINTS]) != NULL) {
100+
if (-NSMALLNEGINTS <= ival && ival < NSMALLPOSINTS) {
101+
v = small_ints[ival + NSMALLNEGINTS];
102102
Py_INCREF(v);
103103
#ifdef COUNT_ALLOCS
104104
if (ival >= 0)
@@ -118,13 +118,6 @@ PyInt_FromLong(long ival)
118118
free_list = (PyIntObject *)v->ob_type;
119119
PyObject_INIT(v, &PyInt_Type);
120120
v->ob_ival = ival;
121-
#if NSMALLNEGINTS + NSMALLPOSINTS > 0
122-
if (-NSMALLNEGINTS <= ival && ival < NSMALLPOSINTS) {
123-
/* save this one for a following allocation */
124-
Py_INCREF(v);
125-
small_ints[ival + NSMALLNEGINTS] = v;
126-
}
127-
#endif
128121
return (PyObject *) v;
129122
}
130123

@@ -945,6 +938,26 @@ PyTypeObject PyInt_Type = {
945938
(freefunc)int_free, /* tp_free */
946939
};
947940

941+
int
942+
PyInt_Init(void)
943+
{
944+
PyIntObject *v;
945+
int ival;
946+
#if NSMALLNEGINTS + NSMALLPOSINTS > 0
947+
for (ival = -NSMALLNEGINTS; ival < NSMALLPOSINTS; ival++) {
948+
if ((free_list = fill_free_list()) == NULL)
949+
return 0;
950+
/* PyObject_New is inlined */
951+
v = free_list;
952+
free_list = (PyIntObject *)v->ob_type;
953+
PyObject_INIT(v, &PyInt_Type);
954+
v->ob_ival = ival;
955+
small_ints[ival + NSMALLNEGINTS] = v;
956+
}
957+
#endif
958+
return 1;
959+
}
960+
948961
void
949962
PyInt_Fini(void)
950963
{

Python/pythonrun.c

+6
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,12 @@ Py_Initialize(void)
124124

125125
_Py_ReadyTypes();
126126

127+
if (!PyFrame_Init())
128+
Py_FatalError("Py_Initialize: can't init frames");
129+
130+
if (!PyInt_Init())
131+
Py_FatalError("Py_Initialize: can't init ints");
132+
127133
interp->modules = PyDict_New();
128134
if (interp->modules == NULL)
129135
Py_FatalError("Py_Initialize: can't make modules dictionary");

0 commit comments

Comments
 (0)