Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit b05afdd

Browse filesBrowse files
authored
gh-115168: Add pystats counter for invalidated executors (GH-115169)
1 parent 96c10c6 commit b05afdd
Copy full SHA for b05afdd

File tree

Expand file treeCollapse file tree

11 files changed

+31
-14
lines changed
Filter options
Expand file treeCollapse file tree

11 files changed

+31
-14
lines changed

‎Include/cpython/optimizer.h

Copy file name to clipboardExpand all lines: Include/cpython/optimizer.h
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,8 @@ void _Py_ExecutorClear(_PyExecutorObject *);
100100
void _Py_BloomFilter_Init(_PyBloomFilter *);
101101
void _Py_BloomFilter_Add(_PyBloomFilter *bloom, void *obj);
102102
PyAPI_FUNC(void) _Py_Executor_DependsOn(_PyExecutorObject *executor, void *obj);
103-
PyAPI_FUNC(void) _Py_Executors_InvalidateDependency(PyInterpreterState *interp, void *obj);
104-
extern void _Py_Executors_InvalidateAll(PyInterpreterState *interp);
103+
PyAPI_FUNC(void) _Py_Executors_InvalidateDependency(PyInterpreterState *interp, void *obj, int is_invalidation);
104+
extern void _Py_Executors_InvalidateAll(PyInterpreterState *interp, int is_invalidation);
105105

106106
/* For testing */
107107
PyAPI_FUNC(PyObject *)PyUnstable_Optimizer_NewCounter(void);

‎Include/cpython/pystats.h

Copy file name to clipboardExpand all lines: Include/cpython/pystats.h
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ typedef struct _optimization_stats {
115115
uint64_t inner_loop;
116116
uint64_t recursive_call;
117117
uint64_t low_confidence;
118+
uint64_t executors_invalidated;
118119
UOpStats opcode[512];
119120
uint64_t unsupported_opcode[256];
120121
uint64_t trace_length_hist[_Py_UOP_HIST_SIZE];

‎Modules/_testinternalcapi.c

Copy file name to clipboardExpand all lines: Modules/_testinternalcapi.c
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1035,7 +1035,7 @@ static PyObject *
10351035
invalidate_executors(PyObject *self, PyObject *obj)
10361036
{
10371037
PyInterpreterState *interp = PyInterpreterState_Get();
1038-
_Py_Executors_InvalidateDependency(interp, obj);
1038+
_Py_Executors_InvalidateDependency(interp, obj, 1);
10391039
Py_RETURN_NONE;
10401040
}
10411041

‎Python/instrumentation.c

Copy file name to clipboardExpand all lines: Python/instrumentation.c
+3-3Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1599,7 +1599,7 @@ _Py_Instrument(PyCodeObject *code, PyInterpreterState *interp)
15991599
if (code->co_executors != NULL) {
16001600
_PyCode_Clear_Executors(code);
16011601
}
1602-
_Py_Executors_InvalidateDependency(interp, code);
1602+
_Py_Executors_InvalidateDependency(interp, code, 1);
16031603
int code_len = (int)Py_SIZE(code);
16041604
/* Exit early to avoid creating instrumentation
16051605
* data for potential statically allocated code
@@ -1820,7 +1820,7 @@ _PyMonitoring_SetEvents(int tool_id, _PyMonitoringEventSet events)
18201820
return -1;
18211821
}
18221822
set_global_version(tstate, new_version);
1823-
_Py_Executors_InvalidateAll(interp);
1823+
_Py_Executors_InvalidateAll(interp, 1);
18241824
return instrument_all_executing_code_objects(interp);
18251825
}
18261826

@@ -1850,7 +1850,7 @@ _PyMonitoring_SetLocalEvents(PyCodeObject *code, int tool_id, _PyMonitoringEvent
18501850
/* Force instrumentation update */
18511851
code->_co_instrumentation_version -= MONITORING_VERSION_INCREMENT;
18521852
}
1853-
_Py_Executors_InvalidateDependency(interp, code);
1853+
_Py_Executors_InvalidateDependency(interp, code, 1);
18541854
if (_Py_Instrument(code, interp)) {
18551855
return -1;
18561856
}

‎Python/optimizer.c

Copy file name to clipboardExpand all lines: Python/optimizer.c
+8-2Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1348,7 +1348,7 @@ _Py_Executor_DependsOn(_PyExecutorObject *executor, void *obj)
13481348
* May cause other executors to be invalidated as well
13491349
*/
13501350
void
1351-
_Py_Executors_InvalidateDependency(PyInterpreterState *interp, void *obj)
1351+
_Py_Executors_InvalidateDependency(PyInterpreterState *interp, void *obj, int is_invalidation)
13521352
{
13531353
_PyBloomFilter obj_filter;
13541354
_Py_BloomFilter_Init(&obj_filter);
@@ -1360,14 +1360,17 @@ _Py_Executors_InvalidateDependency(PyInterpreterState *interp, void *obj)
13601360
_PyExecutorObject *next = exec->vm_data.links.next;
13611361
if (bloom_filter_may_contain(&exec->vm_data.bloom, &obj_filter)) {
13621362
_Py_ExecutorClear(exec);
1363+
if (is_invalidation) {
1364+
OPT_STAT_INC(executors_invalidated);
1365+
}
13631366
}
13641367
exec = next;
13651368
}
13661369
}
13671370

