My debug build of libQtWebKit finished and I thought the horror of linking a huge library is over and that I could start to debug. Turned out that gdb was segfaulting when launching my application. Eeeek., google... well googling for gdb and crash is not really finding gdb things. Okay so I was using cvs to get the latest version of gdb, compiling... *crash*. It seemed to crash in demangling, so just in case I was updating binutils and rebuilding gdb. same crash. Hmmm, let us try a debug build... hmmm. Okay one of these 300 char symbols, using the libiberty/testsuite it worked fine... hmmm. using valgrind... using it again and reading the output... oh stack overflow... Turns out alloca is a nice api... there is no error checking and no way to get a breakpoint set... even with -fno-builtin...I was kicking out alloca on my stracktrace from the crash and made it go away, filed a bug and attached a patch, let us see how long this takes to end up in a version. Fixed my QtWebKit within 30 seconds after seeing the stack trace...
I spent the other half of the day/morning with copying the Q.713 data structure into a headerfile and sketching out my header file for a SCCP lite GSM A-Interface implementation. I hope I can publish this soon. Before starting to implement this I will go back to do some WebKit performance analysis...
And with all the GNU bashing going on, I wonder if GNOME 3.0 will be called NOME 3.0... This reminds me of Goethe and the "Die Geister, die ich ruf werd ich nicht mehr los".
Wednesday, July 29, 2009
Friday, July 24, 2009
Fun reading landline telephony specs
For various reasons I have started reading the GSM 08.0x chapter. It is mostly about communication between a Base Station System (BSS) and a Mobile Switching Center (MSC). The protocol used is actually based on the SCCP protocol from landline telephony networks (SS #7). The most funny part is the way these specs are written. Most sentences in GSM 08.06 end in "this is of national concern", or in the Q.71x specification you see classes of reserved fields. One for international use and one for national use where the national telephone monopoly can set the bits they want.... Just by reading the specs you figure out that international telephony is about monopolies communicating to each other, that is so different to the TCP RFCs...
Saturday, July 18, 2009
The WebKit mailinglists
In the beginning there was webkit-dev but we were overwhelmed by the feedback we got. Last week Maciej announced how to use the new lists.
- webkit-dev should be used for the development of WebCore/JavaScriptCore itself.
- webkit-help should be used for questions on how to use WebKit API in applications, porting to new platforms, building it...
- webkit-jobs is there to not force one to send job posts to every single commiter but to only one place.
Monday, July 06, 2009
Performance musings
Like many others I enjoy being in Las Palmas at the Gran Canaria Desktop Summit. It is great to see new and old friends, put faces to IRC nicknames... While sitting in talks I started to feel the performance itch. What code is the moc actually generating, how fast is it... Luckily Qt Software released their internal tests and you will find some benchmarks in the tests/benchmark directory.
When using QObject::connect currently the following happens. For the sender QMetaObject::indexOfSignal gets called and for the receiver the QMetaObject::indexOfSlot or QMetaObject::indexOfSignal is being invoked. Now the various QMetaObject::index* (for properties, methods, signals, slots) work in the same way. You will start with the current QMetaObject and go through the list of all methods, if you didn't find anything you go to the parent QMetaObject and do the same. What you are doing is a linear search for a signature across the inheritance hierachy. When having found the index of the method for a given QMetaObject you will add the number of methods from your parent QMetaObjects and this will be the id used by QObject::qt_metacall. The first thing the generated code in ::qt_metacall will do is to call the parents qt_metacall to subtract the id.
Hashing and such comes into mind, or having a trie for the whole inheritance chain. With things like gperf you could create a perfect hash for the inheritance chain. The problem with having metadata over the whole inheritance chain is that maybe your baseclass is in a different library and they added a new method, now your hash might not be unique anymore... and obviously you will require more memory when you have the whole inheritance tree...
The easy solution is to sort methods/signals/slots so you can do binary search in the various indexOf* methods in QMetaObject. And so far I have only implemented this, but I have some other ideas from "self" and javascript how to cheat a bit to make recuring actions like QObject::invokeMethod a lot faster (there is no need to search again for the "slot").
Another thing is when having searched/found the index of the slot/signal/method you might just safe the QMetaObject and the id instead of adding the offset and when emitting the signal you avoid going through the hierachy because you actually know which ::qt_metacall we want to call...
The code can be seen in a branch on gitorious and for some tests in the QObject::connect/QObject::disconnect benchmark the new code is 30% faster. This happens when you have to go down in the inheritance tree to find the signal... For some other cases there is no difference. What is missing is code to deal with old generated code...
Looking at QMetaObject and generated code
When using QObject::connect currently the following happens. For the sender QMetaObject::indexOfSignal gets called and for the receiver the QMetaObject::indexOfSlot or QMetaObject::indexOfSignal is being invoked. Now the various QMetaObject::index* (for properties, methods, signals, slots) work in the same way. You will start with the current QMetaObject and go through the list of all methods, if you didn't find anything you go to the parent QMetaObject and do the same. What you are doing is a linear search for a signature across the inheritance hierachy. When having found the index of the method for a given QMetaObject you will add the number of methods from your parent QMetaObjects and this will be the id used by QObject::qt_metacall. The first thing the generated code in ::qt_metacall will do is to call the parents qt_metacall to subtract the id.
What can be done to improve it
Hashing and such comes into mind, or having a trie for the whole inheritance chain. With things like gperf you could create a perfect hash for the inheritance chain. The problem with having metadata over the whole inheritance chain is that maybe your baseclass is in a different library and they added a new method, now your hash might not be unique anymore... and obviously you will require more memory when you have the whole inheritance tree...
The easy solution is to sort methods/signals/slots so you can do binary search in the various indexOf* methods in QMetaObject. And so far I have only implemented this, but I have some other ideas from "self" and javascript how to cheat a bit to make recuring actions like QObject::invokeMethod a lot faster (there is no need to search again for the "slot").
Another thing is when having searched/found the index of the slot/signal/method you might just safe the QMetaObject and the id instead of adding the offset and when emitting the signal you avoid going through the hierachy because you actually know which ::qt_metacall we want to call...
Non academic benchmark
The code can be seen in a branch on gitorious and for some tests in the QObject::connect/QObject::disconnect benchmark the new code is 30% faster. This happens when you have to go down in the inheritance tree to find the signal... For some other cases there is no difference. What is missing is code to deal with old generated code...
Subscribe to:
Posts (Atom)