Skip to content

Commit 96d4fbd

Browse files
swtaarrsadorilson
authored andcommitted
pythongh-115999: Disable the specializing adaptive interpreter in free-threaded builds (python#116013)
For now, disable all specialization when the GIL might be disabled.
1 parent aa765f6 commit 96d4fbd

File tree

9 files changed

+96
-3
lines changed

9 files changed

+96
-3
lines changed

Include/internal/pycore_code.h

+5
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,12 @@ extern int _PyLineTable_PreviousAddressRange(PyCodeAddressRange *range);
245245
/** API for executors */
246246
extern void _PyCode_Clear_Executors(PyCodeObject *code);
247247

248+
#ifdef Py_GIL_DISABLED
249+
// gh-115999 tracks progress on addressing this.
250+
#define ENABLE_SPECIALIZATION 0
251+
#else
248252
#define ENABLE_SPECIALIZATION 1
253+
#endif
249254

250255
/* Specialization functions */
251256

Lib/test/test_capi/test_opt.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
import _testinternalcapi
1010

11-
from test.support import script_helper
11+
from test.support import script_helper, requires_specialization
1212

1313

1414
@contextlib.contextmanager
@@ -31,6 +31,7 @@ def clear_executors(func):
3131
func.__code__ = func.__code__.replace()
3232

3333

34+
@requires_specialization
3435
class TestOptimizerAPI(unittest.TestCase):
3536

3637
def test_new_counter_optimizer_dealloc(self):
@@ -133,6 +134,7 @@ def get_opnames(ex):
133134
return set(iter_opnames(ex))
134135

135136

137+
@requires_specialization
136138
class TestExecutorInvalidation(unittest.TestCase):
137139

138140
def setUp(self):
@@ -211,6 +213,7 @@ def f():
211213
self.assertIsNone(exe)
212214

213215

216+
@requires_specialization
214217
@unittest.skipIf(os.getenv("PYTHON_UOPS_OPTIMIZE") == "0", "Needs uop optimizer to run.")
215218
class TestUops(unittest.TestCase):
216219

@@ -572,6 +575,7 @@ def testfunc(n):
572575
self.assertLessEqual(count, 2)
573576

574577

578+
@requires_specialization
575579
@unittest.skipIf(os.getenv("PYTHON_UOPS_OPTIMIZE") == "0", "Needs uop optimizer to run.")
576580
class TestUopsOptimization(unittest.TestCase):
577581

Lib/test/test_generated_cases.py

+8
Original file line numberDiff line numberDiff line change
@@ -350,12 +350,15 @@ def test_cache_effect(self):
350350
output = """
351351
TARGET(OP) {
352352
_Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr;
353+
(void)this_instr;
353354
next_instr += 4;
354355
INSTRUCTION_STATS(OP);
355356
PyObject *value;
356357
value = stack_pointer[-1];
357358
uint16_t counter = read_u16(&this_instr[1].cache);
359+
(void)counter;
358360
uint32_t extra = read_u32(&this_instr[2].cache);
361+
(void)extra;
359362
stack_pointer += -1;
360363
DISPATCH();
361364
}
@@ -399,6 +402,7 @@ def test_macro_instruction(self):
399402
INSTRUCTION_STATS(OP);
400403
PREDICTED(OP);
401404
_Py_CODEUNIT *this_instr = next_instr - 6;
405+
(void)this_instr;
402406
PyObject *right;
403407
PyObject *left;
404408
PyObject *arg2;
@@ -408,13 +412,15 @@ def test_macro_instruction(self):
408412
left = stack_pointer[-2];
409413
{
410414
uint16_t counter = read_u16(&this_instr[1].cache);
415+
(void)counter;
411416
op1(left, right);
412417
}
413418
/* Skip 2 cache entries */
414419
// OP2
415420
arg2 = stack_pointer[-3];
416421
{
417422
uint32_t extra = read_u32(&this_instr[4].cache);
423+
(void)extra;
418424
res = op2(arg2, left, right);
419425
}
420426
stack_pointer[-3] = res;
@@ -424,13 +430,15 @@ def test_macro_instruction(self):
424430
425431
TARGET(OP1) {
426432
_Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr;
433+
(void)this_instr;
427434
next_instr += 2;
428435
INSTRUCTION_STATS(OP1);
429436
PyObject *right;
430437
PyObject *left;
431438
right = stack_pointer[-1];
432439
left = stack_pointer[-2];
433440
uint16_t counter = read_u16(&this_instr[1].cache);
441+
(void)counter;
434442
op1(left, right);
435443
DISPATCH();
436444
}

Lib/test/test_monitoring.py

+5
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import types
1010
import unittest
1111
import asyncio
12+
from test.support import requires_specialization
1213

1314
PAIR = (0,1)
1415

@@ -815,6 +816,9 @@ def func1():
815816

816817
self.check_events(func1, [("raise", KeyError)])
817818

819+
# gh-116090: This test doesn't really require specialization, but running
820+
# it without specialization exposes a monitoring bug.
821+
@requires_specialization
818822
def test_implicit_stop_iteration(self):
819823

820824
def gen():
@@ -963,6 +967,7 @@ def func():
963967
)
964968
self.assertEqual(events[0], ("throw", IndexError))
965969

970+
@requires_specialization
966971
def test_no_unwind_for_shim_frame(self):
967972

968973
class B:

Lib/test/test_opcache.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import threading
55
import types
66
import unittest
7-
from test.support import threading_helper, check_impl_detail
7+
from test.support import threading_helper, check_impl_detail, requires_specialization
88

99
# Skip this module on other interpreters, it is cpython specific:
1010
if check_impl_detail(cpython=False):
@@ -506,6 +506,7 @@ def f(x, y):
506506

507507

508508
@threading_helper.requires_working_threading()
509+
@requires_specialization
509510
class TestRacesDoNotCrash(unittest.TestCase):
510511
# Careful with these. Bigger numbers have a higher chance of catching bugs,
511512
# but you can also burn through a *ton* of type/dict/function versions:
@@ -1021,6 +1022,7 @@ def write(items):
10211022
class C:
10221023
pass
10231024

1025+
@requires_specialization
10241026
class TestInstanceDict(unittest.TestCase):
10251027

10261028
def setUp(self):

Lib/test/test_type_cache.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import unittest
33
import dis
44
from test import support
5-
from test.support import import_helper
5+
from test.support import import_helper, requires_specialization
66
try:
77
from sys import _clear_type_cache
88
except ImportError:
@@ -94,6 +94,7 @@ class C:
9494

9595

9696
@support.cpython_only
97+
@requires_specialization
9798
class TypeCacheWithSpecializationTests(unittest.TestCase):
9899
def tearDown(self):
99100
_clear_type_cache()

Python/ceval_macros.h

+8
Original file line numberDiff line numberDiff line change
@@ -296,11 +296,19 @@ GETITEM(PyObject *v, Py_ssize_t i) {
296296
#define ADAPTIVE_COUNTER_IS_MAX(COUNTER) \
297297
(((COUNTER) >> ADAPTIVE_BACKOFF_BITS) == ((1 << MAX_BACKOFF_VALUE) - 1))
298298

299+
#ifdef Py_GIL_DISABLED
300+
#define DECREMENT_ADAPTIVE_COUNTER(COUNTER) \
301+
do { \
302+
/* gh-115999 tracks progress on addressing this. */ \
303+
static_assert(0, "The specializing interpreter is not yet thread-safe"); \
304+
} while (0);
305+
#else
299306
#define DECREMENT_ADAPTIVE_COUNTER(COUNTER) \
300307
do { \
301308
assert(!ADAPTIVE_COUNTER_IS_ZERO((COUNTER))); \
302309
(COUNTER) -= (1 << ADAPTIVE_BACKOFF_BITS); \
303310
} while (0);
311+
#endif
304312

305313
#define INCREMENT_ADAPTIVE_COUNTER(COUNTER) \
306314
do { \

0 commit comments

Comments
 (0)