moc: replace inefficient QLists with QVectors
These types are larger than a void*, so holding them in QLists is needlessly inefficient. Worse, the code could come to depend on the fragile property of (inefficient) QLists that references to elements therein never are invalidated. Fix by marking them movable, and holding them in a QVector instead. Change-Id: I42f494ed87854eadc33d78db4479203ff5e0370f Reviewed-by: Lars Knoll <lars.knoll@theqtcompany.com> Reviewed-by: Milian Wolff <milian.wolff@kdab.com> Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com>
This commit is contained in:
parent
3e63a58a96
commit
cc2938b5b6
@ -121,7 +121,7 @@ int Generator::stridx(const QByteArray &s)
|
|||||||
// Returns the sum of all parameters (including return type) for the given
|
// Returns the sum of all parameters (including return type) for the given
|
||||||
// \a list of methods. This is needed for calculating the size of the methods'
|
// \a list of methods. This is needed for calculating the size of the methods'
|
||||||
// parameter type/name meta-data.
|
// parameter type/name meta-data.
|
||||||
static int aggregateParameterCount(const QList<FunctionDef> &list)
|
static int aggregateParameterCount(const QVector<FunctionDef> &list)
|
||||||
{
|
{
|
||||||
int sum = 0;
|
int sum = 0;
|
||||||
for (int i = 0; i < list.count(); ++i)
|
for (int i = 0; i < list.count(); ++i)
|
||||||
@ -194,7 +194,7 @@ void Generator::generateCode()
|
|||||||
|
|
||||||
// filter out undeclared enumerators and sets
|
// filter out undeclared enumerators and sets
|
||||||
{
|
{
|
||||||
QList<EnumDef> enumList;
|
QVector<EnumDef> enumList;
|
||||||
for (int i = 0; i < cdef->enumList.count(); ++i) {
|
for (int i = 0; i < cdef->enumList.count(); ++i) {
|
||||||
EnumDef def = cdef->enumList.at(i);
|
EnumDef def = cdef->enumList.at(i);
|
||||||
if (cdef->enumDeclarations.contains(def.name)) {
|
if (cdef->enumDeclarations.contains(def.name)) {
|
||||||
@ -571,7 +571,7 @@ void Generator::generateCode()
|
|||||||
cname, cname, cdef->classname.constData());
|
cname, cname, cdef->classname.constData());
|
||||||
}
|
}
|
||||||
for (int i = 0; i < cdef->interfaceList.size(); ++i) {
|
for (int i = 0; i < cdef->interfaceList.size(); ++i) {
|
||||||
const QList<ClassDef::Interface> &iface = cdef->interfaceList.at(i);
|
const QVector<ClassDef::Interface> &iface = cdef->interfaceList.at(i);
|
||||||
for (int j = 0; j < iface.size(); ++j) {
|
for (int j = 0; j < iface.size(); ++j) {
|
||||||
fprintf(out, " if (!strcmp(_clname, %s))\n return ", iface.at(j).interfaceId.constData());
|
fprintf(out, " if (!strcmp(_clname, %s))\n return ", iface.at(j).interfaceId.constData());
|
||||||
for (int k = j; k >= 0; --k)
|
for (int k = j; k >= 0; --k)
|
||||||
@ -628,7 +628,7 @@ void Generator::generateClassInfos()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Generator::registerFunctionStrings(const QList<FunctionDef>& list)
|
void Generator::registerFunctionStrings(const QVector<FunctionDef>& list)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < list.count(); ++i) {
|
for (int i = 0; i < list.count(); ++i) {
|
||||||
const FunctionDef &f = list.at(i);
|
const FunctionDef &f = list.at(i);
|
||||||
@ -648,7 +648,7 @@ void Generator::registerFunctionStrings(const QList<FunctionDef>& list)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Generator::generateFunctions(const QList<FunctionDef>& list, const char *functype, int type, int ¶msIndex)
|
void Generator::generateFunctions(const QVector<FunctionDef>& list, const char *functype, int type, int ¶msIndex)
|
||||||
{
|
{
|
||||||
if (list.isEmpty())
|
if (list.isEmpty())
|
||||||
return;
|
return;
|
||||||
@ -694,7 +694,7 @@ void Generator::generateFunctions(const QList<FunctionDef>& list, const char *fu
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Generator::generateFunctionRevisions(const QList<FunctionDef>& list, const char *functype)
|
void Generator::generateFunctionRevisions(const QVector<FunctionDef>& list, const char *functype)
|
||||||
{
|
{
|
||||||
if (list.count())
|
if (list.count())
|
||||||
fprintf(out, "\n // %ss: revision\n", functype);
|
fprintf(out, "\n // %ss: revision\n", functype);
|
||||||
@ -704,7 +704,7 @@ void Generator::generateFunctionRevisions(const QList<FunctionDef>& list, const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Generator::generateFunctionParameters(const QList<FunctionDef>& list, const char *functype)
|
void Generator::generateFunctionParameters(const QVector<FunctionDef>& list, const char *functype)
|
||||||
{
|
{
|
||||||
if (list.isEmpty())
|
if (list.isEmpty())
|
||||||
return;
|
return;
|
||||||
@ -917,7 +917,7 @@ void Generator::generateMetacall()
|
|||||||
fprintf(out, " ");
|
fprintf(out, " ");
|
||||||
|
|
||||||
bool needElse = false;
|
bool needElse = false;
|
||||||
QList<FunctionDef> methodList;
|
QVector<FunctionDef> methodList;
|
||||||
methodList += cdef->signalList;
|
methodList += cdef->signalList;
|
||||||
methodList += cdef->slotList;
|
methodList += cdef->slotList;
|
||||||
methodList += cdef->methodList;
|
methodList += cdef->methodList;
|
||||||
@ -1079,7 +1079,7 @@ QMultiMap<QByteArray, int> Generator::automaticPropertyMetaTypesHelper()
|
|||||||
return automaticPropertyMetaTypes;
|
return automaticPropertyMetaTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
QMap<int, QMultiMap<QByteArray, int> > Generator::methodsWithAutomaticTypesHelper(const QList<FunctionDef> &methodList)
|
QMap<int, QMultiMap<QByteArray, int> > Generator::methodsWithAutomaticTypesHelper(const QVector<FunctionDef> &methodList)
|
||||||
{
|
{
|
||||||
QMap<int, QMultiMap<QByteArray, int> > methodsWithAutomaticTypes;
|
QMap<int, QMultiMap<QByteArray, int> > methodsWithAutomaticTypes;
|
||||||
for (int i = 0; i < methodList.size(); ++i) {
|
for (int i = 0; i < methodList.size(); ++i) {
|
||||||
@ -1133,7 +1133,7 @@ void Generator::generateStaticMetacall()
|
|||||||
isUsed_a = true;
|
isUsed_a = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<FunctionDef> methodList;
|
QVector<FunctionDef> methodList;
|
||||||
methodList += cdef->signalList;
|
methodList += cdef->signalList;
|
||||||
methodList += cdef->slotList;
|
methodList += cdef->slotList;
|
||||||
methodList += cdef->methodList;
|
methodList += cdef->methodList;
|
||||||
|
@ -45,10 +45,10 @@ private:
|
|||||||
bool registerableMetaType(const QByteArray &propertyType);
|
bool registerableMetaType(const QByteArray &propertyType);
|
||||||
void registerClassInfoStrings();
|
void registerClassInfoStrings();
|
||||||
void generateClassInfos();
|
void generateClassInfos();
|
||||||
void registerFunctionStrings(const QList<FunctionDef> &list);
|
void registerFunctionStrings(const QVector<FunctionDef> &list);
|
||||||
void generateFunctions(const QList<FunctionDef> &list, const char *functype, int type, int ¶msIndex);
|
void generateFunctions(const QVector<FunctionDef> &list, const char *functype, int type, int ¶msIndex);
|
||||||
void generateFunctionRevisions(const QList<FunctionDef>& list, const char *functype);
|
void generateFunctionRevisions(const QVector<FunctionDef> &list, const char *functype);
|
||||||
void generateFunctionParameters(const QList<FunctionDef> &list, const char *functype);
|
void generateFunctionParameters(const QVector<FunctionDef> &list, const char *functype);
|
||||||
void generateTypeInfo(const QByteArray &typeName, bool allowEmptyName = false);
|
void generateTypeInfo(const QByteArray &typeName, bool allowEmptyName = false);
|
||||||
void registerEnumStrings();
|
void registerEnumStrings();
|
||||||
void generateEnums(int index);
|
void generateEnums(int index);
|
||||||
@ -59,7 +59,7 @@ private:
|
|||||||
void generateSignal(FunctionDef *def, int index);
|
void generateSignal(FunctionDef *def, int index);
|
||||||
void generatePluginMetaData();
|
void generatePluginMetaData();
|
||||||
QMultiMap<QByteArray, int> automaticPropertyMetaTypesHelper();
|
QMultiMap<QByteArray, int> automaticPropertyMetaTypesHelper();
|
||||||
QMap<int, QMultiMap<QByteArray, int> > methodsWithAutomaticTypesHelper(const QList<FunctionDef> &methodList);
|
QMap<int, QMultiMap<QByteArray, int> > methodsWithAutomaticTypesHelper(const QVector<FunctionDef> &methodList);
|
||||||
|
|
||||||
void strreg(const QByteArray &); // registers a string
|
void strreg(const QByteArray &); // registers a string
|
||||||
int stridx(const QByteArray &); // returns a string's id
|
int stridx(const QByteArray &); // returns a string's id
|
||||||
|
@ -538,7 +538,7 @@ bool Moc::parseMaybeFunction(const ClassDef *cdef, FunctionDef *def)
|
|||||||
|
|
||||||
void Moc::parse()
|
void Moc::parse()
|
||||||
{
|
{
|
||||||
QList<NamespaceDef> namespaceList;
|
QVector<NamespaceDef> namespaceList;
|
||||||
bool templateClass = false;
|
bool templateClass = false;
|
||||||
while (hasNext()) {
|
while (hasNext()) {
|
||||||
Token t = next();
|
Token t = next();
|
||||||
@ -801,7 +801,7 @@ void Moc::parse()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool any_type_contains(const QList<PropertyDef> &properties, const QByteArray &pattern)
|
static bool any_type_contains(const QVector<PropertyDef> &properties, const QByteArray &pattern)
|
||||||
{
|
{
|
||||||
for (const auto &p : properties) {
|
for (const auto &p : properties) {
|
||||||
if (p.type.contains(pattern))
|
if (p.type.contains(pattern))
|
||||||
@ -810,7 +810,7 @@ static bool any_type_contains(const QList<PropertyDef> &properties, const QByteA
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool any_arg_contains(const QList<FunctionDef> &functions, const QByteArray &pattern)
|
static bool any_arg_contains(const QVector<FunctionDef> &functions, const QByteArray &pattern)
|
||||||
{
|
{
|
||||||
for (const auto &f : functions) {
|
for (const auto &f : functions) {
|
||||||
for (const auto &arg : f.arguments) {
|
for (const auto &arg : f.arguments) {
|
||||||
@ -835,7 +835,7 @@ static QByteArrayList make_candidates()
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static QByteArrayList requiredQtContainers(const QList<ClassDef> &classes)
|
static QByteArrayList requiredQtContainers(const QVector<ClassDef> &classes)
|
||||||
{
|
{
|
||||||
static const QByteArrayList candidates = make_candidates();
|
static const QByteArrayList candidates = make_candidates();
|
||||||
|
|
||||||
@ -1319,7 +1319,7 @@ void Moc::parseInterfaces(ClassDef *def)
|
|||||||
{
|
{
|
||||||
next(LPAREN);
|
next(LPAREN);
|
||||||
while (test(IDENTIFIER)) {
|
while (test(IDENTIFIER)) {
|
||||||
QList<ClassDef::Interface> iface;
|
QVector<ClassDef::Interface> iface;
|
||||||
iface += ClassDef::Interface(lexem());
|
iface += ClassDef::Interface(lexem());
|
||||||
while (test(SCOPE)) {
|
while (test(SCOPE)) {
|
||||||
iface.last().className += lexem();
|
iface.last().className += lexem();
|
||||||
|
@ -59,6 +59,7 @@ struct Type
|
|||||||
Token firstToken;
|
Token firstToken;
|
||||||
ReferenceType referenceType;
|
ReferenceType referenceType;
|
||||||
};
|
};
|
||||||
|
Q_DECLARE_TYPEINFO(Type, Q_MOVABLE_TYPE);
|
||||||
|
|
||||||
struct EnumDef
|
struct EnumDef
|
||||||
{
|
{
|
||||||
@ -67,6 +68,7 @@ struct EnumDef
|
|||||||
bool isEnumClass; // c++11 enum class
|
bool isEnumClass; // c++11 enum class
|
||||||
EnumDef() : isEnumClass(false) {}
|
EnumDef() : isEnumClass(false) {}
|
||||||
};
|
};
|
||||||
|
Q_DECLARE_TYPEINFO(EnumDef, Q_MOVABLE_TYPE);
|
||||||
|
|
||||||
struct ArgumentDef
|
struct ArgumentDef
|
||||||
{
|
{
|
||||||
@ -76,6 +78,7 @@ struct ArgumentDef
|
|||||||
QByteArray typeNameForCast; // type name to be used in cast from void * in metacall
|
QByteArray typeNameForCast; // type name to be used in cast from void * in metacall
|
||||||
bool isDefault;
|
bool isDefault;
|
||||||
};
|
};
|
||||||
|
Q_DECLARE_TYPEINFO(ArgumentDef, Q_MOVABLE_TYPE);
|
||||||
|
|
||||||
struct FunctionDef
|
struct FunctionDef
|
||||||
{
|
{
|
||||||
@ -89,7 +92,7 @@ struct FunctionDef
|
|||||||
QByteArray name;
|
QByteArray name;
|
||||||
bool returnTypeIsVolatile;
|
bool returnTypeIsVolatile;
|
||||||
|
|
||||||
QList<ArgumentDef> arguments;
|
QVector<ArgumentDef> arguments;
|
||||||
|
|
||||||
enum Access { Private, Protected, Public };
|
enum Access { Private, Protected, Public };
|
||||||
Access access;
|
Access access;
|
||||||
@ -112,6 +115,7 @@ struct FunctionDef
|
|||||||
|
|
||||||
int revision;
|
int revision;
|
||||||
};
|
};
|
||||||
|
Q_DECLARE_TYPEINFO(FunctionDef, Q_MOVABLE_TYPE);
|
||||||
|
|
||||||
struct PropertyDef
|
struct PropertyDef
|
||||||
{
|
{
|
||||||
@ -130,6 +134,7 @@ struct PropertyDef
|
|||||||
}
|
}
|
||||||
int revision;
|
int revision;
|
||||||
};
|
};
|
||||||
|
Q_DECLARE_TYPEINFO(PropertyDef, Q_MOVABLE_TYPE);
|
||||||
|
|
||||||
|
|
||||||
struct ClassInfoDef
|
struct ClassInfoDef
|
||||||
@ -137,6 +142,7 @@ struct ClassInfoDef
|
|||||||
QByteArray name;
|
QByteArray name;
|
||||||
QByteArray value;
|
QByteArray value;
|
||||||
};
|
};
|
||||||
|
Q_DECLARE_TYPEINFO(ClassInfoDef, Q_MOVABLE_TYPE);
|
||||||
|
|
||||||
struct ClassDef {
|
struct ClassDef {
|
||||||
ClassDef():
|
ClassDef():
|
||||||
@ -144,16 +150,17 @@ struct ClassDef {
|
|||||||
, revisionedMethods(0), revisionedProperties(0), begin(0), end(0){}
|
, revisionedMethods(0), revisionedProperties(0), begin(0), end(0){}
|
||||||
QByteArray classname;
|
QByteArray classname;
|
||||||
QByteArray qualified;
|
QByteArray qualified;
|
||||||
QList<QPair<QByteArray, FunctionDef::Access> > superclassList;
|
QVector<QPair<QByteArray, FunctionDef::Access> > superclassList;
|
||||||
|
|
||||||
struct Interface
|
struct Interface
|
||||||
{
|
{
|
||||||
|
Interface() {} // for QVector, don't use
|
||||||
inline explicit Interface(const QByteArray &_className)
|
inline explicit Interface(const QByteArray &_className)
|
||||||
: className(_className) {}
|
: className(_className) {}
|
||||||
QByteArray className;
|
QByteArray className;
|
||||||
QByteArray interfaceId;
|
QByteArray interfaceId;
|
||||||
};
|
};
|
||||||
QList<QList<Interface> >interfaceList;
|
QVector<QVector<Interface> >interfaceList;
|
||||||
|
|
||||||
bool hasQObject;
|
bool hasQObject;
|
||||||
bool hasQGadget;
|
bool hasQGadget;
|
||||||
@ -164,13 +171,13 @@ struct ClassDef {
|
|||||||
QJsonDocument metaData;
|
QJsonDocument metaData;
|
||||||
} pluginData;
|
} pluginData;
|
||||||
|
|
||||||
QList<FunctionDef> constructorList;
|
QVector<FunctionDef> constructorList;
|
||||||
QList<FunctionDef> signalList, slotList, methodList, publicList;
|
QVector<FunctionDef> signalList, slotList, methodList, publicList;
|
||||||
int notifyableProperties;
|
int notifyableProperties;
|
||||||
QList<PropertyDef> propertyList;
|
QVector<PropertyDef> propertyList;
|
||||||
QList<ClassInfoDef> classInfoList;
|
QVector<ClassInfoDef> classInfoList;
|
||||||
QMap<QByteArray, bool> enumDeclarations;
|
QMap<QByteArray, bool> enumDeclarations;
|
||||||
QList<EnumDef> enumList;
|
QVector<EnumDef> enumList;
|
||||||
QMap<QByteArray, QByteArray> flagAliases;
|
QMap<QByteArray, QByteArray> flagAliases;
|
||||||
int revisionedMethods;
|
int revisionedMethods;
|
||||||
int revisionedProperties;
|
int revisionedProperties;
|
||||||
@ -178,12 +185,15 @@ struct ClassDef {
|
|||||||
int begin;
|
int begin;
|
||||||
int end;
|
int end;
|
||||||
};
|
};
|
||||||
|
Q_DECLARE_TYPEINFO(ClassDef, Q_MOVABLE_TYPE);
|
||||||
|
Q_DECLARE_TYPEINFO(ClassDef::Interface, Q_MOVABLE_TYPE);
|
||||||
|
|
||||||
struct NamespaceDef {
|
struct NamespaceDef {
|
||||||
QByteArray name;
|
QByteArray name;
|
||||||
int begin;
|
int begin;
|
||||||
int end;
|
int end;
|
||||||
};
|
};
|
||||||
|
Q_DECLARE_TYPEINFO(NamespaceDef, Q_MOVABLE_TYPE);
|
||||||
|
|
||||||
class Moc : public Parser
|
class Moc : public Parser
|
||||||
{
|
{
|
||||||
@ -198,7 +208,7 @@ public:
|
|||||||
bool mustIncludeQPluginH;
|
bool mustIncludeQPluginH;
|
||||||
QByteArray includePath;
|
QByteArray includePath;
|
||||||
QList<QByteArray> includeFiles;
|
QList<QByteArray> includeFiles;
|
||||||
QList<ClassDef> classList;
|
QVector<ClassDef> classList;
|
||||||
QMap<QByteArray, QByteArray> interface2IdMap;
|
QMap<QByteArray, QByteArray> interface2IdMap;
|
||||||
QList<QByteArray> metaTypes;
|
QList<QByteArray> metaTypes;
|
||||||
// map from class name to fully qualified name
|
// map from class name to fully qualified name
|
||||||
|
@ -127,7 +127,7 @@ static QString addFunction(const FunctionDef &mm, bool isSignal = false) {
|
|||||||
return QString(); // wasn't a valid type
|
return QString(); // wasn't a valid type
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
QList<ArgumentDef> names = mm.arguments;
|
QVector<ArgumentDef> names = mm.arguments;
|
||||||
QVector<int> types;
|
QVector<int> types;
|
||||||
QString errorMsg;
|
QString errorMsg;
|
||||||
int inputCount = qDBusParametersForMethod(mm, types, errorMsg);
|
int inputCount = qDBusParametersForMethod(mm, types, errorMsg);
|
||||||
@ -396,7 +396,7 @@ int main(int argc, char **argv)
|
|||||||
args.append(QString::fromLocal8Bit(argv[n]));
|
args.append(QString::fromLocal8Bit(argv[n]));
|
||||||
parseCmdLine(args);
|
parseCmdLine(args);
|
||||||
|
|
||||||
QList<ClassDef> classes;
|
QVector<ClassDef> classes;
|
||||||
|
|
||||||
for (int i = 0; i < args.count(); ++i) {
|
for (int i = 0; i < args.count(); ++i) {
|
||||||
const QString arg = args.at(i);
|
const QString arg = args.at(i);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user