Profiling XPCShell

Introduction

Sometimes, you might want to get a performance profile of a certain piece of JavaScript (like an XPCOM module), to see which part takes the most time. You could use Venkman for that. But sometimes, Venkman gives too much noise (because it also profiles chrome code). Or you might want to have a more reproducible testcase. In those cases, an xpcshell script can help. You can just call the code you want to test. But then, you can't use the Venkman UI.

XPCTools

There is profiler in the tree that can profile xpcshell scripts. To use it, you need to enable it in your mozconfig:

 ac_add_options --enable-xpctools

Now you can profile an entire script by setting the environment variable <tt>MOZILLA_JS_PROFILER_OUTPUT</tt> to a filename where you want the output file. For example, on Linux or MacOSX you do:

export MOZILLA_JS_PROFILER_OUTPUT=/tmp/profile.txt

Now, run the script using xpcshell. After running has finished, the output file will contain a profile. A profile will look like this:

 file:///Users/michiel/Mozilla/tree1/...js/calUtils.js
     [2,25420] createDateTime() {60-62} 579 {min 0, max 3, avg 0, sum 427, self 427}
     [2,56810] cp_QI() {860-866} 835 {min 0, max 1, avg 0, sum 950, self 950}

The first line tells which file was profiled. Then, the next lines shows the amount of time spend in the functions in that file. The line consists of:

  • The compile count of the function;
  • The call count of the function;
  • The functions name;
  • The starting line number;
  • The ending line number;
  • The function's size;
  • The amount of time (in milliseconds) the fastest call took;
  • The time of the slowest call;
  • The average time spend;
  • The total time;
  • The time spend in the function itself is given (that is the total time excluding the time spend in functions called from this function).

Notes

  • You need a trunk build from after 2007-05-28. Using an earlier build will cause the profiler to hang
  • The more adventurous can use the nsIXPCToolsProfiler.idl interface directly, but be aware that you must start the profiler before loading the files you want to profile (creating an instance of a component loads the file!)