diff options
| author | Christian Tismer <tismer@stackless.com> | 2025-02-09 17:34:00 +0100 |
|---|---|---|
| committer | Christian Tismer <tismer@stackless.com> | 2025-02-10 14:35:08 +0100 |
| commit | 6f558a0a515a332bd3f53f0a2481b4b64cd03b13 (patch) | |
| tree | 2f3aec9086b2325217767b55afc370351bf8cac1 | |
| parent | 9fdca2340a6bf6eade9add9cdbf971fa292ee822 (diff) | |
binary size: Move a virtual method optimization out of folding
This latest patch to virtual methods simplifies the handling
of overloads significantly and brings the size improvements
on macOS from 13.56% to 15.96% (Limited API off).
Pick-to: 6.8
Change-Id: Id8aa20eab3c80c3171a5c1a1b0937315517b7ab9
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
| -rw-r--r-- | sources/shiboken6/generator/shiboken/cppgenerator.cpp | 43 | ||||
| -rw-r--r-- | sources/shiboken6/generator/shiboken/cppgenerator.h | 3 | ||||
| -rw-r--r-- | sources/shiboken6/libshiboken/basewrapper.cpp | 21 | ||||
| -rw-r--r-- | sources/shiboken6/libshiboken/basewrapper.h | 5 | ||||
| -rw-r--r-- | sources/shiboken6/libshiboken/gilstate.cpp | 12 | ||||
| -rw-r--r-- | sources/shiboken6/libshiboken/gilstate.h | 3 |
6 files changed, 51 insertions, 36 deletions
diff --git a/sources/shiboken6/generator/shiboken/cppgenerator.cpp b/sources/shiboken6/generator/shiboken/cppgenerator.cpp index 6a278bf9e..92e82760d 100644 --- a/sources/shiboken6/generator/shiboken/cppgenerator.cpp +++ b/sources/shiboken6/generator/shiboken/cppgenerator.cpp @@ -1028,15 +1028,14 @@ QString CppGenerator::getVirtualFunctionReturnTypeName(const AbstractMetaFunctio + typeEntry->qualifiedCppName() + u" >()->tp_name"_s; } -// When writing an overridden method of a wrapper class, write the part -// calling the C++ function in case no overload in Python exists. void CppGenerator::writeVirtualMethodCppCall(TextStream &s, const AbstractMetaFunctionCPtr &func, const QString &funcName, const CodeSnipList &snips, const AbstractMetaArgument *lastArg, const TypeEntryCPtr &retType, - const QString &returnStatement, bool hasGil) const + const QString &returnStatement, + bool ownsGil, bool hasGilVar) const { if (!snips.isEmpty()) { writeCodeSnips(s, snips, TypeSystem::CodeSnipPositionBeginning, @@ -1044,15 +1043,15 @@ void CppGenerator::writeVirtualMethodCppCall(TextStream &s, } if (func->isAbstract()) { - if (!hasGil) - s << "Shiboken::GilState gil;\n"; + if (!ownsGil) + s << (hasGilVar ? "gil.acquire();\n" : "Shiboken::GilState gil;\n"); s << "Shiboken::Errors::setPureVirtualMethodError(\"" << func->ownerClass()->name() << '.' << funcName << "\");\n" << returnStatement << '\n'; return; } - if (hasGil) + if (ownsGil) s << "gil.release();\n"; if (retType) @@ -1298,32 +1297,15 @@ void CppGenerator::writeVirtualMethodNative(TextStream &s, << cacheIndex << R"( << "]=" << m_PyMethodCache[)" << cacheIndex << R"(] << '\n';)" << '\n'; } - // PYSIDE-803: Build a boolean cache for unused overrides - const bool multi_line = func->isVoid() || !snips.isEmpty() || isAbstract; - s << "if (m_PyMethodCache[" << cacheIndex << "])" << (multi_line ? " {\n" : "\n") - << indent; - writeVirtualMethodCppCall(s, func, funcName, snips, lastArg, retType, - returnStatement.statement, false); - s << outdent; - if (multi_line) - s << "}\n"; - - s << "Shiboken::GilState gil;\n"; - - // Get out of virtual method call if someone already threw an error. - s << "if (" << shibokenErrorsOccurred << ")\n" << indent - << returnStatement.statement << '\n' << outdent; - - s << "static PyObject *nameCache[2] = {};\n"; writeFuncNameVar(s, func, funcName); - s << "Shiboken::AutoDecRef " << PYTHON_OVERRIDE_VAR - << "(Shiboken::BindingManager::instance().getOverride(this, nameCache, funcName));\n" - << "if (" << PYTHON_OVERRIDE_VAR << ".isNull()) {\n" << indent - << "m_PyMethodCache[" << cacheIndex << "] = true;\n"; + s << "static PyObject *nameCache[2] = {};\n" + << "Shiboken::GilState gil(false);\n" + << "Shiboken::AutoDecRef " << PYTHON_OVERRIDE_VAR << "(Sbk_GetPyOverride(" + << "this, gil, funcName, &m_PyMethodCache[" << cacheIndex << "], nameCache));\n" + << "if (pyOverride.isNull()) {\n" << indent; writeVirtualMethodCppCall(s, func, funcName, snips, lastArg, retType, - returnStatement.statement, true); - s << outdent << "}\n\n"; //WS - + returnStatement.statement, false, true); + s << outdent << "}\n"; if (!snips.isEmpty()) { writeCodeSnips(s, snips, TypeSystem::CodeSnipPositionPyOverride, TypeSystem::ShellCode, func, false, lastArg); @@ -1331,7 +1313,6 @@ void CppGenerator::writeVirtualMethodNative(TextStream &s, writeVirtualMethodPythonOverride(s, func, snips, returnStatement); } - void CppGenerator::writeVirtualMethodPythonOverride(TextStream &s, const AbstractMetaFunctionCPtr &func, const CodeSnipList &snips, diff --git a/sources/shiboken6/generator/shiboken/cppgenerator.h b/sources/shiboken6/generator/shiboken/cppgenerator.h index af6047b26..94b49d041 100644 --- a/sources/shiboken6/generator/shiboken/cppgenerator.h +++ b/sources/shiboken6/generator/shiboken/cppgenerator.h @@ -95,7 +95,8 @@ private: void writeVirtualMethodCppCall(TextStream &s, const AbstractMetaFunctionCPtr &func, const QString &funcName, const QList<CodeSnip> &snips, const AbstractMetaArgument *lastArg, const TypeEntryCPtr &retType, - const QString &returnStatement, bool hasGil) const; + const QString &returnStatement, + bool ownsGil, bool hasGilVar) const; static VirtualMethodReturn virtualMethodReturn(const ApiExtractorResult &api, const AbstractMetaFunctionCPtr &func, diff --git a/sources/shiboken6/libshiboken/basewrapper.cpp b/sources/shiboken6/libshiboken/basewrapper.cpp index 8948c8479..60f8ae77d 100644 --- a/sources/shiboken6/libshiboken/basewrapper.cpp +++ b/sources/shiboken6/libshiboken/basewrapper.cpp @@ -736,6 +736,7 @@ bool SbkObjectType_Check(PyTypeObject *type) // Global functions from folding. +// The common end. PyObject *Sbk_ReturnFromPython_None() { if (Shiboken::Errors::occurred() != nullptr) { @@ -762,6 +763,26 @@ PyObject *Sbk_ReturnFromPython_Self(PyObject *self) return self; } +// The virtual function call +PyObject *Sbk_GetPyOverride(const void *voidThis, Shiboken::GilState &gil, const char *funcName, + bool *resultCache, PyObject **nameCache) +{ + PyObject *pyOverride{}; + if (!*resultCache) { + gil.acquire(); + pyOverride = Shiboken::BindingManager::instance().getOverride(voidThis, nameCache, funcName); + if (pyOverride == nullptr) { + *resultCache = true; + gil.release(); + } else if (Shiboken::Errors::occurred() != nullptr) { + // Give up. + Py_XDECREF(pyOverride); + pyOverride = nullptr; + } + } + return pyOverride; +} + } //extern "C" diff --git a/sources/shiboken6/libshiboken/basewrapper.h b/sources/shiboken6/libshiboken/basewrapper.h index 9d9a60097..425328ae5 100644 --- a/sources/shiboken6/libshiboken/basewrapper.h +++ b/sources/shiboken6/libshiboken/basewrapper.h @@ -7,6 +7,7 @@ #include "sbkpython.h" #include "shibokenmacros.h" #include "sbkmodule.h" +#include "gilstate.h" #include <vector> #include <string> @@ -119,7 +120,9 @@ LIBSHIBOKEN_API bool SbkObjectType_Check(PyTypeObject *type); LIBSHIBOKEN_API PyObject *Sbk_ReturnFromPython_None(); LIBSHIBOKEN_API PyObject *Sbk_ReturnFromPython_Result(PyObject *pyResult); LIBSHIBOKEN_API PyObject *Sbk_ReturnFromPython_Self(PyObject *self); - +LIBSHIBOKEN_API PyObject *Sbk_GetPyOverride(const void *voidThis, Shiboken::GilState &gil, + const char *funcName, bool *resultCache, + PyObject **nameCache); } // extern "C" namespace Shiboken diff --git a/sources/shiboken6/libshiboken/gilstate.cpp b/sources/shiboken6/libshiboken/gilstate.cpp index 4414de648..b5175bd3a 100644 --- a/sources/shiboken6/libshiboken/gilstate.cpp +++ b/sources/shiboken6/libshiboken/gilstate.cpp @@ -6,9 +6,9 @@ namespace Shiboken { -GilState::GilState() +GilState::GilState(bool acquire) { - if (Py_IsInitialized()) { + if (acquire && Py_IsInitialized()) { m_gstate = PyGILState_Ensure(); m_locked = true; } @@ -19,6 +19,14 @@ GilState::~GilState() release(); } +void GilState::acquire() +{ + if (Py_IsInitialized()) { + m_gstate = PyGILState_Ensure(); + m_locked = true; + } +} + void GilState::release() { if (m_locked && Py_IsInitialized()) { diff --git a/sources/shiboken6/libshiboken/gilstate.h b/sources/shiboken6/libshiboken/gilstate.h index 1714d77a5..c23ad4505 100644 --- a/sources/shiboken6/libshiboken/gilstate.h +++ b/sources/shiboken6/libshiboken/gilstate.h @@ -18,8 +18,9 @@ public: GilState &operator=(const GilState &) = delete; GilState &operator=(GilState &&) = delete; - GilState(); + explicit GilState(bool acquire=true); ~GilState(); + void acquire(); void release(); void abandon(); private: |
