Profiling JavaScript with Shark

Xcode ceased to ship Shark in Xcode 4 (released March 14, 2011), so this documentation is largely obsolete. See (and please contribute to) the Instruments documentation instead. (Instruments replaced Shark in Xcode.)

It's now possible to build a copy of Firefox that allows you to start and stop Shark profiles from JavaScript code. With this customized build, you can more easily locate performance problems in JavaScript libraries, web pages, or in Firefox itself. Mozilla also provides Shark-enabled development builds for you to use.

Using the Shark-in-JavaScript support, you can avoid having to manually start and stop Shark, thereby taking your trigger finger out of the equation while timing operations.

Note: Remember, this feature is only available in a custom-built Firefox. It is not part of the standard build. In addition, you must install the latest version of CHUD, which comes with XCode nowadays, in order to use it.

Getting started

The first step is to make sure you have a recent XCode installed.  If you have any problems, download and install it. Even if you think you already have it. You might be out of date.

Download a development build

Mozilla produces Shark-enabled nightly builds for the mozilla-1.9.1 (Firefox 3.5) mozilla-1.9.2 (Firefox 3.6), mozilla-central (trunk), and TraceMonkey source repositiories. You should download the build with filename ending in mac-shark.dmg

Build your Firefox

Alternatively, you can build your own copy of Firefox. Once you've got CHUD installed, and have the Firefox code, you need to set up a mozconfig file that enables the --enable-shark option. It might look like this:

. $topsrcdir/browser/config/mozconfig
mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/ff-opt-libxul
ac_add_options --enable-optimize
ac_add_options --enable-libxul
ac_add_options --enable-shark
ac_add_options --enable-debugger-info-modules
ac_add_options --disable-install-strip

Note: This <tt>mozconfig</tt> file works on Intel Macintosh systems with Leopard but may not work on PowerPC and Tiger, due to libraries being moved around.

Then build Firefox as usual.

If you get a compile-time error such as the following:

~/mozilla-central/js/src/jsdbgapi.cpp:1702:23: error: CHUD/CHUD.h: No such file or directory

then you need to download the CHUD headers in the standalone installer package at https://connect.apple.com/cgi-bin/WebObjects/MemberSite.woa/wa/getSoftware?bundleID=20332.  Alternatively, from the ADC website, go to Member Site > Downloads > Developer Tools.  Various CHUD versions should be included in that page, and you probably want the latest version (4.6.2 as of this writing.)

Note that if installing an old CHUD version breaks your Shark (on Snow Leopard at least), you can fix it by reinstalling Xcode.

Note: As of this writing (2010/3/5), you can get this working in Snow Leopard on a 64-bit machine, but you need a) to install the latest Xcode and CHUD as linked just above, and b) a 32-bit build. Otherwise you'll get a linker error starting with something like:

ld: warning: in /System/Library/PrivateFrameworks/CHUD.framework/CHUD, missing required architecture x86_64 in file

followed by a bunch of missing symbols.

To make a 32-bit build: a) make sure you have a totally fresh build directory (any extra stuff lying around from a 64-bit build will mess things up!), b) prefix your usual configure command with:

CC="gcc -m32" CXX="g++ -m32" AR=ar

and c) add --target=i686-apple-darwin10.0.0 to your configure options in mozconfig.

Using Shark-in-JavaScript

Once you have a build, you have access to four new global functions that let you control Shark. These functions are available to both chrome and content script:

connectShark()
Connects to Shark.
startShark()
Starts profiling.
stopShark()
Stops profiling.
disconnectShark()
Disconnects from Shark.

Usually you will call these in exactly that order, like this:

<script>
connectShark();
startShark();

...
doSomethingReallySlow();
...

stopShark();
disconnectShark();
</script>

For a simple sample of how this works, see Apple's Towers of Hanoi example.

Before running your test, start the Shark utility. If the code will take less than a second or so to run, you should adjust your sample rate to 20µs. To do this, show the configuration editor:

Image:Shark-config.png

Then change the time sample interval as shown below:

Image:Shark-sample.png

To allow your JavaScript code to control Shark, you need to put Shark into remote mode by choosing the "Programmatic (Remote)" sampling mode:

Image:Shark-remote.png

Now you're ready to run your test. This will get you very clean sampling data from which to make optimization decisions.

See also

Document Tags and Contributors

Contributors to this page: Sheppy
Last updated by: Sheppy,