Skip to content
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
1 change: 1 addition & 0 deletions Include/internal/pycore_jit.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ typedef _Py_CODEUNIT *(*jit_func)(

int _PyJIT_Compile(_PyExecutorObject *executor, const _PyUOpInstruction *trace, size_t length);
void _PyJIT_Free(_PyExecutorObject *executor);
void _PyJIT_Fini(void);

#endif // _Py_JIT

Expand Down
2 changes: 1 addition & 1 deletion Include/internal/pycore_opcode_metadata.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Include/internal/pycore_uop_ids.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions Include/internal/pycore_uop_metadata.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Lib/multiprocessing/spawn.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ def get_preparation_data(name):
sys_argv=sys.argv,
orig_dir=process.ORIGINAL_DIR,
dir=os.getcwd(),
start_method=get_start_method(),
start_method=get_start_method(allow_none=True),
)

# Figure out whether to initialise main in the subprocess as a module
Expand Down
20 changes: 20 additions & 0 deletions Lib/test/_test_multiprocessing.py
Original file line number Diff line number Diff line change
Expand Up @@ -5967,6 +5967,26 @@ def test_context(self):
self.assertRaises(ValueError, ctx.set_start_method, None)
self.check_context(ctx)

@staticmethod
def _dummy_func():
pass

@warnings_helper.ignore_fork_in_thread_deprecation_warnings()
def test_spawn_dont_set_context(self):
# Run a process with spawn or forkserver context may change
# the global start method, see gh-109263.
for method in ('fork', 'spawn', 'forkserver'):
multiprocessing.set_start_method(None, force=True)

try:
ctx = multiprocessing.get_context(method)
except ValueError:
continue
process = ctx.Process(target=self._dummy_func)
process.start()
process.join()
self.assertIsNone(multiprocessing.get_start_method(allow_none=True))

def test_context_check_module_types(self):
try:
ctx = multiprocessing.get_context('forkserver')
Expand Down
19 changes: 19 additions & 0 deletions Lib/test/test_capi/test_opt.py
Original file line number Diff line number Diff line change
Expand Up @@ -3114,6 +3114,25 @@ def testfunc(n):
self.assertNotIn("_POP_TOP_INT", uops)
self.assertIn("_POP_TOP_NOP", uops)

def test_binary_subscr_tuple_int(self):
def testfunc(n):
t = (1,)
x = 0
for _ in range(n):
y = t[0]
x += y
return x

res, ex = self._run_with_optimizer(testfunc, TIER2_THRESHOLD)
self.assertEqual(res, TIER2_THRESHOLD)
self.assertIsNotNone(ex)
uops = get_opnames(ex)

self.assertIn("_BINARY_OP_SUBSCR_TUPLE_INT", uops)
self.assertNotIn("_POP_TOP", uops)
self.assertNotIn("_POP_TOP_INT", uops)
self.assertIn("_POP_TOP_NOP", uops)

def test_143026(self):
# https://github.com/python/cpython/issues/143026

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Starting a process from spawn context in :mod:`multiprocessing` no longer
sets the start method globally.
9 changes: 5 additions & 4 deletions Python/bytecodes.c
Original file line number Diff line number Diff line change
Expand Up @@ -975,9 +975,9 @@ dummy_func(
}

macro(BINARY_OP_SUBSCR_TUPLE_INT) =
_GUARD_TOS_INT + _GUARD_NOS_TUPLE + unused/5 + _BINARY_OP_SUBSCR_TUPLE_INT;
_GUARD_TOS_INT + _GUARD_NOS_TUPLE + unused/5 + _BINARY_OP_SUBSCR_TUPLE_INT + _POP_TOP_INT + POP_TOP;

