@@ -540,7 +540,6 @@ add_to_trace(
540540 assert(func == NULL || func->func_code == (PyObject *)code); \
541541 instr = trace_stack[trace_stack_depth].instr;
542542
543-
544543/* Returns the length of the trace on success,
545544 * 0 if it failed to produce a worthwhile trace,
546545 * and -1 on an error.
@@ -561,10 +560,8 @@ translate_bytecode_to_trace(
561560 _Py_BloomFilter_Add (dependencies , initial_code );
562561 _Py_CODEUNIT * initial_instr = instr ;
563562 int trace_length = 0 ;
564- // Leave space for possible trailing _EXIT_TRACE and estimated exit stubs
565- // Reserve 20% of buffer space for exit stubs (empirically sufficient)
566- int max_exit_stubs = (buffer_size * 20 ) / 100 ; // 20% for exit stubs
567- int max_length = buffer_size - 2 - max_exit_stubs ;
563+ // Leave space for possible trailing _EXIT_TRACE
564+ int max_length = buffer_size - 2 ;
568565 struct {
569566 PyFunctionObject * func ;
570567 PyCodeObject * code ;
@@ -650,7 +647,16 @@ translate_bytecode_to_trace(
650647 assert (!OPCODE_HAS_DEOPT (opcode ));
651648 }
652649
653- // Note: Exit stub space is pre-reserved in max_length calculation above
650+ if (OPCODE_HAS_EXIT (opcode )) {
651+ // Make space for side exit and final _EXIT_TRACE:
652+ RESERVE_RAW (2 , "_EXIT_TRACE" );
653+ max_length -- ;
654+ }
655+ if (OPCODE_HAS_ERROR (opcode )) {
656+ // Make space for error stub and final _EXIT_TRACE:
657+ RESERVE_RAW (2 , "_ERROR_POP_N" );
658+ max_length -- ;
659+ }
654660 switch (opcode ) {
655661 case POP_JUMP_IF_NONE :
656662 case POP_JUMP_IF_NOT_NONE :
@@ -725,11 +731,9 @@ translate_bytecode_to_trace(
725731 {
726732 const struct opcode_macro_expansion * expansion = & _PyOpcode_macro_expansion [opcode ];
727733 if (expansion -> nuops > 0 ) {
728- // Reserve space for nuops
734+ // Reserve space for nuops (+ _SET_IP + _EXIT_TRACE)
729735 int nuops = expansion -> nuops ;
730-
731- // Reserve space for nuops (exit stub space already pre-reserved)
732- RESERVE (nuops );
736+ RESERVE (nuops + 1 ); /* One extra for exit */
733737 int16_t last_op = expansion -> uops [nuops - 1 ].uop ;
734738 if (last_op == _RETURN_VALUE || last_op == _RETURN_GENERATOR || last_op == _YIELD_VALUE ) {
735739 // Check for trace stack underflow now:
0 commit comments