Skip to content

Commit 75361d4

Browse files
Upstream changes
1 parent 22bdf7d commit 75361d4

File tree

2 files changed

+71
-29
lines changed

2 files changed

+71
-29
lines changed

Python/generated_tail_call_handlers.c.h

Lines changed: 66 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,8 @@ Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_BINARY_OP_ADD_FLOAT(TAIL_CALL_PA
240240
{
241241
PyObject *left_o = PyStackRef_AsPyObjectBorrow(left);
242242
PyObject *right_o = PyStackRef_AsPyObjectBorrow(right);
243+
assert(PyFloat_CheckExact(left_o));
244+
assert(PyFloat_CheckExact(right_o));
243245
STAT_INC(BINARY_OP, hit);
244246
double dres =
245247
((PyFloatObject *)left_o)->ob_fval +
@@ -276,6 +278,8 @@ Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_BINARY_OP_ADD_INT(TAIL_CALL_PARA
276278
{
277279
PyObject *left_o = PyStackRef_AsPyObjectBorrow(left);
278280
PyObject *right_o = PyStackRef_AsPyObjectBorrow(right);
281+
assert(PyLong_CheckExact(left_o));
282+
assert(PyLong_CheckExact(right_o));
279283
STAT_INC(BINARY_OP, hit);
280284
PyObject *res_o = _PyLong_Add((PyLongObject *)left_o, (PyLongObject *)right_o);
281285
PyStackRef_CLOSE_SPECIALIZED(right, _PyLong_ExactDealloc);
@@ -311,6 +315,8 @@ Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_BINARY_OP_ADD_UNICODE(TAIL_CALL_
311315
{
312316
PyObject *left_o = PyStackRef_AsPyObjectBorrow(left);
313317
PyObject *right_o = PyStackRef_AsPyObjectBorrow(right);
318+
assert(PyUnicode_CheckExact(left_o));
319+
assert(PyUnicode_CheckExact(right_o));
314320
STAT_INC(BINARY_OP, hit);
315321
PyObject *res_o = PyUnicode_Concat(left_o, right_o);
316322
PyStackRef_CLOSE_SPECIALIZED(left, _PyUnicode_ExactDealloc);
@@ -345,6 +351,8 @@ Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_BINARY_OP_INPLACE_ADD_UNICODE(TA
345351
{
346352
PyObject *left_o = PyStackRef_AsPyObjectBorrow(left);
347353
PyObject *right_o = PyStackRef_AsPyObjectBorrow(right);
354+
assert(PyUnicode_CheckExact(left_o));
355+
assert(PyUnicode_CheckExact(right_o));
348356
int next_oparg;
349357
#if TIER_ONE
350358
assert(next_instr->op.code == STORE_FAST);
@@ -407,6 +415,8 @@ Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_BINARY_OP_MULTIPLY_FLOAT(TAIL_CA
407415
{
408416
PyObject *left_o = PyStackRef_AsPyObjectBorrow(left);
409417
PyObject *right_o = PyStackRef_AsPyObjectBorrow(right);
418+
assert(PyFloat_CheckExact(left_o));
419+
assert(PyFloat_CheckExact(right_o));
410420
STAT_INC(BINARY_OP, hit);
411421
double dres =
412422
((PyFloatObject *)left_o)->ob_fval *
@@ -443,6 +453,8 @@ Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_BINARY_OP_MULTIPLY_INT(TAIL_CALL
443453
{
444454
PyObject *left_o = PyStackRef_AsPyObjectBorrow(left);
445455
PyObject *right_o = PyStackRef_AsPyObjectBorrow(right);
456+
assert(PyLong_CheckExact(left_o));
457+
assert(PyLong_CheckExact(right_o));
446458
STAT_INC(BINARY_OP, hit);
447459
PyObject *res_o = _PyLong_Multiply((PyLongObject *)left_o, (PyLongObject *)right_o);
448460
PyStackRef_CLOSE_SPECIALIZED(right, _PyLong_ExactDealloc);
@@ -478,6 +490,8 @@ Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_BINARY_OP_SUBTRACT_FLOAT(TAIL_CA
478490
{
479491
PyObject *left_o = PyStackRef_AsPyObjectBorrow(left);
480492
PyObject *right_o = PyStackRef_AsPyObjectBorrow(right);
493+
assert(PyFloat_CheckExact(left_o));
494+
assert(PyFloat_CheckExact(right_o));
481495
STAT_INC(BINARY_OP, hit);
482496
double dres =
483497
((PyFloatObject *)left_o)->ob_fval -
@@ -514,6 +528,8 @@ Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_BINARY_OP_SUBTRACT_INT(TAIL_CALL
514528
{
515529
PyObject *left_o = PyStackRef_AsPyObjectBorrow(left);
516530
PyObject *right_o = PyStackRef_AsPyObjectBorrow(right);
531+
assert(PyLong_CheckExact(left_o));
532+
assert(PyLong_CheckExact(right_o));
517533
STAT_INC(BINARY_OP, hit);
518534
PyObject *res_o = _PyLong_Subtract((PyLongObject *)left_o, (PyLongObject *)right_o);
519535
PyStackRef_CLOSE_SPECIALIZED(right, _PyLong_ExactDealloc);
@@ -3393,7 +3409,7 @@ Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_COMPARE_OP(TAIL_CALL_PARAMS){
33933409
left = stack_pointer[-2];
33943410
uint16_t counter = read_u16(&this_instr[1].cache);
33953411
(void)counter;
3396-
#if ENABLE_SPECIALIZATION
3412+
#if ENABLE_SPECIALIZATION_FT
33973413
if (ADAPTIVE_COUNTER_TRIGGERS(counter)) {
33983414
next_instr = this_instr;
33993415
_PyFrame_SetStackPointer(frame, stack_pointer);
@@ -3932,11 +3948,15 @@ Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_END_ASYNC_FOR(TAIL_CALL_PARAMS){
39323948
}
39333949

39343950
Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_END_FOR(TAIL_CALL_PARAMS){
3935-
frame->instr_ptr = next_instr;
39363951
next_instr += 1;
39373952
INSTRUCTION_STATS(END_FOR);
39383953
_PyStackRef value;
39393954
value = stack_pointer[-1];
3955+
/* Don't update instr_ptr, so that POP_ITER sees
3956+
* the FOR_ITER as the previous instruction.
3957+
* This has the benign side effect that if value is
3958+
* finalized it will see the location as the FOR_ITER's.
3959+
*/
39403960
PyStackRef_CLOSE(value);
39413961
stack_pointer += -1;
39423962
assert(WITHIN_STACK_BOUNDS());
@@ -4121,10 +4141,8 @@ Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_FOR_ITER(TAIL_CALL_PARAMS){
41214141
/* iterator ended normally */
41224142
assert(next_instr[oparg].op.code == END_FOR ||
41234143
next_instr[oparg].op.code == INSTRUMENTED_END_FOR);
4124-
PyStackRef_CLOSE(iter);
4125-
STACK_SHRINK(1);
4126-
/* Jump forward oparg, then skip following END_FOR and POP_TOP instruction */
4127-
JUMPBY(oparg + 2);
4144+
/* Jump forward oparg, then skip following END_FOR */
4145+
JUMPBY(oparg + 1);
41284146
DISPATCH();
41294147
}
41304148
next = PyStackRef_FromPyObjectSteal(next_o);
@@ -4212,10 +4230,8 @@ Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_FOR_ITER_LIST(TAIL_CALL_PARAMS){
42124230
Py_DECREF(seq);
42134231
}
42144232
#endif
4215-
PyStackRef_CLOSE(iter);
4216-
STACK_SHRINK(1);
4217-
/* Jump forward oparg, then skip following END_FOR and POP_TOP instructions */
4218-
JUMPBY(oparg + 2);
4233+
/* Jump forward oparg, then skip following END_FOR instruction */
4234+
JUMPBY(oparg + 1);
42194235
DISPATCH();
42204236
}
42214237
}
@@ -4255,10 +4271,8 @@ Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_FOR_ITER_RANGE(TAIL_CALL_PARAMS)
42554271
assert(Py_TYPE(r) == &PyRangeIter_Type);
42564272
STAT_INC(FOR_ITER, hit);
42574273
if (r->len <= 0) {
4258-
STACK_SHRINK(1);
4259-
PyStackRef_CLOSE(iter);
4260-
// Jump over END_FOR and POP_TOP instructions.
4261-
JUMPBY(oparg + 2);
4274+
// Jump over END_FOR instruction.
4275+
JUMPBY(oparg + 1);
42624276
DISPATCH();
42634277
}
42644278
}
@@ -4305,10 +4319,8 @@ Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_FOR_ITER_TUPLE(TAIL_CALL_PARAMS)
43054319
it->it_seq = NULL;
43064320
Py_DECREF(seq);
43074321
}
4308-
PyStackRef_CLOSE(iter);
4309-
STACK_SHRINK(1);
4310-
/* Jump forward oparg, then skip following END_FOR and POP_TOP instructions */
4311-
JUMPBY(oparg + 2);
4322+
/* Jump forward oparg, then skip following END_FOR instruction */
4323+
JUMPBY(oparg + 1);
43124324
DISPATCH();
43134325
}
43144326
}
@@ -4736,7 +4748,7 @@ Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_INSTRUMENTED_CALL_KW(TAIL_CALL_P
47364748
}
47374749

47384750
Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_INSTRUMENTED_END_FOR(TAIL_CALL_PARAMS){
4739-
_Py_CODEUNIT* const this_instr = frame->instr_ptr = next_instr;
4751+
_Py_CODEUNIT* const this_instr = next_instr;
47404752
(void)this_instr;
47414753
next_instr += 1;
47424754
INSTRUCTION_STATS(INSTRUMENTED_END_FOR);
@@ -4800,6 +4812,7 @@ Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_INSTRUMENTED_FOR_ITER(TAIL_CALL_
48004812
stack_pointer = _PyFrame_GetStackPointer(frame);
48014813
if (next != NULL) {
48024814
PUSH(PyStackRef_FromPyObjectSteal(next));
4815+
INSTRUMENTED_JUMP(this_instr, next_instr, PY_MONITORING_EVENT_BRANCH_LEFT);
48034816
}
48044817
else {
48054818
if (_PyErr_Occurred(tstate)) {
@@ -4817,11 +4830,8 @@ Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_INSTRUMENTED_FOR_ITER(TAIL_CALL_
48174830
/* iterator ended normally */
48184831
assert(next_instr[oparg].op.code == END_FOR ||
48194832
next_instr[oparg].op.code == INSTRUMENTED_END_FOR);
4820-
STACK_SHRINK(1);
4821-
PyStackRef_CLOSE(iter_stackref);
4822-
/* Skip END_FOR and POP_TOP */
4823-
_Py_CODEUNIT *target = next_instr + oparg + 2;
4824-
INSTRUMENTED_JUMP(this_instr, target, PY_MONITORING_EVENT_BRANCH_RIGHT);
4833+
/* Skip END_FOR */
4834+
JUMPBY(oparg + 1);
48254835
}
48264836
DISPATCH();
48274837
}
@@ -4928,11 +4938,28 @@ Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_INSTRUMENTED_LOAD_SUPER_ATTR(TAI
49284938
}
49294939

49304940
Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_INSTRUMENTED_NOT_TAKEN(TAIL_CALL_PARAMS){
4941+
_Py_CODEUNIT* const prev_instr = frame->instr_ptr;
49314942
_Py_CODEUNIT* const this_instr = frame->instr_ptr = next_instr;
49324943
(void)this_instr;
49334944
next_instr += 1;
49344945
INSTRUCTION_STATS(INSTRUMENTED_NOT_TAKEN);
4935-
INSTRUMENTED_JUMP(this_instr, next_instr, PY_MONITORING_EVENT_BRANCH_LEFT);
4946+
(void)this_instr; // INSTRUMENTED_JUMP requires this_instr
4947+
INSTRUMENTED_JUMP(prev_instr, next_instr, PY_MONITORING_EVENT_BRANCH_LEFT);
4948+
DISPATCH();
4949+
}
4950+
4951+
Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_INSTRUMENTED_POP_ITER(TAIL_CALL_PARAMS){
4952+
_Py_CODEUNIT* const prev_instr = frame->instr_ptr;
4953+
_Py_CODEUNIT* const this_instr = frame->instr_ptr = next_instr;
4954+
(void)this_instr;
4955+
next_instr += 1;
4956+
INSTRUCTION_STATS(INSTRUMENTED_POP_ITER);
4957+
_PyStackRef iter;
4958+
iter = stack_pointer[-1];
4959+
INSTRUMENTED_JUMP(prev_instr, this_instr+1, PY_MONITORING_EVENT_BRANCH_RIGHT);
4960+
PyStackRef_CLOSE(iter);
4961+
stack_pointer += -1;
4962+
assert(WITHIN_STACK_BOUNDS());
49364963
DISPATCH();
49374964
}
49384965

@@ -6857,6 +6884,18 @@ Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_POP_EXCEPT(TAIL_CALL_PARAMS){
68576884
DISPATCH();
68586885
}
68596886

6887+
Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_POP_ITER(TAIL_CALL_PARAMS){
6888+
frame->instr_ptr = next_instr;
6889+
next_instr += 1;
6890+
INSTRUCTION_STATS(POP_ITER);
6891+
_PyStackRef value;
6892+
value = stack_pointer[-1];
6893+
PyStackRef_CLOSE(value);
6894+
stack_pointer += -1;
6895+
assert(WITHIN_STACK_BOUNDS());
6896+
DISPATCH();
6897+
}
6898+
68606899
Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_POP_JUMP_IF_FALSE(TAIL_CALL_PARAMS){
68616900
_Py_CODEUNIT* const this_instr = frame->instr_ptr = next_instr;
68626901
(void)this_instr;
@@ -8531,6 +8570,7 @@ static py_tail_call_funcptr INSTRUCTION_TABLE[256] = {
85318570
[INSTRUMENTED_LINE] = _TAIL_CALL_INSTRUMENTED_LINE,
85328571
[INSTRUMENTED_LOAD_SUPER_ATTR] = _TAIL_CALL_INSTRUMENTED_LOAD_SUPER_ATTR,
85338572
[INSTRUMENTED_NOT_TAKEN] = _TAIL_CALL_INSTRUMENTED_NOT_TAKEN,
8573+
[INSTRUMENTED_POP_ITER] = _TAIL_CALL_INSTRUMENTED_POP_ITER,
85348574
[INSTRUMENTED_POP_JUMP_IF_FALSE] = _TAIL_CALL_INSTRUMENTED_POP_JUMP_IF_FALSE,
85358575
[INSTRUMENTED_POP_JUMP_IF_NONE] = _TAIL_CALL_INSTRUMENTED_POP_JUMP_IF_NONE,
85368576
[INSTRUMENTED_POP_JUMP_IF_NOT_NONE] = _TAIL_CALL_INSTRUMENTED_POP_JUMP_IF_NOT_NONE,
@@ -8590,6 +8630,7 @@ static py_tail_call_funcptr INSTRUCTION_TABLE[256] = {
85908630
[NOP] = _TAIL_CALL_NOP,
85918631
[NOT_TAKEN] = _TAIL_CALL_NOT_TAKEN,
85928632
[POP_EXCEPT] = _TAIL_CALL_POP_EXCEPT,
8633+
[POP_ITER] = _TAIL_CALL_POP_ITER,
85938634
[POP_JUMP_IF_FALSE] = _TAIL_CALL_POP_JUMP_IF_FALSE,
85948635
[POP_JUMP_IF_NONE] = _TAIL_CALL_POP_JUMP_IF_NONE,
85958636
[POP_JUMP_IF_NOT_NONE] = _TAIL_CALL_POP_JUMP_IF_NOT_NONE,
@@ -8642,7 +8683,6 @@ static py_tail_call_funcptr INSTRUCTION_TABLE[256] = {
86428683
[UNPACK_SEQUENCE_TWO_TUPLE] = _TAIL_CALL_UNPACK_SEQUENCE_TWO_TUPLE,
86438684
[WITH_EXCEPT_START] = _TAIL_CALL_WITH_EXCEPT_START,
86448685
[YIELD_VALUE] = _TAIL_CALL_YIELD_VALUE,
8645-
[117] = _TAIL_CALL_UNKNOWN_OPCODE,
86468686
[118] = _TAIL_CALL_UNKNOWN_OPCODE,
86478687
[119] = _TAIL_CALL_UNKNOWN_OPCODE,
86488688
[120] = _TAIL_CALL_UNKNOWN_OPCODE,
@@ -8681,7 +8721,6 @@ static py_tail_call_funcptr INSTRUCTION_TABLE[256] = {
86818721
[232] = _TAIL_CALL_UNKNOWN_OPCODE,
86828722
[233] = _TAIL_CALL_UNKNOWN_OPCODE,
86838723
[234] = _TAIL_CALL_UNKNOWN_OPCODE,
8684-
[235] = _TAIL_CALL_UNKNOWN_OPCODE,
86858724
};
86868725
#undef TIER_ONE
86878726
#undef IN_TAIL_CALL_INTERP

Tools/cases_generator/tier1_generator.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,9 +134,12 @@ def write_single_inst(out: CWriter, emitter: Emitter, name: str, inst: Instructi
134134
if inst.properties.needs_prev:
135135
out.emit(f"_Py_CODEUNIT* const prev_instr = frame->instr_ptr;\n")
136136
if needs_this and not inst.is_target:
137-
out.emit(f"_Py_CODEUNIT* const this_instr = frame->instr_ptr = next_instr;\n")
137+
if inst.properties.no_save_ip:
138+
out.emit(f"_Py_CODEUNIT* const this_instr = next_instr;\n")
139+
else:
140+
out.emit(f"_Py_CODEUNIT* const this_instr = frame->instr_ptr = next_instr;\n")
138141
out.emit(unused_guard)
139-
else:
142+
elif not inst.properties.no_save_ip:
140143
out.emit(f"frame->instr_ptr = next_instr;\n")
141144
out.emit(f"next_instr += {inst.size};\n")
142145
out.emit(f"INSTRUCTION_STATS({name});\n")

0 commit comments

Comments
 (0)