Skip to content

Commit 3b2d74c

Browse files
markshannonwarsaw
authored andcommitted
pythonGH-100987: Don't cache references to the names and consts array in _PyEval_EvalFrameDefault. (python#102640)
* Rename local variables, names and consts, from the interpeter loop. Will allow non-code objects in frames for better introspection of C builtins and extensions. * Remove unused dummy variables.
1 parent 4c6e7d5 commit 3b2d74c

File tree

3 files changed

+44
-53
lines changed

3 files changed

+44
-53
lines changed

Python/bytecodes.c

+21-23
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,6 @@ dummy_func(
7070
unsigned int oparg,
7171
_Py_atomic_int * const eval_breaker,
7272
_PyCFrame cframe,
73-
PyObject *names,
74-
PyObject *consts,
7573
_Py_CODEUNIT *next_instr,
7674
PyObject **stack_pointer,
7775
PyObject *kwnames,
@@ -115,7 +113,7 @@ dummy_func(
115113
}
116114

117115
inst(LOAD_CONST, (-- value)) {
118-
value = GETITEM(consts, oparg);
116+
value = GETITEM(frame->f_code->co_consts, oparg);
119117
Py_INCREF(value);
120118
}
121119

@@ -554,7 +552,7 @@ dummy_func(
554552
}
555553

556554
inst(RETURN_CONST, (--)) {
557-
PyObject *retval = GETITEM(consts, oparg);
555+
PyObject *retval = GETITEM(frame->f_code->co_consts, oparg);
558556
Py_INCREF(retval);
559557
assert(EMPTY());
560558
_PyFrame_SetStackPointer(frame, stack_pointer);
@@ -844,7 +842,7 @@ dummy_func(
844842
}
845843

846844
inst(STORE_NAME, (v -- )) {
847-
PyObject *name = GETITEM(names, oparg);
845+
PyObject *name = GETITEM(frame->f_code->co_names, oparg);
848846
PyObject *ns = LOCALS();
849847
int err;
850848
if (ns == NULL) {
@@ -862,7 +860,7 @@ dummy_func(
862860
}
863861

864862
inst(DELETE_NAME, (--)) {
865-
PyObject *name = GETITEM(names, oparg);
863+
PyObject *name = GETITEM(frame->f_code->co_names, oparg);
866864
PyObject *ns = LOCALS();
867865
int err;
868866
if (ns == NULL) {
@@ -956,7 +954,7 @@ dummy_func(
956954
#if ENABLE_SPECIALIZATION
957955
if (ADAPTIVE_COUNTER_IS_ZERO(counter)) {
958956
assert(cframe.use_tracing == 0);
959-
PyObject *name = GETITEM(names, oparg);
957+
PyObject *name = GETITEM(frame->f_code->co_names, oparg);
960958
next_instr--;
961959
_Py_Specialize_StoreAttr(owner, next_instr, name);
962960
DISPATCH_SAME_OPARG();
@@ -967,29 +965,29 @@ dummy_func(
967965
#else
968966
(void)counter; // Unused.
969967
#endif /* ENABLE_SPECIALIZATION */
970-
PyObject *name = GETITEM(names, oparg);
968+
PyObject *name = GETITEM(frame->f_code->co_names, oparg);
971969
int err = PyObject_SetAttr(owner, name, v);
972970
Py_DECREF(v);
973971
Py_DECREF(owner);
974972
ERROR_IF(err, error);
975973
}
976974

977975
inst(DELETE_ATTR, (owner --)) {
978-
PyObject *name = GETITEM(names, oparg);
976+
PyObject *name = GETITEM(frame->f_code->co_names, oparg);
979977
int err = PyObject_SetAttr(owner, name, (PyObject *)NULL);
980978
Py_DECREF(owner);
981979
ERROR_IF(err, error);
982980
}
983981

984982
inst(STORE_GLOBAL, (v --)) {
985-
PyObject *name = GETITEM(names, oparg);
983+
PyObject *name = GETITEM(frame->f_code->co_names, oparg);
986984
int err = PyDict_SetItem(GLOBALS(), name, v);
987985
Py_DECREF(v);
988986
ERROR_IF(err, error);
989987
}
990988

991989
inst(DELETE_GLOBAL, (--)) {
992-
PyObject *name = GETITEM(names, oparg);
990+
PyObject *name = GETITEM(frame->f_code->co_names, oparg);
993991
int err;
994992
err = PyDict_DelItem(GLOBALS(), name);
995993
// Can't use ERROR_IF here.
@@ -1003,7 +1001,7 @@ dummy_func(
10031001
}
10041002

10051003
inst(LOAD_NAME, ( -- v)) {
1006-
PyObject *name = GETITEM(names, oparg);
1004+
PyObject *name = GETITEM(frame->f_code->co_names, oparg);
10071005
PyObject *locals = LOCALS();
10081006
if (locals == NULL) {
10091007
_PyErr_Format(tstate, PyExc_SystemError,
@@ -1074,15 +1072,15 @@ dummy_func(
10741072
_PyLoadGlobalCache *cache = (_PyLoadGlobalCache *)next_instr;
10751073
if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
10761074
assert(cframe.use_tracing == 0);
1077-
PyObject *name = GETITEM(names, oparg>>1);
1075+
PyObject *name = GETITEM(frame->f_code->co_names, oparg>>1);
10781076
next_instr--;
10791077
_Py_Specialize_LoadGlobal(GLOBALS(), BUILTINS(), next_instr, name);
10801078
DISPATCH_SAME_OPARG();
10811079
}
10821080
STAT_INC(LOAD_GLOBAL, deferred);
10831081
DECREMENT_ADAPTIVE_COUNTER(cache->counter);
10841082
#endif /* ENABLE_SPECIALIZATION */
1085-
PyObject *name = GETITEM(names, oparg>>1);
1083+
PyObject *name = GETITEM(frame->f_code->co_names, oparg>>1);
10861084
if (PyDict_CheckExact(GLOBALS())
10871085
&& PyDict_CheckExact(BUILTINS()))
10881086
{
@@ -1436,15 +1434,15 @@ dummy_func(
14361434
_PyAttrCache *cache = (_PyAttrCache *)next_instr;
14371435
if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
14381436
assert(cframe.use_tracing == 0);
1439-
PyObject *name = GETITEM(names, oparg>>1);
1437+
PyObject *name = GETITEM(frame->f_code->co_names, oparg>>1);
14401438
next_instr--;
14411439
_Py_Specialize_LoadAttr(owner, next_instr, name);
14421440
DISPATCH_SAME_OPARG();
14431441
}
14441442
STAT_INC(LOAD_ATTR, deferred);
14451443
DECREMENT_ADAPTIVE_COUNTER(cache->counter);
14461444
#endif /* ENABLE_SPECIALIZATION */
1447-
PyObject *name = GETITEM(names, oparg >> 1);
1445+
PyObject *name = GETITEM(frame->f_code->co_names, oparg >> 1);
14481446
if (oparg & 1) {
14491447
/* Designed to work in tandem with CALL, pushes two values. */
14501448
PyObject* meth = NULL;
@@ -1525,7 +1523,7 @@ dummy_func(
15251523
PyDictObject *dict = (PyDictObject *)_PyDictOrValues_GetDict(dorv);
15261524
DEOPT_IF(dict == NULL, LOAD_ATTR);
15271525
assert(PyDict_CheckExact((PyObject *)dict));
1528-
PyObject *name = GETITEM(names, oparg>>1);
1526+
PyObject *name = GETITEM(frame->f_code->co_names, oparg>>1);
15291527
uint16_t hint = index;
15301528
DEOPT_IF(hint >= (size_t)dict->ma_keys->dk_nentries, LOAD_ATTR);
15311529
if (DK_IS_UNICODE(dict->ma_keys)) {
@@ -1616,7 +1614,7 @@ dummy_func(
16161614
DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), LOAD_ATTR);
16171615
STAT_INC(LOAD_ATTR, hit);
16181616

1619-
PyObject *name = GETITEM(names, oparg >> 1);
1617+
PyObject *name = GETITEM(frame->f_code->co_names, oparg >> 1);
16201618
Py_INCREF(f);
16211619
_PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, f, 2);
16221620
// Manipulate stack directly because we exit with DISPATCH_INLINED().
@@ -1661,7 +1659,7 @@ dummy_func(
16611659
PyDictObject *dict = (PyDictObject *)_PyDictOrValues_GetDict(dorv);
16621660
DEOPT_IF(dict == NULL, STORE_ATTR);
16631661
assert(PyDict_CheckExact((PyObject *)dict));
1664-
PyObject *name = GETITEM(names, oparg);
1662+
PyObject *name = GETITEM(frame->f_code->co_names, oparg);
16651663
DEOPT_IF(hint >= (size_t)dict->ma_keys->dk_nentries, STORE_ATTR);
16661664
PyObject *old_value;
16671665
uint64_t new_version;
@@ -1855,14 +1853,14 @@ dummy_func(
18551853
}
18561854

18571855
inst(IMPORT_NAME, (level, fromlist -- res)) {
1858-
PyObject *name = GETITEM(names, oparg);
1856+
PyObject *name = GETITEM(frame->f_code->co_names, oparg);
18591857
res = import_name(tstate, frame, name, fromlist, level);
18601858
DECREF_INPUTS();
18611859
ERROR_IF(res == NULL, error);
18621860
}
18631861

18641862
inst(IMPORT_FROM, (from -- from, res)) {
1865-
PyObject *name = GETITEM(names, oparg);
1863+
PyObject *name = GETITEM(frame->f_code->co_names, oparg);
18661864
res = import_from(tstate, from, name);
18671865
ERROR_IF(res == NULL, error);
18681866
}
@@ -2360,8 +2358,8 @@ dummy_func(
23602358

23612359
inst(KW_NAMES, (--)) {
23622360
assert(kwnames == NULL);
2363-
assert(oparg < PyTuple_GET_SIZE(consts));
2364-
kwnames = GETITEM(consts, oparg);
2361+
assert(oparg < PyTuple_GET_SIZE(frame->f_code->co_consts));
2362+
kwnames = GETITEM(frame->f_code->co_consts, oparg);
23652363
}
23662364

23672365
// Cache layout: counter/1, func_version/2, min_args/1

Python/ceval.c

-7
Original file line numberDiff line numberDiff line change
@@ -773,18 +773,11 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
773773
/* Local "register" variables.
774774
* These are cached values from the frame and code object. */
775775

776-
PyObject *names;
777-
PyObject *consts;
778776
_Py_CODEUNIT *next_instr;
779777
PyObject **stack_pointer;
780778

781779
/* Sets the above local variables from the frame */
782780
#define SET_LOCALS_FROM_FRAME() \
783-
{ \
784-
PyCodeObject *co = frame->f_code; \
785-
names = co->co_names; \
786-
consts = co->co_consts; \
787-
} \
788781
assert(_PyInterpreterFrame_LASTI(frame) >= -1); \
789782
/* Jump back to the last instruction executed... */ \
790783
next_instr = frame->prev_instr + 1; \

0 commit comments

Comments
 (0)