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.
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
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:
Then change the time sample interval as shown below:
To allow your JavaScript code to control Shark, you need to put Shark into remote mode by choosing the "Programmatic (Remote)" sampling mode:
Now you're ready to run your test. This will get you very clean sampling data from which to make optimization decisions.