Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Isolate the Default Object Allocator between Interpreters #101659

Closed
ericsnowcurrently opened this issue Feb 7, 2023 · 1 comment
Closed

Isolate the Default Object Allocator between Interpreters #101659

ericsnowcurrently opened this issue Feb 7, 2023 · 1 comment
Assignees
Labels
3.12 bugs and security fixes interpreter-core (Objects, Python, Grammar, and Parser dirs) topic-subinterpreters type-feature A feature request or enhancement

Comments

@ericsnowcurrently
Copy link
Member

ericsnowcurrently commented Feb 7, 2023

(see gh-100227)

By default, the allocator for the "object" and "mem" domains is historically known as "obmalloc". The implementation of the allocator is _PyObject_Malloc(), etc., for which the runtime state is found in _PyRuntimeState.obmalloc. Thus all interpreters currently share the runtime state for the default allocator.

Isolating that state to each interpreter is important for a per-interpreter GIL (my short-term motivation here), but there are other benefits. For example, it helps us manage resources (e.g. objects) relative to the lifecycle of each interpreter, and to do so more efficiently. Furthermore, any situation where we share memory between interpreters is an invitation for memory leaks and other bugs.

The solution here should be as simple as moving the "obmalloc" state to PyInterpreterState.

Linked PRs

@ericsnowcurrently ericsnowcurrently added type-feature A feature request or enhancement interpreter-core (Objects, Python, Grammar, and Parser dirs) topic-subinterpreters 3.12 bugs and security fixes labels Feb 7, 2023
@ericsnowcurrently ericsnowcurrently self-assigned this Feb 7, 2023
@ericsnowcurrently
Copy link
Member Author

FYI, one consequence of debugging CI failures in gh-101660 is that I was reminded that we may be able to take advantage of an object's corresponding obmalloc pool/arena to determine to which interpreter that object belongs. I'll open an issue about that once this one is settled.

carljm added a commit to carljm/cpython that referenced this issue Mar 14, 2023
* main: (50 commits)
  pythongh-102674: Remove _specialization_stats from Lib/opcode.py (python#102685)
  pythongh-102660: Handle m_copy Specially for the sys and builtins Modules (pythongh-102661)
  pythongh-102354: change python3 to python in docs examples (python#102696)
  pythongh-81057: Add a CI Check for New Unsupported C Global Variables (pythongh-102506)
  pythonGH-94851: check unicode consistency of static strings in debug mode (python#102684)
  pythongh-100315: clarification to `__slots__` docs. (python#102621)
  pythonGH-100227: cleanup initialization of global interned dict (python#102682)
  doc: Remove a duplicate 'versionchanged' in library/asyncio-task (pythongh-102677)
  pythongh-102013: Add PyUnstable_GC_VisitObjects (python#102014)
  pythonGH-102670: Use sumprod() to simplify, speed up, and improve accuracy of statistics functions (pythonGH-102649)
  pythongh-102627: Replace address pointing toward malicious web page (python#102630)
  pythongh-98831: Use DECREF_INPUTS() more (python#102409)
  pythongh-101659: Avoid Allocation for Shared Exceptions in the _xxsubinterpreters Module (pythongh-102659)
  pythongh-101524: Fix the ChannelID tp_name (pythongh-102655)
  pythongh-102069: Fix `__weakref__` descriptor generation for custom dataclasses (python#102075)
  pythongh-98169 dataclasses.astuple support DefaultDict (python#98170)
  pythongh-102650: Remove duplicate include directives from multiple source files (python#102651)
  pythonGH-100987: Don't cache references to the names and consts array in `_PyEval_EvalFrameDefault`. (python#102640)
  pythongh-87092: refactor assemble() to a number of separate functions, which do not need the compiler struct (python#102562)
  pythongh-102192: Replace PyErr_Fetch/Restore etc by more efficient alternatives (python#102631)
  ...
Fidget-Spinner pushed a commit to Fidget-Spinner/cpython that referenced this issue Mar 27, 2023
ericsnowcurrently added a commit that referenced this issue Mar 31, 2023
…103151)

This involves 3 changes: some general cleanup, checks to match the kind of module, and switch from testing against sys to _imp.

This is a precursor to gh-103150, though the changes are meant to stand on their own.
ericsnowcurrently added a commit that referenced this issue Apr 5, 2023
…103287)

Using the raw allocator for any of the global state makes sense, especially as we move to a per-interpreter obmalloc state (gh-101660).
ericsnowcurrently added a commit that referenced this issue Apr 6, 2023
The function is like Py_AtExit() but for a single interpreter.  This is a companion to the atexit module's register() function, taking a C callback instead of a Python one.

We also update the _xxinterpchannels module to use _Py_AtExit(), which is the motivating case.  (This is inspired by pain points felt while working on gh-101660.)
gaogaotiantian pushed a commit to gaogaotiantian/cpython that referenced this issue Apr 8, 2023
pythongh-103287)

Using the raw allocator for any of the global state makes sense, especially as we move to a per-interpreter obmalloc state (pythongh-101660).
gaogaotiantian pushed a commit to gaogaotiantian/cpython that referenced this issue Apr 8, 2023
The function is like Py_AtExit() but for a single interpreter.  This is a companion to the atexit module's register() function, taking a C callback instead of a Python one.

We also update the _xxinterpchannels module to use _Py_AtExit(), which is the motivating case.  (This is inspired by pain points felt while working on pythongh-101660.)
warsaw pushed a commit to warsaw/cpython that referenced this issue Apr 11, 2023
warsaw pushed a commit to warsaw/cpython that referenced this issue Apr 11, 2023
pythongh-103151)

This involves 3 changes: some general cleanup, checks to match the kind of module, and switch from testing against sys to _imp.

This is a precursor to pythongh-103150, though the changes are meant to stand on their own.
warsaw pushed a commit to warsaw/cpython that referenced this issue Apr 11, 2023
pythongh-103287)

Using the raw allocator for any of the global state makes sense, especially as we move to a per-interpreter obmalloc state (pythongh-101660).
warsaw pushed a commit to warsaw/cpython that referenced this issue Apr 11, 2023
The function is like Py_AtExit() but for a single interpreter.  This is a companion to the atexit module's register() function, taking a C callback instead of a Python one.

We also update the _xxinterpchannels module to use _Py_AtExit(), which is the motivating case.  (This is inspired by pain points felt while working on pythongh-101660.)
ericsnowcurrently added a commit that referenced this issue Apr 24, 2023
This is strictly about moving the "obmalloc" runtime state from
`_PyRuntimeState` to `PyInterpreterState`.  Doing so improves isolation
between interpreters, specifically most of the memory (incl. objects)
allocated for each interpreter's use.  This is important for a
per-interpreter GIL, but such isolation is valuable even without it.

FWIW, a per-interpreter obmalloc is the proverbial
canary-in-the-coalmine when it comes to the isolation of objects between
interpreters.  Any object that leaks (unintentionally) to another
interpreter is highly likely to cause a crash (on debug builds at
least).  That's a useful thing to know, relative to interpreter
isolation.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3.12 bugs and security fixes interpreter-core (Objects, Python, Grammar, and Parser dirs) topic-subinterpreters type-feature A feature request or enhancement
Projects
Status: Done
Development

No branches or pull requests

1 participant