Skip to content

[3.9] bpo-40514: Remove --with-experimental-isolated-subinterpreters in 3.9 #20228

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

Merged
merged 2 commits into from
May 19, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions Include/internal/pycore_ceval.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,7 @@ extern PyObject *_PyEval_EvalCode(
PyObject *kwdefs, PyObject *closure,
PyObject *name, PyObject *qualname);

#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
extern int _PyEval_ThreadsInitialized(PyInterpreterState *interp);
#else
extern int _PyEval_ThreadsInitialized(struct pyruntimestate *runtime);
#endif
extern PyStatus _PyEval_InitGIL(PyThreadState *tstate);
extern void _PyEval_FiniGIL(PyThreadState *tstate);

Expand Down
3 changes: 0 additions & 3 deletions Include/internal/pycore_interp.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,6 @@ struct _ceval_state {
/* Request for dropping the GIL */
_Py_atomic_int gil_drop_request;
struct _pending_calls pending;
#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
struct _gil_runtime_state gil;
#endif
};

/* fs_codec.encoding is initialized to NULL.
Expand Down
12 changes: 0 additions & 12 deletions Include/internal/pycore_pystate.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,18 +49,10 @@ _Py_ThreadCanHandlePendingCalls(void)
/* Variable and macro for in-line access to current thread
and interpreter state */

#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
PyAPI_FUNC(PyThreadState*) _PyThreadState_GetTSS(void);
#endif

static inline PyThreadState*
_PyRuntimeState_GetThreadState(_PyRuntimeState *runtime)
{
#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
return _PyThreadState_GetTSS();
#else
return (PyThreadState*)_Py_atomic_load_relaxed(&runtime->gilstate.tstate_current);
#endif
}

/* Get the current Python thread state.
Expand All @@ -75,11 +67,7 @@ _PyRuntimeState_GetThreadState(_PyRuntimeState *runtime)
static inline PyThreadState*
_PyThreadState_GET(void)
{
#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
return _PyThreadState_GetTSS();
#else
return _PyRuntimeState_GetThreadState(&_PyRuntime);
#endif
}

/* Redefine PyThreadState_GET() as an alias to _PyThreadState_GET() */
Expand Down
2 changes: 0 additions & 2 deletions Include/internal/pycore_runtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,7 @@ struct _ceval_runtime_state {
the main thread of the main interpreter can handle signals: see
_Py_ThreadCanHandleSignals(). */
_Py_atomic_int signals_pending;
#ifndef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
struct _gil_runtime_state gil;
#endif
};

/* GIL state */
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Remove ``--with-experimental-isolated-subinterpreters`` configure option in
Python 3.9: the experiment continues in the master branch, but it's no
longer needed in 3.9.
15 changes: 0 additions & 15 deletions Modules/_xxsubinterpretersmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -1939,20 +1939,6 @@ _run_script_in_interpreter(PyInterpreterState *interp, const char *codestr,
return -1;
}

#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
// Switch to interpreter.
PyThreadState *new_tstate = PyInterpreterState_ThreadHead(interp);
PyThreadState *save1 = PyEval_SaveThread();

(void)PyThreadState_Swap(new_tstate);

// Run the script.
_sharedexception *exc = NULL;
int result = _run_script(interp, codestr, shared, &exc);