13681371
/* Invalidate all executors */
13691372
void
1370-
_Py_Executors_InvalidateAll(PyInterpreterState *interp)
1373+
_Py_Executors_InvalidateAll(PyInterpreterState *interp, int is_invalidation)
13711374
{
13721375
while (interp->executor_list_head) {
13731376
_PyExecutorObject *executor = interp->executor_list_head;
@@ -1378,5 +1381,8 @@ _Py_Executors_InvalidateAll(PyInterpreterState *interp)
13781381
else {
13791382
_Py_ExecutorClear(executor);
13801383
}
1384+
if (is_invalidation) {
1385+
OPT_STAT_INC(executors_invalidated);
1386+
}
13811387
}
13821388
}

‎Python/optimizer_analysis.c

Copy file name to clipboardExpand all lines: Python/optimizer_analysis.c
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -405,7 +405,7 @@ globals_watcher_callback(PyDict_WatchEvent event, PyObject* dict,
405405
{
406406
RARE_EVENT_STAT_INC(watched_globals_modification);
407407
assert(get_mutations(dict) < _Py_MAX_ALLOWED_GLOBALS_MODIFICATIONS);
408-
_Py_Executors_InvalidateDependency(_PyInterpreterState_GET(), dict);
408+
_Py_Executors_InvalidateDependency(_PyInterpreterState_GET(), dict, 1);
409409
increment_mutations(dict);
410410
PyDict_Unwatch(GLOBALS_WATCHER_ID, dict);
411411
return 0;

‎Python/pylifecycle.c

Copy file name to clipboardExpand all lines: Python/pylifecycle.c
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -612,7 +612,7 @@ builtins_dict_watcher(PyDict_WatchEvent event, PyObject *dict, PyObject *key, Py
612612
{
613613
PyInterpreterState *interp = _PyInterpreterState_GET();
614614
if (interp->rare_events.builtin_dict < _Py_MAX_ALLOWED_BUILTINS_MODIFICATIONS) {
615-
_Py_Executors_InvalidateAll(interp);
615+
_Py_Executors_InvalidateAll(interp, 1);
616616
}
617617
RARE_EVENT_INTERP_INC(interp, builtin_dict);
618618
return 0;
@@ -1628,7 +1628,7 @@ finalize_modules(PyThreadState *tstate)
16281628
PyInterpreterState *interp = tstate->interp;
16291629

16301630
// Invalidate all executors and turn off tier 2 optimizer
1631-
_Py_Executors_InvalidateAll(interp);
1631+
_Py_Executors_InvalidateAll(interp, 0);
16321632
_PyOptimizerObject *old = _Py_SetOptimizer(interp, NULL);
16331633
Py_XDECREF(old);
16341634

‎Python/pystate.c

Copy file name to clipboardExpand all lines: Python/pystate.c
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2666,7 +2666,7 @@ _PyInterpreterState_SetEvalFrameFunc(PyInterpreterState *interp,
26662666
return;
26672667
}
26682668
if (eval_frame != NULL) {
2669-
_Py_Executors_InvalidateAll(interp);
2669+
_Py_Executors_InvalidateAll(interp, 1);
26702670
}
26712671
RARE_EVENT_INC(set_eval_frame_func);
26722672
interp->eval_frame = eval_frame;

‎Python/specialize.c

Copy file name to clipboardExpand all lines: Python/specialize.c
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,7 @@ print_optimization_stats(FILE *out, OptimizationStats *stats)
236236
fprintf(out, "Optimization inner loop: %" PRIu64 "\n", stats->inner_loop);
237237
fprintf(out, "Optimization recursive call: %" PRIu64 "\n", stats->recursive_call);
238238
fprintf(out, "Optimization low confidence: %" PRIu64 "\n", stats->low_confidence);
239+
fprintf(out, "Executors invalidated: %" PRIu64 "\n", stats->executors_invalidated);
239240

240241
print_histogram(out, "Trace length", stats->trace_length_hist);
241242
print_histogram(out, "Trace run length", stats->trace_run_length_hist);

‎Python/sysmodule.c

Copy file name to clipboardExpand all lines: Python/sysmodule.c
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2138,7 +2138,7 @@ sys__clear_internal_caches_impl(PyObject *module)
21382138
/*[clinic end generated code: output=0ee128670a4966d6 input=253e741ca744f6e8]*/
21392139
{
21402140
PyInterpreterState *interp = _PyInterpreterState_GET();
2141-
_Py_Executors_InvalidateAll(interp);
2141+
_Py_Executors_InvalidateAll(interp, 0);
21422142
PyType_ClearCache();
21432143
Py_RETURN_NONE;
21442144
}

‎Tools/scripts/summarize_stats.py

Copy file name to clipboardExpand all lines: Tools/scripts/summarize_stats.py
+10-1Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,7 @@ def get_optimization_stats(self) -> dict[str, tuple[int, int | None]]:
451451
inner_loop = self._data["Optimization inner loop"]
452452
recursive_call = self._data["Optimization recursive call"]
453453
low_confidence = self._data["Optimization low confidence"]
454+
executors_invalidated = self._data["Executors invalidated"]
454455

455456
return {
456457
Doc(
@@ -493,11 +494,19 @@ def get_optimization_stats(self) -> dict[str, tuple[int, int | None]]:
493494
"A trace is abandoned because the likelihood of the jump to top being taken "
494495
"is too low.",
495496
): (low_confidence, attempts),
497+
Doc(
498+
"Executors invalidated",
499+
"The number of executors that were invalidated due to watched "
500+
"dictionary changes.",
501+
): (executors_invalidated, created),
496502
Doc("Traces executed", "The number of traces that were executed"): (
497503
executed,
498504
None,
499505
),
500-
Doc("Uops executed", "The total number of uops (micro-operations) that were executed"): (
506+
Doc(
507+
"Uops executed",
508+
"The total number of uops (micro-operations) that were executed",
509+
): (
501510
uops,
502511
executed,
503512
),

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.