Author eric.snow
Recipients Mark.Shannon, eric.snow
Date 2021-12-01.18:50:38
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <>
Currently we allocate each new PyInterpreterState in PyInterpreterState_New().  Furthermore, PyInterpreterState is full of pointers which are almost all allocated on the heap during runtime init.  We can statically allocate (and initialize?) most of what goes into PyInterpreterState, as well as the main interpreter itself (as part of _PyRuntimeState).  This includes each interpreter's initial PyThreadState.


* [ ] add `PyInterpreterState main;` to _PyRuntimeState.interpreters and use it
* [ ] change references from the pointer to the value
* [ ] add `PyThreadState _main;` to PyInterpreterState.threads and use it
* [ ] change references from the pointer to the value
* [ ] change PyInterpreterState pointer fields to values (as much as possible)
* [ ] change PyThreadState pointer fields to values (as much as possible)


* fewer possible failures (no memory) during runtime/interpreter/thread init
* improved memory locality for pointers looked up relative to interpreter/thread state

There is one non-trivial bit: embedding the various PyObject values in PyInterpreterState and PyThreadState means hard-coding the various pieces of the object there (e.g. for dict, its keys/values; for list, its array), as well as adding necessary init code to PyInterpreterState_New() and PyThreadState_New().  The resulting added complexity can be mitigated somewhat with macros or even code generation.  (In fact, there is probably significant overlap with Guido's deepfreeze tool.)  Regardless, we'll probably need to factor out init funcs for a number of object types, where currently there are only "Py*_New()" funcs that combine allocation and init.
Date User Action Args
2021-12-01 18:50:39eric.snowsetrecipients: + eric.snow, Mark.Shannon
2021-12-01 18:50:39eric.snowsetmessageid: <>
2021-12-01 18:50:39eric.snowlinkissue45953 messages
2021-12-01 18:50:38eric.snowcreate