Skip to content

Commit caa279d

Browse files
bpo-40514: Drop EXPERIMENTAL_ISOLATED_SUBINTERPRETERS (gh-93185)
This was added for bpo-40514 (gh-84694) to test out a per-interpreter GIL. However, it has since proven unnecessary to keep the experiment in the repo. (It can be done as a branch in a fork like normal.) So here we are removing: * the configure option * the macro * the code enabled by the macro
1 parent e6a5767 commit caa279d

18 files changed

+9
-233
lines changed

Doc/whatsnew/3.12.rst

+4
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,10 @@ Removed
115115

116116
(Contributed by Erlend E. Aasland in :gh:`92548`)
117117

118+
* The ``--experimental-isolated-subinterpreters`` configure flag
119+
(and corresponding ``EXPERIMENTAL_ISOLATED_SUBINTERPRETERS``)
120+
have been removed.
121+
118122

119123
Porting to Python 3.12
120124
======================

Include/internal/pycore_ceval.h

-4
Original file line numberDiff line numberDiff line change
@@ -81,11 +81,7 @@ _PyEval_Vector(PyThreadState *tstate,
8181
PyObject* const* args, size_t argcount,
8282
PyObject *kwnames);
8383

84-
#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
85-
extern int _PyEval_ThreadsInitialized(PyInterpreterState *interp);
86-
#else
8784
extern int _PyEval_ThreadsInitialized(struct pyruntimestate *runtime);
88-
#endif
8985
extern PyStatus _PyEval_InitGIL(PyThreadState *tstate);
9086
extern void _PyEval_FiniGIL(PyInterpreterState *interp);
9187

Include/internal/pycore_interp.h

-3
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,6 @@ struct _ceval_state {
5151
/* Request for dropping the GIL */
5252
_Py_atomic_int gil_drop_request;
5353
struct _pending_calls pending;
54-
#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
55-
struct _gil_runtime_state gil;
56-
#endif
5754
};
5855

5956

Include/internal/pycore_pystate.h

-12
Original file line numberDiff line numberDiff line change
@@ -64,18 +64,10 @@ _Py_ThreadCanHandlePendingCalls(void)
6464
/* Variable and macro for in-line access to current thread
6565
and interpreter state */
6666

67-
#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
68-
PyAPI_FUNC(PyThreadState*) _PyThreadState_GetTSS(void);
69-
#endif
70-
7167
static inline PyThreadState*
7268
_PyRuntimeState_GetThreadState(_PyRuntimeState *runtime)
7369
{
74-
#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
75-
return _PyThreadState_GetTSS();
76-
#else
7770
return (PyThreadState*)_Py_atomic_load_relaxed(&runtime->gilstate.tstate_current);
78-
#endif
7971
}
8072

8173
/* Get the current Python thread state.
@@ -90,11 +82,7 @@ _PyRuntimeState_GetThreadState(_PyRuntimeState *runtime)
9082
static inline PyThreadState*
9183
_PyThreadState_GET(void)
9284
{
93-
#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
94-
return _PyThreadState_GetTSS();
95-
#else
9685
return _PyRuntimeState_GetThreadState(&_PyRuntime);
97-
#endif
9886
}
9987

10088
PyAPI_FUNC(void) _Py_NO_RETURN _Py_FatalError_TstateNULL(const char *func);

Include/internal/pycore_runtime.h

-2
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,7 @@ struct _ceval_runtime_state {
2323
the main thread of the main interpreter can handle signals: see
2424
_Py_ThreadCanHandleSignals(). */
2525
_Py_atomic_int signals_pending;
26-
#ifndef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
2726
struct _gil_runtime_state gil;
28-
#endif
2927
};
3028

3129
/* GIL state */
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
The ``--experimental-isolated-subinterpreters`` configure option and
2+
``EXPERIMENTAL_ISOLATED_SUBINTERPRETERS`` macro have been removed.

Modules/_xxsubinterpretersmodule.c

-15
Original file line numberDiff line numberDiff line change
@@ -1932,20 +1932,6 @@ _run_script_in_interpreter(PyInterpreterState *interp, const char *codestr,
19321932
return -1;
19331933
}
19341934

