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

gh-115999: Disable the specializing adaptive interpreter in free-threaded builds #116013

Merged
merged 7 commits into from
Mar 1, 2024
5 changes: 5 additions & 0 deletions Include/internal/pycore_code.h
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,12 @@ extern int _PyLineTable_PreviousAddressRange(PyCodeAddressRange *range);
/** API for executors */
extern void _PyCode_Clear_Executors(PyCodeObject *code);

#ifdef Py_GIL_DISABLED
// gh-115999 tracks progress on addressing this.
#define ENABLE_SPECIALIZATION 0
#else
#define ENABLE_SPECIALIZATION 1
#endif

/* Specialization functions */

Expand Down
6 changes: 5 additions & 1 deletion Lib/test/test_capi/test_opt.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import _testinternalcapi

from test.support import script_helper
from test.support import script_helper, requires_specialization


@contextlib.contextmanager
Expand All @@ -31,6 +31,7 @@ def clear_executors(func):
func.__code__ = func.__code__.replace()


@requires_specialization
class TestOptimizerAPI(unittest.TestCase):

def test_new_counter_optimizer_dealloc(self):
Expand Down Expand Up @@ -133,6 +134,7 @@ def get_opnames(ex):
return set(iter_opnames(ex))


@requires_specialization
class TestExecutorInvalidation(unittest.TestCase):

def setUp(self):
Expand Down Expand Up @@ -211,6 +213,7 @@ def f():
self.assertIsNone(exe)


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

Expand Down Expand Up @@ -572,6 +575,7 @@ def testfunc(n):
self.assertLessEqual(count, 2)


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

Expand Down
8 changes: 8 additions & 0 deletions Lib/test/test_generated_cases.py
Original file line number Diff line number Diff line change
Expand Up @@ -350,12 +350,15 @@ def test_cache_effect(self):
output = """
TARGET(OP) {
_Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr;
(void)this_instr;
next_instr += 4;
INSTRUCTION_STATS(OP);
PyObject *value;
value = stack_pointer[-1];
uint16_t counter = read_u16(&this_instr[1].cache);
(void)counter;
uint32_t extra = read_u32(&this_instr[2].cache);
(void)extra;
stack_pointer += -1;
DISPATCH();
}
Expand Down Expand Up @@ -399,6 +402,7 @@ def test_macro_instruction(self):
INSTRUCTION_STATS(OP);
PREDICTED(OP);
_Py_CODEUNIT *this_instr = next_instr - 6;
(void)this_instr;
PyObject *right;
PyObject *left;
PyObject *arg2;
Expand All @@ -408,13 +412,15 @@ def test_macro_instruction(self):
left = stack_pointer[-2];
{
uint16_t counter = read_u16(&this_instr[1].cache);
(void)counter;
op1(left, right);
}
/* Skip 2 cache entries */
// OP2
arg2 = stack_pointer[-3];
{
uint32_t extra = read_u32(&this_instr[4].cache);
(void)extra;
res = op2(arg2, left, right);
}
stack_pointer[-3] = res;
Expand All @@ -424,13 +430,15 @@ def test_macro_instruction(self):

TARGET(OP1) {
_Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr;
(void)this_instr;
next_instr += 2;
INSTRUCTION_STATS(OP1);
PyObject *right;
PyObject *left;
right = stack_pointer[-1];
left = stack_pointer[-2];
uint16_t counter = read_u16(&this_instr[1].cache);
(void)counter;
op1(left, right);
DISPATCH();
}
Expand Down
5 changes: 5 additions & 0 deletions Lib/test/test_monitoring.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import types
import unittest
import asyncio
from test.support import requires_specialization

PAIR = (0,1)

Expand Down Expand Up @@ -815,6 +816,9 @@ def func1():

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

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

def gen():
Expand Down Expand Up @@ -963,6 +967,7 @@ def func():
)
self.assertEqual(events[0], ("throw", IndexError))

@requires_specialization
gvanrossum marked this conversation as resolved.
Show resolved Hide resolved
def test_no_unwind_for_shim_frame(self):

class B:
Expand Down
4 changes: 3 additions & 1 deletion Lib/test/test_opcache.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import threading
import types
import unittest
from test.support import threading_helper, check_impl_detail
from test.support import threading_helper, check_impl_detail, requires_specialization

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


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

@requires_specialization
class TestInstanceDict(unittest.TestCase):

def setUp(self):
Expand Down
3 changes: 2 additions & 1 deletion Lib/test/test_type_cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import unittest
import dis
from test import support
from test.support import import_helper
from test.support import import_helper, requires_specialization
try:
from sys import _clear_type_cache
except ImportError:
Expand Down Expand Up @@ -94,6 +94,7 @@ class C:


@support.cpython_only
@requires_specialization
class TypeCacheWithSpecializationTests(unittest.TestCase):
def tearDown(self):
_clear_type_cache()
Expand Down
8 changes: 8 additions & 0 deletions Python/ceval_macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -296,11 +296,19 @@ GETITEM(PyObject *v, Py_ssize_t i) {
#define ADAPTIVE_COUNTER_IS_MAX(COUNTER) \
(((COUNTER) >> ADAPTIVE_BACKOFF_BITS) == ((1 << MAX_BACKOFF_VALUE) - 1))

#ifdef Py_GIL_DISABLED
#define DECREMENT_ADAPTIVE_COUNTER(COUNTER) \
do { \
/* gh-115999 tracks progress on addressing this. */ \
static_assert(0, "The specializing interpreter is not yet thread-safe"); \
} while (0);
#else
#define DECREMENT_ADAPTIVE_COUNTER(COUNTER) \
do { \
assert(!ADAPTIVE_COUNTER_IS_ZERO((COUNTER))); \
(COUNTER) -= (1 << ADAPTIVE_BACKOFF_BITS); \
} while (0);
#endif

#define INCREMENT_ADAPTIVE_COUNTER(COUNTER) \
do { \
Expand Down
Loading
Loading