// Switch back.
PyEval_RestoreThread(save1);
#else
// Switch to interpreter.
PyThreadState *save_tstate = NULL;
if (interp != PyInterpreterState_Get()) {
Expand All @@ -1970,7 +1956,6 @@ _run_script_in_interpreter(PyInterpreterState *interp, const char *codestr,
if (save_tstate != NULL) {
PyThreadState_Swap(save_tstate);
}
#endif

// Propagate any exception out to the caller.
if (exc != NULL) {
Expand Down
8 changes: 0 additions & 8 deletions Modules/gcmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -1181,14 +1181,6 @@ collect(PyThreadState *tstate, int generation,
_PyTime_t t1 = 0; /* initialize to prevent a compiler warning */
GCState *gcstate = &tstate->interp->gc;

#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
if (tstate->interp->config._isolated_interpreter) {
// bpo-40533: The garbage collector must not be run on parallel on
// Python objects shared by multiple interpreters.
return 0;
}
#endif

if (gcstate->debug & DEBUG_STATS) {
PySys_WriteStderr("gc: collecting generation %d...\n", generation);
show_stats_each_generations(gcstate);
Expand Down
6 changes: 0 additions & 6 deletions Objects/dictobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -251,12 +251,6 @@ static uint64_t pydict_global_version = 0;
#define PyDict_MAXFREELIST 80
#endif

/* bpo-40521: dict free lists are shared by all interpreters. */
#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
# undef PyDict_MAXFREELIST
# define PyDict_MAXFREELIST 0
#endif

#if PyDict_MAXFREELIST > 0
static PyDictObject *free_list[PyDict_MAXFREELIST];
static int numfree = 0;
Expand Down
6 changes: 0 additions & 6 deletions Objects/frameobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -559,12 +559,6 @@ static PyGetSetDef frame_getsetlist[] = {
/* max value for numfree */
#define PyFrame_MAXFREELIST 200

/* bpo-40521: frame free lists are shared by all interpreters. */
#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
# undef PyFrame_MAXFREELIST
# define PyFrame_MAXFREELIST 0
#endif

#if PyFrame_MAXFREELIST > 0
static PyFrameObject *free_list = NULL;
static int numfree = 0; /* number of frames currently in free_list */
Expand Down
6 changes: 0 additions & 6 deletions Objects/listobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,12 +101,6 @@ list_preallocate_exact(PyListObject *self, Py_ssize_t size)
# define PyList_MAXFREELIST 80
#endif

/* bpo-40521: list free lists are shared by all interpreters. */
#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
# undef PyList_MAXFREELIST
# define PyList_MAXFREELIST 0
#endif

static PyListObject *free_list[PyList_MAXFREELIST];
static int numfree = 0;

Expand Down
6 changes: 0 additions & 6 deletions Objects/tupleobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,6 @@ class tuple "PyTupleObject *" "&PyTuple_Type"
#define PyTuple_MAXFREELIST 2000 /* Maximum number of tuples of each size to save */
#endif

/* bpo-40521: tuple free lists are shared by all interpreters. */
#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
# undef PyTuple_MAXSAVESIZE
# define PyTuple_MAXSAVESIZE 0
#endif

#if PyTuple_MAXSAVESIZE > 0
/* Entries 1 up to PyTuple_MAXSAVESIZE are free lists, entry 0 is the empty
tuple () of which at most one instance will be allocated.
Expand Down
10 changes: 2 additions & 8 deletions Objects/typeobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,7 @@ class object "PyObject *" "&PyBaseObject_Type"

#include "clinic/typeobject.c.h"

/* bpo-40521: Type method cache is shared by all subinterpreters */
#ifndef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
# define MCACHE
#endif
#define MCACHE

#ifdef MCACHE
/* Support type attribute cache */
Expand Down Expand Up @@ -63,10 +60,7 @@ static size_t method_cache_misses = 0;
static size_t method_cache_collisions = 0;
#endif

/* bpo-40521: Interned strings are shared by all subinterpreters */
#ifndef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
# define INTERN_NAME_STRINGS
#endif
#define INTERN_NAME_STRINGS

/* alphabetical order */
_Py_IDENTIFIER(__abstractmethods__);
Expand Down
10 changes: 2 additions & 8 deletions Objects/unicodeobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -198,10 +198,7 @@ extern "C" {
# define OVERALLOCATE_FACTOR 4
#endif

/* bpo-40521: Interned strings are shared by all interpreters. */
#ifndef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
# define INTERNED_STRINGS
#endif
#define INTERNED_STRINGS

/* This dictionary holds all interned unicode strings. Note that references
to strings in this dictionary are *not* counted in the string's ob_refcnt.
Expand Down Expand Up @@ -288,10 +285,7 @@ unicode_decode_utf8(const char *s, Py_ssize_t size,
/* List of static strings. */
static _Py_Identifier *static_strings = NULL;

/* bpo-40521: Latin1 singletons are shared by all interpreters. */
#ifndef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
# define LATIN1_SINGLETONS
#endif
#define LATIN1_SINGLETONS

#ifdef LATIN1_SINGLETONS
/* Single character Unicode strings in the Latin-1 range are being
Expand Down
55 changes: 0 additions & 55 deletions Python/ceval.c
Original file line number Diff line number Diff line change
Expand Up @@ -250,21 +250,6 @@ ensure_tstate_not_null(const char *func, PyThreadState *tstate)
}


#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
int
_PyEval_ThreadsInitialized(PyInterpreterState *interp)
{
return gil_created(&interp->ceval.gil);
}

int
PyEval_ThreadsInitialized(void)
{
// Fatal error if there is no current interpreter
PyInterpreterState *interp = PyInterpreterState_Get();
return _PyEval_ThreadsInitialized(interp);
}
#else
int
_PyEval_ThreadsInitialized(_PyRuntimeState *runtime)
{
Expand All @@ -277,25 +262,18 @@ PyEval_ThreadsInitialized(void)
_PyRuntimeState *runtime = &_PyRuntime;
return _PyEval_ThreadsInitialized(runtime);
}
#endif

PyStatus
_PyEval_InitGIL(PyThreadState *tstate)
{
#ifndef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
if (!_Py_IsMainInterpreter(tstate)) {
/* Currently, the GIL is shared by all interpreters,
and only the main interpreter is responsible to create
and destroy it. */
return _PyStatus_OK();
}
#endif

#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
struct _gil_runtime_state *gil = &tstate->interp->ceval.gil;
#else
struct _gil_runtime_state *gil = &tstate->interp->runtime->ceval.gil;
#endif
assert(!gil_created(gil));

PyThread_init_thread();
Expand All @@ -310,20 +288,14 @@ _PyEval_InitGIL(PyThreadState *tstate)
void
_PyEval_FiniGIL(PyThreadState *tstate)
{
#ifndef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
if (!_Py_IsMainInterpreter(tstate)) {
/* Currently, the GIL is shared by all interpreters,
and only the main interpreter is responsible to create
and destroy it. */
return;
}
#endif

#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
struct _gil_runtime_state *gil = &tstate->interp->ceval.gil;
#else
struct _gil_runtime_state *gil = &tstate->interp->runtime->ceval.gil;
#endif
if (!gil_created(gil)) {
/* First Py_InitializeFromConfig() call: the GIL doesn't exist
yet: do nothing. */
Expand Down Expand Up @@ -408,13 +380,9 @@ PyEval_AcquireThread(PyThreadState *tstate)
take_gil(tstate);

struct _gilstate_runtime_state *gilstate = &tstate->interp->runtime->gilstate;
#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
(void)_PyThreadState_Swap(gilstate, tstate);
#else
if (_PyThreadState_Swap(gilstate, tstate) != NULL) {
Py_FatalError("non-NULL old thread state");
}
#endif
}

void
Expand Down Expand Up @@ -444,11 +412,7 @@ _PyEval_ReInitThreads(_PyRuntimeState *runtime)
PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime);
ensure_tstate_not_null(__func__, tstate);

#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
struct _gil_runtime_state *gil = &tstate->interp->ceval.gil;
#else
struct _gil_runtime_state *gil = &runtime->ceval.gil;
#endif
if (!gil_created(gil)) {
return;
}
Expand Down Expand Up @@ -480,21 +444,12 @@ PyThreadState *
PyEval_SaveThread(void)
{
_PyRuntimeState *runtime = &_PyRuntime;
#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
PyThreadState *old_tstate = _PyThreadState_GET();
PyThreadState *tstate = _PyThreadState_Swap(&runtime->gilstate, old_tstate);
#else
PyThreadState *tstate = _PyThreadState_Swap(&runtime->gilstate, NULL);
#endif
ensure_tstate_not_null(__func__, tstate);

struct _ceval_runtime_state *ceval = &runtime->ceval;
struct _ceval_state *ceval2 = &tstate->interp->ceval;
#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
assert(gil_created(&ceval2->gil));
#else
assert(gil_created(&ceval->gil));
#endif
drop_gil(ceval, ceval2, tstate);
return tstate;
}
Expand Down Expand Up @@ -753,9 +708,7 @@ void
_PyEval_InitRuntimeState(struct _ceval_runtime_state *ceval)
{
_Py_CheckRecursionLimit = Py_DEFAULT_RECURSION_LIMIT;
#ifndef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
_gil_initialize(&ceval->gil);
#endif
}

int
Expand All @@ -771,10 +724,6 @@ _PyEval_InitState(struct _ceval_state *ceval)
return -1;
}

#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
_gil_initialize(&ceval->gil);
#endif

return 0;
}

Expand Down Expand Up @@ -919,13 +868,9 @@ eval_frame_handle_pending(PyThreadState *tstate)

take_gil(tstate);

#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
(void)_PyThreadState_Swap(&runtime->gilstate, tstate);
#else
if (_PyThreadState_Swap(&runtime->gilstate, tstate) != NULL) {
Py_FatalError("orphan tstate");
}
#endif
}

/* Check for asynchronous exception. */
Expand Down
Loading