1935-
#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
1936-
// Switch to interpreter.
1937-
PyThreadState *new_tstate = PyInterpreterState_ThreadHead(interp);
1938-
PyThreadState *save1 = PyEval_SaveThread();
1939-
1940-
(void)PyThreadState_Swap(new_tstate);
1941-
1942-
// Run the script.
1943-
_sharedexception *exc = NULL;
1944-
int result = _run_script(interp, codestr, shared, &exc);
1945-
1946-
// Switch back.
1947-
PyEval_RestoreThread(save1);
1948-
#else
19491935
// Switch to interpreter.
19501936
PyThreadState *save_tstate = NULL;
19511937
if (interp != PyInterpreterState_Get()) {
@@ -1963,7 +1949,6 @@ _run_script_in_interpreter(PyInterpreterState *interp, const char *codestr,
19631949
if (save_tstate != NULL) {
19641950
PyThreadState_Swap(save_tstate);
19651951
}
1966-
#endif
19671952

19681953
// Propagate any exception out to the caller.
19691954
if (exc != NULL) {

Modules/gcmodule.c

-8
Original file line numberDiff line numberDiff line change
@@ -1195,14 +1195,6 @@ gc_collect_main(PyThreadState *tstate, int generation,
11951195
assert(gcstate->garbage != NULL);
11961196
assert(!_PyErr_Occurred(tstate));
11971197

1198-
#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
1199-
if (tstate->interp->config._isolated_interpreter) {
1200-
// bpo-40533: The garbage collector must not be run on parallel on
1201-
// Python objects shared by multiple interpreters.
1202-
return 0;
1203-
}
1204-
#endif
1205-
12061198
if (gcstate->debug & DEBUG_STATS) {
12071199
PySys_WriteStderr("gc: collecting generation %d...\n", generation);
12081200
show_stats_each_generations(gcstate);

Objects/typeobject.c

+3-22
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,6 @@ typedef struct PySlot_Offset {
5454
} PySlot_Offset;
5555

5656

57-
/* bpo-40521: Interned strings are shared by all subinterpreters */
58-
#ifndef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
59-
# define INTERN_NAME_STRINGS
60-
#endif
61-
6257
static PyObject *
6358
slot_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
6459

@@ -4027,7 +4022,7 @@ type_setattro(PyTypeObject *type, PyObject *name, PyObject *value)
40274022
if (name == NULL)
40284023
return -1;
40294024
}
4030-
#ifdef INTERN_NAME_STRINGS
4025+
/* bpo-40521: Interned strings are shared by all subinterpreters */
40314026
if (!PyUnicode_CHECK_INTERNED(name)) {
40324027
PyUnicode_InternInPlace(&name);
40334028
if (!PyUnicode_CHECK_INTERNED(name)) {
@@ -4037,7 +4032,6 @@ type_setattro(PyTypeObject *type, PyObject *name, PyObject *value)
40374032
return -1;
40384033
}
40394034
}
4040-
#endif
40414035
}
40424036
else {
40434037
/* Will fail in _PyObject_GenericSetAttrWithDict. */
@@ -8474,17 +8468,11 @@ _PyTypes_InitSlotDefs(void)
84748468
for (slotdef *p = slotdefs; p->name; p++) {
84758469
/* Slots must be ordered by their offset in the PyHeapTypeObject. */
84768470
assert(!p[1].name || p->offset <= p[1].offset);
8477-
#ifdef INTERN_NAME_STRINGS
8471+
/* bpo-40521: Interned strings are shared by all subinterpreters */
84788472
p->name_strobj = PyUnicode_InternFromString(p->name);
84798473
if (!p->name_strobj || !PyUnicode_CHECK_INTERNED(p->name_strobj)) {
84808474
return _PyStatus_NO_MEMORY();
84818475
}
8482-
#else
8483-
p->name_strobj = PyUnicode_FromString(p->name);
8484-
if (!p->name_strobj) {
8485-
return _PyStatus_NO_MEMORY();
8486-
}
8487-
#endif
84888476
}
84898477
slotdefs_initialized = 1;
84908478
return _PyStatus_OK();
@@ -8509,24 +8497,17 @@ update_slot(PyTypeObject *type, PyObject *name)
85098497
int offset;
85108498

85118499
assert(PyUnicode_CheckExact(name));
8512-
#ifdef INTERN_NAME_STRINGS
85138500
assert(PyUnicode_CHECK_INTERNED(name));
8514-
#endif
85158501

85168502
assert(slotdefs_initialized);
85178503
pp = ptrs;
85188504
for (p = slotdefs; p->name; p++) {
85198505
assert(PyUnicode_CheckExact(p->name_strobj));
85208506
assert(PyUnicode_CheckExact(name));
8521-
#ifdef INTERN_NAME_STRINGS
8507+
/* bpo-40521: Using interned strings. */
85228508
if (p->name_strobj == name) {
85238509
*pp++ = p;
85248510
}
8525-
#else
8526-
if (p->name_strobj == name || _PyUnicode_EQ(p->name_strobj, name)) {
8527-
*pp++ = p;
8528-
}
8529-
#endif
85308511
}
85318512
*pp = NULL;
85328513
for (pp = ptrs; *pp; pp++) {

Objects/unicodeobject.c

-17
Original file line numberDiff line numberDiff line change
@@ -190,11 +190,6 @@ extern "C" {
190190
# define OVERALLOCATE_FACTOR 4
191191
#endif
192192

193-
/* bpo-40521: Interned strings are shared by all interpreters. */
194-
#ifndef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
195-
# define INTERNED_STRINGS
196-
#endif
197-
198193
/* This dictionary holds all interned unicode strings. Note that references
199194
to strings in this dictionary are *not* counted in the string's ob_refcnt.
200195
When the interned string reaches a refcnt of 0 the string deallocation
@@ -203,9 +198,7 @@ extern "C" {
203198
Another way to look at this is that to say that the actual reference
204199
count of a string is: s->ob_refcnt + (s->state ? 2 : 0)
205200
*/
206-
#ifdef INTERNED_STRINGS
207201
static PyObject *interned = NULL;
208-
#endif
209202

210203
/* Forward declaration */
211204
static inline int
@@ -1530,7 +1523,6 @@ unicode_dealloc(PyObject *unicode)
15301523
}
15311524
#endif
15321525

1533-
#ifdef INTERNED_STRINGS
15341526
if (PyUnicode_CHECK_INTERNED(unicode)) {
15351527
/* Revive the dead object temporarily. PyDict_DelItem() removes two
15361528
references (key and value) which were ignored by
@@ -1546,7 +1538,6 @@ unicode_dealloc(PyObject *unicode)
15461538
assert(Py_REFCNT(unicode) == 1);
15471539
Py_SET_REFCNT(unicode, 0);
15481540
}
1549-
#endif
15501541

15511542
if (_PyUnicode_HAS_UTF8_MEMORY(unicode)) {
15521543
PyObject_Free(_PyUnicode_UTF8(unicode));
@@ -10568,13 +10559,11 @@ _PyUnicode_EqualToASCIIId(PyObject *left, _Py_Identifier *right)
1056810559
if (PyUnicode_CHECK_INTERNED(left))
1056910560
return 0;
1057010561

10571-
#ifdef INTERNED_STRINGS
1057210562
assert(_PyUnicode_HASH(right_uni) != -1);
1057310563
Py_hash_t hash = _PyUnicode_HASH(left);
1057410564
if (hash != -1 && hash != _PyUnicode_HASH(right_uni)) {
1057510565
return 0;
1057610566
}
10577-
#endif
1057810567

1057910568
return unicode_compare_eq(left, right_uni);
1058010569
}
@@ -14645,7 +14634,6 @@ PyUnicode_InternInPlace(PyObject **p)
1464514634
return;
1464614635
}
1464714636

14648-
#ifdef INTERNED_STRINGS
1464914637
if (interned == NULL) {
1465014638
interned = PyDict_New();
1465114639
if (interned == NULL) {
@@ -14671,11 +14659,6 @@ PyUnicode_InternInPlace(PyObject **p)
1467114659
this. */
1467214660
Py_SET_REFCNT(s, Py_REFCNT(s) - 2);
1467314661
_PyUnicode_STATE(s).interned = 1;
14674-
#else
14675-
// PyDict expects that interned strings have their hash
14676-
// (PyASCIIObject.hash) already computed.
14677-
(void)unicode_hash(s);
14678-
#endif
1467914662
}
1468014663

1468114664
// Function kept for the stable ABI.

0 commit comments

Comments
 (0)