Tag Archives: JIT

FOSDEM talk reflections 3/3: HipHop, communities, public procurement

Nikerabbit arrives at the MediaWiki meetup at FOSDEM

Meetup of MediaWiki community. Or Wikimedia tech? How to call the Wikimedia software development ecosystem? (Photo by henna, copyright status unknown.)

This is the third post about FOSDEM 2013; see 1/3: I18n in the WEB, Mozilla i18n and L20n for the first and2/3: docs, code and community health, stabilityfor the second. Links to the abstracts in the headers.

Scaling PHP with HipHop

HipHop is still alive, and faster than ever. It has evolved from PHP to C translator to a JIT bytecode interpreter system, just like PHP itself is, without JIT of course. The speedups they are seeing are impressive (it was deployed on Facebook about a month ago). Given that they have removed the compile everything before deploy step, it is now much more feasible to use.

I’m considering to give HipHop a try on translatewiki.net later this year, probably after we have upgraded to at least Ubuntu 12.04, where Facebook provides packages for it. It is still a pain in the ass to set up manually, as it was few years ago. Wikimedia Foundation (WMF) has dropped its evaluation, but perhaps they will reconsider after our experiences, and HipHop, or hhvm as it is called now, has indeed changed a lot since then.

It was highlighted that the supported language features and libraries of hhvm and PHP vary to an extent. hhvm provides some nice features like strict type hinting, but it is unlikely I can use those anytime soon, since there is no way to take advantage of these on hhvm without breaking support for normal PHP, which is something that really cannot be done in the MediaWiki ecosystem.

Community/BOF meetup

Almost 20 people were around, a few outside of WMF. Discussions circled around events like the Amsterdam Hackathon and MediaWiki groups. The most interesting part (to me) is how to call the Wikimedia software development ecosystem, so it can be marketed properly. Suggestions ranged from extending the meaning of MediaWiki to cover everything including mobile, gadgets and so on; using Wikipedia as it is the brand most well known; or creating a new Wikitech brand.