op(_BINARY_OP_SUBSCR_TUPLE_INT, (tuple_st, sub_st -- res)) {
op(_BINARY_OP_SUBSCR_TUPLE_INT, (tuple_st, sub_st -- res, ts, ss)) {
PyObject *sub = PyStackRef_AsPyObjectBorrow(sub_st);
PyObject *tuple = PyStackRef_AsPyObjectBorrow(tuple_st);

Expand All @@ -991,9 +991,10 @@ dummy_func(
STAT_INC(BINARY_OP, hit);
PyObject *res_o = PyTuple_GET_ITEM(tuple, index);
assert(res_o != NULL);
PyStackRef_CLOSE_SPECIALIZED(sub_st, _PyLong_ExactDealloc);
res = PyStackRef_FromPyObjectNew(res_o);
DECREF_INPUTS();
ts = tuple_st;
ss = sub_st;
INPUTS_DEAD();
}

op(_GUARD_NOS_DICT, (nos, unused -- nos, unused)) {
Expand Down
24 changes: 8 additions & 16 deletions Python/executor_cases.c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 16 additions & 5 deletions Python/generated_cases.c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 23 additions & 0 deletions Python/jit.c
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,8 @@ typedef struct {
uintptr_t instruction_starts[UOP_MAX_TRACE_LENGTH];
} jit_state;

static size_t _Py_jit_shim_size = 0;

// Warning! AArch64 requires you to get your hands dirty. These are your gloves:

// value[value_start : value_start + len]
Expand Down Expand Up @@ -676,6 +678,7 @@ _PyJIT_Compile(_PyExecutorObject *executor, const _PyUOpInstruction trace[], siz
* We compile this once only as it effectively a normal
* function, but we need to use the JIT because it needs
* to understand the jit-specific calling convention.
* Don't forget to call _PyJIT_Fini later!
*/
static _PyJitEntryFuncPtr
compile_shim(void)
Expand Down Expand Up @@ -717,6 +720,7 @@ compile_shim(void)
jit_free(memory, total_size);
return NULL;
}
_Py_jit_shim_size = total_size;
return (_PyJitEntryFuncPtr)memory;
}

Expand All @@ -739,6 +743,7 @@ _Py_LazyJitShim(
return _Py_jit_entry(executor, frame, stack_pointer, tstate);
}

// Free executor's memory allocated with _PyJIT_Compile
void
_PyJIT_Free(_PyExecutorObject *executor)
{
Expand All @@ -754,4 +759,22 @@ _PyJIT_Free(_PyExecutorObject *executor)
}
}

// Free shim memory allocated with compile_shim
void
_PyJIT_Fini(void)
{
PyMutex_Lock(&lazy_jit_mutex);
unsigned char *memory = (unsigned char *)_Py_jit_entry;
size_t size = _Py_jit_shim_size;
if (size) {
_Py_jit_entry = _Py_LazyJitShim;
_Py_jit_shim_size = 0;
if (jit_free(memory, size)) {
PyErr_FormatUnraisable("Exception ignored while "
"freeing JIT entry code");
}
}
PyMutex_Unlock(&lazy_jit_mutex);
}

#endif // _Py_JIT
4 changes: 3 additions & 1 deletion Python/optimizer_bytecodes.c
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ dummy_func(void) {
i = sub_st;
}

op(_BINARY_OP_SUBSCR_TUPLE_INT, (tuple_st, sub_st -- res)) {
op(_BINARY_OP_SUBSCR_TUPLE_INT, (tuple_st, sub_st -- res, ts, ss)) {
assert(sym_matches_type(tuple_st, &PyTuple_Type));
if (sym_is_const(ctx, sub_st)) {
assert(PyLong_CheckExact(sym_get_const(ctx, sub_st)));
Expand All @@ -354,6 +354,8 @@ dummy_func(void) {
else {
res = sym_new_not_null(ctx);
}
ts = tuple_st;
ss = sub_st;
}

op(_TO_BOOL, (value -- res)) {
Expand Down
10 changes: 8 additions & 2 deletions Python/optimizer_cases.c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions Python/pylifecycle.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@
#include "pycore_uniqueid.h" // _PyObject_FinalizeUniqueIdPool()
#include "pycore_warnings.h" // _PyWarnings_InitState()
#include "pycore_weakref.h" // _PyWeakref_GET_REF()
#ifdef _Py_JIT
#include "pycore_jit.h" // _PyJIT_Fini()
#endif

#include "opcode.h"

Expand Down Expand Up @@ -2267,6 +2270,7 @@ _Py_Finalize(_PyRuntimeState *runtime)
/* Print debug stats if any */
_PyEval_Fini();


/* Flush sys.stdout and sys.stderr (again, in case more was printed) */
if (flush_std_files() < 0) {
status = -1;
Expand Down Expand Up @@ -2346,6 +2350,10 @@ _Py_Finalize(_PyRuntimeState *runtime)

finalize_interp_clear(tstate);

#ifdef _Py_JIT
/* Free JIT shim memory */
_PyJIT_Fini();
#endif

#ifdef Py_TRACE_REFS
/* Display addresses (& refcnts) of all objects still alive.
Expand Down
3 changes: 3 additions & 0 deletions Tools/tsan/suppressions_free_threading.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,6 @@ thread:pthread_create
# PyObject_Realloc internally does memcpy which isn't atomic so can race
# with non-locking reads. See #132070
race:PyObject_Realloc

# gh-143100: set_swap_bodies in setobject.c calls memcpy, which isn't atomic
race:set_swap_bodies
Loading