Aim, shoot, weigh! - hunting for samples in the forest of JIT

Many people are using OProfile for system measurements on Linux. This is a very handy profiling tool (supports hardware performance counters and has a very low runtime overhead) although it is in alpha phase. Using OProfile to measure any application performance is a straightforward task on Linux: you should get the latest OProfile for your machine or device, build, configure and run the daemon, and start measuring an application or your whole system. Finally, you can execute several scripts which report the performance numbers to you (according to your reporting requests). It sounds easy, doesn't it?

For common analysis, the default OProfile measurement method is enough, but for JIT-generated code, there is one more step which we have to consider. JIT code is allocated at runtime in memory. In WebKit, there are neither symbols nor sources corresponding to them. Theoretically, OProfile can count JIT samples and report them in the requested form, but no details can be seen about them. In order to have detailed information about JIT code, they have to be registered to OProfile's analysis system.

There is a library called OPagent which has to be used in order to register JIT-related information for further analysis. The basic method is to pass the memory region (addresses) of JIT code and a symbolic name to OPagent. This will reveal the symbol names of JIT code to the opreport tool. Lets see:

 samples       %   image name  symbol name
    7281  9.8634   jsc         JSC::Heap::allocate(unsigned int)
    2932  3.9719   jsc         JSC::jsNumberCell(JSC::JSGlobalData*, double)
     140  0.1897     [tests/sunspider-0.9/access-nbody.js:95-126]
     139  0.1883     :fannkuch[tests/sunspider-0.9/access-fannkuch.js:5-62]
     111  0.1504     :partial[tests/sunspider-0.9/math-partial-sums.js:5-28]

Now, we have summarized results for each JIT code segment. The next step of profiling is annotation. As you might know, the JIT machine code in WebKit comes from JavaScript. So, here we have to rise the following question: which source code is responsible for those JIT samples? The JIT code generator? No! The WebKit does not take too much time there. The generators runs once, while the generated code can be run multiple times. The generated machine code? Definitely yes! Do we have a source code to annotate? Unfortunately, only assembly code can be produced here. For JIT developers, the machine code is good enough, but I do not think that everyone knowns architecture-specific instructions well. Lets step one lever higher! The JIT code is generated from byte-code (SquirrelFish). The situation is the same here. The JIT ninjas know SquirrelFish as well as their nunchakus, but I bet the others would be even more frightened by the byte-code. So, nothing else remains but the JavaScript source.

  14  0.0118 :function DrawLine(From, To) { /* total: 843  0.7093 */
   8  0.0067 :  NumPix = Math.round(Q.LastPx + NumPix);
   2  0.0017 :  var i = Q.LastPx;
  51  0.0429 :  for (; i < NumPix; i++) {
  15  0.0126 :    Num += NumAdd;
  44  0.0370 :    if (Num >= Den) {
  12  0.0101 :      Num -= Den;
   7  0.0059 :      x += IncX1;
  11  0.0093 :      y += IncY1;
             :    }
  26  0.0219 :    x += IncX2;
  26  0.0219 :    y += IncY2;
             :  }
  10  0.0084 :  Q.LastPx = NumPix;

This looks nice, doesn't it? Additionally, this can help JavaScript developers to tune their code to perform better on WebKit. They can check our paper about JavaScript transformations and their effect on performance (Guidelines for JavaScript Programs: Are They Still Necessary? at

If you are interested in OProfile-based JIT profiling for WebKit, let me guide you how you can have such a nice performance report from OProfile!

  • Get OProfile source from CVS!
    There were/are some bugs in OProfile which block to have detailed information about JIT code. I have created a patch which solves this issue. I hope that these modifications will be landed in the trunk soon. Just to make sure, I am going to upload those patches here as well.
  • Build and install OProfile for your target machine/device.
  • Get WebKit source
    • Patch WebKit with OProfile support
      You can download the latest patch from here. It would be nice if WebKit would have this feature built-in by default, but it takes time for the patch to get landed.
  • Build and install WebKit on your target machine/device.
    Choose your port from:
    Follow your port specific build instructions.
  • Start your OProfile daemon, for example:
    opcontrol --start-daemon --e:CPU_CYCLES:10000:0:1:1 --no-vmlinux
  • Measure a sample JavaScript code, for example:
    opcontrol --start
    opcontrol --stop
    opcontrol --dump
  • Create a summarized report, for example:
    opreport -l WebKitBuild/Release/jsc
  • Create an annotation report, for example:
    opannotate --source --include-file=crypto-md5.js

Have a Fun! Comments and suggestions are welcome!

op100407.patch_.txt2.53 KB

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • No HTML tags allowed
  • Lines and paragraphs break automatically.

More information about formatting options

This question is for testing whether you are a human visitor and to prevent automated spam submissions.
Fill in the blank