You are currently viewing a snapshot of www.mozilla.org taken on April 21, 2008. Most of this content is highly out of date (some pages haven't been updated since the project began in 1998) and exists for historical purposes only. If there are any pages on this archive site that you think should be added back to www.mozilla.org, please file a bug.



Profiling Mozilla using Quantify under Solaris

Questions or comments to news://news.mozilla.org/netscape.public.mozilla.unix.

Author: Dan Mosedale <dmose@mozilla.org>

This document was written while using Quantify version 4.5.1 for Solaris 2.6 with the Sun Workshop 5.0 compilers in -compat=4 mode. However, almost everything here is likely to apply to gcc/gdb as well, and Quantify does indeed support (some versions of) it. If you do have experience with other versions and/or compilers, please post to news://news.mozilla.org/netscape.public.mozilla.unix, and I'll add details to this page.

  1. Find a Solaris machine with plenty of memory, swap, CPU cycles, and fast I/O.

    • I've been using an Ultra 2 with one 296-Mhz UltraSPARC-II processor, 256 megabytes of RAM, and 512 megabytes of swap space. It's still slow going.
    • Install any necessary patches for the OS, compilers, and C++ runtime. See the Mozilla on Solaris FAQ for some information about this.
  2. Get a working Solaris build with the proper optimization & debugging options.

    • Use the --disable-debug flag to configure. Even though we want debugging symbols in the object, we don't want all the extra assertion checks, as these will hurt performance.
    • Set the --enable-optimize and --enable-X11-shm flags to configure. There's no point in profiling code without the usual optimizations.
    • Be sure to build with debugging symbols by adding "-g" to CFLAGS and CXXFLAGS before running configure.
    • Unless you're trying to profile using a networked X connection, read the section in the Mozilla on Solaris FAQ about X11 shared memory and make sure that it's actually working.
  3. Build a quantified version of the browser.

    • I like to use the -collection-granularity=function option to Quantify, as this makes the runs less painfully slow:
      cd xpfe/bootstrap
      gmake QUANTIFYOPTIONS="-collection-granularity=function" \
          quantify
      
  4. Invoke Quantify.

    • In order to get useful data out of Quantify, lazy binding in the runtime linker must be turned off. This will change the performance characteristics of the code somewhat; see Rational Technical Note 6063 for details. To do this, make sure that the LD_BIND_NOW environment variable is set to 1, and that the QUANTIFYOPTIONS environment variable contains the -force-dlopen-rtld-now switch. I generally also use -record-dynamic-library-data=no, since I presume that the previous changes cause any data recorded to be less meaningful.
    • -avoid-recording-system-calls=SYS_exit,SYS_poll,SYS_door will filter out some other junk that would otherwise contaminate the data.
    • My experience is that running data collection for the entire duration of the program doesn't usually generate terribly helpful data. So I've had the most success starting quantify under the debugger with data collection turned off using -record-data=no, and then calling into the Quantify API from the debugger to turn it on for just the duration of the task that I want to profile.
    • Typically, I end up with an invocation of mozilla looking something like this:
      cd ../../dist/bin
      env LD_BIND_NOW=1 QUANTIFYOPTIONS="\
        -force-dlopen-rtld-now -record-dynamic-library-data=no \
        -avoid-recording-system-calls=SYS_exit,SYS_poll,SYS_door \
        -record-data=no" \
        ./run-mozilla.sh -g -d dbx mozilla-bin.quantify
      
  5. Use the debugger to control data collection.

    Start the program under debugger control. When you get to the point where you want to turn on profiling, break into the debugger. Then turn on data recording:

    (dbx 2) print quantify_start_recording_data()
    quantify_start_recording_data() = 1
    
    Continue executing your program, and perform whatever task it is you'd like to profile. When you've finished, break into the debugger again, turn off data recording, and tell Quantify to save the data:
    (dbx 4) print quantify_stop_recording_data()
    quantify_stop_recording_data() = 1
    (dbx 5) print quantify_save_data()
    [gobs of output elided to save space]
    quantify_save_data() = 1
    (dbx 6)
    
    The output from quantify_save_data() will tell you how to then view the data using quantify -view.

    Note: gdb users will need to use the call command to invoke Quantify's API functions instead of print.