Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Move the cached values in resolve_slotdups() to PyInterpreterState.
  • Loading branch information
ericsnowcurrently committed Nov 14, 2022
commit f748f82dee129e96c134988801e294845220d1a5
3 changes: 3 additions & 0 deletions Include/internal/pycore_global_objects.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ extern "C" {

#include "pycore_gc.h" // PyGC_Head
#include "pycore_global_strings.h" // struct _Py_global_strings
#include "pycore_typeobject.h" // pytype_slotdef


// These would be in pycore_long.h if it weren't for an include cycle.
Expand Down Expand Up @@ -56,6 +57,8 @@ struct _Py_interp_cached_objects {
int _not_set;
/* object.__reduce__ */
PyObject *objreduce;
PyObject *type_slots_pname;
pytype_slotdef *type_slots_ptrs[MAX_EQUIV];
};

#define _Py_INTERP_STATIC_OBJECT(interp, NAME) \
Expand Down
9 changes: 9 additions & 0 deletions Include/internal/pycore_typeobject.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,15 @@ extern void _PyTypes_Fini(PyInterpreterState *);

/* other API */

/* Length of array of slotdef pointers used to store slots with the
same __name__. There should be at most MAX_EQUIV-1 slotdef entries with
the same __name__, for any __name__. Since that's a static property, it is
appropriate to declare fixed-size arrays for this. */
#define MAX_EQUIV 10

typedef struct wrapperbase pytype_slotdef;


// Type attribute lookup cache: speed up attribute and method lookups,
// see _PyType_Lookup().
struct type_cache_entry {
Expand Down
37 changes: 16 additions & 21 deletions Objects/typeobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -8526,8 +8526,6 @@ __ne__ etc. all map to tp_richcompare) and one name may map to multiple slots
an all-zero entry.
*/

typedef struct wrapperbase slotdef;

#undef TPSLOT
#undef FLSLOT
#undef AMSLOT
Expand Down Expand Up @@ -8576,7 +8574,7 @@ typedef struct wrapperbase slotdef;
ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_r, \
#NAME "($self, value, /)\n--\n\n" DOC)

static slotdef slotdefs[] = {
static pytype_slotdef slotdefs[] = {
TPSLOT(__getattribute__, tp_getattr, NULL, NULL, ""),
TPSLOT(__getattr__, tp_getattr, NULL, NULL, ""),
TPSLOT(__setattr__, tp_setattr, NULL, NULL, ""),
Expand Down Expand Up @@ -8801,12 +8799,6 @@ slotptr(PyTypeObject *type, int ioffset)
return (void **)ptr;
}

/* Length of array of slotdef pointers used to store slots with the
same __name__. There should be at most MAX_EQUIV-1 slotdef entries with
the same __name__, for any __name__. Since that's a static property, it is
appropriate to declare fixed-size arrays for this. */
#define MAX_EQUIV 10

/* 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 **
Expand All @@ -8815,9 +8807,10 @@ 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;
PyInterpreterState *interp = _PyInterpreterState_Get();
#define pname _Py_INTERP_CACHED_OBJECT(interp, type_slots_pname)
#define ptrs _Py_INTERP_CACHED_OBJECT(interp, type_slots_ptrs)
pytype_slotdef *p, **pp;
void **res, **ptr;

if (pname != name) {
Expand All @@ -8844,6 +8837,8 @@ resolve_slotdups(PyTypeObject *type, PyObject *name)
res = ptr;
}
return res;
#undef pname
#undef ptrs
}


Expand Down Expand Up @@ -8901,8 +8896,8 @@ resolve_slotdups(PyTypeObject *type, PyObject *name)
* When done, return a pointer to the next slotdef with a different offset,
* because that's convenient for fixup_slot_dispatchers(). This function never
* sets an exception: if an internal error happens (unlikely), it's ignored. */
static slotdef *
update_one_slot(PyTypeObject *type, slotdef *p)
static pytype_slotdef *
update_one_slot(PyTypeObject *type, pytype_slotdef *p)
{
PyObject *descr;
PyWrapperDescrObject *d;
Expand Down Expand Up @@ -9017,7 +9012,7 @@ update_one_slot(PyTypeObject *type, slotdef *p)
static int
update_slots_callback(PyTypeObject *type, void *data)
{
slotdef **pp = (slotdef **)data;
pytype_slotdef **pp = (pytype_slotdef **)data;
for (; *pp; pp++) {
update_one_slot(type, *pp);
}
Expand All @@ -9028,9 +9023,9 @@ update_slots_callback(PyTypeObject *type, void *data)
static int
update_slot(PyTypeObject *type, PyObject *name)
{
slotdef *ptrs[MAX_EQUIV];
slotdef *p;
slotdef **pp;
pytype_slotdef *ptrs[MAX_EQUIV];
pytype_slotdef *p;
pytype_slotdef **pp;
int offset;

assert(PyUnicode_CheckExact(name));
Expand Down Expand Up @@ -9067,15 +9062,15 @@ static void
fixup_slot_dispatchers(PyTypeObject *type)
{
assert(!PyErr_Occurred());
for (slotdef *p = slotdefs; p->name; ) {
for (pytype_slotdef *p = slotdefs; p->name; ) {
p = update_one_slot(type, p);
}
}

static void
update_all_slots(PyTypeObject* type)
{
slotdef *p;
pytype_slotdef *p;

/* Clear the VALID_VERSION flag of 'type' and all its subclasses. */
PyType_Modified(type);
Expand Down Expand Up @@ -9246,7 +9241,7 @@ static int
add_operators(PyTypeObject *type)
{
PyObject *dict = type->tp_dict;
slotdef *p;
pytype_slotdef *p;
PyObject *descr;
void **ptr;

Expand Down
4 changes: 0 additions & 4 deletions Tools/c-analyzer/cpython/globals-to-fix.tsv
Original file line number Diff line number Diff line change
Expand Up @@ -312,9 +312,6 @@ Python/context.c - _token_missing -
Python/hamt.c - _empty_bitmap_node -
Python/hamt.c - _empty_hamt -

# state
Objects/typeobject.c resolve_slotdups pname -


##################################
# global non-objects to fix in core code
Expand Down Expand Up @@ -436,7 +433,6 @@ Python/perf_trampoline.c - extra_code_index -
Python/perf_trampoline.c - code_arena -
Python/perf_trampoline.c - trampoline_api -
Objects/typeobject.c - next_version_tag -
Objects/typeobject.c resolve_slotdups ptrs -
Parser/pegen.c - memo_statistics -
Python/bootstrap_hash.c - urandom_cache -
Python/ceval_gil.c make_pending_calls busy -
Expand Down