mirror of
https://github.com/python/cpython
synced 2024-09-16 01:21:09 +00:00
bpo-44032: Move pointer to code object from frame-object to frame specials array. (GH-26771)
This commit is contained in:
parent
7f01f77f8f
commit
0982ded179
|
@ -22,7 +22,6 @@ typedef signed char PyFrameState;
|
|||
struct _frame {
|
||||
PyObject_HEAD
|
||||
struct _frame *f_back; /* previous frame, or NULL */
|
||||
PyCodeObject *f_code; /* code segment */
|
||||
PyObject **f_valuestack; /* points after the last local */
|
||||
PyObject *f_trace; /* Trace function */
|
||||
/* Borrowed reference to a generator, or NULL */
|
||||
|
|
|
@ -8,7 +8,8 @@ enum {
|
|||
FRAME_SPECIALS_GLOBALS_OFFSET = 0,
|
||||
FRAME_SPECIALS_BUILTINS_OFFSET = 1,
|
||||
FRAME_SPECIALS_LOCALS_OFFSET = 2,
|
||||
FRAME_SPECIALS_SIZE = 3
|
||||
FRAME_SPECIALS_CODE_OFFSET = 3,
|
||||
FRAME_SPECIALS_SIZE = 4
|
||||
};
|
||||
|
||||
static inline PyObject **
|
||||
|
@ -30,6 +31,13 @@ _PyFrame_GetBuiltins(PyFrameObject *f)
|
|||
return _PyFrame_Specials(f)[FRAME_SPECIALS_BUILTINS_OFFSET];
|
||||
}
|
||||
|
||||
/* Returns a *borrowed* reference. */
|
||||
static inline PyCodeObject *
|
||||
_PyFrame_GetCode(PyFrameObject *f)
|
||||
{
|
||||
return (PyCodeObject *)_PyFrame_Specials(f)[FRAME_SPECIALS_CODE_OFFSET];
|
||||
}
|
||||
|
||||
int _PyFrame_TakeLocals(PyFrameObject *f);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -1275,7 +1275,7 @@ class C(object): pass
|
|||
# frame
|
||||
import inspect
|
||||
x = inspect.currentframe()
|
||||
check(x, size('5P3i4cP'))
|
||||
check(x, size('4P3i4cP'))
|
||||
# function
|
||||
def func(): pass
|
||||
check(func, size('14P'))
|
||||
|
|
|
@ -46,7 +46,7 @@ PyFrame_GetLineNumber(PyFrameObject *f)
|
|||
return f->f_lineno;
|
||||
}
|
||||
else {
|
||||
return PyCode_Addr2Line(f->f_code, f->f_lasti*2);
|
||||
return PyCode_Addr2Line(_PyFrame_GetCode(f), f->f_lasti*2);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -472,7 +472,7 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno, void *Py_UNUSED(ignore
|
|||
}
|
||||
new_lineno = (int)l_new_lineno;
|
||||
|
||||
if (new_lineno < f->f_code->co_firstlineno) {
|
||||
if (new_lineno < _PyFrame_GetCode(f)->co_firstlineno) {
|
||||
PyErr_Format(PyExc_ValueError,
|
||||
"line %d comes before the current code block",
|
||||
new_lineno);
|
||||
|
@ -481,8 +481,8 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno, void *Py_UNUSED(ignore
|
|||
|
||||
/* PyCode_NewWithPosOnlyArgs limits co_code to be under INT_MAX so this
|
||||
* should never overflow. */
|
||||
int len = (int)(PyBytes_GET_SIZE(f->f_code->co_code) / sizeof(_Py_CODEUNIT));
|
||||
int *lines = marklines(f->f_code, len);
|
||||
int len = (int)(PyBytes_GET_SIZE(_PyFrame_GetCode(f)->co_code) / sizeof(_Py_CODEUNIT));
|
||||
int *lines = marklines(_PyFrame_GetCode(f), len);
|
||||
if (lines == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -496,7 +496,7 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno, void *Py_UNUSED(ignore
|
|||
return -1;
|
||||
}
|
||||
|
||||
int64_t *stacks = mark_stacks(f->f_code, len);
|
||||
int64_t *stacks = mark_stacks(_PyFrame_GetCode(f), len);
|
||||
if (stacks == NULL) {
|
||||
PyMem_Free(lines);
|
||||
return -1;
|
||||
|
@ -610,11 +610,17 @@ frame_dealloc(PyFrameObject *f)
|
|||
}
|
||||
|
||||
Py_TRASHCAN_SAFE_BEGIN(f)
|
||||
PyCodeObject *co = f->f_code;
|
||||
PyCodeObject *co = NULL;
|
||||
|
||||
/* Kill all local variables including specials. */
|
||||
if (f->f_localsptr) {
|
||||
for (int i = 0; i < co->co_nlocalsplus+FRAME_SPECIALS_SIZE; i++) {
|
||||
/* Don't clear code object until the end */
|
||||
co = _PyFrame_GetCode(f);
|
||||
PyObject **specials = _PyFrame_Specials(f);
|
||||
Py_CLEAR(specials[FRAME_SPECIALS_GLOBALS_OFFSET]);
|
||||
Py_CLEAR(specials[FRAME_SPECIALS_BUILTINS_OFFSET]);
|
||||
Py_CLEAR(specials[FRAME_SPECIALS_LOCALS_OFFSET]);
|
||||
for (int i = 0; i < co->co_nlocalsplus; i++) {
|
||||
Py_CLEAR(f->f_localsptr[i]);
|
||||
}
|
||||
/* Free items on stack */
|
||||
|
@ -625,6 +631,7 @@ frame_dealloc(PyFrameObject *f)
|
|||
PyMem_Free(f->f_localsptr);
|
||||
f->f_own_locals_memory = 0;
|
||||
}
|
||||
f->f_localsptr = NULL;
|
||||
}
|
||||
f->f_stackdepth = 0;
|
||||
Py_XDECREF(f->f_back);
|
||||
|
@ -643,7 +650,7 @@ frame_dealloc(PyFrameObject *f)
|
|||
PyObject_GC_Del(f);
|
||||
}
|
||||
|
||||
Py_DECREF(co);
|
||||
Py_XDECREF(co);
|
||||
Py_TRASHCAN_SAFE_END(f)
|
||||
}
|
||||
|
||||
|
@ -683,7 +690,7 @@ frame_tp_clear(PyFrameObject *f)
|
|||
f->f_state = FRAME_CLEARED;
|
||||
|
||||
Py_CLEAR(f->f_trace);
|
||||
PyCodeObject *co = f->f_code;
|
||||
PyCodeObject *co = _PyFrame_GetCode(f);
|
||||
/* locals */
|
||||
for (int i = 0; i < co->co_nlocalsplus; i++) {
|
||||
Py_CLEAR(f->f_localsptr[i]);
|
||||
|
@ -722,7 +729,7 @@ frame_sizeof(PyFrameObject *f, PyObject *Py_UNUSED(ignored))
|
|||
Py_ssize_t res;
|
||||
res = sizeof(PyFrameObject);
|
||||
if (f->f_own_locals_memory) {
|
||||
PyCodeObject *code = f->f_code;
|
||||
PyCodeObject *code = _PyFrame_GetCode(f);
|
||||
res += (code->co_nlocalsplus+code->co_stacksize) * sizeof(PyObject *);
|
||||
}
|
||||
return PyLong_FromSsize_t(res);
|
||||
|
@ -735,7 +742,7 @@ static PyObject *
|
|||
frame_repr(PyFrameObject *f)
|
||||
{
|
||||
int lineno = PyFrame_GetLineNumber(f);
|
||||
PyCodeObject *code = f->f_code;
|
||||
PyCodeObject *code = _PyFrame_GetCode(f);
|
||||
return PyUnicode_FromFormat(
|
||||
"<frame at %p, file %R, line %d, code %S>",
|
||||
f, code->co_filename, lineno, code->co_name);
|
||||
|
@ -876,7 +883,7 @@ _PyFrame_New_NoTrack(PyThreadState *tstate, PyFrameConstructor *con, PyObject *l
|
|||
PyObject **specials = f->f_localsptr + code->co_nlocalsplus;
|
||||
f->f_valuestack = specials + FRAME_SPECIALS_SIZE;
|
||||
f->f_back = (PyFrameObject*)Py_XNewRef(tstate->frame);
|
||||
f->f_code = (PyCodeObject *)Py_NewRef(con->fc_code);
|
||||
specials[FRAME_SPECIALS_CODE_OFFSET] = Py_NewRef(con->fc_code);
|
||||
specials[FRAME_SPECIALS_BUILTINS_OFFSET] = Py_NewRef(con->fc_builtins);
|
||||
specials[FRAME_SPECIALS_GLOBALS_OFFSET] = Py_NewRef(con->fc_globals);
|
||||
specials[FRAME_SPECIALS_LOCALS_OFFSET] = Py_XNewRef(locals);
|
||||
|
@ -921,7 +928,7 @@ static int
|
|||
_PyFrame_OpAlreadyRan(PyFrameObject *f, int opcode, int oparg)
|
||||
{
|
||||
const _Py_CODEUNIT *code =
|
||||
(const _Py_CODEUNIT *)PyBytes_AS_STRING(f->f_code->co_code);
|
||||
(const _Py_CODEUNIT *)PyBytes_AS_STRING(_PyFrame_GetCode(f)->co_code);
|
||||
for (int i = 0; i < f->f_lasti; i++) {
|
||||
if (_Py_OPCODE(code[i]) == opcode && _Py_OPARG(code[i]) == oparg) {
|
||||
return 1;
|
||||
|
@ -948,7 +955,7 @@ PyFrame_FastToLocalsWithError(PyFrameObject *f)
|
|||
if (locals == NULL)
|
||||
return -1;
|
||||
}
|
||||
co = f->f_code;
|
||||
co = _PyFrame_GetCode(f);
|
||||
fast = f->f_localsptr;
|
||||
for (int i = 0; i < co->co_nlocalsplus; i++) {
|
||||
_PyLocalsPlusKind kind = co->co_localspluskinds[i];
|
||||
|
@ -1041,7 +1048,7 @@ PyFrame_LocalsToFast(PyFrameObject *f, int clear)
|
|||
if (locals == NULL)
|
||||
return;
|
||||
fast = f->f_localsptr;
|
||||
co = f->f_code;
|
||||
co = _PyFrame_GetCode(f);
|
||||
|
||||
PyErr_Fetch(&error_type, &error_value, &error_traceback);
|
||||
for (int i = 0; i < co->co_nlocalsplus; i++) {
|
||||
|
@ -1134,7 +1141,7 @@ PyCodeObject *
|
|||
PyFrame_GetCode(PyFrameObject *frame)
|
||||
{
|
||||
assert(frame != NULL);
|
||||
PyCodeObject *code = frame->f_code;
|
||||
PyCodeObject *code = _PyFrame_GetCode(frame);
|
||||
assert(code != NULL);
|
||||
Py_INCREF(code);
|
||||
return code;
|
||||
|
|
|
@ -1451,7 +1451,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag)
|
|||
/* push frame */
|
||||
tstate->frame = f;
|
||||
specials = f->f_valuestack - FRAME_SPECIALS_SIZE;
|
||||
co = f->f_code;
|
||||
co = (PyCodeObject *)specials[FRAME_SPECIALS_CODE_OFFSET];
|
||||
|
||||
if (cframe.use_tracing) {
|
||||
if (tstate->c_tracefunc != NULL) {
|
||||
|
@ -5388,9 +5388,10 @@ call_trace_protected(Py_tracefunc func, PyObject *obj,
|
|||
static void
|
||||
initialize_trace_info(PyTraceInfo *trace_info, PyFrameObject *frame)
|
||||
{
|
||||
if (trace_info->code != frame->f_code) {
|
||||
trace_info->code = frame->f_code;
|
||||
_PyCode_InitAddressRange(frame->f_code, &trace_info->bounds);
|
||||
PyCodeObject *code = _PyFrame_GetCode(frame);
|
||||
if (trace_info->code != code) {
|
||||
trace_info->code = code;
|
||||
_PyCode_InitAddressRange(code, &trace_info->bounds);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5405,7 +5406,7 @@ call_trace(Py_tracefunc func, PyObject *obj,
|
|||
tstate->tracing++;
|
||||
tstate->cframe->use_tracing = 0;
|
||||
if (frame->f_lasti < 0) {
|
||||
frame->f_lineno = frame->f_code->co_firstlineno;
|
||||
frame->f_lineno = _PyFrame_GetCode(frame)->co_firstlineno;
|
||||
}
|
||||
else {
|
||||
initialize_trace_info(&tstate->trace_info, frame);
|
||||
|
@ -5684,7 +5685,7 @@ PyEval_MergeCompilerFlags(PyCompilerFlags *cf)
|
|||
int result = cf->cf_flags != 0;
|
||||
|
||||
if (current_frame != NULL) {
|
||||
const int codeflags = current_frame->f_code->co_flags;
|
||||
const int codeflags = _PyFrame_GetCode(current_frame)->co_flags;
|
||||
const int compilerflags = codeflags & PyCF_MASK;
|
||||
if (compilerflags) {
|
||||
result = 1;
|
||||
|
@ -6289,7 +6290,7 @@ unicode_concatenate(PyThreadState *tstate, PyObject *v, PyObject *w,
|
|||
}
|
||||
case STORE_NAME:
|
||||
{
|
||||
PyObject *names = f->f_code->co_names;
|
||||
PyObject *names = _PyFrame_GetCode(f)->co_names;
|
||||
PyObject *name = GETITEM(names, oparg);
|
||||
PyObject *locals = f->f_valuestack[
|
||||
FRAME_SPECIALS_LOCALS_OFFSET-FRAME_SPECIALS_SIZE];
|
||||
|
@ -6376,7 +6377,7 @@ dtrace_function_entry(PyFrameObject *f)
|
|||
const char *funcname;
|
||||
int lineno;
|
||||
|
||||
PyCodeObject *code = f->f_code;
|
||||
PyCodeObject *code = _PyFrame_GetCode(f);
|
||||
filename = PyUnicode_AsUTF8(code->co_filename);
|
||||
funcname = PyUnicode_AsUTF8(code->co_name);
|
||||
lineno = PyFrame_GetLineNumber(f);
|
||||
|
@ -6391,7 +6392,7 @@ dtrace_function_return(PyFrameObject *f)
|
|||
const char *funcname;
|
||||
int lineno;
|
||||
|
||||
PyCodeObject *code = f->f_code;
|
||||
PyCodeObject *code = _PyFrame_GetCode(f);
|
||||
filename = PyUnicode_AsUTF8(code->co_filename);
|
||||
funcname = PyUnicode_AsUTF8(code->co_name);
|
||||
lineno = PyFrame_GetLineNumber(f);
|
||||
|
@ -6418,10 +6419,10 @@ maybe_dtrace_line(PyFrameObject *frame,
|
|||
if (line != frame->f_lineno || frame->f_lasti < instr_prev) {
|
||||
if (line != -1) {
|
||||
frame->f_lineno = line;
|
||||
co_filename = PyUnicode_AsUTF8(frame->f_code->co_filename);
|
||||
co_filename = PyUnicode_AsUTF8(_PyFrame_GetCode(frame)->co_filename);
|
||||
if (!co_filename)
|
||||
co_filename = "?";
|
||||
co_name = PyUnicode_AsUTF8(frame->f_code->co_name);
|
||||
co_name = PyUnicode_AsUTF8(_PyFrame_GetCode(frame)->co_name);
|
||||
if (!co_name)
|
||||
co_name = "?";
|
||||
PyDTrace_LINE(co_filename, co_name, line);
|
||||
|
|
|
@ -856,6 +856,8 @@ def proxyval(self, visited):
|
|||
|
||||
FRAME_SPECIALS_GLOBAL_OFFSET = 0
|
||||
FRAME_SPECIALS_BUILTINS_OFFSET = 1
|
||||
FRAME_SPECIALS_CODE_OFFSET = 3
|
||||
FRAME_SPECIALS_SIZE = 4
|
||||
|
||||
class PyFrameObjectPtr(PyObjectPtr):
|
||||
_typename = 'PyFrameObject'
|
||||
|
@ -864,7 +866,7 @@ def __init__(self, gdbval, cast_to=None):
|
|||
PyObjectPtr.__init__(self, gdbval, cast_to)
|
||||
|
||||
if not self.is_optimized_out():
|
||||
self.co = PyCodeObjectPtr.from_pyobject_ptr(self.field('f_code'))
|
||||
self.co = self._f_code()
|
||||
self.co_name = self.co.pyop_field('co_name')
|
||||
self.co_filename = self.co.pyop_field('co_filename')
|
||||
|
||||
|
@ -890,11 +892,18 @@ def iter_locals(self):
|
|||
pyop_name = PyObjectPtr.from_pyobject_ptr(self.co_localsplusnames[i])
|
||||
yield (pyop_name, pyop_value)
|
||||
|
||||
def _f_specials(self, index, cls=PyObjectPtr):
|
||||
f_valuestack = self.field('f_valuestack')
|
||||
return cls.from_pyobject_ptr(f_valuestack[index - FRAME_SPECIALS_SIZE])
|
||||
|
||||
def _f_globals(self):
|
||||
f_localsplus = self.field('f_localsptr')
|
||||
nlocalsplus = int_from_int(self.co.field('co_nlocalsplus'))
|
||||
index = nlocalsplus + FRAME_SPECIALS_GLOBAL_OFFSET
|
||||
return PyObjectPtr.from_pyobject_ptr(f_localsplus[index])
|
||||
return self._f_specials(FRAME_SPECIALS_GLOBAL_OFFSET)
|
||||
|
||||
def _f_builtins(self):
|
||||
return self._f_specials(FRAME_SPECIALS_BUILTINS_OFFSET)
|
||||
|
||||
def _f_code(self):
|
||||
return self._f_specials(FRAME_SPECIALS_CODE_OFFSET, PyCodeObjectPtr)
|
||||
|
||||
def iter_globals(self):
|
||||
'''
|
||||
|
@ -907,12 +916,6 @@ def iter_globals(self):
|
|||
pyop_globals = self._f_globals()
|
||||
return pyop_globals.iteritems()
|
||||
|
||||
def _f_builtins(self):
|
||||
f_localsplus = self.field('f_localsptr')
|
||||
nlocalsplus = int_from_int(self.co.field('co_nlocalsplus'))
|
||||
index = nlocalsplus + FRAME_SPECIALS_BUILTINS_OFFSET
|
||||
return PyObjectPtr.from_pyobject_ptr(f_localsplus[index])
|
||||
|
||||
def iter_builtins(self):
|
||||
'''
|
||||
Yield a sequence of (name,value) pairs of PyObjectPtr instances, for
|
||||
|
|
Loading…
Reference in a new issue