Skip to content

Commit 3985abd

Browse files
markshannonFidget-Spinner
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 aaca52a commit 3985abd

File tree

3 files changed

+43
-52
lines changed

3 files changed

+43
-52
lines changed

Python/bytecodes.c

+20-22
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,
@@ -627,7 +625,7 @@ dummy_func(
627625
}
628626

629627
inst(RETURN_CONST, (--)) {
630-
PyObject *retval = GETITEM(consts, oparg);
628+
PyObject *retval = GETITEM(frame->f_code->co_consts, oparg);
631629
Py_INCREF(retval);
632630
assert(EMPTY());
633631
_PyFrame_SetStackPointer(frame, stack_pointer);
@@ -917,7 +915,7 @@ dummy_func(
917915
}
918916

919917
inst(STORE_NAME, (v -- )) {
920-
PyObject *name = GETITEM(names, oparg);
918+
PyObject *name = GETITEM(frame->f_code->co_names, oparg);
921919
PyObject *ns = LOCALS();
922920
int err;
923921
if (ns == NULL) {
@@ -935,7 +933,7 @@ dummy_func(
935933
}
936934

937935
inst(DELETE_NAME, (--)) {
938-
PyObject *name = GETITEM(names, oparg);
936+
PyObject *name = GETITEM(frame->f_code->co_names, oparg);
939937
PyObject *ns = LOCALS();
940938
int err;
941939
if (ns == NULL) {
@@ -1029,7 +1027,7 @@ dummy_func(
10291027
#if ENABLE_SPECIALIZATION
10301028
if (ADAPTIVE_COUNTER_IS_ZERO(counter)) {
10311029
assert(cframe.use_tracing == 0);
1032-
PyObject *name = GETITEM(names, oparg);
1030+
PyObject *name = GETITEM(frame->f_code->co_names, oparg);
10331031
next_instr--;
10341032
_Py_Specialize_StoreAttr(owner, next_instr, name);
10351033
DISPATCH_SAME_OPARG();
@@ -1040,29 +1038,29 @@ dummy_func(
10401038
#else
10411039
(void)counter; // Unused.
10421040
#endif /* ENABLE_SPECIALIZATION */
1043-
PyObject *name = GETITEM(names, oparg);
1041+
PyObject *name = GETITEM(frame->f_code->co_names, oparg);
10441042
int err = PyObject_SetAttr(owner, name, v);
10451043
Py_DECREF(v);
10461044
Py_DECREF(owner);
10471045
ERROR_IF(err, error);
10481046
}
10491047

10501048
inst(DELETE_ATTR, (owner --)) {
1051-
PyObject *name = GETITEM(names, oparg);
1049+
PyObject *name = GETITEM(frame->f_code->co_names, oparg);
10521050
int err = PyObject_SetAttr(owner, name, (PyObject *)NULL);
10531051
Py_DECREF(owner);
10541052
ERROR_IF(err, error);
10551053
}
10561054

10571055
inst(STORE_GLOBAL, (v --)) {
1058-
PyObject *name = GETITEM(names, oparg);
1056+
PyObject *name = GETITEM(frame->f_code->co_names, oparg);
10591057
int err = PyDict_SetItem(GLOBALS(), name, v);
10601058
Py_DECREF(v);
10611059
ERROR_IF(err, error);
10621060
}
10631061

10641062
inst(DELETE_GLOBAL, (--)) {
1065-
PyObject *name = GETITEM(names, oparg);
1063+
PyObject *name = GETITEM(frame->f_code->co_names, oparg);
10661064
int err;
10671065
err = PyDict_DelItem(GLOBALS(), name);
10681066
// Can't use ERROR_IF here.
@@ -1076,7 +1074,7 @@ dummy_func(
10761074
}
10771075

10781076
inst(LOAD_NAME, ( -- v)) {
1079-
PyObject *name = GETITEM(names, oparg);
1077+
PyObject *name = GETITEM(frame->f_code->co_names, oparg);
10801078
PyObject *locals = LOCALS();
10811079
if (locals == NULL) {
10821080
_PyErr_Format(tstate, PyExc_SystemError,
@@ -1147,15 +1145,15 @@ dummy_func(
11471145
_PyLoadGlobalCache *cache = (_PyLoadGlobalCache *)next_instr;
11481146
if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
11491147
assert(cframe.use_tracing == 0);
1150-
PyObject *name = GETITEM(names, oparg>>1);
1148+
PyObject *name = GETITEM(frame->f_code->co_names, oparg>>1);
11511149
next_instr--;
11521150
_Py_Specialize_LoadGlobal(GLOBALS(), BUILTINS(), next_instr, name);
11531151
DISPATCH_SAME_OPARG();
11541152
}
11551153
STAT_INC(LOAD_GLOBAL, deferred);
11561154
DECREMENT_ADAPTIVE_COUNTER(cache->counter);
11571155
#endif /* ENABLE_SPECIALIZATION */
1158-
PyObject *name = GETITEM(names, oparg>>1);
1156+
PyObject *name = GETITEM(frame->f_code->co_names, oparg>>1);
11591157
if (PyDict_CheckExact(GLOBALS())
11601158
&& PyDict_CheckExact(BUILTINS()))
11611159
{
@@ -1509,15 +1507,15 @@ dummy_func(
15091507
_PyAttrCache *cache = (_PyAttrCache *)next_instr;
15101508
if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
15111509
assert(cframe.use_tracing == 0);
1512-
PyObject *name = GETITEM(names, oparg>>1);
1510+
PyObject *name = GETITEM(frame->f_code->co_names, oparg>>1);
15131511
next_instr--;
15141512
_Py_Specialize_LoadAttr(owner, next_instr, name);
15151513
DISPATCH_SAME_OPARG();
15161514
}
15171515
STAT_INC(LOAD_ATTR, deferred);
15181516
DECREMENT_ADAPTIVE_COUNTER(cache->counter);
15191517
#endif /* ENABLE_SPECIALIZATION */
1520-
PyObject *name = GETITEM(names, oparg >> 1);
1518+
PyObject *name = GETITEM(frame->f_code->co_names, oparg >> 1);
15211519
if (oparg & 1) {
15221520
/* Designed to work in tandem with CALL, pushes two values. */
15231521
PyObject* meth = NULL;
@@ -1598,7 +1596,7 @@ dummy_func(
15981596
PyDictObject *dict = (PyDictObject *)_PyDictOrValues_GetDict(dorv);
15991597
DEOPT_IF(dict == NULL, LOAD_ATTR);
16001598
assert(PyDict_CheckExact((PyObject *)dict));
1601-
PyObject *name = GETITEM(names, oparg>>1);
1599+
PyObject *name = GETITEM(frame->f_code->co_names, oparg>>1);
16021600
uint16_t hint = index;
16031601
DEOPT_IF(hint >= (size_t)dict->ma_keys->dk_nentries, LOAD_ATTR);
16041602
if (DK_IS_UNICODE(dict->ma_keys)) {
@@ -1689,7 +1687,7 @@ dummy_func(
16891687
DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), LOAD_ATTR);
16901688
STAT_INC(LOAD_ATTR, hit);
16911689

1692-
PyObject *name = GETITEM(names, oparg >> 1);
1690+
PyObject *name = GETITEM(frame->f_code->co_names, oparg >> 1);
16931691
Py_INCREF(f);
16941692
_PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, f, 2);
16951693
// Manipulate stack directly because we exit with DISPATCH_INLINED().
@@ -1734,7 +1732,7 @@ dummy_func(
17341732
PyDictObject *dict = (PyDictObject *)_PyDictOrValues_GetDict(dorv);
17351733
DEOPT_IF(dict == NULL, STORE_ATTR);
17361734
assert(PyDict_CheckExact((PyObject *)dict));
1737-
PyObject *name = GETITEM(names, oparg);
1735+
PyObject *name = GETITEM(frame->f_code->co_names, oparg);
17381736
DEOPT_IF(hint >= (size_t)dict->ma_keys->dk_nentries, STORE_ATTR);
17391737
PyObject *old_value;
17401738
uint64_t new_version;
@@ -1928,14 +1926,14 @@ dummy_func(
19281926
}
19291927

19301928
inst(IMPORT_NAME, (level, fromlist -- res)) {
1931-
PyObject *name = GETITEM(names, oparg);
1929+
PyObject *name = GETITEM(frame->f_code->co_names, oparg);
19321930
res = import_name(tstate, frame, name, fromlist, level);
19331931
DECREF_INPUTS();
19341932
ERROR_IF(res == NULL, error);
19351933
}
19361934

19371935
inst(IMPORT_FROM, (from -- from, res)) {
1938-
PyObject *name = GETITEM(names, oparg);
1936+
PyObject *name = GETITEM(frame->f_code->co_names, oparg);
19391937
res = import_from(tstate, from, name);
19401938
ERROR_IF(res == NULL, error);
19411939
}
@@ -2588,8 +2586,8 @@ dummy_func(
25882586

25892587
inst(KW_NAMES, (--)) {
25902588
assert(kwnames == NULL);
2591-
assert(oparg < PyTuple_GET_SIZE(consts));
2592-
kwnames = GETITEM(consts, oparg);
2589+
assert(oparg < PyTuple_GET_SIZE(frame->f_code->co_consts));
2590+
kwnames = GETITEM(frame->f_code->co_consts, oparg);
25932591
}
25942592

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

Python/ceval.c

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

784-
PyObject *names;
785-
PyObject *consts;
786784
_Py_CODEUNIT *next_instr;
787785
PyObject **stack_pointer;
788786

789787
/* Sets the above local variables from the frame */
790788
#define SET_LOCALS_FROM_FRAME() \
791-
{ \
792-
PyCodeObject *co = frame->f_code; \
793-
names = co->co_names; \
794-
consts = co->co_consts; \
795-
} \
796789
assert(_PyInterpreterFrame_LASTI(frame) >= -1); \
797790
/* Jump back to the last instruction executed... */ \
798791
next_instr = frame->prev_instr + 1; \

Python/generated_cases.c.h

+23-23
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)