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
5 changes: 5 additions & 0 deletions Doc/library/logging.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1011,6 +1011,11 @@ the options available to you.
| exc_info | You shouldn't need to | Exception tuple (à la ``sys.exc_info``) or, |
| | format this yourself. | if no exception has occurred, ``None``. |
+----------------+-------------------------+-----------------------------------------------+
| exc_text | You shouldn't need to | Exception information formatted as a string. |
| | format this yourself. | This is set when :meth:`Formatter.format` is |
| | | invoked, or ``None`` if no exception has |
| | | occurred. |
+----------------+-------------------------+-----------------------------------------------+
| filename | ``%(filename)s`` | Filename portion of ``pathname``. |
+----------------+-------------------------+-----------------------------------------------+
| funcName | ``%(funcName)s`` | Name of function containing the logging call. |
Expand Down
4 changes: 2 additions & 2 deletions Include/internal/pycore_opcode_metadata.h

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

1 change: 0 additions & 1 deletion Include/internal/pycore_tstate.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ typedef struct _PyJitTracerInitialState {

typedef struct _PyJitTracerPreviousState {
bool dependencies_still_valid;
bool instr_is_super;
int code_max_size;
int code_curr_size;
int instr_oparg;
Expand Down
10 changes: 5 additions & 5 deletions Include/internal/pycore_uop_ids.h

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

30 changes: 15 additions & 15 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: 2 additions & 0 deletions Lib/_opcode_metadata.py

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

41 changes: 41 additions & 0 deletions Lib/test/test_capi/test_opt.py
Original file line number Diff line number Diff line change
Expand Up @@ -3152,6 +3152,47 @@ def f1():
"""), PYTHON_JIT="1")
self.assertEqual(result[0].rc, 0, result)

def test_143092(self):
def f1():
a = "a"
for i in range(50):
x = a[i % len(a)]

s = ""
for _ in range(10):
s += ""

class A: ...
class B: ...

match s:
case int(): ...
case str(): ...
case dict(): ...

(
u0,
*u1,
u2,
u4,
u5,
u6,
u7,
u8,
u9, u10, u11,
u12, u13, u14, u15, u16, u17, u18, u19, u20, u21, u22, u23, u24, u25, u26, u27, u28, u29,
) = [None, None, None, None, None, None, None, None, None, None, None, None, None, None, None,
None, None, None, None, None, None, None, None, None, None, None, None, None, None, None,
None, None, None, None, None, None, None, None, None, None, None, None, None, None, None,
None, None, None, None, None, None, None, None,]

s = ""
for _ in range(10):
s += ""
s += ""

for i in range(TIER2_THRESHOLD * 10):
f1()

def global_identity(x):
return x
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix a crash in the JIT when dealing with ``list.append(x)`` style code.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Set :data:`sys.flags.inspect` to ``1`` when :envvar:`PYTHONINSPECT` is ``0``.
Previously, it was set to ``0`` in this case.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
The non-``compat32`` :mod:`email` policies now correctly handle refolding
encoded words that contain bytes that can not be decoded in their specified
character set. Previously this resulting in an encoding exception during
character set. Previously this resulted in an encoding exception during
folding.
2 changes: 1 addition & 1 deletion Objects/genobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -559,7 +559,7 @@ gen_set_exception(PyObject *typ, PyObject *val, PyObject *tb)
static PyObject *
gen_throw_current_exception(PyGenObject *gen)
{
assert(gen->gi_frame_state == FRAME_EXECUTING);
assert(FT_ATOMIC_LOAD_INT8_RELAXED(gen->gi_frame_state) == FRAME_EXECUTING);

PyObject *result;
if (gen_send_ex2(gen, Py_None, &result, 1) == PYGEN_RETURN) {
Expand Down
58 changes: 20 additions & 38 deletions Python/bytecodes.c
Original file line number Diff line number Diff line change
Expand Up @@ -588,7 +588,7 @@ dummy_func(
BINARY_OP_SUBSCR_STR_INT,
BINARY_OP_SUBSCR_DICT,
BINARY_OP_SUBSCR_GETITEM,
// BINARY_OP_INPLACE_ADD_UNICODE, // See comments at that opcode.
BINARY_OP_INPLACE_ADD_UNICODE,
BINARY_OP_EXTEND,
};

Expand Down Expand Up @@ -762,13 +762,10 @@ dummy_func(
macro(BINARY_OP_ADD_UNICODE) =
_GUARD_TOS_UNICODE + _GUARD_NOS_UNICODE + unused/5 + _BINARY_OP_ADD_UNICODE + _POP_TOP_UNICODE + _POP_TOP_UNICODE;

// This is a subtle one. It's a super-instruction for
// BINARY_OP_ADD_UNICODE followed by STORE_FAST
// where the store goes into the left argument.
// So the inputs are the same as for all BINARY_OP
// specializations, but there is no output.
// At the end we just skip over the STORE_FAST.
op(_BINARY_OP_INPLACE_ADD_UNICODE, (left, right --)) {
// This is a subtle one. We write NULL to the local
// of the following STORE_FAST and leave the result for STORE_FAST
// later to store.
op(_BINARY_OP_INPLACE_ADD_UNICODE, (left, right -- res)) {
PyObject *left_o = PyStackRef_AsPyObjectBorrow(left);
assert(PyUnicode_CheckExact(left_o));
assert(PyUnicode_CheckExact(PyStackRef_AsPyObjectBorrow(right)));
Expand Down Expand Up @@ -796,20 +793,16 @@ dummy_func(
* that the string is safe to mutate.
*/
assert(Py_REFCNT(left_o) >= 2 || !PyStackRef_IsHeapSafe(left));
PyStackRef_CLOSE_SPECIALIZED(left, _PyUnicode_ExactDealloc);
DEAD(left);
PyObject *temp = PyStackRef_AsPyObjectSteal(*target_local);
PyObject *right_o = PyStackRef_AsPyObjectSteal(right);
PyObject *right_o = PyStackRef_AsPyObjectBorrow(right);
PyUnicode_Append(&temp, right_o);
*target_local = PyStackRef_FromPyObjectSteal(temp);
Py_DECREF(right_o);
ERROR_IF(PyStackRef_IsNull(*target_local));
#if TIER_ONE
// The STORE_FAST is already done. This is done here in tier one,
// and during trace projection in tier two:
assert(next_instr->op.code == STORE_FAST);
SKIP_OVER(1);
#endif
PyStackRef_CLOSE_SPECIALIZED(right, _PyUnicode_ExactDealloc);
DEAD(right);
PyStackRef_CLOSE_SPECIALIZED(left, _PyUnicode_ExactDealloc);
DEAD(left);
ERROR_IF(temp == NULL);
res = PyStackRef_FromPyObjectSteal(temp);
*target_local = PyStackRef_NULL;
}

op(_GUARD_BINARY_OP_EXTEND, (descr/4, left, right -- left, right)) {
Expand Down Expand Up @@ -4330,8 +4323,7 @@ dummy_func(
DEOPT_IF(callable_o != interp->callable_cache.list_append);
}

// This is secretly a super-instruction
op(_CALL_LIST_APPEND, (callable, self, arg -- c, s)) {
op(_CALL_LIST_APPEND, (callable, self, arg -- none, c, s)) {
assert(oparg == 1);
PyObject *self_o = PyStackRef_AsPyObjectBorrow(self);

Expand All @@ -4344,13 +4336,9 @@ dummy_func(
}
c = callable;
s = self;
INPUTS_DEAD();
#if TIER_ONE
// Skip the following POP_TOP. This is done here in tier one, and
// during trace projection in tier two:
assert(next_instr->op.code == POP_TOP);
SKIP_OVER(1);
#endif
DEAD(callable);
DEAD(self);
none = PyStackRef_None;
}

op(_CALL_METHOD_DESCRIPTOR_O, (callable, self_or_null, args[oparg] -- res)) {
Expand Down Expand Up @@ -5598,15 +5586,9 @@ dummy_func(
// Super instructions. Instruction deopted. There's a mismatch in what the stack expects
// in the optimizer. So we have to reflect in the trace correctly.
_PyThreadStateImpl *_tstate = (_PyThreadStateImpl *)tstate;
if ((_tstate->jit_tracer_state.prev_state.instr->op.code == CALL_LIST_APPEND &&
opcode == POP_TOP) ||
(_tstate->jit_tracer_state.prev_state.instr->op.code == BINARY_OP_INPLACE_ADD_UNICODE &&
opcode == STORE_FAST)) {
_tstate->jit_tracer_state.prev_state.instr_is_super = true;
}
else {
_tstate->jit_tracer_state.prev_state.instr = next_instr;
}
// JIT should have disabled super instructions, as we can
// do these optimizations ourselves in the JIT.
_tstate->jit_tracer_state.prev_state.instr = next_instr;
PyObject *prev_code = PyStackRef_AsPyObjectBorrow(frame->f_executable);
if (_tstate->jit_tracer_state.prev_state.instr_code != (PyCodeObject *)prev_code) {
Py_SETREF(_tstate->jit_tracer_state.prev_state.instr_code, (PyCodeObject*)Py_NewRef((prev_code)));
Expand Down
Loading
Loading