gh-121547: deduplicate the code of const_cache update functions (#121548)

This commit is contained in:
Irit Katriel 2024-07-10 11:34:54 +01:00 committed by GitHub
parent e2822360da
commit cced22c760
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 22 additions and 25 deletions

View File

@ -741,9 +741,11 @@ dict_add_o(PyObject *dict, PyObject *o)
return arg; return arg;
} }
// Merge const *o* recursively and return constant key object. /* Merge const *o* and return constant key object.
* If recursive, insert all elements if o is a tuple or frozen set.
*/
static PyObject* static PyObject*
merge_consts_recursive(PyObject *const_cache, PyObject *o) const_cache_insert(PyObject *const_cache, PyObject *o, bool recursive)
{ {
assert(PyDict_CheckExact(const_cache)); assert(PyDict_CheckExact(const_cache));
// None and Ellipsis are immortal objects, and key is the singleton. // None and Ellipsis are immortal objects, and key is the singleton.
@ -767,6 +769,10 @@ merge_consts_recursive(PyObject *const_cache, PyObject *o)
} }
Py_DECREF(t); Py_DECREF(t);
if (!recursive) {
return key;
}
// We registered o in const_cache. // We registered o in const_cache.
// When o is a tuple or frozenset, we want to merge its // When o is a tuple or frozenset, we want to merge its
// items too. // items too.
@ -774,7 +780,7 @@ merge_consts_recursive(PyObject *const_cache, PyObject *o)
Py_ssize_t len = PyTuple_GET_SIZE(o); Py_ssize_t len = PyTuple_GET_SIZE(o);
for (Py_ssize_t i = 0; i < len; i++) { for (Py_ssize_t i = 0; i < len; i++) {
PyObject *item = PyTuple_GET_ITEM(o, i); PyObject *item = PyTuple_GET_ITEM(o, i);
PyObject *u = merge_consts_recursive(const_cache, item); PyObject *u = const_cache_insert(const_cache, item, recursive);
if (u == NULL) { if (u == NULL) {
Py_DECREF(key); Py_DECREF(key);
return NULL; return NULL;
@ -816,7 +822,7 @@ merge_consts_recursive(PyObject *const_cache, PyObject *o)
PyObject *item; PyObject *item;
Py_hash_t hash; Py_hash_t hash;
while (_PySet_NextEntry(o, &pos, &item, &hash)) { while (_PySet_NextEntry(o, &pos, &item, &hash)) {
PyObject *k = merge_consts_recursive(const_cache, item); PyObject *k = const_cache_insert(const_cache, item, recursive);
if (k == NULL) { if (k == NULL) {
Py_DECREF(tuple); Py_DECREF(tuple);
Py_DECREF(key); Py_DECREF(key);
@ -850,6 +856,12 @@ merge_consts_recursive(PyObject *const_cache, PyObject *o)
return key; return key;
} }
static PyObject*
merge_consts_recursive(PyObject *const_cache, PyObject *o)
{
return const_cache_insert(const_cache, o, true);
}
static Py_ssize_t static Py_ssize_t
compiler_add_const(PyObject *const_cache, struct compiler_unit *u, PyObject *o) compiler_add_const(PyObject *const_cache, struct compiler_unit *u, PyObject *o)
{ {
@ -7506,37 +7518,22 @@ compute_code_flags(struct compiler *c)
return flags; return flags;
} }
// Merge *obj* with constant cache. // Merge *obj* with constant cache, without recursion.
// Unlike merge_consts_recursive(), this function doesn't work recursively.
int int
_PyCompile_ConstCacheMergeOne(PyObject *const_cache, PyObject **obj) _PyCompile_ConstCacheMergeOne(PyObject *const_cache, PyObject **obj)
{ {
assert(PyDict_CheckExact(const_cache)); PyObject *key = const_cache_insert(const_cache, *obj, false);
PyObject *key = _PyCode_ConstantKey(*obj);
if (key == NULL) { if (key == NULL) {
return ERROR; return ERROR;
} }
if (PyTuple_CheckExact(key)) {
PyObject *t; PyObject *item = PyTuple_GET_ITEM(key, 1);
int res = PyDict_SetDefaultRef(const_cache, key, key, &t);
Py_DECREF(key);
if (res < 0) {
return ERROR;
}
if (res == 0) { // inserted: obj is new constant.
Py_DECREF(t);
return SUCCESS;
}
if (PyTuple_CheckExact(t)) {
PyObject *item = PyTuple_GET_ITEM(t, 1);
Py_SETREF(*obj, Py_NewRef(item)); Py_SETREF(*obj, Py_NewRef(item));
Py_DECREF(t); Py_DECREF(key);
} }
else { else {
Py_SETREF(*obj, t); Py_SETREF(*obj, key);
} }
return SUCCESS; return SUCCESS;
} }