#include "pycore_setobject.h" // _PySet_NextEntry()
#include "pycore_stats.h"
#include "pycore_weakref.h" // FT_CLEAR_WEAKREFS()
-
+#include "pycore_optimizer.h" // _Py_JITTracer_InvalidateDependency
static const char *
func_event_name(PyFunction_WatchEvent event) {
if (_PyObject_ResurrectEnd(self)) {
return;
}
+#if _Py_TIER2
+ _Py_JITTracer_InvalidateDependency(PyThreadState_GET(), self);
+#endif
_PyObject_GC_UNTRACK(op);
FT_CLEAR_WEAKREFS(self, op->func_weakreflist);
(void)func_clear((PyObject*)op);
interp->compiling = false;
return 0;
}
+ // One of our depencies while tracing was invalidated. Not worth compiling.
+ if (!tstate->interp->jit_tracer_dependencies_still_valid) {
+ interp->compiling = false;
+ return 0;
+ }
_PyExecutorObject *executor;
int err = uop_optimize(frame, tstate, &executor, progress_needed);
if (err <= 0) {
int oparg,
int jump_taken)
{
- if (PyStackRef_IsNull(frame->f_funcobj)) {
- goto unsupported;
- }
int is_first_instr = tstate->interp->jit_tracer_initial_instr == this_instr;
bool progress_needed = (tstate->interp->jit_tracer_initial_chain_depth % MAX_CHAIN_DEPTH) == 0 && is_first_instr;;
}
if (uop == _PUSH_FRAME || uop == _RETURN_VALUE || uop == _RETURN_GENERATOR || uop == _YIELD_VALUE) {
PyCodeObject *new_code = (PyCodeObject *)PyStackRef_AsPyObjectBorrow(frame->f_executable);
- PyFunctionObject *new_func = (PyCodeObject *)PyStackRef_AsPyObjectBorrow(frame->f_funcobj);
+ PyFunctionObject *new_func = (PyFunctionObject *)PyStackRef_AsPyObjectBorrow(frame->f_funcobj);
if (new_func != NULL) {
operand = (uintptr_t)new_func;
+ DPRINTF(2, "Adding %p func to op\n", (void *)operand);
+ _Py_BloomFilter_Add(dependencies, new_func);
}
else if (new_code != NULL) {
operand = (uintptr_t)new_code | 1;
+ DPRINTF(2, "Adding %p code to op\n", (void *)operand);
+ _Py_BloomFilter_Add(dependencies, new_code);
}
else {
operand = 0;
tstate->interp->jit_tracer_initial_stack_depth = curr_stackdepth;
tstate->interp->jit_tracer_initial_chain_depth = chain_depth;
tstate->interp->jit_tracer_current_frame = frame;
+ tstate->interp->jit_tracer_dependencies_still_valid = true;
}
void
_Py_Executors_InvalidateAll(interp, is_invalidation);
}
+void
+_Py_JITTracer_InvalidateDependency(PyThreadState *old_tstate, void *obj)
+{
+ _PyBloomFilter obj_filter;
+ _Py_BloomFilter_Init(&obj_filter);
+ _Py_BloomFilter_Add(&obj_filter, obj);
+ HEAD_LOCK(&_PyRuntime);
+
+ PyInterpreterState *interp = old_tstate->interp;
+
+ _Py_FOR_EACH_TSTATE_UNLOCKED(interp, tstate) {
+ if (bloom_filter_may_contain(&tstate->interp->jit_tracer_dependencies, &obj_filter))
+ {
+ tstate->interp->jit_tracer_dependencies_still_valid = false;
+ }
+
+ }
+ HEAD_UNLOCK(&_PyRuntime);
+}
/* Invalidate all executors */
void
_Py_Executors_InvalidateAll(PyInterpreterState *interp, int is_invalidation)