bpo-43693: Revert commits 2c1e2583fd and b2bf2bc1ec (GH-26530)

* Revert "bpo-43693: Compute deref offsets in compiler (gh-25152)"

This reverts commit b2bf2bc1ec.

* Revert "bpo-43693: Add new internal code objects fields: co_fastlocalnames and co_fastlocalkinds. (gh-26388)"

This reverts commit 2c1e2583fd.

These two commits are breaking the refleak buildbots.
This commit is contained in:
Pablo Galindo 2021-06-04 17:51:05 +01:00 committed by GitHub
parent a46c220edc
commit 17c4edc4e0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 5707 additions and 6028 deletions

View file

@ -2047,16 +2047,16 @@ static int
compiler_make_closure(struct compiler *c, PyCodeObject *co, Py_ssize_t flags,
PyObject *qualname)
{
Py_ssize_t i, free = PyCode_GetNumFree(co);
if (qualname == NULL)
qualname = co->co_name;
if (co->co_nfreevars) {
int i = co->co_nlocals + co->co_ncellvars;
for (; i < co->co_nlocalsplus; ++i) {
if (free) {
for (i = 0; i < free; ++i) {
/* Bypass com_addop_varname because it will generate
LOAD_DEREF but LOAD_CLOSURE is needed.
*/
PyObject *name = PyTuple_GET_ITEM(co->co_localsplusnames, i);
PyObject *name = PyTuple_GET_ITEM(co->co_freevars, i);
/* Special case: If a class contains a method with a
free variable that has the same name as a method,
@ -2076,10 +2076,6 @@ compiler_make_closure(struct compiler *c, PyCodeObject *co, Py_ssize_t flags,
arg = compiler_lookup_arg(c->u->u_freevars, name);
}
if (arg == -1) {
PyObject *freevars = _PyCode_GetFreevars(co);
if (freevars == NULL) {
PyErr_Clear();
}
PyErr_Format(PyExc_SystemError,
"compiler_lookup_arg(name=%R) with reftype=%d failed in %S; "
"freevars of code %S: %R",
@ -2087,13 +2083,13 @@ compiler_make_closure(struct compiler *c, PyCodeObject *co, Py_ssize_t flags,
reftype,
c->u->u_name,
co->co_name,
freevars);
co->co_freevars);
return 0;
}
ADDOP_I(c, LOAD_CLOSURE, arg);
}
flags |= 0x08;
ADDOP_I(c, BUILD_TUPLE, co->co_nfreevars);
ADDOP_I(c, BUILD_TUPLE, free);
}
ADDOP_LOAD_CONST(c, (PyObject*)co);
ADDOP_LOAD_CONST(c, qualname);
@ -7180,46 +7176,6 @@ merge_const_one(struct compiler *c, PyObject **obj)
return 1;
}
// This is in codeobject.c.
extern void _Py_set_localsplus_info(int, PyObject *, _PyLocalsPlusKind,
PyObject *, _PyLocalsPlusKinds);
static void
compute_localsplus_info(struct compiler *c,
PyObject *names, _PyLocalsPlusKinds kinds)
{
int nlocalsplus = (int)PyTuple_GET_SIZE(names);
PyObject *k, *v;
Py_ssize_t pos = 0;
while (PyDict_Next(c->u->u_varnames, &pos, &k, &v)) {
int offset = (int)PyLong_AS_LONG(v);
assert(offset >= 0);
assert(offset < nlocalsplus);
// For now we do not distinguish arg kinds.
_Py_set_localsplus_info(offset, k, CO_FAST_LOCAL, names, kinds);
}
int nlocals = (int)PyDict_GET_SIZE(c->u->u_varnames);
pos = 0;
while (PyDict_Next(c->u->u_cellvars, &pos, &k, &v)) {
int offset = (int)PyLong_AS_LONG(v);
assert(offset >= 0);
offset += nlocals;
assert(offset < nlocalsplus);
_Py_set_localsplus_info(offset, k, CO_FAST_CELL, names, kinds);
}
pos = 0;
while (PyDict_Next(c->u->u_freevars, &pos, &k, &v)) {
int offset = (int)PyLong_AS_LONG(v);
assert(offset >= 0);
offset += nlocals;
assert(offset < nlocalsplus);
_Py_set_localsplus_info(offset, k, CO_FAST_FREE, names, kinds);
}
}
static PyCodeObject *
makecode(struct compiler *c, struct assembler *a, PyObject *constslist,
int maxdepth)
@ -7227,22 +7183,36 @@ makecode(struct compiler *c, struct assembler *a, PyObject *constslist,
PyCodeObject *co = NULL;
PyObject *names = NULL;
PyObject *consts = NULL;
PyObject *localsplusnames = NULL;
_PyLocalsPlusKinds localspluskinds = NULL;
PyObject *varnames = NULL;
PyObject *name = NULL;
PyObject *freevars = NULL;
PyObject *cellvars = NULL;
int flags;
int posorkeywordargcount, posonlyargcount, kwonlyargcount;
names = dict_keys_inorder(c->u->u_names, 0);
if (!names) {
varnames = dict_keys_inorder(c->u->u_varnames, 0);
if (!names || !varnames) {
goto error;
}
if (!merge_const_one(c, &names)) {
cellvars = dict_keys_inorder(c->u->u_cellvars, 0);
if (!cellvars)
goto error;
freevars = dict_keys_inorder(c->u->u_freevars, PyTuple_GET_SIZE(cellvars));
if (!freevars)
goto error;
if (!merge_const_one(c, &names) ||
!merge_const_one(c, &varnames) ||
!merge_const_one(c, &cellvars) ||
!merge_const_one(c, &freevars))
{
goto error;
}
int flags = compute_code_flags(c);
if (flags < 0) {
flags = compute_code_flags(c);
if (flags < 0)
goto error;
}
consts = PyList_AsTuple(constslist); /* PyCode_New requires a tuple */
if (consts == NULL) {
@ -7252,32 +7222,9 @@ makecode(struct compiler *c, struct assembler *a, PyObject *constslist,
goto error;
}
assert(c->u->u_posonlyargcount < INT_MAX);
assert(c->u->u_argcount < INT_MAX);
assert(c->u->u_kwonlyargcount < INT_MAX);
int posonlyargcount = (int)c->u->u_posonlyargcount;
int posorkwargcount = (int)c->u->u_argcount;
assert(INT_MAX - posonlyargcount - posorkwargcount > 0);
int kwonlyargcount = (int)c->u->u_kwonlyargcount;
Py_ssize_t nlocals = PyDict_GET_SIZE(c->u->u_varnames);
Py_ssize_t ncellvars = PyDict_GET_SIZE(c->u->u_cellvars);
Py_ssize_t nfreevars = PyDict_GET_SIZE(c->u->u_freevars);
assert(nlocals < INT_MAX);
assert(ncellvars < INT_MAX);
assert(nfreevars < INT_MAX);
assert(INT_MAX - nlocals - ncellvars - nfreevars > 0);
int nlocalsplus = (int)nlocals + (int)ncellvars + (int)nfreevars;
localsplusnames = PyTuple_New(nlocalsplus);
if (localsplusnames == NULL) {
goto error;
}
if (_PyCode_InitLocalsPlusKinds(nlocalsplus, &localspluskinds) < 0) {
goto error;
}
compute_localsplus_info(c, localsplusnames, localspluskinds);
posonlyargcount = Py_SAFE_DOWNCAST(c->u->u_posonlyargcount, Py_ssize_t, int);
posorkeywordargcount = Py_SAFE_DOWNCAST(c->u->u_argcount, Py_ssize_t, int);
kwonlyargcount = Py_SAFE_DOWNCAST(c->u->u_kwonlyargcount, Py_ssize_t, int);
struct _PyCodeConstructor con = {
.filename = c->c_filename,
.name = c->u->u_name,
@ -7290,10 +7237,11 @@ makecode(struct compiler *c, struct assembler *a, PyObject *constslist,
.consts = consts,
.names = names,
.localsplusnames = localsplusnames,
.localspluskinds = localspluskinds,
.varnames = varnames,
.cellvars = cellvars,
.freevars = freevars,
.argcount = posonlyargcount + posorkwargcount,
.argcount = posonlyargcount + posorkeywordargcount,
.posonlyargcount = posonlyargcount,
.kwonlyargcount = kwonlyargcount,
@ -7301,30 +7249,18 @@ makecode(struct compiler *c, struct assembler *a, PyObject *constslist,
.exceptiontable = a->a_except_table,
};
if (_PyCode_Validate(&con) < 0) {
goto error;
}
if (!merge_const_one(c, &localsplusnames)) {
_PyCode_ClearLocalsPlusKinds(con.localspluskinds);
goto error;
}
con.localsplusnames = localsplusnames;
co = _PyCode_New(&con);
if (co == NULL) {
goto error;
}
localspluskinds = NULL; // This keeps it from getting freed below.
error:
Py_XDECREF(names);
Py_XDECREF(consts);
Py_XDECREF(localsplusnames);
_PyCode_ClearLocalsPlusKinds(localspluskinds);
Py_XDECREF(varnames);
Py_XDECREF(name);
Py_XDECREF(freevars);
Py_XDECREF(cellvars);
return co;
}
@ -7435,24 +7371,6 @@ guarantee_lineno_for_exits(struct assembler *a, int firstlineno) {
}
}
static void
offset_derefs(basicblock *entryblock, int nlocals)
{
for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
for (int i = 0; i < b->b_iused; i++) {
struct instr *inst = &b->b_instr[i];
switch(inst->i_opcode) {
case LOAD_CLOSURE:
case LOAD_DEREF:
case STORE_DEREF:
case DELETE_DEREF:
case LOAD_CLASSDEREF:
inst->i_oparg += nlocals;
}
}
}
}
static PyCodeObject *
assemble(struct compiler *c, int addNone)
{
@ -7508,9 +7426,6 @@ assemble(struct compiler *c, int addNone)
a.a_entry = entryblock;
a.a_nblocks = nblocks;
assert(PyDict_GET_SIZE(c->u->u_varnames) < INT_MAX);
offset_derefs(entryblock, (int)PyDict_GET_SIZE(c->u->u_varnames));
consts = consts_dict_keys_inorder(c->u->u_consts);
if (consts == NULL) {
goto error;