diff --git a/Cinder/cinder.cpp b/Cinder/cinder.cpp index cf47bce1825..1fd8bbbee28 100644 --- a/Cinder/cinder.cpp +++ b/Cinder/cinder.cpp @@ -177,7 +177,11 @@ int Cinder_Init() { Ci_hook_code_sizeof_shadowcode = Ci_code_sizeof_shadowcode; Ci_hook_PyShadowFrame_HasGen = _PyShadowFrame_HasGen; Ci_hook_PyShadowFrame_GetGen = _PyShadowFrame_GetGen; - + Ci_hook_PyJIT_GenVisitRefs = _PyJIT_GenVisitRefs; + Ci_hook_PyJIT_GenDealloc = _PyJIT_GenDealloc; + Ci_hook_PyJIT_GenSend = _PyJIT_GenSend; + Ci_hook_PyJIT_GenYieldFromValue = _PyJIT_GenYieldFromValue; + Ci_hook_PyJIT_GenMaterializeFrame = _PyJIT_GenMaterializeFrame; // This should be the very last hook installed Ci_cinderx_initialized = 1; diff --git a/CinderX/known-core-python-exported-symbols b/CinderX/known-core-python-exported-symbols index 671900a034e..9fc41b2c9f1 100644 --- a/CinderX/known-core-python-exported-symbols +++ b/CinderX/known-core-python-exported-symbols @@ -24,6 +24,7 @@ CiGen_restore_error Ci_GetAIter Ci_GetANext Ci_hook_PyDescr_NewMethod +Ci_hook_PyJIT_GenDealloc Ci_List_APPEND Ci_List_Repeat Ci_list_subscript diff --git a/Include/cinderhooks.h b/Include/cinderhooks.h index 080e7dc2b6a..033ead1ebf7 100644 --- a/Include/cinderhooks.h +++ b/Include/cinderhooks.h @@ -64,3 +64,24 @@ CiAPI_DATA(Ci_HookType_PyShadowFrame_HasGen) Ci_hook_PyShadowFrame_HasGen; typedef PyGenObject *(*Ci_HookType_PyShadowFrame_GetGen)( struct _PyShadowFrame *sf); CiAPI_DATA(Ci_HookType_PyShadowFrame_GetGen) Ci_hook_PyShadowFrame_GetGen; + +typedef int (*Ci_HookType_PyJIT_GenVisitRefs)(PyGenObject *gen, visitproc visit, + void *arg); +CiAPI_DATA(Ci_HookType_PyJIT_GenVisitRefs) Ci_hook_PyJIT_GenVisitRefs; + +typedef void (*Ci_HookType_PyJIT_GenDealloc)(PyGenObject *gen); +CiAPI_DATA(Ci_HookType_PyJIT_GenDealloc) Ci_hook_PyJIT_GenDealloc; + +typedef PyObject *(*Ci_HookType_PyJIT_GenSend)(PyGenObject *gen, PyObject *arg, + int exc, PyFrameObject *f, + PyThreadState *tstate, + int finish_yield_from); +CiAPI_DATA(Ci_HookType_PyJIT_GenSend) Ci_hook_PyJIT_GenSend; + +typedef PyObject *(*Ci_HookType_PyJIT_GenYieldFromValue)(PyGenObject *gen); +CiAPI_DATA(Ci_HookType_PyJIT_GenYieldFromValue) Ci_hook_PyJIT_GenYieldFromValue; + +typedef PyFrameObject *(*Ci_HookType_PyJIT_GenMaterializeFrame)( + PyGenObject *gen); +CiAPI_DATA(Ci_HookType_PyJIT_GenMaterializeFrame) + Ci_hook_PyJIT_GenMaterializeFrame; diff --git a/Objects/genobject.c b/Objects/genobject.c index 11b26dfdb70..0a6a8cb50d3 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -11,6 +11,7 @@ #include "opcode.h" #include "Jit/pyjit.h" #include "cinder/exports.h" +#include "cinderhooks.h" #include "pycore_gc.h" // _PyGC_UNSET_FINALIZED static PyObject *gen_close(PyGenObject *, PyObject *); @@ -55,14 +56,14 @@ gen_traverse(PyGenObject *gen, visitproc visit, void *arg) Py_VISIT(gen->gi_code); Py_VISIT(gen->gi_name); Py_VISIT(gen->gi_qualname); -#ifdef ENABLE_CINDERX - if (gen->gi_jit_data) { - int r = _PyJIT_GenVisitRefs(gen, visit, arg); + + if (Ci_cinderx_initialized && gen->gi_jit_data) { + int r = Ci_hook_PyJIT_GenVisitRefs(gen, visit, arg); if (r) { return r; } } -#endif + /* No need to visit cr_origin, because it's just tuples/str/int, so can't participate in a reference cycle. */ return exc_state_traverse(&gen->gi_exc_state, visit, arg); @@ -174,11 +175,9 @@ gen_dealloc(PyGenObject *gen) gen->gi_frame->f_gen = NULL; Py_CLEAR(gen->gi_frame); } -#ifdef ENABLE_CINDERX - if (gen->gi_jit_data) { - _PyJIT_GenDealloc(gen); + if (Ci_cinderx_initialized && gen->gi_jit_data) { + Ci_hook_PyJIT_GenDealloc(gen); } -#endif if (((PyCodeObject *)gen->gi_code)->co_flags & CO_COROUTINE) { Py_CLEAR(((PyCoroObject *)gen)->cr_origin); } @@ -296,18 +295,14 @@ gen_send_ex2(PyGenObject *gen, PyObject *arg, PyObject **presult, gen->gi_shadow_frame.prev = tstate->shadow_frame; tstate->shadow_frame = &gen->gi_shadow_frame; -#ifdef ENABLE_CINDERX - if (gen->gi_jit_data) { - result = _PyJIT_GenSend(gen, arg, exc, f, tstate, finish_yield_from); + if (Ci_cinderx_initialized && gen->gi_jit_data) { + result = Ci_hook_PyJIT_GenSend(gen, arg, exc, f, tstate, finish_yield_from); /* We might get a frame in shadow-frame mode if a deopt occurs. */ assert(!f || f == gen->gi_frame); f = gen->gi_frame; } else { -#endif result = _PyEval_EvalFrame(tstate, f, exc); -#ifdef ENABLE_CINDERX } -#endif _PyShadowFrame_Pop(tstate, &gen->gi_shadow_frame); tstate->exc_info = gen->gi_exc_state.previous_item; gen->gi_exc_state.previous_item = NULL; @@ -480,11 +475,9 @@ _PyGen_yf(PyGenObject *gen) PyObject *yf = NULL; PyFrameObject *f = gen->gi_frame; -#ifdef ENABLE_CINDERX - if (gen->gi_jit_data) { - return _PyJIT_GenYieldFromValue(gen); + if (Ci_cinderx_initialized && gen->gi_jit_data) { + return Ci_hook_PyJIT_GenYieldFromValue(gen); } -#endif if (f) { PyObject *bytecode = f->f_code->co_code; @@ -937,11 +930,9 @@ Ci_genlike_getframe(PyGenObject *gen, const char* attr_name) } PyFrameObject *frame = gen->gi_frame; -#ifdef ENABLE_CINDERX - if (gen->gi_jit_data) { - frame = _PyJIT_GenMaterializeFrame(gen); + if (Ci_cinderx_initialized && gen->gi_jit_data) { + frame = Ci_hook_PyJIT_GenMaterializeFrame(gen); } -#endif if (frame == NULL) { Py_RETURN_NONE; } diff --git a/Python/cinderhooks.c b/Python/cinderhooks.c index f391794ca50..54559e4a495 100644 --- a/Python/cinderhooks.c +++ b/Python/cinderhooks.c @@ -26,3 +26,9 @@ Ci_HookType_code_sizeof_shadowcode Ci_hook_code_sizeof_shadowcode = NULL; Ci_HookType_PyShadowFrame_HasGen Ci_hook_PyShadowFrame_HasGen = NULL; Ci_HookType_PyShadowFrame_GetGen Ci_hook_PyShadowFrame_GetGen = NULL; + +Ci_HookType_PyJIT_GenVisitRefs Ci_hook_PyJIT_GenVisitRefs = NULL; +Ci_HookType_PyJIT_GenDealloc Ci_hook_PyJIT_GenDealloc = NULL; +Ci_HookType_PyJIT_GenSend Ci_hook_PyJIT_GenSend = NULL; +Ci_HookType_PyJIT_GenYieldFromValue Ci_hook_PyJIT_GenYieldFromValue = NULL; +Ci_HookType_PyJIT_GenMaterializeFrame Ci_hook_PyJIT_GenMaterializeFrame = NULL;