There are pros and cons to each of the above, but one thing is true: There is no name that can currently be used to refer to everything technical done around MediaWiki and Wikimedia that would also be understood by potential participants. Also, MediaWiki development is not perceived to be cool anymore, because it’s PHP. But it isn’t. MediaWiki development is also Redis, Varnish, puppet, git, Solr, HipHop, semantic, node.js, mobile, OpenStack, and more. Quim Gil will continue work on coming up with a brand. Curious visitors can also compare this to what KDE did recently when they expanded the meaning of KDE to be not only the desktop, but also the community and everything they do. The change process wasn’t painless for them, and wouldn’t be for us, but at the same time (<a target=_blank …read more
Source: FULL ARTICLE at Planet KDE

QML Engine Internals, Part 3: Binding Types

This blog post is part of an ongoing series about the internals of the QML engine.

In the last blog post, we covered how bindings in the QML engine work. In this post, we’ll examine the different kind of bindings and have a brief look about the future of JavaScript engines in QML.
Some of this content is already covered by my DevDays talk QtQuick Under the Hood. In addition to that, there will be new content in this post as well.

Recap

To recap, let’s quickly look at a simple binding:

text: "Window Area: " + (parent.width * parent.height)

Each binding like this one is actually a JavaScript function which is evaluated at runtime by the v8 engine. The result of the evaluation is the return value of the function, which is then assigned to the text property. v8 doesn’t know about Qt’s objects and properties, when encountering objects like parent or properties like width it asks the context wrapper and the object wrapper in QML to resolve them. These wrappers remember which properties were accessed while a binding was evaluated, and can therefore automatically connect to the changed signal (e.g. widthChanged()) of each property and connect it to a slot that re-evaluates the binding.

With the way bindings work now freshly in mind again, let’s move on and have a look at the different binding types.

Binding Types

In the last post, I stated that each binding is represented by an instance of the QQmlBinding class. That was actually a lie-to-children. Having a full-blown QQmlBinding instance for each binding would be much to costly – there are hundreds if not thousands of bindings in a typical QML application, therefore a binding needs to be lightweight. In addition, each binding is compiled separately when loading a QML file, so there is a lot of overhead by invoking the v8 compiler many times during loading.

QV8Bindings

To resolve the large overhead of QQmlBinding, there is another binding class, confusingly named QV8Bindings. QV8Bindings is a collection of all bindings in a QML file, using an array of the much more lightweight QV8Bindings::Binding structure. The QML devs have gone to great lengths of minimizing the memory usage of this structure – they even exploit the fact that the last 2 bits of a pointer are unused because of alignment, and use that unused space to store flags (a common enough pattern that QML has a special-purpose class QFlagPointer for this). As a result, a QV8Bindings::Binding is only 64 bytes large.

The big advantage of QV8Bindings compared to QQmlBinding is that it compiles all bindings together, so only one v8 compiler invocation is needed. In QQmlCompiler::completeComponentBuild(), you can see that when compiling a QML file, all binding functions are concatenated together into one big JavaScript program, and stored in QQmlCompiledData (a structure that contains all kind of compiled data for each QML file). When the QML file is first instantiated, the v8 program is compiled, which happens in QV8Bindings::QV8Bindings(). The compiled program is then also stored in QQmlCompiledData and the original source is discarded. When instantiating the same QML file another time, the QML engine re-uses the QQmlCompiledData from before and does not need to compile the bindings program again. This is not the case with QQmlBinding, which need to be compiled each time a QML file is instantiated.
To sum up: Since QV8Bindings packs together all bindings of the same QML file, it uses much less memory for each individual binding and can compile all bindings together in one go.

So, where does that leave us QQmlBinding, why does this class even exist? In some cases, bindings are non-shareable, for example because they use closures or eval(). In this case, each binding function requires a different context, and can therefore not be compiled together with the other bindings that share the same context. Therefore, in these special and rare cases, a binding will get its own QQmlBinding instance instead. The decision on what binding type is used happens when compiling the QML file, in QQmlCompiler::completeComponentBuild(). There, a SharedBindingTester is used to check which bindings will be part of QV8Bindings and which will become their own QQmlBinding. SharedBindingTester is visitor for the JS AST. If you look at the code, you’ll see that the SharedBindingTester also tests whether a binding is safe, which is used to avoid evaluating bindings multiple times when instantiating a QML file, which is best described in the commit message for this optimization.

To keep things in the QML code simple, both QQmlBinding and QV8Bindings::Binding inherit from QQmlAbstractBinding.

QV4Bindings

If you have looked at the QML engine code a bit, you will probably have noticed the class QV4Bindings, which is also a subclass of QQmlAbstractBinding. Yet another binding type? What is this one about? Like QV8Bindings, this is a collection of bindings of a QML file. Unlike QV8Bindings, QV4Bindings stores only so-called optimized bindings, also wrongly and confusingly called compiled bindings. Some bindings can be optimized, in which case they will be part of QV4Bindings, some bindings can not, and will be part of QV8Bindings.
So what is this optimization? v4 bindings are not evaluated by the v8 engine. Instead, v4 bindings are compiled to bytecode, and run through a bytecode interpreter. This bytecode compiler and interpreter can not deal with all JavaScript expressions, simply because ahead-of-time compilation of JavaScript is impossible for all cases.

But why bytecode? After all, the v8 engine compiles to machine code, isn’t that faster than a bytecode interpreter? Turns out it isn’t: the v8 engine has quite a bit of overhead when invoking it and when it needs to call out to the QML engine to resolve objects and properties. In addition, the v8 engine sometimes recompiles a function on the fly, with more optimizations, when it is called multiple times. All of this is too much overhead for the QML usecase, which typically are a lot of one-line binding functions. Here is the result of a benchmark I did for my DevDays talk. I basically let the QML engine evaluate a binding a few hundred times. The binding was a simple one which the v4 compiler could deal with. To compare that to using the v8 engine, I used the environment variable QML_DISABLE_OPTIMIZER=1 to disable v4 bindings altogether.

v4 benchmark

As you can see, the v4 bytecode engine is indeed faster than v8 for this particular usecase.

Internally, v4 is a register machine. Much like a CPU, it has registers to store temporary values. Unlike a CPU, it does not load and store values from memory – instead it loads and stores values from QObject properties. Using the environment variable QML_BINDINGS_DUMP=1, let’s have a look at a simple binding:

text: parent.width * parent.height

The output will be:

Program.bindings: 2
Program.dataLength: 92
Program.subscriptions: 4
     [SNIP of other, unrelated bindings)
     160        14:15:
     176                Block                   Mask(1)
     192                LoadScope               -> Output_Reg(0)
     208                FetchAndSubscribe       Object_Reg(0) Fast_Accessor(0x7f05f6e51060) -> Output_Reg(0) Subscription_Slot(1)
     272                FetchAndSubscribe       Object_Reg(0) Fast_Accessor(0x7f05f6e51090) -> Output_Reg(0) Subscription_Slot(2)
     336                LoadScope               -> Output_Reg(1)
     352                FetchAndSubscribe       Object_Reg(1) Fast_Accessor(0x7f05f6e51060) -> Output_Reg(1) Subscription_Slot(1)
     416                FetchAndSubscribe       Object_Reg(1) Fast_Accessor(0x7f05f6e510a0) -> Output_Reg(1) Subscription_Slot(3)
     480                MulNumber               Input_Reg(0) Input_Reg(1) -> Output_Reg(0)
     496                ConvertNumberToString   Input_Reg(0) -> Output_Reg(1)
     512                Store                   Input_Reg(1) -> Object_Reg(0) Property_Index(42)

As you can see, the properties width and height are loaded into register 0 and 1, then these registers are multiplied together, and the result stored in the text property (which happens to be property number 42 in the QQuickText class). The instruction FetchAndSubscribe not only loads a property, but also subscribes to its changed signal, which is needed for automatic binding updates to work. In the above “assembler” code, you can also see another advantage: The v4 compiler resolve objects and properties at compile-time, and stores the property index in the bytecode. Thus, at runtime, no name lookup is needed, the properties can be accessed directly by index. Contrast that to the v8 engine, which calls out to QML object and context wrappers to resolve object and property names, which of course is much more overhead. The disadvantage is that the v4 engine can not deal with dynamic objects, for example those exported from C++ via setContextProperty(). A binding containing such a dynamic object will be part of QV8Bindings.

Summary of Binding Types

To sum up, there are 3 binding types, all inheriting from QQmlAbstractBinding:

  1. QV4Bindings::Binding
  2. QV8Bindings::Binding
  3. QQmlBinding

v4 bindings are fastest as they use a custom bytecode engine. Both QV8Bindings and QQmlBinding use the v8 JS engine for evaluation, however QV8Bindings packs together all bindings to compile them all in one go, and QQmlBindings are compiled individually and on each QML component instantiation.

Here is a (nonsensical) example with all binding types:

import QtQuick 2.0

Rectangle 
    width: 360
    height: 360

    Text {
        anchors.centerIn: parent
        text: parent.width * parent.height
        font.pointSize: eval("14")
        font.wordSpacing: parent.width > 10 ? 90 : ~parent.width
    }
}

