aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Tismer <tismer@stackless.com>2025-02-09 17:34:00 +0100
committerChristian Tismer <tismer@stackless.com>2025-02-10 14:35:08 +0100
commit6f558a0a515a332bd3f53f0a2481b4b64cd03b13 (patch)
tree2f3aec9086b2325217767b55afc370351bf8cac1
parent9fdca2340a6bf6eade9add9cdbf971fa292ee822 (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.cpp43
-rw-r--r--sources/shiboken6/generator/shiboken/cppgenerator.h3
-rw-r--r--sources/shiboken6/libshiboken/basewrapper.cpp21
-rw-r--r--sources/shiboken6/libshiboken/basewrapper.h5
-rw-r--r--sources/shiboken6/libshiboken/gilstate.cpp12
-rw-r--r--sources/shiboken6/libshiboken/gilstate.h3
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: