Skip to content

Commit

Permalink
Make cinder.cpp more C++
Browse files Browse the repository at this point in the history
Summary: Use  lambdas to make the code a bit more concise and a few other tweaks.

Reviewed By: alexmalyshev

Differential Revision: D50866123

fbshipit-source-id: 4850b8f07fd9e4687e1dc7be6f9ef71a439fadd1
  • Loading branch information
jbower-fb authored and facebook-github-bot committed Nov 3, 2023
1 parent 32cd103 commit b87875d
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 106 deletions.
195 changes: 89 additions & 106 deletions Cinder/cinder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,41 +6,40 @@
#include "Jit/pyjit.h"
#include "StaticPython/classloader.h"
#include "StaticPython/descrobject_vectorcall.h"
#include "Shadowcode/shadowcode.h"

static int cinder_dict_watcher_id = -1;
static int cinder_type_watcher_id = -1;
static int cinder_func_watcher_id = -1;
static int cinder_code_watcher_id = -1;

static int cinder_dict_watcher(
PyDict_WatchEvent event,
PyObject* dict,
PyObject* key,
PyObject* new_value) {
switch (event) {
case PyDict_EVENT_ADDED:
case PyDict_EVENT_MODIFIED:
case PyDict_EVENT_DELETED:
if (!PyUnicode_CheckExact(key)) {
_PyJIT_NotifyDictUnwatch(dict);
} else {
_PyJIT_NotifyDictKey(dict, key, new_value);
_PyClassLoader_NotifyDictChange((PyDictObject *)dict, key);
}
break;
case PyDict_EVENT_CLEARED:
_PyJIT_NotifyDictClear(dict);
break;
case PyDict_EVENT_CLONED:
case PyDict_EVENT_DEALLOCATED:
_PyJIT_NotifyDictUnwatch(dict);
break;
}
return 0;
}

static int cinder_install_dict_watcher() {
int watcher_id = PyDict_AddWatcher(cinder_dict_watcher);
int watcher_id = PyDict_AddWatcher([](
PyDict_WatchEvent event,
PyObject* dict,
PyObject* key,
PyObject* new_value) {
switch (event) {
case PyDict_EVENT_ADDED:
case PyDict_EVENT_MODIFIED:
case PyDict_EVENT_DELETED:
if (!PyUnicode_CheckExact(key)) {
_PyJIT_NotifyDictUnwatch(dict);
} else {
_PyJIT_NotifyDictKey(dict, key, new_value);
_PyClassLoader_NotifyDictChange((PyDictObject *)dict, key);
}
break;
case PyDict_EVENT_CLEARED:
_PyJIT_NotifyDictClear(dict);
break;
case PyDict_EVENT_CLONED:
case PyDict_EVENT_DEALLOCATED:
_PyJIT_NotifyDictUnwatch(dict);
break;
}
return 0;
});
if (watcher_id < 0) {
return -1;
}
Expand All @@ -62,17 +61,12 @@ void Cinder_UnwatchDict(PyObject* dict) {
}
}

// actually including shadowcode.h from cpp throws lots of errors
extern "C" void _PyShadow_TypeModified(PyTypeObject *type);

static int cinder_type_watcher(PyTypeObject* type) {
_PyShadow_TypeModified(type);
_PyJIT_TypeModified(type);
return 0;
}

