DOM/Engineering: Difference between revisions
m (some details on xpcom and webidl) |
m (→Performance / Validation: are we fast yet, etc.) |
||
Line 125: | Line 125: | ||
=== Telemetry === | === Telemetry === | ||
=== Talos Performance Tests === | |||
=== Focused Tracking Sites === | |||
Starting with the famous https://arewefastyet.com/ site that tracked and compared JS engine performance, there's been a history of "are we BLANK yet" sites created by teams to focus on specific initiatives. http://arewemetayet.com/ tracks all of these sites including feature-completeness dashboards that conform to the naming scheme. We call out some of these below. | |||
==== Are We Fast Yet (AWFY) ==== | |||
==== Are We Slim Yet (AWSY) ==== |
Revision as of 20:47, 4 August 2018
Disclaimer: This document is currently just in its infancy.
This page attempts to serve as a cheat-sheet for the things DOM engineers may do by linking to the documentation on how to do it or calling out where we need more documentation. We try and transcend being a list of links by contextualizing the links and inlining and deep-linking when the target link is more than a page. For example, while there are other pages that capture the many test frameworks, readers should be able to ctrl-f for "reftest" and get a brief definition of what a reftest is and from there a link to more details.
Please feel free to edit to make the document more usable.
Building Firefox
Install Bootstrapping Dependencies
MDN has excellent per-platform guides on how to set up your first build. There's some overlap between those guides and the next section here about checking out the code. The core thing to know is that you want to check out "mozilla-unified".
Checking Out the Code
You can use hg (mercurial) or git, but it's strongly advised that you at least try using mercurial with bookmarks and the unified repo to start, even if you're a git expert.
Everything you could want to know about using Mercurial with Firefox can be found on the Mercurial for Mozillians page. But good first steps are:
- Install Mercurial.
- Check out the unified repo that has all of the branches you'd care about in one place.
Configuring the Build
The MDN Configuring Build Options page has all the details you'd want.
The core configuration options you are likely to care about are:
ac_add_options --enable-debug
- Enable assertions and other DEBUG-conditional code. These massively slow down the browser and increase console spam, but are quite useful when you're making low level changes and you wan to make sure invariants are checked by assertions.ac_add_options --enable-optimize="-Og"
- Setting a specific optimization level so that the debugger will have an easier time of inspecting the state of the program. "Og" was gcc-specific last time I checked; if you're building with clang you might need something different.
Making Builds Go Faster
- You can use Icecream to distribute builds to other machines on whatever network you're using. Each Mozilla office has its own build server you can use. If you work remotely, you can also see massive speed-ups from adding a second comparable machine.
- You can use ccache in conjunction with ice cream. ccache caches deterministic build results which is useful when the only thing that has changed for a file are the timestamps of its dependencies.
- Remember to update your configuration so that "make" knows how many jobs to spawn in parallel!
Spec-Work: Implementing for Content
Communication: Participate in Spec Development
- Listen and participate.
- Watch the github repo.
- Join the mailing list.
Mechanics: WebIDL
WebIDL (spec), or the Web Interface Definition Language, defines the APIs that Firefox exposes to JavaScript content.
Understanding
Doing
Mechanics: Testing
There are two broad categories of tests you'll deal with.
- Web Platform Tests are cross-browser tests. The contents of testing/web-platform-tests are periodically automatically synchronized to/from the github repo at https://github.com/web-platform-tests/wpt.
- Firefox specific tests. There are actually a number of
Browser Chrome-Work: Implementing for Privileged Browser UI
"Browser chrome" is the browser UI. (This is the etymology of Google's "Chrome" browser, which will forever require you to make clarifications whenever you say the word "chrome".)
XPConnect versus WebIDL
Some inaccurate but workable definitions:
- XPIDL ".idl" files in the tree define XPCOM interfaces. These interfaces define methods, constants, and getters and setters, as well as meta-data about them. These are conceptually language agnostic but in practice you'll see a lot of C++-specific details included in the files.
- XPCOM covers both a bunch of important system glue code as well as the mechanics that make the interfaces and their language-specific calling conventions work.
- XPConnect is a binding layer implemented in C++ that allows JavaScript to interact with XPCOM. JS doesn't have the low level ability to do this on its own. XPConnect is single-threaded and only available on the main thread of each process. Any JS code running on other threads is either running in a privileged ChromeWorker or regular DOM Worker, SharedWorker, ServiceWorker, or Worklet.
- Firefox's WebIDL bindings are a high-performance binding layer created to expose APIs to web page content with low overhead. They trade increased code size for speed. XPConnect dynamically interprets memory-mapped type definitions every time calls are made which is slower but avoids bloating Firefox's on-disk or in-memory size (because the type definitions are more compact than the comparable machine code used by WebIDL).
As covered above, we have a mechanism to expose WebIDL only to system-privileged contexts by marking WebIDL interfaces or methods Exposed=System. This raises the question of when you should use XPIDL/XPCOM and when you should use WebIDL for APIs that are only exposed to privilege execution.
- The shortest answer is that you should use XPConnect unless your API is going to be called so frequently from system-privileged JS code that you are certain the XPConnect overhead would show up in a profile. Or, better, you already tried XPCOM and it did show in profiles.
- If the API needs to be exposed to C++ and/or Rust in addition to JS, you should consider XPCOM anyways because the WebIDL bindings are designed for consumption by JS, not C++ and Rust code.
Bugs
Handling Reported Bugs
- Be aware of what's going on:
- Watching: Bugzilla has a number of "watching" mechanism to help you track what's going on via email.
- You can opt to receive bugmail for all activity in a given component without being CC'ed on the bug via the preferences' Component Watching preferences page. While this is useful, it can be a bit much. Messages you receive because you're watching a component will have an "X-Bugzilla-Reason" header value of "None" that you can use to filter on to differentiate from reasons like "CC". "X-Bugzilla-Watch-Reason" will also include "Component-Watcher" in that case among its other space-delimited terms.
- You can also watch what your team-mates are doing by using the "User Watching" functionality on the Email Preferences preferences page. "X-Bugzilla-Reason" will be "None" in this case just like for component watching, but you can filter using "X-Bugzilla-Who" which will be the email address of the watched person, as well as "X-Bugzilla-Watch-Reason" which will also include their email address and terms that identify their relation to the bug such as "AssignedTo" and "CC" separated by spaces.
- Triage: However, that all can get a bit overwhelming. You don't need to read every bug that comes into your mailbox. Which is why we have a triage process for components. Triagers will go through un-triaged bugs in a component and evaluate them and set a needinfo flag or assignee to take next steps to deal with the bug. The triage process is documented in the mozilla/bug-handling github repo.
- Watching: Bugzilla has a number of "watching" mechanism to help you track what's going on via email.
Security Bugs
- https://wiki.mozilla.org/Security_Severity_Ratings
- https://wiki.mozilla.org/Security/Bug_Approval_Process
- null pointer crashes should be fixed but don't need the whole process.
Crash reports
Firefox binaries are instrumented with crash-reporting handlers. These crash reports are sent to https://crash-stats.mozilla.com/ where they are processed and surfaced. Users can see a list of crashes they have personally reported by going to about:crashes in their browser.
There's a variety of information on how to understand a crash report:
You can also be granted privileges after agreeing to privacy guidelines in order to download Windows-style "minidump" files created by breakpad that contain more details than can be found on the public crash report page. The information includes details like the contents of stack memory (which may include data that has privacy implications, hence the privacy agreement).
Debugging
General links:
Using rr to record and replay (on linux)
[rr https://rr-project.org/] is a magic super tool that can record the execution of Firefox, logging all the non-determinism so that you can replay the exact execution later with support for reverse execution. Once you reproduce a bug, you can revisit that execution endlessly.
Cheat sheet:
./mach test --debugger=rr ...
to record a test run of interest.rr ps
to get a list of all the processes that existed during the most recent run.rr replay -p PID
to replay the execution of the given process of interest and launch a gdb instance against it. If you want to debug multiple processes at the same time and have enough system memory), you should use multiple invocations of this command at the same time.- Then use gdb like you normally would.
Remote Debugging of Firefox
Firefox's local debugging APIs can also be accessed remotely. This can be useful for debugging mobile versions of Firefox.
Logging
MOZ_LOG
Improving upon the prior NSPR logging mechanism exposed via NSPR_LOG_MODULES, C++ code can perform conditional logging at a granular per-"module" basis using MOZ_LOG that can be enabled several ways:
- When launching Firefox via the MOZ_LOG environment variable without output going to stdout by default, or a file if MOZ_LOG_FILE is specified.
- ex: MOZ_LOG=IndexedDB:5 enables verbose IndexedDB logging.
- While Firefox is running via the about:networking page.
- Using preferences by modifying the preferences file when Firefox is not running, or at runtime using "about:config".
- An int pref "logging.IndexedDB" with a value of 5 enables verbose IndexedDB logging.
- A string pref "logging.IndexedDB" with a value of "verbose" enables verbose IndexedDB logging. Valid values are "error", "warning", "info", "debug", and "verbose" in order of increasing detail/spamminess.
More info:
- MDN's Gecko Logging page covers how to use the logging mechanism in your code and how to enable it.
- MDN's HTTP Logging page documents the about:networking page that makes it possible to enable and configure
Performance / Validation
Telemetry
Talos Performance Tests
Focused Tracking Sites
Starting with the famous https://arewefastyet.com/ site that tracked and compared JS engine performance, there's been a history of "are we BLANK yet" sites created by teams to focus on specific initiatives. http://arewemetayet.com/ tracks all of these sites including feature-completeness dashboards that conform to the naming scheme. We call out some of these below.