[Qt-interest] getting inside the moc

Thiago Macieira thiago.macieira at trolltech.com
Mon May 11 12:02:40 CEST 2009


Em Segunda-feira 11 Maio 2009, às 11:02:53, Girish Ramakrishnan escreveu:
> > And how are the array of signal and slots associated? In the qt_meta_data
> > array there is something like:
> >
> >  // signals: signature, parameters, type, tag, flags
> >       22,    8,    7,    7, 0x05,
> >       41,    7,    7,    7, 0x05,
> >       73,   54,    7,    7, 0x05,
> >
> > but how has to be read the above map?
>
> The values index into the qt_meta_stringdata. So, for the first signal,
> qt_meta_stringdata[22] will have the signature, [8] will have the
> params, [7] the return value and so on. flags has to do with access
> permissions and other flags :-)

The flags themselves are a combination of QMetaMethod::Access and 
QMetaMethod::MethodType. For example, 0x05 is "Protected" and "Signal". Note 
that the integers for properties, enums and classinfos are different.

This is a further optimisation to avoid relocations on the meta object data. 
If you write something like this:

struct signaldata
{
    const char *signature;
    const char *params;
    const char *returntype;
};
static const signaldata qt_meta_signaldata[] = {
    { "signal1(QString)", "text", "" },
    { "signal2()", "", "" },
    { 0, 0, 0}
}

or even optimise it to:

static const char * const qt_meta_stringdata[] = {
    "signal1(QString)", "text", "",
    "signal2()", "", "",
    0
};

which would be a typical way of organising a string table, then the compiler 
has to generate relocations. That's because either variable is an array of 
pointers and the value of those pointers cannot be determined at compile time 
or link time. It has to be determined at run-time, once the library is loaded 
into memory and its base address is calculated.

As such, this array of pointers is requires six relocations. Now multiply that 
by the number of classes with meta objects, especially considering that 
classes often have more than two meta methods.

What's more, data that needs to be fixed up after loading from disk is, by 
definition, not sharable. It's data exclusive to the calling process.

Instead, we write:

static const char qt_meta_stringdata[] =
    "signal1(QString)\0text\0signal2()\0\0";
static const int qt_meta_indexdata[] = {
    0,   17,   16,   22,   16,   16,   -1
};

And instead of accessing qt_meta_stringdata[1] to get the "text" string, we 
access qt_meta_stringdata + qt_meta_indexdata[1]. Also note how the empty 
strings all have the value of 16, which is one character before "text" (that 
is, the first \0).

Both variables a relocation-free (no fixup needed after loading from disk), 
which means that they can be placed in a sharable section of the binary. 

BTW, sharable is good :-) If you want to use this technique, you can find this 
Perl script of mine to help you out: 
http://websvn.kde.org/trunk/KDE/kdesdk/scripts/generate_string_table.pl?view=markup

PS: the QMetaObject structure itself requires relocations (the pointers to 
both the string table and the int table), but that's exactly two relocations 
per meta object. The best we could do would be 1 relocation, but that would 
require encoding the flags and other integer data in the middle of the 
character data. We've also toyed with the idea of inserting a hashing table 
there.

> > Is there any document about how the moc works and signals/slots are
> > implemented?
>
> Not that I am aware of, but it is not really that black-magic. Have a
> look at src/tools/moc/. generator.cpp is very easy to read. And the code
> in qobject.cpp will explain how the metadata is used.

Also src/corelib/kernel/qmetaobject.cpp.

Other sources of information are the three dynamic meta-object writers in Qt:
	MetaObjectGenerator (http://labs.trolltech.com/gitweb?p=qt-
snapshot;a=blob;f=src/activeqt/container/qaxbase.cpp;hb=master)
	QDBusMetaObjectGenerator (http://labs.trolltech.com/gitweb?p=qt-
snapshot;a=blob;f=src/dbus/qdbusmetaobject.cpp;hb=master)
	a third one coming in Qt 4.6 (not merged in yet)

-- 
Thiago Macieira - thiago.macieira (AT) nokia.com
  Senior Product Manager - Nokia, Qt Software
     Sandakerveien 116, NO-0402 Oslo, Norway
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: This is a digitally signed message part.
Url : http://lists.qt-project.org/pipermail/qt-interest-old/attachments/20090511/22285cdf/attachment.bin 


More information about the Qt-interest-old mailing list