Using QML_COMPILER_DUMP=1, you’ll see the QML compiler uses STORE_COMPILED_BINDING two times, STORE_V8_BINDING once and STORE_BINDING once as well.

STORE_BINDING is for QQmlBinding, it is used for font.pointSize, as that binding uses eval() and can therefore not be shared.

The bindings for anchors.centerIn and text are both v4 bindings (STORE_COMPILED_BINDING instruction, QV4Bindings::Binding class).

Finally, font.wordSpacing is an ordinary QV8Bindings::Binding (STORE_V8_BINDING instruction). The v4 bytecode compiler and interpreter is smart enough to deal with the tenary operator, but the complement operator is not yet implemented, therefore the QML compiler chose to use v8 bindings instead.

The future

In the future, all of this is going to change, and for one reason: iOS. iOS does not allow JIT compilers. Because of that, v8 can not be used – it always compiles JavaScript to machine code, and that is not allowed on iOS. iOS simply does not allow to mark memory regions as executable. Thus, v8 does not run on iOS. Digia is dedicated to support iOS in the future though, so a replacement is needed for v8. And that is what some people are working on at the moment: A new JavaScript engine, called V4VM that is going to replace v8 in QML.

I’d expect that at least the QV4Bindings class will disappear because of this, and QV4Bindings and all other places in QML that used the v8 engine will use V4VM instead. Replacing the bindings is probably the easiest part. v8 is however used directly in quite a lot of places in the QML engine, so replacing those usages with V4VM will be a huge undertaking.

To run on iOS, V4VM needs to be a bytecode interpreter. Actually, V4VM supports 3 different backends:

  1. LLVM
  2. MASM
  3. Moth

V4VM is abstracted reasonably well – V4VM first creates a V4VM-specific intermediate representation of the code, which is then passed on to the backend. As a result, the LLVM-specific code, which converts the V4VM IR to LLVM code, then lets LLVM compile that to machine code, is only about 1400 lines.

Moth is the custom bytecode interpreter and will be used on iOS. Both MASM and LLVM are third-party libraries that compile to machine code, so those will be used on other platforms. I don’t really know why they have two backends doing the same thing, but I heard that the LLVM dependency is probably too heavy, so I guess MASM would be used in most cases on non-iOS systems. Note that MASM is not the Microsoft assembler, but Macro Assembler, which is the assembler from JavaScriptCore, copied into V4VM.

V4VM is under heavy development at the moment. One of the top contributors is actually Lars Knall, Qt’s chief maintainer. For the curious, there is the #qt-v4vm IRC channel to watch.

Altogether, I don’t have much information on V4VM yet. It will probably be quite suitable for QML’s usecase, i.e. small binding functions. Beyond that, there are lots of unknowns, for example how resolving of Qt’s objects and properties will work, and how much ahead-of-time compilation will be possible, and how MASM and Moth handle the cases where ahead-of-time compilation is not possible.

I for one am very curious about this new engine and am looking forward to learn more about it, as more details will hopefully emerge in the future.

Source: FULL ARTICLE at Planet KDE