aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2019-04-26 09:31:48 +0200
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2019-04-30 11:51:32 +0000
commite83e07dd9fba3a2c69afe07cbee70346a1ee6ec8 (patch)
tree7c8287ba6a5270d08538180a70f5b24511cbc0d6 /sources/shiboken2/generator/shiboken2/shibokengenerator.cpp
parentf332f2e8e66a5fa67b302893a13f0be3687ccc38 (diff)
shiboken/Generators: Cache class information lists per class
The function ShibokenGenerator::getFunctionGroups(class) is called many times for each function during code generation and causes a slowdown for the OpenGL version function classes, which have 1000 member functions. Split away getGlobalFunctionGroups() for the case scope=0 and introduce a global-static cache for class information that is more involved to determine for use by the various generators. Speeds up the generation of the QtGui module including the OpenGL version functions from 420s to 90s. Task-number: PYSIDE-955 Change-Id: I6b6aa35ef2197aa9cddbf339db9eb0220932f361 Reviewed-by: Christian Tismer <tismer@stackless.com>
Diffstat (limited to 'sources/shiboken2/generator/shiboken2/shibokengenerator.cpp')
-rw-r--r--sources/shiboken2/generator/shiboken2/shibokengenerator.cpp96
1 files changed, 72 insertions, 24 deletions
diff --git a/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp b/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp
index 002ab8cfb..12efb68c3 100644
--- a/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp
+++ b/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp
@@ -118,6 +118,16 @@ static QString resolveScopePrefix(const AbstractMetaEnum *metaEnum,
return resolveScopePrefix(parts, value);
}
+struct GeneratorClassInfoCacheEntry
+{
+ ShibokenGenerator::FunctionGroups functionGroups;
+ bool needsGetattroFunction = false;
+};
+
+using GeneratorClassInfoCache = QHash<const AbstractMetaClass *, GeneratorClassInfoCacheEntry>;
+
+Q_GLOBAL_STATIC(GeneratorClassInfoCache, generatorClassInfoCache)
+
ShibokenGenerator::ShibokenGenerator()
{
if (m_pythonPrimitiveTypeName.isEmpty())
@@ -1739,7 +1749,10 @@ void ShibokenGenerator::writeCodeSnips(QTextStream& s,
argsRemoved++;
}
- OverloadData od(getFunctionGroups(func->implementingClass())[func->name()], this);
+ const auto &groups = func->implementingClass()
+ ? getFunctionGroups(func->implementingClass())
+ : getGlobalFunctionGroups();
+ OverloadData od(groups[func->name()], this);
bool usePyArgs = pythonFunctionWrapperUsesListOfArguments(od);
// Replace %PYARG_# variables.
@@ -2174,17 +2187,19 @@ bool ShibokenGenerator::hasMultipleInheritanceInAncestry(const AbstractMetaClass
return hasMultipleInheritanceInAncestry(metaClass->baseClass());
}
-typedef QMap<QString, AbstractMetaFunctionList> FunctionGroupMap;
-typedef FunctionGroupMap::const_iterator FunctionGroupMapIt;
-
bool ShibokenGenerator::classNeedsGetattroFunction(const AbstractMetaClass* metaClass)
{
+ return getGeneratorClassInfo(metaClass).needsGetattroFunction;
+}
+
+bool ShibokenGenerator::classNeedsGetattroFunctionImpl(const AbstractMetaClass* metaClass)
+{
if (!metaClass)
return false;
if (metaClass->typeEntry()->isSmartPointer())
return true;
- const FunctionGroupMap &functionGroup = getFunctionGroups(metaClass);
- for (FunctionGroupMapIt it = functionGroup.cbegin(), end = functionGroup.cend(); it != end; ++it) {
+ const auto &functionGroup = getFunctionGroups(metaClass);
+ for (auto it = functionGroup.cbegin(), end = functionGroup.cend(); it != end; ++it) {
AbstractMetaFunctionList overloads;
for (AbstractMetaFunction *func : qAsConst(it.value())) {
if (func->isAssignmentOperator() || func->isCastOperator() || func->isModifiedRemoved()
@@ -2212,8 +2227,8 @@ AbstractMetaFunctionList ShibokenGenerator::getMethodsWithBothStaticAndNonStatic
{
AbstractMetaFunctionList methods;
if (metaClass) {
- const FunctionGroupMap &functionGroups = getFunctionGroups(metaClass);
- for (FunctionGroupMapIt it = functionGroups.cbegin(), end = functionGroups.cend(); it != end; ++it) {
+ const auto &functionGroups = getFunctionGroups(metaClass);
+ for (auto it = functionGroups.cbegin(), end = functionGroups.cend(); it != end; ++it) {
AbstractMetaFunctionList overloads;
for (AbstractMetaFunction *func : qAsConst(it.value())) {
if (func->isAssignmentOperator() || func->isCastOperator() || func->isModifiedRemoved()
@@ -2358,23 +2373,56 @@ static bool isGroupable(const AbstractMetaFunction* func)
return true;
}
-QMap< QString, AbstractMetaFunctionList > ShibokenGenerator::getFunctionGroups(const AbstractMetaClass* scope)
+ShibokenGenerator::FunctionGroups ShibokenGenerator::getGlobalFunctionGroups() const
{
- AbstractMetaFunctionList lst = scope ? scope->functions() : globalFunctions();
+ const AbstractMetaFunctionList &lst = globalFunctions();
+ FunctionGroups results;
+ for (AbstractMetaFunction *func : lst) {
+ if (isGroupable(func))
+ results[func->name()].append(func);
+ }
+ return results;
+}
- QMap<QString, AbstractMetaFunctionList> results;
- for (AbstractMetaFunction *func : qAsConst(lst)) {
+const GeneratorClassInfoCacheEntry &ShibokenGenerator::getGeneratorClassInfo(const AbstractMetaClass *scope)
+{
+ auto cache = generatorClassInfoCache();
+ auto it = cache->find(scope);
+ if (it == cache->end()) {
+ it = cache->insert(scope, {});
+ it.value().functionGroups = getFunctionGroupsImpl(scope);
+ it.value().needsGetattroFunction = classNeedsGetattroFunctionImpl(scope);
+ }
+ return it.value();
+}
+
+ShibokenGenerator::FunctionGroups ShibokenGenerator::getFunctionGroups(const AbstractMetaClass *scope)
+{
+ Q_ASSERT(scope);
+ return getGeneratorClassInfo(scope).functionGroups;
+}
+
+ShibokenGenerator::FunctionGroups ShibokenGenerator::getFunctionGroupsImpl(const AbstractMetaClass *scope)
+{
+ const AbstractMetaFunctionList &lst = scope->functions();
+
+ FunctionGroups results;
+ for (AbstractMetaFunction *func : lst) {
if (isGroupable(func)) {
- AbstractMetaFunctionList &list = results[func->name()];
- // If there are virtuals methods in the mix (PYSIDE-570,
- // QFileSystemModel::index(QString,int) and
- // QFileSystemModel::index(int,int,QModelIndex)) override, make sure
- // the overriding method of the most-derived class is seen first
- // and inserted into the "seenSignatures" set.
- if (func->isVirtual())
- list.prepend(func);
- else
- list.append(func);
+ auto it = results.find(func->name());
+ if (it == results.end()) {
+ results.insert(func->name(), AbstractMetaFunctionList(1, func));
+ } else {
+ // If there are virtuals methods in the mix (PYSIDE-570,
+ // QFileSystemModel::index(QString,int) and
+ // QFileSystemModel::index(int,int,QModelIndex)) override, make sure
+ // the overriding method of the most-derived class is seen first
+ // and inserted into the "seenSignatures" set.
+ if (func->isVirtual())
+ it.value().prepend(func);
+ else
+ it.value().append(func);
+ }
}
}
return results;
@@ -2503,8 +2551,8 @@ bool ShibokenGenerator::doSetup()
Q_ASSERT(moduleEntry);
getCode(snips, moduleEntry);
- const FunctionGroupMap &functionGroups = getFunctionGroups();
- for (FunctionGroupMapIt it = functionGroups.cbegin(), end = functionGroups.cend(); it != end; ++it) {
+ const auto &functionGroups = getGlobalFunctionGroups();
+ for (auto it = functionGroups.cbegin(), end = functionGroups.cend(); it != end; ++it) {
for (AbstractMetaFunction *func : it.value())
getCode(snips, func->injectedCodeSnips());
}