mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 13:41:24 +00:00 
			
		
		
		
	GH-112354: Initial implementation of warm up on exits and trace-stitching (GH-114142)
This commit is contained in:
		
							parent
							
								
									acda1757bc
								
							
						
					
					
						commit
						7b21403ccd
					
				
					 29 changed files with 744 additions and 198 deletions
				
			
		|  | @ -16,6 +16,7 @@ | |||
| #include "pycore_moduleobject.h"  // PyModuleObject | ||||
| #include "pycore_object.h"        // _PyObject_GC_TRACK() | ||||
| #include "pycore_opcode_metadata.h" // EXTRA_CASES | ||||
| #include "pycore_optimizer.h"     // _PyUOpExecutor_Type | ||||
| #include "pycore_opcode_utils.h"  // MAKE_FUNCTION_* | ||||
| #include "pycore_pyerrors.h"      // _PyErr_GetRaisedException() | ||||
| #include "pycore_pystate.h"       // _PyInterpreterState_GET() | ||||
|  | @ -738,15 +739,16 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int | |||
|         goto resume_with_error; | ||||
|     } | ||||
| 
 | ||||
|     /* State shared between Tier 1 and Tier 2 interpreter */ | ||||
|     _PyExecutorObject *current_executor = NULL; | ||||
| 
 | ||||
|     /* Local "register" variables.
 | ||||
|      * These are cached values from the frame and code object.  */ | ||||
| 
 | ||||
|     _Py_CODEUNIT *next_instr; | ||||
|     PyObject **stack_pointer; | ||||
| 
 | ||||
| #ifndef _Py_JIT | ||||
|     /* Tier 2 interpreter state */ | ||||
|     _PyExecutorObject *current_executor = NULL; | ||||
|     const _PyUOpInstruction *next_uop = NULL; | ||||
| #endif | ||||
| 
 | ||||
| start_frame: | ||||
|     if (_Py_EnterRecursivePy(tstate)) { | ||||
|  | @ -960,18 +962,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int | |||
| enter_tier_two: | ||||
| 
 | ||||
| #ifdef _Py_JIT | ||||
| 
 | ||||
|     ;  // ;)
 | ||||
|     jit_func jitted = current_executor->jit_code; | ||||
|     next_instr = jitted(frame, stack_pointer, tstate); | ||||
|     frame = tstate->current_frame; | ||||
|     Py_DECREF(current_executor); | ||||
|     if (next_instr == NULL) { | ||||
|         goto resume_with_error; | ||||
|     } | ||||
|     stack_pointer = _PyFrame_GetStackPointer(frame); | ||||
|     DISPATCH(); | ||||
| 
 | ||||
|     assert(0); | ||||
| #else | ||||
| 
 | ||||
| #undef LOAD_IP | ||||
|  | @ -1007,12 +998,12 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int | |||
| #endif | ||||
| 
 | ||||
|     OPT_STAT_INC(traces_executed); | ||||
|     _PyUOpInstruction *next_uop = current_executor->trace; | ||||
|     uint16_t uopcode; | ||||
| #ifdef Py_STATS | ||||
|     uint64_t trace_uop_execution_counter = 0; | ||||
| #endif | ||||
| 
 | ||||
|     assert(next_uop->opcode == _START_EXECUTOR || next_uop->opcode == _COLD_EXIT); | ||||
|     for (;;) { | ||||
|         uopcode = next_uop->opcode; | ||||
|         DPRINTF(3, | ||||
|  | @ -1075,23 +1066,39 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int | |||
|     frame->return_offset = 0;  // Don't leave this random
 | ||||
|     _PyFrame_SetStackPointer(frame, stack_pointer); | ||||
|     Py_DECREF(current_executor); | ||||
|     tstate->previous_executor = NULL; | ||||
|     goto resume_with_error; | ||||
| 
 | ||||
| // Jump here from DEOPT_IF()
 | ||||
| deoptimize: | ||||
|     next_instr = next_uop[-1].target + _PyCode_CODE(_PyFrame_GetCode(frame)); | ||||
|     DPRINTF(2, "DEOPT: [UOp %d (%s), oparg %d, operand %" PRIu64 ", target %d @ %d -> %s]\n", | ||||
|     DPRINTF(2, "DEOPT: [UOp %d (%s), oparg %d, operand %" PRIu64 ", target %d -> %s]\n", | ||||
|             uopcode, _PyUOpName(uopcode), next_uop[-1].oparg, next_uop[-1].operand, next_uop[-1].target, | ||||
|             (int)(next_uop - current_executor->trace - 1), | ||||
|             _PyOpcode_OpName[frame->instr_ptr->op.code]); | ||||
|             _PyOpcode_OpName[next_instr->op.code]); | ||||
|     OPT_HIST(trace_uop_execution_counter, trace_run_length_hist); | ||||
|     UOP_STAT_INC(uopcode, miss); | ||||
|     Py_DECREF(current_executor); | ||||
|     tstate->previous_executor = NULL; | ||||
|     DISPATCH(); | ||||
| 
 | ||||
| // Jump here from EXIT_IF()
 | ||||
| side_exit: | ||||
|     OPT_HIST(trace_uop_execution_counter, trace_run_length_hist); | ||||
|     UOP_STAT_INC(uopcode, miss); | ||||
|     uint32_t exit_index = next_uop[-1].exit_index; | ||||
|     assert(exit_index < current_executor->exit_count); | ||||
|     _PyExitData *exit = ¤t_executor->exits[exit_index]; | ||||
|     DPRINTF(2, "SIDE EXIT: [UOp %d (%s), oparg %d, operand %" PRIu64 ", exit %u, temp %d, target %d -> %s]\n", | ||||
|             uopcode, _PyUOpName(uopcode), next_uop[-1].oparg, next_uop[-1].operand, exit_index, exit->temperature, | ||||
|             exit->target, _PyOpcode_OpName[_PyCode_CODE(_PyFrame_GetCode(frame))[exit->target].op.code]); | ||||
|     Py_INCREF(exit->executor); | ||||
|     tstate->previous_executor = (PyObject *)current_executor; | ||||
|     GOTO_TIER_TWO(exit->executor); | ||||
| 
 | ||||
| #endif  // _Py_JIT
 | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| #if defined(__GNUC__) | ||||
| #  pragma GCC diagnostic pop | ||||
| #elif defined(_MSC_VER) /* MS_WINDOWS */ | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Mark Shannon
						Mark Shannon