Skip to content
Closed
Prev Previous commit
Next Next commit
Fix static locals for objects.
  • Loading branch information
ericsnowcurrently committed May 17, 2019
commit 6dc09fa07a90aa023f26a3211aff9f4d0ad694f0
23 changes: 9 additions & 14 deletions Objects/classobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ static int numfree = 0;

_Py_IDENTIFIER(__name__);
_Py_IDENTIFIER(__qualname__);
_Py_IDENTIFIER(__doc__);

PyObject *
PyMethod_Function(PyObject *im)
Expand Down Expand Up @@ -116,13 +117,13 @@ static PyMemberDef method_memberlist[] = {
static PyObject *
method_get_doc(PyMethodObject *im, void *context)
{
static PyObject *docstr;
if (docstr == NULL) {
docstr= PyUnicode_InternFromString("__doc__");
if (docstr == NULL)
return NULL;
}
return PyObject_GetAttr(im->im_func, docstr);
// if (cached_str___doc__ == NULL) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

checking in a block of commented out code looks wrong... what's up here?

// cached_str___doc__= PyUnicode_InternFromString("__doc__");
// if (cached_str___doc__ == NULL)
// return NULL;
// }
// return PyObject_GetAttr(im->im_func, cached_str___doc__);
return _PyObject_GetAttrId(im->im_func, &PyId___doc__);
}

static PyGetSetDef method_getset[] = {
Expand Down Expand Up @@ -413,13 +414,7 @@ static PyMemberDef instancemethod_memberlist[] = {
static PyObject *
instancemethod_get_doc(PyObject *self, void *context)
{
static PyObject *docstr;
if (docstr == NULL) {
docstr = PyUnicode_InternFromString("__doc__");
if (docstr == NULL)
return NULL;
}
return PyObject_GetAttr(PyInstanceMethod_GET_FUNCTION(self), docstr);
return _PyObject_GetAttrId(PyInstanceMethod_GET_FUNCTION(self), &PyId___doc__);
}

static PyGetSetDef instancemethod_getset[] = {
Expand Down
31 changes: 16 additions & 15 deletions Objects/codeobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -226,22 +226,23 @@ PyCode_New(int argcount, int posonlyargcount, int kwonlyargcount,
return co;
}

static PyObject *cached_emptystring = NULL;
static PyObject *cached_nulltuple = NULL;

PyCodeObject *
PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno)
{
static PyObject *emptystring = NULL;
static PyObject *nulltuple = NULL;
PyObject *filename_ob = NULL;
PyObject *funcname_ob = NULL;
PyCodeObject *result = NULL;
if (emptystring == NULL) {
emptystring = PyBytes_FromString("");
if (emptystring == NULL)
if (cached_emptystring == NULL) {
cached_emptystring = PyBytes_FromString("");
if (cached_emptystring == NULL)
goto failed;
}
if (nulltuple == NULL) {
nulltuple = PyTuple_New(0);
if (nulltuple == NULL)
if (cached_nulltuple == NULL) {
cached_nulltuple = PyTuple_New(0);
if (cached_nulltuple == NULL)
goto failed;
}
funcname_ob = PyUnicode_FromString(funcname);
Expand All @@ -257,16 +258,16 @@ PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno)
0, /* nlocals */
0, /* stacksize */
0, /* flags */
emptystring, /* code */
nulltuple, /* consts */
nulltuple, /* names */
nulltuple, /* varnames */
nulltuple, /* freevars */
nulltuple, /* cellvars */
cached_emptystring, /* code */
cached_nulltuple, /* consts */
cached_nulltuple, /* names */
cached_nulltuple, /* varnames */
cached_nulltuple, /* freevars */
cached_nulltuple, /* cellvars */
filename_ob, /* filename */
funcname_ob, /* name */
firstlineno, /* firstlineno */
emptystring /* lnotab */
cached_emptystring /* lnotab */
);

failed:
Expand Down
22 changes: 12 additions & 10 deletions Objects/exceptions.c
Original file line number Diff line number Diff line change
Expand Up @@ -2949,6 +2949,9 @@ _set_legacy_print_statement_msg(PySyntaxErrorObject *self, Py_ssize_t start)
return 1;
}

static PyObject *cached_print_prefix = NULL;
static PyObject *cached_exec_prefix = NULL;

static int
_check_for_legacy_statements(PySyntaxErrorObject *self, Py_ssize_t start)
{
Expand All @@ -2957,8 +2960,6 @@ _check_for_legacy_statements(PySyntaxErrorObject *self, Py_ssize_t start)
* 0: nothing happened
* 1: the check triggered & the error message was changed
*/
static PyObject *print_prefix = NULL;
static PyObject *exec_prefix = NULL;
Py_ssize_t text_len = PyUnicode_GET_LENGTH(self->text), match;
int kind = PyUnicode_KIND(self->text);
void *data = PyUnicode_DATA(self->text);
Expand All @@ -2976,13 +2977,13 @@ _check_for_legacy_statements(PySyntaxErrorObject *self, Py_ssize_t start)
}

/* Check for legacy print statements */
if (print_prefix == NULL) {
print_prefix = PyUnicode_InternFromString("print ");
if (print_prefix == NULL) {
if (cached_print_prefix == NULL) {
cached_print_prefix = PyUnicode_InternFromString("print ");
if (cached_print_prefix == NULL) {
return -1;
}
}
match = PyUnicode_Tailmatch(self->text, print_prefix,
match = PyUnicode_Tailmatch(self->text, cached_print_prefix,
start, text_len, -1);
if (match == -1) {
return -1;
Expand All @@ -2992,13 +2993,14 @@ _check_for_legacy_statements(PySyntaxErrorObject *self, Py_ssize_t start)
}

/* Check for legacy exec statements */
if (exec_prefix == NULL) {
exec_prefix = PyUnicode_InternFromString("exec ");
if (exec_prefix == NULL) {
if (cached_exec_prefix == NULL) {
cached_exec_prefix = PyUnicode_InternFromString("exec ");
if (cached_exec_prefix == NULL) {
return -1;
}
}
match = PyUnicode_Tailmatch(self->text, exec_prefix, start, text_len, -1);
match = PyUnicode_Tailmatch(self->text, cached_exec_prefix,
start, text_len, -1);
if (match == -1) {
return -1;
}
Expand Down
11 changes: 3 additions & 8 deletions Objects/funcobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,13 @@
#include "code.h"
#include "structmember.h"

_Py_IDENTIFIER(__name__);

PyObject *
PyFunction_NewWithQualName(PyObject *code, PyObject *globals, PyObject *qualname)
{
PyFunctionObject *op;
PyObject *doc, *consts, *module;
static PyObject *__name__ = NULL;

if (__name__ == NULL) {
__name__ = PyUnicode_InternFromString("__name__");
if (__name__ == NULL)
return NULL;
}

op = PyObject_GC_New(PyFunctionObject, &PyFunction_Type);
if (op == NULL)
Expand Down Expand Up @@ -54,7 +49,7 @@ PyFunction_NewWithQualName(PyObject *code, PyObject *globals, PyObject *qualname

/* __module__: If module name is in globals, use it.
Otherwise, use None. */
module = PyDict_GetItemWithError(globals, __name__);
module = _PyDict_GetItemIdWithError(globals, &PyId___name__);
if (module) {
Py_INCREF(module);
op->func_module = module;
Expand Down
5 changes: 4 additions & 1 deletion Objects/listobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -152,12 +152,15 @@ _PyList_DebugMallocStats(FILE *out)
numfree, sizeof(PyListObject));
}

#ifdef SHOW_ALLOC_COUNT
static int initialized = 0;
#endif

PyObject *
PyList_New(Py_ssize_t size)
{
PyListObject *op;
#ifdef SHOW_ALLOC_COUNT
static int initialized = 0;
if (!initialized) {
Py_AtExit(show_alloc);
initialized = 1;
Expand Down
10 changes: 6 additions & 4 deletions Objects/longobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -2439,9 +2439,9 @@ digit beyond the first.
const char *scan, *lastdigit;
char prev = 0;

static double log_base_BASE[37] = {0.0e0,};
static int convwidth_base[37] = {0,};
static twodigits convmultmax_base[37] = {0,};
static double log_base_BASE[37] = {0.0e0,}; // Static is okay here (global cache).
static int convwidth_base[37] = {0,}; // Static is okay here (global cache).
static twodigits convmultmax_base[37] = {0,}; // Static is okay here (global cache).

if (log_base_BASE[base] == 0.0) {
twodigits convmax = base;
Expand Down Expand Up @@ -2918,7 +2918,9 @@ _PyLong_Frexp(PyLongObject *a, Py_ssize_t *e)
/* Correction term for round-half-to-even rounding. For a digit x,
"x + half_even_correction[x & 7]" gives x rounded to the nearest
multiple of 4, rounding ties to a multiple of 8. */
static const int half_even_correction[8] = {0, -1, -2, 1, 0, -1, 2, 1};
static const int half_even_correction[8] = { // Static is okay here (immutable data).
0, -1, -2, 1, 0, -1, 2, 1
};

a_size = Py_ABS(Py_SIZE(a));
if (a_size == 0) {
Expand Down
3 changes: 2 additions & 1 deletion Objects/obmalloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1150,6 +1150,8 @@ _Py_GetAllocatedBlocks(void)
}


static int debug_stats = -1;

/* Allocate a new arena. If we run out of memory, return NULL. Else
* allocate a new arena, and return the address of an arena_object
* describing the new arena. It's expected that the caller will set
Expand All @@ -1161,7 +1163,6 @@ new_arena(void)
struct arena_object* arenaobj;
uint excess; /* number of bytes above pool alignment */
void *address;
static int debug_stats = -1;

if (debug_stats == -1) {
const char *opt = Py_GETENV("PYTHONMALLOCSTATS");
Expand Down
19 changes: 11 additions & 8 deletions Objects/typeobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ _Py_IDENTIFIER(__len__);
_Py_IDENTIFIER(__module__);
_Py_IDENTIFIER(__name__);
_Py_IDENTIFIER(__new__);
_Py_IDENTIFIER(__reduce__);
_Py_IDENTIFIER(__set_name__);
_Py_IDENTIFIER(__setitem__);
_Py_IDENTIFIER(builtins);
Expand Down Expand Up @@ -4552,6 +4553,8 @@ object___reduce___impl(PyObject *self)
return _common_reduce(self, 0);
}

static PyObject *objreduce = NULL;

/*[clinic input]
object.__reduce_ex__

Expand All @@ -4565,9 +4568,7 @@ static PyObject *
object___reduce_ex___impl(PyObject *self, int protocol)
/*[clinic end generated code: output=2e157766f6b50094 input=f326b43fb8a4c5ff]*/
{
static PyObject *objreduce;
PyObject *reduce, *res;
_Py_IDENTIFIER(__reduce__);

if (objreduce == NULL) {
objreduce = _PyDict_GetItemId(PyBaseObject_Type.tp_dict,
Expand Down Expand Up @@ -7078,23 +7079,25 @@ slotptr(PyTypeObject *type, int ioffset)
appropriate to declare fixed-size arrays for this. */
#define MAX_EQUIV 10

/* These act as a little cache. */
static PyObject *last_slot_name = NULL;
static slotdef *last_slot_ptrs[MAX_EQUIV];

/* Return a slot pointer for a given name, but ONLY if the attribute has
exactly one slot function. The name must be an interned string. */
static void **
resolve_slotdups(PyTypeObject *type, PyObject *name)
{
/* XXX Maybe this could be optimized more -- but is it worth it? */

/* pname and ptrs act as a little cache */
static PyObject *pname;
static slotdef *ptrs[MAX_EQUIV];
slotdef *p, **pp;
void **res, **ptr;
slotdef **ptrs = last_slot_ptrs;

if (pname != name) {
if (last_slot_name != name) {
/* Collect all slotdefs that match name into ptrs. */
pname = name;
pp = ptrs;
last_slot_name = name;
pp = last_slot_ptrs;
for (p = slotdefs; p->name_strobj; p++) {
if (p->name_strobj == name)
*pp++ = p;
Expand Down
12 changes: 8 additions & 4 deletions Objects/unicodeobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -4158,7 +4158,8 @@ unicode_decode_call_errorhandler_wchar(
Py_ssize_t *endinpos, PyObject **exceptionObject, const char **inptr,
wchar_t **buf, Py_ssize_t *bufsize, Py_ssize_t *outpos)
{
static const char *argparse = "Un;decoding error handler must return (str, int) tuple";
static const char *argparse = // Static is okay here (immutable data).
"Un;decoding error handler must return (str, int) tuple";

PyObject *restuple = NULL;
PyObject *repunicode = NULL;
Expand Down Expand Up @@ -4262,7 +4263,8 @@ unicode_decode_call_errorhandler_writer(
Py_ssize_t *endinpos, PyObject **exceptionObject, const char **inptr,
_PyUnicodeWriter *writer /* PyObject **output, Py_ssize_t *outpos */)
{
static const char *argparse = "Un;decoding error handler must return (str, int) tuple";
static const char *argparse = // Static is okay here (immutable data).
"Un;decoding error handler must return (str, int) tuple";

PyObject *restuple = NULL;
PyObject *repunicode = NULL;
Expand Down Expand Up @@ -6705,7 +6707,8 @@ unicode_encode_call_errorhandler(const char *errors,
Py_ssize_t startpos, Py_ssize_t endpos,
Py_ssize_t *newpos)
{
static const char *argparse = "On;encoding error handler must return (str/bytes, int) tuple";
static const char *argparse = // Static is okay here (immutable data).
"On;encoding error handler must return (str/bytes, int) tuple";
Py_ssize_t len;
PyObject *restuple;
PyObject *resunicode;
Expand Down Expand Up @@ -8694,7 +8697,8 @@ unicode_translate_call_errorhandler(const char *errors,
Py_ssize_t startpos, Py_ssize_t endpos,
Py_ssize_t *newpos)
{
static const char *argparse = "Un;translating error handler must return (str, int) tuple";
static const char *argparse = // Static is okay here (immutable data).
"Un;translating error handler must return (str, int) tuple";

Py_ssize_t i_newpos;
PyObject *restuple;
Expand Down