Skip to content

Commit

Permalink
Add cinderhooks for SP type patching support
Browse files Browse the repository at this point in the history
Summary: Add cinderhooks for SP `type_setattro` hooks, for now.

Reviewed By: DinoV

Differential Revision: D49510369

fbshipit-source-id: bee51b0841340f6bd4f9ebad3626fe355673d707
  • Loading branch information
jbower-fb authored and facebook-github-bot committed Oct 23, 2023
1 parent 2f6d74e commit 5d3725d
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 12 deletions.
3 changes: 3 additions & 0 deletions Cinder/cinder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "cinderhooks.h"
#include "cinder/cinder.h"
#include "Jit/pyjit.h"
#include "StaticPython/classloader.h"

static int cinder_dict_watcher_id = -1;
static int cinder_type_watcher_id = -1;
Expand Down Expand Up @@ -179,6 +180,8 @@ int Cinder_Init() {
Ci_hook_type_created = _PyJIT_TypeCreated;
Ci_hook_type_destroyed = _PyJIT_TypeDestroyed;
Ci_hook_type_name_modified = _PyJIT_TypeNameModified;
Ci_hook_type_pre_setattr = _PyClassLoader_InitTypeForPatching;
Ci_hook_type_setattr = _PyClassLoader_UpdateSlot;
init_already_existing_types();

if (cinder_install_dict_watcher() < 0) {
Expand Down
10 changes: 10 additions & 0 deletions Include/cinderhooks.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,17 @@

/* Hooks needed by CinderX that have not been added to upstream. */

/* Hooks for JIT type profiling. */

typedef void(*Ci_TypeCallback)(PyTypeObject *type);
CiAPI_DATA(Ci_TypeCallback) Ci_hook_type_created;
CiAPI_DATA(Ci_TypeCallback) Ci_hook_type_destroyed;
CiAPI_DATA(Ci_TypeCallback) Ci_hook_type_name_modified;

/* Hooks for Static Python. */

typedef int(*Ci_TypeRaisingCallback)(PyTypeObject *type);
CiAPI_DATA(Ci_TypeRaisingCallback) Ci_hook_type_pre_setattr;

typedef int(*Ci_TypeAttrRaisingCallback)(PyTypeObject *type, PyObject *name, PyObject *value);
CiAPI_DATA(Ci_TypeAttrRaisingCallback) Ci_hook_type_setattr;
16 changes: 4 additions & 12 deletions Objects/typeobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -4405,15 +4405,9 @@ type_setattro(PyTypeObject *type, PyObject *name, PyObject *value)
existing = PyDict_GetItem(type->tp_dict, name);
Py_XINCREF(existing);
}
#ifdef ENABLE_CINDERX
if (type->tp_flags & Ci_Py_TPFLAGS_IS_STATICALLY_DEFINED) {
/* We're running in an environment where we're patching types. Prepare
* the type for tracking patches if it hasn't already been prepared */
if (_PyClassLoader_InitTypeForPatching(type)) {
return -1;
}
if (Ci_hook_type_pre_setattr) {
Ci_hook_type_pre_setattr(type);
}
#endif
res = _PyObject_GenericSetAttrWithDict((PyObject *)type, name, value, NULL);
if (res == 0) {
/* Clear the VALID_VERSION flag of 'type' and all its
Expand All @@ -4428,9 +4422,8 @@ type_setattro(PyTypeObject *type, PyObject *name, PyObject *value)
}
_PyType_ClearNoShadowingInstances(type, value);
assert(_PyType_CheckConsistency(type));
#ifdef ENABLE_CINDERX
if (existing != value) {
int slotupdate_res = _PyClassLoader_UpdateSlot(type, name, value);
if (Ci_hook_type_setattr && existing != value) {
int slotupdate_res = Ci_hook_type_setattr(type, name, value);
if (slotupdate_res == -1) {
// We failed to update the slot, so restore the existing value
int revert_res = _PyObject_GenericSetAttrWithDict((PyObject *)type, name, existing, NULL);
Expand All @@ -4441,7 +4434,6 @@ type_setattro(PyTypeObject *type, PyObject *name, PyObject *value)
}
res = res || slotupdate_res;
}
#endif
}
Py_XDECREF(existing);
Py_DECREF(name);
Expand Down
5 changes: 5 additions & 0 deletions Python/cinderhooks.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
#include "Python.h"
#include "cinderhooks.h"

/* JIT type profiling. */
Ci_TypeCallback Ci_hook_type_created = NULL;
Ci_TypeCallback Ci_hook_type_destroyed = NULL;
Ci_TypeCallback Ci_hook_type_name_modified = NULL;

/* Static Python. */
Ci_TypeRaisingCallback Ci_hook_type_pre_setattr = NULL;
Ci_TypeAttrRaisingCallback Ci_hook_type_setattr = NULL;
3 changes: 3 additions & 0 deletions StaticPython/classloader.c
Original file line number Diff line number Diff line change
Expand Up @@ -2455,6 +2455,9 @@ int
get_func_or_special_callable(PyTypeObject *type, PyObject *name, PyObject **result);

int _PyClassLoader_InitTypeForPatching(PyTypeObject *type) {
if (!(type->tp_flags & Ci_Py_TPFLAGS_IS_STATICALLY_DEFINED)) {
return 0;
}
_PyType_VTable *vtable = (_PyType_VTable *)type->tp_cache;
if (vtable != NULL && vtable->vt_original != NULL) {
return 0;
Expand Down

0 comments on commit 5d3725d

Please sign in to comment.