+
-
+
-
-
+
+
@@ -13014,7 +13017,7 @@
-
+
@@ -13085,9 +13088,9 @@
-
-
-
+
+
+
@@ -13171,7 +13174,7 @@
-
+
@@ -13205,8 +13208,8 @@
-
-
+
+
@@ -13238,7 +13241,7 @@
-
+
@@ -14204,41 +14207,41 @@
-
+
-
+
-
+
-
+
-
+
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
@@ -14531,7 +14534,7 @@
-
+
@@ -14540,7 +14543,7 @@
-
+
@@ -14785,7 +14788,7 @@
-
+
@@ -14812,7 +14815,7 @@
-
+
@@ -14872,7 +14875,7 @@
-
+
@@ -14916,7 +14919,7 @@
-
+
@@ -15043,7 +15046,7 @@
-
+
@@ -15588,7 +15591,7 @@
-
+
@@ -15602,7 +15605,7 @@
-
+
@@ -15759,80 +15762,80 @@
-
-
-
-
+
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
-
-
+
+
+
-
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
-
+
+
-
-
-
+
+
+
@@ -16274,10 +16277,10 @@
-
-
-
-
+
+
+
+
@@ -16365,7 +16368,7 @@
-
+
diff --git a/Include/cpython/code.h b/Include/cpython/code.h
index d7c9aee46440b5..66cf4eccb8fcc9 100644
--- a/Include/cpython/code.h
+++ b/Include/cpython/code.h
@@ -89,6 +89,7 @@ typedef uint16_t _Py_CODEUNIT;
PyObject *co_qualname; /* unicode (qualname, for reference) */ \
PyObject *co_linetable; /* bytes object that holds location info */ \
PyObject *co_weakreflist; /* to support weakrefs to code objects */ \
+ PyObject *_co_code; /* cached co_code object/attribute */ \
char *_co_linearray; /* array of line offsets */ \
/* Scratch space for extra data relating to the code object. \
Type is a void* to keep the format private in codeobject.c to force \
diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-05-31-16-36-30.gh-issue-93382.Jf6gAj.rst b/Misc/NEWS.d/next/Core and Builtins/2022-05-31-16-36-30.gh-issue-93382.Jf6gAj.rst
new file mode 100644
index 00000000000000..1fe821edf5a148
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2022-05-31-16-36-30.gh-issue-93382.Jf6gAj.rst
@@ -0,0 +1,2 @@
+Cache the result of :c:func:`PyCode_GetCode` function to restore the O(1)
+lookup of the :attr:`~types.CodeType.co_code` attribute.
diff --git a/Objects/codeobject.c b/Objects/codeobject.c
index 0e914566e30c87..8b9ca890431c6c 100644
--- a/Objects/codeobject.c
+++ b/Objects/codeobject.c
@@ -334,6 +334,7 @@ init_code(PyCodeObject *co, struct _PyCodeConstructor *con)
/* not set */
co->co_weakreflist = NULL;
co->co_extra = NULL;
+ co->_co_code = NULL;
co->co_warmup = QUICKENING_INITIAL_WARMUP_VALUE;
co->_co_linearray_entry_size = 0;
@@ -1421,12 +1422,17 @@ deopt_code(_Py_CODEUNIT *instructions, Py_ssize_t len)
PyObject *
_PyCode_GetCode(PyCodeObject *co)
{
+ if (co->_co_code != NULL) {
+ return Py_NewRef(co->_co_code);
+ }
PyObject *code = PyBytes_FromStringAndSize((const char *)_PyCode_CODE(co),
_PyCode_NBYTES(co));
if (code == NULL) {
return NULL;
}
deopt_code((_Py_CODEUNIT *)PyBytes_AS_STRING(code), Py_SIZE(co));
+ assert(co->_co_code == NULL);
+ co->_co_code = Py_NewRef(code);
return code;
}
@@ -1585,6 +1591,7 @@ code_dealloc(PyCodeObject *co)
Py_XDECREF(co->co_qualname);
Py_XDECREF(co->co_linetable);
Py_XDECREF(co->co_exceptiontable);
+ Py_XDECREF(co->_co_code);
if (co->co_weakreflist != NULL) {
PyObject_ClearWeakRefs((PyObject*)co);
}
@@ -2142,6 +2149,7 @@ _PyStaticCode_Dealloc(PyCodeObject *co)
deopt_code(_PyCode_CODE(co), Py_SIZE(co));
co->co_warmup = QUICKENING_INITIAL_WARMUP_VALUE;
PyMem_Free(co->co_extra);
+ Py_CLEAR(co->_co_code);
co->co_extra = NULL;
if (co->co_weakreflist != NULL) {
PyObject_ClearWeakRefs((PyObject *)co);
diff --git a/Programs/test_frozenmain.h b/Programs/test_frozenmain.h
index 1c279134e94dc9..eec2e0cc6048fa 100644
--- a/Programs/test_frozenmain.h
+++ b/Programs/test_frozenmain.h
@@ -1,7 +1,7 @@
// Auto-generated by Programs/freeze_test_frozenmain.py
unsigned char M_test_frozenmain[] = {
227,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,
- 0,0,0,0,0,115,176,0,0,0,151,0,100,0,100,1,
+ 0,0,0,0,0,243,176,0,0,0,151,0,100,0,100,1,
108,0,90,0,100,0,100,1,108,1,90,1,2,0,101,2,
100,2,166,1,0,0,171,1,0,0,0,0,0,0,0,0,
1,0,2,0,101,2,100,3,101,0,106,3,0,0,0,0,
@@ -24,10 +24,10 @@ unsigned char M_test_frozenmain[] = {
32,122,2,58,32,41,7,218,3,115,121,115,218,17,95,116,
101,115,116,105,110,116,101,114,110,97,108,99,97,112,105,218,
5,112,114,105,110,116,218,4,97,114,103,118,218,11,103,101,
- 116,95,99,111,110,102,105,103,115,114,2,0,0,0,218,3,
+ 116,95,99,111,110,102,105,103,115,114,3,0,0,0,218,3,
107,101,121,169,0,243,0,0,0,0,250,18,116,101,115,116,
95,102,114,111,122,101,110,109,97,105,110,46,112,121,250,8,
- 60,109,111,100,117,108,101,62,114,17,0,0,0,1,0,0,
+ 60,109,111,100,117,108,101,62,114,18,0,0,0,1,0,0,
0,115,152,0,0,0,248,240,6,0,1,11,128,10,128,10,
128,10,216,0,24,208,0,24,208,0,24,208,0,24,224,0,
5,128,5,208,6,26,209,0,27,212,0,27,208,0,27,216,
@@ -37,6 +37,6 @@ unsigned char M_test_frozenmain[] = {
7,1,42,240,0,7,1,42,128,67,240,14,0,5,10,128,
69,208,10,40,144,67,208,10,40,208,10,40,152,54,160,35,
156,59,208,10,40,208,10,40,209,4,41,212,4,41,208,4,
- 41,208,4,41,240,15,7,1,42,240,0,7,1,42,114,15,
+ 41,208,4,41,240,15,7,1,42,240,0,7,1,42,114,16,
0,0,0,
};
diff --git a/Tools/scripts/deepfreeze.py b/Tools/scripts/deepfreeze.py
index 50d0b345ed407d..43a7a98fcc503c 100644
--- a/Tools/scripts/deepfreeze.py
+++ b/Tools/scripts/deepfreeze.py
@@ -279,6 +279,7 @@ def generate_code(self, name: str, code: types.CodeType) -> str:
self.write(f".co_name = {co_name},")
self.write(f".co_qualname = {co_qualname},")
self.write(f".co_linetable = {co_linetable},")
+ self.write(f"._co_code = NULL,")
self.write("._co_linearray = NULL,")
self.write(f".co_code_adaptive = {co_code_adaptive},")
name_as_code = f"(PyCodeObject *)&{name}"
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