bpo-44032: Move data stack to thread from FrameObject. (GH-26076)

* Remove 'zombie' frames. We won't need them once we are allocating fixed-size frames.

* Add co_nlocalplus field to code object to avoid recomputing size of locals + frees + cells.

* Move locals, cells and freevars out of frame object into separate memory buffer.

* Use per-threadstate allocated memory chunks for local variables.

* Move globals and builtins from frame object to per-thread stack.

* Move (slow) locals frame object to per-thread stack.

* Move internal frame functions to internal header.
This commit is contained in:
Mark Shannon 2021-05-21 10:57:35 +01:00 committed by GitHub
parent be4dd7fcd9
commit b11a951f16
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 454 additions and 250 deletions

View file

@ -854,6 +854,8 @@ class PyNoneStructPtr(PyObjectPtr):
def proxyval(self, visited):
return None
FRAME_SPECIALS_GLOBAL_OFFSET = 0
FRAME_SPECIALS_BUILTINS_OFFSET = 1
class PyFrameObjectPtr(PyObjectPtr):
_typename = 'PyFrameObject'
@ -879,13 +881,19 @@ class PyFrameObjectPtr(PyObjectPtr):
if self.is_optimized_out():
return
f_localsplus = self.field('f_localsplus')
f_localsplus = self.field('f_localsptr')
for i in safe_range(self.co_nlocals):
pyop_value = PyObjectPtr.from_pyobject_ptr(f_localsplus[i])
if not pyop_value.is_null():
pyop_name = PyObjectPtr.from_pyobject_ptr(self.co_varnames[i])
yield (pyop_name, pyop_value)
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])
def iter_globals(self):
'''
Yield a sequence of (name,value) pairs of PyObjectPtr instances, for
@ -894,9 +902,15 @@ class PyFrameObjectPtr(PyObjectPtr):
if self.is_optimized_out():
return ()
pyop_globals = self.pyop_field('f_globals')
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
@ -905,7 +919,7 @@ class PyFrameObjectPtr(PyObjectPtr):
if self.is_optimized_out():
return ()
pyop_builtins = self.pyop_field('f_builtins')
pyop_builtins = self._f_builtins()
return pyop_builtins.iteritems()
def get_var_by_name(self, name):