static int cinder_install_type_watcher() {
int watcher_id = PyType_AddWatcher(cinder_type_watcher);
int watcher_id = PyType_AddWatcher([](PyTypeObject* type) {
_PyShadow_TypeModified(type);
_PyJIT_TypeModified(type);
return 0;
});
if (watcher_id < 0) {
return -1;
}
Expand All @@ -88,93 +82,82 @@ void Cinder_UnwatchType(PyTypeObject* type) {
PyType_Unwatch(cinder_type_watcher_id, (PyObject *)type);
}

static int cinder_func_watcher(
PyFunction_WatchEvent event,
PyFunctionObject* func,
PyObject* new_value) {
switch (event) {
case PyFunction_EVENT_CREATE:
PyEntry_init(func);
break;
case PyFunction_EVENT_MODIFY_CODE:
_PyJIT_FuncModified(func);
// having deopted the func, we want to immediately consider recompiling.
// func_set_code will assign this again later, but we do it early so
// PyEntry_init can consider the new code object now
Py_INCREF(new_value);
Py_XSETREF(func->func_code, new_value);
PyEntry_init(func);
break;
case PyFunction_EVENT_MODIFY_DEFAULTS:
break;
case PyFunction_EVENT_MODIFY_KWDEFAULTS:
break;
case PyFunction_EVENT_MODIFY_QUALNAME:
// allow reconsideration of whether this function should be compiled
if (!_PyJIT_IsCompiled((PyObject*)func)) {
// func_set_qualname will assign this again, but we need to assign it
// now so that PyEntry_init can consider the new qualname
static int cinder_install_func_watcher() {
int watcher_id = PyFunction_AddWatcher([](
PyFunction_WatchEvent event,
PyFunctionObject* func,
PyObject* new_value) {
switch (event) {
case PyFunction_EVENT_CREATE:
PyEntry_init(func);
break;
case PyFunction_EVENT_MODIFY_CODE:
_PyJIT_FuncModified(func);
// having deopted the func, we want to immediately consider recompiling.
// func_set_code will assign this again later, but we do it early so
// PyEntry_init can consider the new code object now
Py_INCREF(new_value);
Py_XSETREF(func->func_qualname, new_value);
Py_XSETREF(func->func_code, new_value);
PyEntry_init(func);
}
break;
case PyFunction_EVENT_DESTROY:
_PyJIT_FuncDestroyed(func);
break;
}
return 0;
}

static int init_funcs_visitor(PyObject* obj, void*) {
if (PyFunction_Check(obj)) {
PyEntry_init((PyFunctionObject*)obj);
}
return 1;
}

static void init_already_existing_funcs() {
PyUnstable_GC_VisitObjects(init_funcs_visitor, NULL);
}

static int cinder_install_func_watcher() {
int watcher_id = PyFunction_AddWatcher(cinder_func_watcher);
break;
case PyFunction_EVENT_MODIFY_DEFAULTS:
break;
case PyFunction_EVENT_MODIFY_KWDEFAULTS:
break;
case PyFunction_EVENT_MODIFY_QUALNAME:
// allow reconsideration of whether this function should be compiled
if (!_PyJIT_IsCompiled((PyObject*)func)) {
// func_set_qualname will assign this again, but we need to assign it
// now so that PyEntry_init can consider the new qualname
Py_INCREF(new_value);
Py_XSETREF(func->func_qualname, new_value);
PyEntry_init(func);
}
break;
case PyFunction_EVENT_DESTROY:
_PyJIT_FuncDestroyed(func);
break;
}
return 0;
});
if (watcher_id < 0) {
return -1;
}
cinder_func_watcher_id = watcher_id;
return 0;
}

// actually including shadowcode.h from cpp throws lots of errors
extern "C" void _PyShadow_ClearCache(PyObject *co);

static int cinder_code_watcher(PyCodeEvent event, PyCodeObject* co) {
if (event == PY_CODE_EVENT_DESTROY) {
_PyShadow_ClearCache((PyObject *)co);
_PyJIT_CodeDestroyed(co);
}
return 0;
static void init_already_existing_funcs() {
PyUnstable_GC_VisitObjects([](PyObject* obj, void*){
if (PyFunction_Check(obj)) {
PyEntry_init((PyFunctionObject*)obj);
}
return 1;
}, nullptr);
}

static int cinder_install_code_watcher() {
int watcher_id = PyCode_AddWatcher(cinder_code_watcher);
int watcher_id = PyCode_AddWatcher([](PyCodeEvent event, PyCodeObject* co) {
if (event == PY_CODE_EVENT_DESTROY) {
_PyShadow_ClearCache((PyObject *)co);
_PyJIT_CodeDestroyed(co);
}
return 0;
});
if (watcher_id < 0) {
return -1;
}
cinder_code_watcher_id = watcher_id;
return 0;
}

static int init_types_visitor(PyObject* obj, void*) {
if (PyType_Check(obj) && PyType_HasFeature((PyTypeObject*)obj, Py_TPFLAGS_READY)) {
_PyJIT_TypeCreated((PyTypeObject*)obj);
}
return 1;
}

static void init_already_existing_types() {
PyUnstable_GC_VisitObjects(init_types_visitor, NULL);
PyUnstable_GC_VisitObjects([](PyObject* obj, void*) {
if (PyType_Check(obj) && PyType_HasFeature((PyTypeObject*)obj, Py_TPFLAGS_READY)) {
_PyJIT_TypeCreated((PyTypeObject*)obj);
}
return 1;
}, nullptr);
}

int Cinder_Init() {
Expand Down Expand Up @@ -202,7 +185,7 @@ int Cinder_Init() {
//
// TODO(T168696266): Remove this once we migrate to cinderx.
PyObject *res = Cinder_GetParallelGCSettings();
if (res == NULL) {
if (res == nullptr) {
return -1;
}
Py_DECREF(res);
Expand Down
3 changes: 3 additions & 0 deletions Shadowcode/shadowcode.h
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,9 @@ _PyShadow_TrySplitDictLookup(_PyShadow_InstanceAttrEntry *entry,
PyObject *dict,
int opcode)
{
// opcode may not be used if INLINE_CACHE_PROFILE is not defined.
(void)opcode;

PyDictObject *dictobj = (PyDictObject *)dict;
if (_Py_LIKELY(dictobj != NULL)) {
if (!_PyDict_HasSplitTable(dictobj)) {
Expand Down

0 comments on commit b87875d

Please sign in to comment.