Skip to content

Commit

Permalink
hookify genobject.c
Browse files Browse the repository at this point in the history
Summary: Adds dynamic CinderX checks to `genobject.c`

Reviewed By: oclbdk

Differential Revision: D50978199

fbshipit-source-id: 7deef8c67cc4fa8795a273625b04bb0a73e3a6ab
  • Loading branch information
pilleye authored and facebook-github-bot committed Nov 8, 2023
1 parent efc861f commit 0cd6234
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 23 deletions.
6 changes: 5 additions & 1 deletion Cinder/cinder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions CinderX/known-core-python-exported-symbols
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
21 changes: 21 additions & 0 deletions Include/cinderhooks.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
35 changes: 13 additions & 22 deletions Objects/genobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 *);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
Expand Down
6 changes: 6 additions & 0 deletions Python/cinderhooks.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

0 comments on commit 0cd6234

Please sign in to comment.