Skip to content

Commit 852b4d4

Browse files
Fidget-Spinnerkumaraditya303sweeneyde
authored
[3.11] gh-93382: Cache result of PyCode_GetCode in codeobject (GH-93383) (#93493)
Co-authored-by: Kumar Aditya <59607654+kumaraditya303@users.noreply.github.com> Co-authored-by: Dennis Sweeney <36520290+sweeneyde@users.noreply.github.com>
1 parent 96a7614 commit 852b4d4

File tree

6 files changed

+543
-528
lines changed

6 files changed

+543
-528
lines changed

Doc/data/python3.11.abi

Lines changed: 527 additions & 524 deletions
Large diffs are not rendered by default.

Include/cpython/code.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ typedef uint16_t _Py_CODEUNIT;
8989
PyObject *co_qualname; /* unicode (qualname, for reference) */ \
9090
PyObject *co_linetable; /* bytes object that holds location info */ \
9191
PyObject *co_weakreflist; /* to support weakrefs to code objects */ \
92+
PyObject *_co_code; /* cached co_code object/attribute */ \
9293
char *_co_linearray; /* array of line offsets */ \
9394
/* Scratch space for extra data relating to the code object. \
9495
Type is a void* to keep the format private in codeobject.c to force \
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Cache the result of :c:func:`PyCode_GetCode` function to restore the O(1)
2+
lookup of the :attr:`~types.CodeType.co_code` attribute.

Objects/codeobject.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,7 @@ init_code(PyCodeObject *co, struct _PyCodeConstructor *con)
334334
/* not set */
335335
co->co_weakreflist = NULL;
336336
co->co_extra = NULL;
337+
co->_co_code = NULL;
337338

338339
co->co_warmup = QUICKENING_INITIAL_WARMUP_VALUE;
339340
co->_co_linearray_entry_size = 0;
@@ -1421,12 +1422,17 @@ deopt_code(_Py_CODEUNIT *instructions, Py_ssize_t len)
14211422
PyObject *
14221423
_PyCode_GetCode(PyCodeObject *co)
14231424
{
1425+
if (co->_co_code != NULL) {
1426+
return Py_NewRef(co->_co_code);
1427+
}
14241428
PyObject *code = PyBytes_FromStringAndSize((const char *)_PyCode_CODE(co),
14251429
_PyCode_NBYTES(co));
14261430
if (code == NULL) {
14271431
return NULL;
14281432
}
14291433
deopt_code((_Py_CODEUNIT *)PyBytes_AS_STRING(code), Py_SIZE(co));
1434+
assert(co->_co_code == NULL);
1435+
co->_co_code = Py_NewRef(code);
14301436
return code;
14311437
}
14321438

@@ -1585,6 +1591,7 @@ code_dealloc(PyCodeObject *co)
15851591
Py_XDECREF(co->co_qualname);
15861592
Py_XDECREF(co->co_linetable);
15871593
Py_XDECREF(co->co_exceptiontable);
1594+
Py_XDECREF(co->_co_code);
15881595
if (co->co_weakreflist != NULL) {
15891596
PyObject_ClearWeakRefs((PyObject*)co);
15901597
}
@@ -2142,6 +2149,7 @@ _PyStaticCode_Dealloc(PyCodeObject *co)
21422149
deopt_code(_PyCode_CODE(co), Py_SIZE(co));
21432150
co->co_warmup = QUICKENING_INITIAL_WARMUP_VALUE;
21442151
PyMem_Free(co->co_extra);
2152+
Py_CLEAR(co->_co_code);
21452153
co->co_extra = NULL;
21462154
if (co->co_weakreflist != NULL) {
21472155
PyObject_ClearWeakRefs((PyObject *)co);

Programs/test_frozenmain.h

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Tools/scripts/deepfreeze.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,7 @@ def generate_code(self, name: str, code: types.CodeType) -> str:
279279
self.write(f".co_name = {co_name},")
280280
self.write(f".co_qualname = {co_qualname},")
281281
self.write(f".co_linetable = {co_linetable},")
282+
self.write(f"._co_code = NULL,")
282283
self.write("._co_linearray = NULL,")
283284
self.write(f".co_code_adaptive = {co_code_adaptive},")
284285
name_as_code = f"(PyCodeObject *)&{name}"

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy