From b87875dc00a60fa6a7687aebcdd2e6fb3346a5d4 Mon Sep 17 00:00:00 2001 From: Jacob Bower <jbower@meta.com> Date: Thu, 2 Nov 2023 21:54:59 -0700 Subject: [PATCH] Make cinder.cpp more C++ 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 --- Cinder/cinder.cpp | 195 ++++++++++++++++++---------------------- Shadowcode/shadowcode.h | 3 + 2 files changed, 92 insertions(+), 106 deletions(-) diff --git a/Cinder/cinder.cpp b/Cinder/cinder.cpp index 74f0f426772..725a66b1354 100644 --- a/Cinder/cinder.cpp +++ b/Cinder/cinder.cpp @@ -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; } @@ -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; } @@ -88,57 +82,44 @@ 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; } @@ -146,19 +127,23 @@ static int cinder_install_func_watcher() { 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; } @@ -166,15 +151,13 @@ static int cinder_install_code_watcher() { 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() { @@ -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); diff --git a/Shadowcode/shadowcode.h b/Shadowcode/shadowcode.h index b1a46942272..ee3daf1bceb 100644 --- a/Shadowcode/shadowcode.h +++ b/Shadowcode/shadowcode.h @@ -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)) {