<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.mozilla.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Sfink</id>
	<title>MozillaWiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.mozilla.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Sfink"/>
	<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/Special:Contributions/Sfink"/>
	<updated>2026-07-08T11:27:14Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.39.10</generator>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=Sfink/Moving_GC&amp;diff=1255716</id>
		<title>Sfink/Moving GC</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=Sfink/Moving_GC&amp;diff=1255716"/>
		<updated>2025-11-19T19:57:40Z</updated>

		<summary type="html">&lt;p&gt;Sfink: clarify some small things&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;All garbage collectors (GC) need to know what objects are reachable and therefore need&lt;br /&gt;
to be alive. Tracing GCs require a way to find the exact set of objects that are&lt;br /&gt;
currently reachable. This requires knowing about all pointers into the JS heap&lt;br /&gt;
(&amp;quot;roots&amp;quot;), as well as all pointers within the JS heap (the &amp;quot;heap graph&amp;quot;). GC&lt;br /&gt;
will do a graph traversal starting from the roots and visiting everything&lt;br /&gt;
reachable.&lt;br /&gt;
&lt;br /&gt;
A generational garbage collector (GGC) defines a subset of the JS heap as the&lt;br /&gt;
&amp;quot;nursery&amp;quot;, and allocates most objects out of this nursery in the expectation&lt;br /&gt;
that many of them will die quickly (become unused and unreachable). The&lt;br /&gt;
collector periodically sweeps through the nursery, packing only the live&lt;br /&gt;
objects into another area so that the nursery is empty and available for new&lt;br /&gt;
allocations again. It is important that this nursery sweep (a &amp;quot;minor&lt;br /&gt;
collection&amp;quot;) only needs to look at the *live* objects (plus some bookkeeping&lt;br /&gt;
information), NOT the full heap or even a percentage of it -- you want the&lt;br /&gt;
cost of minor collections to be proportional to only the amount of live data in&lt;br /&gt;
the nursery, and independent of the amount of garbage.&lt;br /&gt;
&lt;br /&gt;
This requires two main capabilities: (1) the ability to move objects around,&lt;br /&gt;
and (2) a record of all external pointers into the nursery.&lt;br /&gt;
&lt;br /&gt;
Incremental garbage collection (IGC) adds an additional requirement: at the&lt;br /&gt;
beginning of an incremental collection, all roots (external pointers) into the&lt;br /&gt;
heap are recorded, then the main program is allowed to continue running but is&lt;br /&gt;
interrupted periodically so the incremental collector can gradually trace the&lt;br /&gt;
whole heap graph. Because the graph can change during the overall duration of this sweep, any&lt;br /&gt;
intra-heap reference that is deleted must be marked (treated as live): such&lt;br /&gt;
referents are usually either dead or reachable from somewhere else, but it&#039;s also possible that the main program&lt;br /&gt;
moved a reference from a part of the heap that has not yet been scanned to a&lt;br /&gt;
part that has already been scanned, and so the referent will not get marked during the&lt;br /&gt;
rest of the incremental collection. This adds a required capability (3): a&lt;br /&gt;
record of all pointers within the heap that were deleted while incremental GC&lt;br /&gt;
was active. (Note: this is actually accomplished by pushing them on the same mark stack used to record the current state of the incremental GC.)&lt;br /&gt;
&lt;br /&gt;
Capability #1 means that we need to be able to find and update all pointers&lt;br /&gt;
from outside the JS heap into the JS heap. (Intra-heap pointers can be found&lt;br /&gt;
and updated by scanning, so they don&#039;t need any special handling.) The embedding uses APIs to register certain data structures as part of the root set, as well as callbacks to record other root pointers during the GC. For pointers on the stack, we use the Stack Rooting API; see js/public/RootingAPI.h.&lt;br /&gt;
&lt;br /&gt;
Capabilities #2 and #3 mean that we need &amp;quot;write barriers&amp;quot; for all JS heap&lt;br /&gt;
pointers stored within the C++ heap, which is a fancy way of saying that if you&lt;br /&gt;
modify a pointer into the heap, you may need to do something before and/or after&lt;br /&gt;
the write to update bookkeeping information. Capability #2 requires a&lt;br /&gt;
&amp;quot;post-write barrier&amp;quot; aka post barrier, an action taken after the write occurs, to store a record of&lt;br /&gt;
any new pointer value that points (or might point) into the nursery. Capability #3&lt;br /&gt;
requires a &amp;quot;pre-write barrier&amp;quot; aka pre barrier, an action taken before the write occurs, so it can&lt;br /&gt;
mark the overwritten value as live (before it is lost from the&lt;br /&gt;
graph). The exact timing isn&#039;t critical; the pre barrier really just needs the old value&lt;br /&gt;
and the post barrier needs the new value, but both could run either before or after the actual&lt;br /&gt;
write (as long as there&#039;s no possibility of a GC in between the barrier and the write!)&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
You can divide memory into 4 partitions: the stack, the non-JS (C++) heap, the&lt;br /&gt;
JS nursery, and the JS tenured area. (Or you could say there&#039;s the stack and&lt;br /&gt;
the heap, and the heap is divided into JS and non-JS parts, and the JS part is&lt;br /&gt;
separated into a nursery and a tenured area, but it&#039;s the pointers between&lt;br /&gt;
these areas that matter so we&#039;ll keep them separate.)&lt;br /&gt;
&lt;br /&gt;
Pointers from the stack to either part of the JS heap must be findable and&lt;br /&gt;
updatable during a moving GC. This is usually accomplished with Rooted&amp;lt;T&amp;gt;,&lt;br /&gt;
Handle&amp;lt;T&amp;gt;, and MutableHandle&amp;lt;T&amp;gt;, though aggregates of various sorts will also&lt;br /&gt;
use Auto*Rooter classes. Pointers from the stack to either the&lt;br /&gt;
stack or the C++ heap don&#039;t matter (such pointers are not pointing to GC things.)&lt;br /&gt;
&lt;br /&gt;
Pointers from the C++ heap to the JS heap must be findable and updatable, and&lt;br /&gt;
writes must be barriered. Pointers from the C++ heap to the C++ heap don&#039;t matter to the GC. Pointers&lt;br /&gt;
from the C++ heap to the stack are kind of funky but don&#039;t matter to the GC.&lt;br /&gt;
&lt;br /&gt;
Pointers from the tenured area to anywhere in the JS heap are automatically&lt;br /&gt;
findable and updatable, since you can scan the JS heap. Writes do need to be&lt;br /&gt;
barriered, in case they change to point to the nursery (for GGC) or move an&lt;br /&gt;
unscanned subgraph into the already-scanned region (for IGC). Pointers from&lt;br /&gt;
tenured to the stack (?!) or the C++ heap don&#039;t matter (again, these aren&#039;t pointing at GC things.)&lt;br /&gt;
&lt;br /&gt;
Pointers from the nursery are the same as those from tenured, except it doesn&#039;t&lt;br /&gt;
matter for GGC if a nursery pointer points to the nursery vs tenured since everything still alive in the nursery will be scanned. So the&lt;br /&gt;
post barrier is not needed. The pre barrier is not needed because incremental GC does a nursery collection when it begins, and anything&lt;br /&gt;
allocated from that point to the end of the GC will always be treated as live.&lt;/div&gt;</summary>
		<author><name>Sfink</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=Javascript:Hazard_Builds&amp;diff=1235338</id>
		<title>Javascript:Hazard Builds</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=Javascript:Hazard_Builds&amp;diff=1235338"/>
		<updated>2021-04-28T18:24:25Z</updated>

		<summary type="html">&lt;p&gt;Sfink: attempt4&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{OutdatedSpiderMonkey|replacement=https://firefox-source-docs.mozilla.org/js/HazardAnalysis/}} &lt;br /&gt;
&lt;br /&gt;
== Static Analysis for Rooting and Heap Write Hazards ==&lt;br /&gt;
&lt;br /&gt;
Treeherder can run two static analysis builds: the full browser (linux64-haz), just the JS shell (linux64-shell-haz). They show up on treeherder as &#039;&#039;&#039;H&#039;&#039;&#039; and &#039;&#039;&#039;SM(H)&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Diagnosing a hazard failure ===&lt;br /&gt;
&lt;br /&gt;
The first step is to look at what sort of hazard is being reported. There are two types that cause the job to fail: stack rooting hazards for garbage collection, and heap write thread safety hazards for stylo.&lt;br /&gt;
&lt;br /&gt;
The summary output will include either the string &amp;quot;&amp;lt;N&amp;gt; rooting hazards detected&amp;quot; or &amp;quot;&amp;lt;N&amp;gt; heap write hazards detected out of &amp;lt;M&amp;gt; allowed&amp;quot;. See the appropriate section below for each.&lt;br /&gt;
&lt;br /&gt;
=== Diagnosing a rooting hazards failure ===&lt;br /&gt;
&lt;br /&gt;
Click on the &#039;&#039;&#039;H&#039;&#039;&#039; build link, select the &amp;quot;Job details&amp;quot; pane on the bottom right, follow the &amp;quot;Inspect Task&amp;quot; link, and download the &amp;quot;&amp;lt;code&amp;gt;public/build/hazards.txt.gz&amp;lt;/code&amp;gt;&amp;quot; file.&lt;br /&gt;
&lt;br /&gt;
Example snippet:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Function &#039;jsopcode.cpp:uint8 DecompileExpressionFromStack(JSContext*, int32, int32, class JS::Handle&amp;lt;JS::Value&amp;gt;, int8**)&#039; has unrooted &#039;ed&#039; of type &#039;ExpressionDecompiler&#039; live across GC call &#039;uint8 ExpressionDecompiler::decompilePC(uint8*)&#039; at js/src/jsopcode.cpp:1866&lt;br /&gt;
    js/src/jsopcode.cpp:1866: Assume(74,75, !__temp_23*, true)&lt;br /&gt;
    js/src/jsopcode.cpp:1867: Assign(75,76, return := 0)&lt;br /&gt;
    js/src/jsopcode.cpp:1867: Call(76,77, ed.~ExpressionDecompiler())&lt;br /&gt;
GC Function: uint8 ExpressionDecompiler::decompilePC(uint8*)&lt;br /&gt;
    JSString* js::ValueToSource(JSContext*, class JS::Handle&amp;lt;JS::Value&amp;gt;)&lt;br /&gt;
    uint8 js::Invoke(JSContext*, JS::Value*, JS::Value*, uint32, JS::Value*, class JS::MutableHandle&amp;lt;JS::Value&amp;gt;)&lt;br /&gt;
    uint8 js::Invoke(JSContext*, JS::CallArgs, uint32)&lt;br /&gt;
    JSScript* JSFunction::getOrCreateScript(JSContext*)&lt;br /&gt;
    uint8 JSFunction::createScriptForLazilyInterpretedFunction(JSContext*, class JS::Handle&amp;lt;JSFunction*&amp;gt;)&lt;br /&gt;
    uint8 JSRuntime::cloneSelfHostedFunctionScript(JSContext*, class JS::Handle&amp;lt;js::PropertyName*&amp;gt;, class JS::Handle&amp;lt;JSFunction*&amp;gt;)&lt;br /&gt;
    JSScript* js::CloneScript(JSContext*, class JS::Handle&amp;lt;JSObject*&amp;gt;, class JS::Handle&amp;lt;JSFunction*&amp;gt;, const class JS::Handle&amp;lt;JSScript*&amp;gt;, uint32)&lt;br /&gt;
    JSObject* js::CloneStaticBlockObject(JSContext*, class JS::Handle&amp;lt;JSObject*&amp;gt;, class JS::Handle&amp;lt;js::StaticBlockObject*&amp;gt;)&lt;br /&gt;
    js::StaticBlockObject* js::StaticBlockObject::create(js::ExclusiveContext*)&lt;br /&gt;
    js::Shape* js::EmptyShape::getInitialShape(js::ExclusiveContext*, js::Class*, js::TaggedProto, JSObject*, JSObject*, uint32, uint32)&lt;br /&gt;
    js::Shape* js::EmptyShape::getInitialShape(js::ExclusiveContext*, js::Class*, js::TaggedProto, JSObject*, JSObject*, uint64, uint32)&lt;br /&gt;
    js::UnownedBaseShape* js::BaseShape::getUnowned(js::ExclusiveContext*, js::StackBaseShape*)&lt;br /&gt;
    js::BaseShape* js_NewGCBaseShape(js::ThreadSafeContext*) [with js::AllowGC allowGC = (js::AllowGC)1u]&lt;br /&gt;
    js::BaseShape* js::gc::NewGCThing(js::ThreadSafeContext*, uint32, uint64, uint32) [with T = js::BaseShape; js::AllowGC allowGC = (js::AllowGC)1u; size_t = long unsigned int]&lt;br /&gt;
    void js::gc::RunDebugGC(JSContext*)&lt;br /&gt;
    void js::MinorGC(JSRuntime*, uint32)&lt;br /&gt;
    GC&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This means that a rooting hazard was discovered at &amp;lt;code&amp;gt;js/src/jsopcode.cpp&amp;lt;/code&amp;gt; line 1866, in the function &amp;lt;code&amp;gt;DecompileExpressionFromStack&amp;lt;/code&amp;gt; (it is prefixed with the filename because it&#039;s a static function.) The problem is that they&#039;re an unrooted variable &#039;&amp;lt;code&amp;gt;ed&amp;lt;/code&amp;gt;&#039; that holds an &amp;lt;code&amp;gt;ExpressionDecompiler&amp;lt;/code&amp;gt; live across a call to &amp;lt;code&amp;gt;decompilePC&amp;lt;/code&amp;gt;. &amp;quot;Live&amp;quot; means that the variable is used after the call to &amp;lt;code&amp;gt;decompilePC&amp;lt;/code&amp;gt; returns. &amp;lt;code&amp;gt;decompilePC&amp;lt;/code&amp;gt; may trigger a GC according to the static call stack given starting from the line beginning with &amp;quot;GC Function:&amp;quot;. The hazard itself has some barely comprehensible Assume(...) and Call(...) gibberish that describes the exact path of the variable into the function call. That stuff is rarely useful -- usually, you&#039;ll only need to look at it if it&#039;s complaining about a temporary and you want to know where the temporary came from. The type &#039;&amp;lt;code&amp;gt;ExpressionDecompiler&amp;lt;/code&amp;gt;&#039; is believed to hold pointers to GC-controlled objects of some sort. The analysis currently does not describe the exact field it is worried about.&lt;br /&gt;
&lt;br /&gt;
To unpack this a little, the analysis is saying the following can happen:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;ExpressionDecompiler&amp;lt;/code&amp;gt; contains some pointer to a GC thing. For example, it might have a field &#039;&amp;lt;code&amp;gt;obj&amp;lt;/code&amp;gt;&#039; of type &#039;&amp;lt;code&amp;gt;JSObject*&amp;lt;/code&amp;gt;&#039;.&lt;br /&gt;
* &amp;lt;code&amp;gt;DecompileExpressionFromStack&amp;lt;/code&amp;gt; is called.&lt;br /&gt;
* A pointer is stored in that field of the &#039;&amp;lt;code&amp;gt;ed&amp;lt;/code&amp;gt;&#039; variable.&lt;br /&gt;
* &amp;lt;code&amp;gt;decompilePC&amp;lt;/code&amp;gt; is invoked, which calls &amp;lt;code&amp;gt;ValueToSource&amp;lt;/code&amp;gt;, which calls &amp;lt;code&amp;gt;Invoke&amp;lt;/code&amp;gt;, which eventually calls &amp;lt;code&amp;gt;js::MinorGC&amp;lt;/code&amp;gt;&lt;br /&gt;
* during the resulting garbage collection, the object pointed to by &amp;lt;code&amp;gt;ed.obj&amp;lt;/code&amp;gt; is moved to a different location. All pointers stored in the JS heap are updated automatically, as are all rooted pointers. &amp;lt;code&amp;gt;ed.obj&amp;lt;/code&amp;gt; is not, because the GC doesn&#039;t know about it.&lt;br /&gt;
* after &amp;lt;code&amp;gt;decompilePC&amp;lt;/code&amp;gt; returns, something accesses &amp;lt;code&amp;gt;ed.obj&amp;lt;/code&amp;gt;. This is now a stale pointer, and may refer to just about anything -- the wrong object, an invalid object, or whatever. Badness 10000, as TeX would say.&lt;br /&gt;
&lt;br /&gt;
=== Diagnosing a heap write hazard failure ===&lt;br /&gt;
&lt;br /&gt;
For the thread unsafe heap write analysis, a hazard means that some Gecko_* function calls, directly or indirectly, code that writes to something on the heap, or calls an unknown function that *might* write to something on the heap. The analysis requires quite a few annotations to describe things that are actually safe. This section will be expanded as we gain more experience with the analysis, but here are some common issues:&lt;br /&gt;
&lt;br /&gt;
* Adding a new Gecko_* function: often, you will need to annotate any outparams or owned (thread-local) parameters in the &amp;lt;code&amp;gt;treatAsSafeArgument&amp;lt;/code&amp;gt; function in &amp;lt;code&amp;gt;js/src/devtools/rootAnalysis/analyzeHeapWrites.js&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Calling some libc function: if you add a call to some random libc function (eg sin() or floor() or ceil(), though the latter two are already annotated), the analysis will report an &amp;quot;External Function&amp;quot;. Add it to &amp;lt;code&amp;gt;checkExternalFunction&amp;lt;/code&amp;gt;, assuming it *doesn&#039;t* have the possibility of writing to shared heap memory.&lt;br /&gt;
* If you call some non-returning (crashing) function that the analysis doesn&#039;t know about, you&#039;ll need to add it to &amp;lt;code&amp;gt;ignoreContents&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
On the other hand, you might have a real thread safety issue on your hands. Shared caches are common problems. Fix it.&lt;br /&gt;
&lt;br /&gt;
=== Analysis implementation ===&lt;br /&gt;
&lt;br /&gt;
These builds are performed as follows:&lt;br /&gt;
&lt;br /&gt;
* run the script testing/taskcluster/scripts/builder/build-haz-linux.sh, which sets up a build environment and runs the analysis within it, then uploads the resulting files&lt;br /&gt;
** compile an optimized JS shell to later run the analysis&lt;br /&gt;
** compile the browser with gcc, using a slightly modified version of the sixgill (http://svn.sixgill.org) gcc plugin, producing a set of .xdb files describing everything encountered during the compilation&lt;br /&gt;
** analyze the .xdb files with scripts in js/src/devtools/rootAnalysis&lt;br /&gt;
&lt;br /&gt;
=== Running the analysis ===&lt;br /&gt;
&lt;br /&gt;
==== Pushing to try ====&lt;br /&gt;
&lt;br /&gt;
The easiest way to run an analysis is to push to try with the trychooser line |try: -b do -p linux64-haz| (or, if the hazards of interest are contained entirely within js/src, use |try: -b do -p linux64-shell-haz| for a much faster result). The expected turnaround time for linux64-haz is just under 2 hours.&lt;br /&gt;
&lt;br /&gt;
The output will be uploaded and a link named &amp;quot;results&amp;quot; will be placed into the &amp;quot;job details&amp;quot; info pane on treeherder. If the analysis fails, you will see the number of failures. Navigate to the hazards.txt.gz file.&lt;br /&gt;
&lt;br /&gt;
==== Running locally ====&lt;br /&gt;
&lt;br /&gt;
To run the browser analysis, you must be on a Fedora/RedHat/CentOS linux64 machine. See js/src/devtools/rootAnalysis/README.md.&lt;br /&gt;
&lt;br /&gt;
If you are running Debian or Ubuntu, then there is currently a problem running the full browser analysis. You can coerce the shell-only build to work by doing something like:&lt;br /&gt;
&lt;br /&gt;
  sudo apt-get install autoconf2.13 libnspr4 libnspr4-dev&lt;br /&gt;
  sudo ln -s autoconf2.13 /usr/bin/autoconf-2.13&lt;br /&gt;
  export CFLAGS=&amp;quot;-B/usr/lib/x86_64-linux-gnu -I/usr/include/x86_64-linux-gnu&amp;quot;&lt;br /&gt;
  export CXXFLAGS=&amp;quot;-B/usr/lib/x86_64-linux-gnu -I/usr/include/x86_64-linux-gnu&amp;quot;&lt;br /&gt;
&lt;br /&gt;
before running the script.&lt;br /&gt;
&lt;br /&gt;
=== So you broke the analysis by adding a hazard. Now what? ===&lt;br /&gt;
&lt;br /&gt;
Backout, fix the hazard, or (final resort) update the expected number of hazards in js/src/devtools/rootAnalysis/expect.browser.json (but don&#039;t do that).&lt;br /&gt;
&lt;br /&gt;
The most common way to fix a hazard is to change the variable to be a Rooted type, as described in http://dxr.mozilla.org/mozilla-central/source/js/public/RootingAPI.h#l21&lt;br /&gt;
&lt;br /&gt;
For more complicated cases, ask on #jsapi. If you don&#039;t get a response, ping sfink or jonco for rooting hazards, bholley or sfink for heap write hazards. Or if it&#039;s a deeper issue with the analysis logic, try bhackett (the author of both analyses.)&lt;/div&gt;</summary>
		<author><name>Sfink</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=Javascript:Hazard_Builds&amp;diff=1235337</id>
		<title>Javascript:Hazard Builds</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=Javascript:Hazard_Builds&amp;diff=1235337"/>
		<updated>2021-04-28T18:23:51Z</updated>

		<summary type="html">&lt;p&gt;Sfink: attempt3&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{OutdatedSpiderMonkey|replacement=[https://firefox-source-docs.mozilla.org/js/HazardAnalysis/|https://firefox-source-docs.mozilla.org/js/HazardAnalysis/]}} &lt;br /&gt;
&lt;br /&gt;
== Static Analysis for Rooting and Heap Write Hazards ==&lt;br /&gt;
&lt;br /&gt;
Treeherder can run two static analysis builds: the full browser (linux64-haz), just the JS shell (linux64-shell-haz). They show up on treeherder as &#039;&#039;&#039;H&#039;&#039;&#039; and &#039;&#039;&#039;SM(H)&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Diagnosing a hazard failure ===&lt;br /&gt;
&lt;br /&gt;
The first step is to look at what sort of hazard is being reported. There are two types that cause the job to fail: stack rooting hazards for garbage collection, and heap write thread safety hazards for stylo.&lt;br /&gt;
&lt;br /&gt;
The summary output will include either the string &amp;quot;&amp;lt;N&amp;gt; rooting hazards detected&amp;quot; or &amp;quot;&amp;lt;N&amp;gt; heap write hazards detected out of &amp;lt;M&amp;gt; allowed&amp;quot;. See the appropriate section below for each.&lt;br /&gt;
&lt;br /&gt;
=== Diagnosing a rooting hazards failure ===&lt;br /&gt;
&lt;br /&gt;
Click on the &#039;&#039;&#039;H&#039;&#039;&#039; build link, select the &amp;quot;Job details&amp;quot; pane on the bottom right, follow the &amp;quot;Inspect Task&amp;quot; link, and download the &amp;quot;&amp;lt;code&amp;gt;public/build/hazards.txt.gz&amp;lt;/code&amp;gt;&amp;quot; file.&lt;br /&gt;
&lt;br /&gt;
Example snippet:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Function &#039;jsopcode.cpp:uint8 DecompileExpressionFromStack(JSContext*, int32, int32, class JS::Handle&amp;lt;JS::Value&amp;gt;, int8**)&#039; has unrooted &#039;ed&#039; of type &#039;ExpressionDecompiler&#039; live across GC call &#039;uint8 ExpressionDecompiler::decompilePC(uint8*)&#039; at js/src/jsopcode.cpp:1866&lt;br /&gt;
    js/src/jsopcode.cpp:1866: Assume(74,75, !__temp_23*, true)&lt;br /&gt;
    js/src/jsopcode.cpp:1867: Assign(75,76, return := 0)&lt;br /&gt;
    js/src/jsopcode.cpp:1867: Call(76,77, ed.~ExpressionDecompiler())&lt;br /&gt;
GC Function: uint8 ExpressionDecompiler::decompilePC(uint8*)&lt;br /&gt;
    JSString* js::ValueToSource(JSContext*, class JS::Handle&amp;lt;JS::Value&amp;gt;)&lt;br /&gt;
    uint8 js::Invoke(JSContext*, JS::Value*, JS::Value*, uint32, JS::Value*, class JS::MutableHandle&amp;lt;JS::Value&amp;gt;)&lt;br /&gt;
    uint8 js::Invoke(JSContext*, JS::CallArgs, uint32)&lt;br /&gt;
    JSScript* JSFunction::getOrCreateScript(JSContext*)&lt;br /&gt;
    uint8 JSFunction::createScriptForLazilyInterpretedFunction(JSContext*, class JS::Handle&amp;lt;JSFunction*&amp;gt;)&lt;br /&gt;
    uint8 JSRuntime::cloneSelfHostedFunctionScript(JSContext*, class JS::Handle&amp;lt;js::PropertyName*&amp;gt;, class JS::Handle&amp;lt;JSFunction*&amp;gt;)&lt;br /&gt;
    JSScript* js::CloneScript(JSContext*, class JS::Handle&amp;lt;JSObject*&amp;gt;, class JS::Handle&amp;lt;JSFunction*&amp;gt;, const class JS::Handle&amp;lt;JSScript*&amp;gt;, uint32)&lt;br /&gt;
    JSObject* js::CloneStaticBlockObject(JSContext*, class JS::Handle&amp;lt;JSObject*&amp;gt;, class JS::Handle&amp;lt;js::StaticBlockObject*&amp;gt;)&lt;br /&gt;
    js::StaticBlockObject* js::StaticBlockObject::create(js::ExclusiveContext*)&lt;br /&gt;
    js::Shape* js::EmptyShape::getInitialShape(js::ExclusiveContext*, js::Class*, js::TaggedProto, JSObject*, JSObject*, uint32, uint32)&lt;br /&gt;
    js::Shape* js::EmptyShape::getInitialShape(js::ExclusiveContext*, js::Class*, js::TaggedProto, JSObject*, JSObject*, uint64, uint32)&lt;br /&gt;
    js::UnownedBaseShape* js::BaseShape::getUnowned(js::ExclusiveContext*, js::StackBaseShape*)&lt;br /&gt;
    js::BaseShape* js_NewGCBaseShape(js::ThreadSafeContext*) [with js::AllowGC allowGC = (js::AllowGC)1u]&lt;br /&gt;
    js::BaseShape* js::gc::NewGCThing(js::ThreadSafeContext*, uint32, uint64, uint32) [with T = js::BaseShape; js::AllowGC allowGC = (js::AllowGC)1u; size_t = long unsigned int]&lt;br /&gt;
    void js::gc::RunDebugGC(JSContext*)&lt;br /&gt;
    void js::MinorGC(JSRuntime*, uint32)&lt;br /&gt;
    GC&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This means that a rooting hazard was discovered at &amp;lt;code&amp;gt;js/src/jsopcode.cpp&amp;lt;/code&amp;gt; line 1866, in the function &amp;lt;code&amp;gt;DecompileExpressionFromStack&amp;lt;/code&amp;gt; (it is prefixed with the filename because it&#039;s a static function.) The problem is that they&#039;re an unrooted variable &#039;&amp;lt;code&amp;gt;ed&amp;lt;/code&amp;gt;&#039; that holds an &amp;lt;code&amp;gt;ExpressionDecompiler&amp;lt;/code&amp;gt; live across a call to &amp;lt;code&amp;gt;decompilePC&amp;lt;/code&amp;gt;. &amp;quot;Live&amp;quot; means that the variable is used after the call to &amp;lt;code&amp;gt;decompilePC&amp;lt;/code&amp;gt; returns. &amp;lt;code&amp;gt;decompilePC&amp;lt;/code&amp;gt; may trigger a GC according to the static call stack given starting from the line beginning with &amp;quot;GC Function:&amp;quot;. The hazard itself has some barely comprehensible Assume(...) and Call(...) gibberish that describes the exact path of the variable into the function call. That stuff is rarely useful -- usually, you&#039;ll only need to look at it if it&#039;s complaining about a temporary and you want to know where the temporary came from. The type &#039;&amp;lt;code&amp;gt;ExpressionDecompiler&amp;lt;/code&amp;gt;&#039; is believed to hold pointers to GC-controlled objects of some sort. The analysis currently does not describe the exact field it is worried about.&lt;br /&gt;
&lt;br /&gt;
To unpack this a little, the analysis is saying the following can happen:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;ExpressionDecompiler&amp;lt;/code&amp;gt; contains some pointer to a GC thing. For example, it might have a field &#039;&amp;lt;code&amp;gt;obj&amp;lt;/code&amp;gt;&#039; of type &#039;&amp;lt;code&amp;gt;JSObject*&amp;lt;/code&amp;gt;&#039;.&lt;br /&gt;
* &amp;lt;code&amp;gt;DecompileExpressionFromStack&amp;lt;/code&amp;gt; is called.&lt;br /&gt;
* A pointer is stored in that field of the &#039;&amp;lt;code&amp;gt;ed&amp;lt;/code&amp;gt;&#039; variable.&lt;br /&gt;
* &amp;lt;code&amp;gt;decompilePC&amp;lt;/code&amp;gt; is invoked, which calls &amp;lt;code&amp;gt;ValueToSource&amp;lt;/code&amp;gt;, which calls &amp;lt;code&amp;gt;Invoke&amp;lt;/code&amp;gt;, which eventually calls &amp;lt;code&amp;gt;js::MinorGC&amp;lt;/code&amp;gt;&lt;br /&gt;
* during the resulting garbage collection, the object pointed to by &amp;lt;code&amp;gt;ed.obj&amp;lt;/code&amp;gt; is moved to a different location. All pointers stored in the JS heap are updated automatically, as are all rooted pointers. &amp;lt;code&amp;gt;ed.obj&amp;lt;/code&amp;gt; is not, because the GC doesn&#039;t know about it.&lt;br /&gt;
* after &amp;lt;code&amp;gt;decompilePC&amp;lt;/code&amp;gt; returns, something accesses &amp;lt;code&amp;gt;ed.obj&amp;lt;/code&amp;gt;. This is now a stale pointer, and may refer to just about anything -- the wrong object, an invalid object, or whatever. Badness 10000, as TeX would say.&lt;br /&gt;
&lt;br /&gt;
=== Diagnosing a heap write hazard failure ===&lt;br /&gt;
&lt;br /&gt;
For the thread unsafe heap write analysis, a hazard means that some Gecko_* function calls, directly or indirectly, code that writes to something on the heap, or calls an unknown function that *might* write to something on the heap. The analysis requires quite a few annotations to describe things that are actually safe. This section will be expanded as we gain more experience with the analysis, but here are some common issues:&lt;br /&gt;
&lt;br /&gt;
* Adding a new Gecko_* function: often, you will need to annotate any outparams or owned (thread-local) parameters in the &amp;lt;code&amp;gt;treatAsSafeArgument&amp;lt;/code&amp;gt; function in &amp;lt;code&amp;gt;js/src/devtools/rootAnalysis/analyzeHeapWrites.js&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Calling some libc function: if you add a call to some random libc function (eg sin() or floor() or ceil(), though the latter two are already annotated), the analysis will report an &amp;quot;External Function&amp;quot;. Add it to &amp;lt;code&amp;gt;checkExternalFunction&amp;lt;/code&amp;gt;, assuming it *doesn&#039;t* have the possibility of writing to shared heap memory.&lt;br /&gt;
* If you call some non-returning (crashing) function that the analysis doesn&#039;t know about, you&#039;ll need to add it to &amp;lt;code&amp;gt;ignoreContents&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
On the other hand, you might have a real thread safety issue on your hands. Shared caches are common problems. Fix it.&lt;br /&gt;
&lt;br /&gt;
=== Analysis implementation ===&lt;br /&gt;
&lt;br /&gt;
These builds are performed as follows:&lt;br /&gt;
&lt;br /&gt;
* run the script testing/taskcluster/scripts/builder/build-haz-linux.sh, which sets up a build environment and runs the analysis within it, then uploads the resulting files&lt;br /&gt;
** compile an optimized JS shell to later run the analysis&lt;br /&gt;
** compile the browser with gcc, using a slightly modified version of the sixgill (http://svn.sixgill.org) gcc plugin, producing a set of .xdb files describing everything encountered during the compilation&lt;br /&gt;
** analyze the .xdb files with scripts in js/src/devtools/rootAnalysis&lt;br /&gt;
&lt;br /&gt;
=== Running the analysis ===&lt;br /&gt;
&lt;br /&gt;
==== Pushing to try ====&lt;br /&gt;
&lt;br /&gt;
The easiest way to run an analysis is to push to try with the trychooser line |try: -b do -p linux64-haz| (or, if the hazards of interest are contained entirely within js/src, use |try: -b do -p linux64-shell-haz| for a much faster result). The expected turnaround time for linux64-haz is just under 2 hours.&lt;br /&gt;
&lt;br /&gt;
The output will be uploaded and a link named &amp;quot;results&amp;quot; will be placed into the &amp;quot;job details&amp;quot; info pane on treeherder. If the analysis fails, you will see the number of failures. Navigate to the hazards.txt.gz file.&lt;br /&gt;
&lt;br /&gt;
==== Running locally ====&lt;br /&gt;
&lt;br /&gt;
To run the browser analysis, you must be on a Fedora/RedHat/CentOS linux64 machine. See js/src/devtools/rootAnalysis/README.md.&lt;br /&gt;
&lt;br /&gt;
If you are running Debian or Ubuntu, then there is currently a problem running the full browser analysis. You can coerce the shell-only build to work by doing something like:&lt;br /&gt;
&lt;br /&gt;
  sudo apt-get install autoconf2.13 libnspr4 libnspr4-dev&lt;br /&gt;
  sudo ln -s autoconf2.13 /usr/bin/autoconf-2.13&lt;br /&gt;
  export CFLAGS=&amp;quot;-B/usr/lib/x86_64-linux-gnu -I/usr/include/x86_64-linux-gnu&amp;quot;&lt;br /&gt;
  export CXXFLAGS=&amp;quot;-B/usr/lib/x86_64-linux-gnu -I/usr/include/x86_64-linux-gnu&amp;quot;&lt;br /&gt;
&lt;br /&gt;
before running the script.&lt;br /&gt;
&lt;br /&gt;
=== So you broke the analysis by adding a hazard. Now what? ===&lt;br /&gt;
&lt;br /&gt;
Backout, fix the hazard, or (final resort) update the expected number of hazards in js/src/devtools/rootAnalysis/expect.browser.json (but don&#039;t do that).&lt;br /&gt;
&lt;br /&gt;
The most common way to fix a hazard is to change the variable to be a Rooted type, as described in http://dxr.mozilla.org/mozilla-central/source/js/public/RootingAPI.h#l21&lt;br /&gt;
&lt;br /&gt;
For more complicated cases, ask on #jsapi. If you don&#039;t get a response, ping sfink or jonco for rooting hazards, bholley or sfink for heap write hazards. Or if it&#039;s a deeper issue with the analysis logic, try bhackett (the author of both analyses.)&lt;/div&gt;</summary>
		<author><name>Sfink</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=Javascript:Hazard_Builds&amp;diff=1235336</id>
		<title>Javascript:Hazard Builds</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=Javascript:Hazard_Builds&amp;diff=1235336"/>
		<updated>2021-04-28T18:23:09Z</updated>

		<summary type="html">&lt;p&gt;Sfink: attempt2&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{OutdatedSpiderMonkey|replacement=[https://firefox-source-docs.mozilla.org/js/HazardAnalysis/|]}} &lt;br /&gt;
&lt;br /&gt;
== Static Analysis for Rooting and Heap Write Hazards ==&lt;br /&gt;
&lt;br /&gt;
Treeherder can run two static analysis builds: the full browser (linux64-haz), just the JS shell (linux64-shell-haz). They show up on treeherder as &#039;&#039;&#039;H&#039;&#039;&#039; and &#039;&#039;&#039;SM(H)&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Diagnosing a hazard failure ===&lt;br /&gt;
&lt;br /&gt;
The first step is to look at what sort of hazard is being reported. There are two types that cause the job to fail: stack rooting hazards for garbage collection, and heap write thread safety hazards for stylo.&lt;br /&gt;
&lt;br /&gt;
The summary output will include either the string &amp;quot;&amp;lt;N&amp;gt; rooting hazards detected&amp;quot; or &amp;quot;&amp;lt;N&amp;gt; heap write hazards detected out of &amp;lt;M&amp;gt; allowed&amp;quot;. See the appropriate section below for each.&lt;br /&gt;
&lt;br /&gt;
=== Diagnosing a rooting hazards failure ===&lt;br /&gt;
&lt;br /&gt;
Click on the &#039;&#039;&#039;H&#039;&#039;&#039; build link, select the &amp;quot;Job details&amp;quot; pane on the bottom right, follow the &amp;quot;Inspect Task&amp;quot; link, and download the &amp;quot;&amp;lt;code&amp;gt;public/build/hazards.txt.gz&amp;lt;/code&amp;gt;&amp;quot; file.&lt;br /&gt;
&lt;br /&gt;
Example snippet:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Function &#039;jsopcode.cpp:uint8 DecompileExpressionFromStack(JSContext*, int32, int32, class JS::Handle&amp;lt;JS::Value&amp;gt;, int8**)&#039; has unrooted &#039;ed&#039; of type &#039;ExpressionDecompiler&#039; live across GC call &#039;uint8 ExpressionDecompiler::decompilePC(uint8*)&#039; at js/src/jsopcode.cpp:1866&lt;br /&gt;
    js/src/jsopcode.cpp:1866: Assume(74,75, !__temp_23*, true)&lt;br /&gt;
    js/src/jsopcode.cpp:1867: Assign(75,76, return := 0)&lt;br /&gt;
    js/src/jsopcode.cpp:1867: Call(76,77, ed.~ExpressionDecompiler())&lt;br /&gt;
GC Function: uint8 ExpressionDecompiler::decompilePC(uint8*)&lt;br /&gt;
    JSString* js::ValueToSource(JSContext*, class JS::Handle&amp;lt;JS::Value&amp;gt;)&lt;br /&gt;
    uint8 js::Invoke(JSContext*, JS::Value*, JS::Value*, uint32, JS::Value*, class JS::MutableHandle&amp;lt;JS::Value&amp;gt;)&lt;br /&gt;
    uint8 js::Invoke(JSContext*, JS::CallArgs, uint32)&lt;br /&gt;
    JSScript* JSFunction::getOrCreateScript(JSContext*)&lt;br /&gt;
    uint8 JSFunction::createScriptForLazilyInterpretedFunction(JSContext*, class JS::Handle&amp;lt;JSFunction*&amp;gt;)&lt;br /&gt;
    uint8 JSRuntime::cloneSelfHostedFunctionScript(JSContext*, class JS::Handle&amp;lt;js::PropertyName*&amp;gt;, class JS::Handle&amp;lt;JSFunction*&amp;gt;)&lt;br /&gt;
    JSScript* js::CloneScript(JSContext*, class JS::Handle&amp;lt;JSObject*&amp;gt;, class JS::Handle&amp;lt;JSFunction*&amp;gt;, const class JS::Handle&amp;lt;JSScript*&amp;gt;, uint32)&lt;br /&gt;
    JSObject* js::CloneStaticBlockObject(JSContext*, class JS::Handle&amp;lt;JSObject*&amp;gt;, class JS::Handle&amp;lt;js::StaticBlockObject*&amp;gt;)&lt;br /&gt;
    js::StaticBlockObject* js::StaticBlockObject::create(js::ExclusiveContext*)&lt;br /&gt;
    js::Shape* js::EmptyShape::getInitialShape(js::ExclusiveContext*, js::Class*, js::TaggedProto, JSObject*, JSObject*, uint32, uint32)&lt;br /&gt;
    js::Shape* js::EmptyShape::getInitialShape(js::ExclusiveContext*, js::Class*, js::TaggedProto, JSObject*, JSObject*, uint64, uint32)&lt;br /&gt;
    js::UnownedBaseShape* js::BaseShape::getUnowned(js::ExclusiveContext*, js::StackBaseShape*)&lt;br /&gt;
    js::BaseShape* js_NewGCBaseShape(js::ThreadSafeContext*) [with js::AllowGC allowGC = (js::AllowGC)1u]&lt;br /&gt;
    js::BaseShape* js::gc::NewGCThing(js::ThreadSafeContext*, uint32, uint64, uint32) [with T = js::BaseShape; js::AllowGC allowGC = (js::AllowGC)1u; size_t = long unsigned int]&lt;br /&gt;
    void js::gc::RunDebugGC(JSContext*)&lt;br /&gt;
    void js::MinorGC(JSRuntime*, uint32)&lt;br /&gt;
    GC&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This means that a rooting hazard was discovered at &amp;lt;code&amp;gt;js/src/jsopcode.cpp&amp;lt;/code&amp;gt; line 1866, in the function &amp;lt;code&amp;gt;DecompileExpressionFromStack&amp;lt;/code&amp;gt; (it is prefixed with the filename because it&#039;s a static function.) The problem is that they&#039;re an unrooted variable &#039;&amp;lt;code&amp;gt;ed&amp;lt;/code&amp;gt;&#039; that holds an &amp;lt;code&amp;gt;ExpressionDecompiler&amp;lt;/code&amp;gt; live across a call to &amp;lt;code&amp;gt;decompilePC&amp;lt;/code&amp;gt;. &amp;quot;Live&amp;quot; means that the variable is used after the call to &amp;lt;code&amp;gt;decompilePC&amp;lt;/code&amp;gt; returns. &amp;lt;code&amp;gt;decompilePC&amp;lt;/code&amp;gt; may trigger a GC according to the static call stack given starting from the line beginning with &amp;quot;GC Function:&amp;quot;. The hazard itself has some barely comprehensible Assume(...) and Call(...) gibberish that describes the exact path of the variable into the function call. That stuff is rarely useful -- usually, you&#039;ll only need to look at it if it&#039;s complaining about a temporary and you want to know where the temporary came from. The type &#039;&amp;lt;code&amp;gt;ExpressionDecompiler&amp;lt;/code&amp;gt;&#039; is believed to hold pointers to GC-controlled objects of some sort. The analysis currently does not describe the exact field it is worried about.&lt;br /&gt;
&lt;br /&gt;
To unpack this a little, the analysis is saying the following can happen:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;ExpressionDecompiler&amp;lt;/code&amp;gt; contains some pointer to a GC thing. For example, it might have a field &#039;&amp;lt;code&amp;gt;obj&amp;lt;/code&amp;gt;&#039; of type &#039;&amp;lt;code&amp;gt;JSObject*&amp;lt;/code&amp;gt;&#039;.&lt;br /&gt;
* &amp;lt;code&amp;gt;DecompileExpressionFromStack&amp;lt;/code&amp;gt; is called.&lt;br /&gt;
* A pointer is stored in that field of the &#039;&amp;lt;code&amp;gt;ed&amp;lt;/code&amp;gt;&#039; variable.&lt;br /&gt;
* &amp;lt;code&amp;gt;decompilePC&amp;lt;/code&amp;gt; is invoked, which calls &amp;lt;code&amp;gt;ValueToSource&amp;lt;/code&amp;gt;, which calls &amp;lt;code&amp;gt;Invoke&amp;lt;/code&amp;gt;, which eventually calls &amp;lt;code&amp;gt;js::MinorGC&amp;lt;/code&amp;gt;&lt;br /&gt;
* during the resulting garbage collection, the object pointed to by &amp;lt;code&amp;gt;ed.obj&amp;lt;/code&amp;gt; is moved to a different location. All pointers stored in the JS heap are updated automatically, as are all rooted pointers. &amp;lt;code&amp;gt;ed.obj&amp;lt;/code&amp;gt; is not, because the GC doesn&#039;t know about it.&lt;br /&gt;
* after &amp;lt;code&amp;gt;decompilePC&amp;lt;/code&amp;gt; returns, something accesses &amp;lt;code&amp;gt;ed.obj&amp;lt;/code&amp;gt;. This is now a stale pointer, and may refer to just about anything -- the wrong object, an invalid object, or whatever. Badness 10000, as TeX would say.&lt;br /&gt;
&lt;br /&gt;
=== Diagnosing a heap write hazard failure ===&lt;br /&gt;
&lt;br /&gt;
For the thread unsafe heap write analysis, a hazard means that some Gecko_* function calls, directly or indirectly, code that writes to something on the heap, or calls an unknown function that *might* write to something on the heap. The analysis requires quite a few annotations to describe things that are actually safe. This section will be expanded as we gain more experience with the analysis, but here are some common issues:&lt;br /&gt;
&lt;br /&gt;
* Adding a new Gecko_* function: often, you will need to annotate any outparams or owned (thread-local) parameters in the &amp;lt;code&amp;gt;treatAsSafeArgument&amp;lt;/code&amp;gt; function in &amp;lt;code&amp;gt;js/src/devtools/rootAnalysis/analyzeHeapWrites.js&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Calling some libc function: if you add a call to some random libc function (eg sin() or floor() or ceil(), though the latter two are already annotated), the analysis will report an &amp;quot;External Function&amp;quot;. Add it to &amp;lt;code&amp;gt;checkExternalFunction&amp;lt;/code&amp;gt;, assuming it *doesn&#039;t* have the possibility of writing to shared heap memory.&lt;br /&gt;
* If you call some non-returning (crashing) function that the analysis doesn&#039;t know about, you&#039;ll need to add it to &amp;lt;code&amp;gt;ignoreContents&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
On the other hand, you might have a real thread safety issue on your hands. Shared caches are common problems. Fix it.&lt;br /&gt;
&lt;br /&gt;
=== Analysis implementation ===&lt;br /&gt;
&lt;br /&gt;
These builds are performed as follows:&lt;br /&gt;
&lt;br /&gt;
* run the script testing/taskcluster/scripts/builder/build-haz-linux.sh, which sets up a build environment and runs the analysis within it, then uploads the resulting files&lt;br /&gt;
** compile an optimized JS shell to later run the analysis&lt;br /&gt;
** compile the browser with gcc, using a slightly modified version of the sixgill (http://svn.sixgill.org) gcc plugin, producing a set of .xdb files describing everything encountered during the compilation&lt;br /&gt;
** analyze the .xdb files with scripts in js/src/devtools/rootAnalysis&lt;br /&gt;
&lt;br /&gt;
=== Running the analysis ===&lt;br /&gt;
&lt;br /&gt;
==== Pushing to try ====&lt;br /&gt;
&lt;br /&gt;
The easiest way to run an analysis is to push to try with the trychooser line |try: -b do -p linux64-haz| (or, if the hazards of interest are contained entirely within js/src, use |try: -b do -p linux64-shell-haz| for a much faster result). The expected turnaround time for linux64-haz is just under 2 hours.&lt;br /&gt;
&lt;br /&gt;
The output will be uploaded and a link named &amp;quot;results&amp;quot; will be placed into the &amp;quot;job details&amp;quot; info pane on treeherder. If the analysis fails, you will see the number of failures. Navigate to the hazards.txt.gz file.&lt;br /&gt;
&lt;br /&gt;
==== Running locally ====&lt;br /&gt;
&lt;br /&gt;
To run the browser analysis, you must be on a Fedora/RedHat/CentOS linux64 machine. See js/src/devtools/rootAnalysis/README.md.&lt;br /&gt;
&lt;br /&gt;
If you are running Debian or Ubuntu, then there is currently a problem running the full browser analysis. You can coerce the shell-only build to work by doing something like:&lt;br /&gt;
&lt;br /&gt;
  sudo apt-get install autoconf2.13 libnspr4 libnspr4-dev&lt;br /&gt;
  sudo ln -s autoconf2.13 /usr/bin/autoconf-2.13&lt;br /&gt;
  export CFLAGS=&amp;quot;-B/usr/lib/x86_64-linux-gnu -I/usr/include/x86_64-linux-gnu&amp;quot;&lt;br /&gt;
  export CXXFLAGS=&amp;quot;-B/usr/lib/x86_64-linux-gnu -I/usr/include/x86_64-linux-gnu&amp;quot;&lt;br /&gt;
&lt;br /&gt;
before running the script.&lt;br /&gt;
&lt;br /&gt;
=== So you broke the analysis by adding a hazard. Now what? ===&lt;br /&gt;
&lt;br /&gt;
Backout, fix the hazard, or (final resort) update the expected number of hazards in js/src/devtools/rootAnalysis/expect.browser.json (but don&#039;t do that).&lt;br /&gt;
&lt;br /&gt;
The most common way to fix a hazard is to change the variable to be a Rooted type, as described in http://dxr.mozilla.org/mozilla-central/source/js/public/RootingAPI.h#l21&lt;br /&gt;
&lt;br /&gt;
For more complicated cases, ask on #jsapi. If you don&#039;t get a response, ping sfink or jonco for rooting hazards, bholley or sfink for heap write hazards. Or if it&#039;s a deeper issue with the analysis logic, try bhackett (the author of both analyses.)&lt;/div&gt;</summary>
		<author><name>Sfink</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=Javascript:Hazard_Builds&amp;diff=1235335</id>
		<title>Javascript:Hazard Builds</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=Javascript:Hazard_Builds&amp;diff=1235335"/>
		<updated>2021-04-28T18:22:43Z</updated>

		<summary type="html">&lt;p&gt;Sfink: attempt to re-point to fx-source-docs&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{OutdatedSpiderMonkey|replacement=[https://firefox-source-docs.mozilla.org/js/HazardAnalysis/]}} &lt;br /&gt;
&lt;br /&gt;
== Static Analysis for Rooting and Heap Write Hazards ==&lt;br /&gt;
&lt;br /&gt;
Treeherder can run two static analysis builds: the full browser (linux64-haz), just the JS shell (linux64-shell-haz). They show up on treeherder as &#039;&#039;&#039;H&#039;&#039;&#039; and &#039;&#039;&#039;SM(H)&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Diagnosing a hazard failure ===&lt;br /&gt;
&lt;br /&gt;
The first step is to look at what sort of hazard is being reported. There are two types that cause the job to fail: stack rooting hazards for garbage collection, and heap write thread safety hazards for stylo.&lt;br /&gt;
&lt;br /&gt;
The summary output will include either the string &amp;quot;&amp;lt;N&amp;gt; rooting hazards detected&amp;quot; or &amp;quot;&amp;lt;N&amp;gt; heap write hazards detected out of &amp;lt;M&amp;gt; allowed&amp;quot;. See the appropriate section below for each.&lt;br /&gt;
&lt;br /&gt;
=== Diagnosing a rooting hazards failure ===&lt;br /&gt;
&lt;br /&gt;
Click on the &#039;&#039;&#039;H&#039;&#039;&#039; build link, select the &amp;quot;Job details&amp;quot; pane on the bottom right, follow the &amp;quot;Inspect Task&amp;quot; link, and download the &amp;quot;&amp;lt;code&amp;gt;public/build/hazards.txt.gz&amp;lt;/code&amp;gt;&amp;quot; file.&lt;br /&gt;
&lt;br /&gt;
Example snippet:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Function &#039;jsopcode.cpp:uint8 DecompileExpressionFromStack(JSContext*, int32, int32, class JS::Handle&amp;lt;JS::Value&amp;gt;, int8**)&#039; has unrooted &#039;ed&#039; of type &#039;ExpressionDecompiler&#039; live across GC call &#039;uint8 ExpressionDecompiler::decompilePC(uint8*)&#039; at js/src/jsopcode.cpp:1866&lt;br /&gt;
    js/src/jsopcode.cpp:1866: Assume(74,75, !__temp_23*, true)&lt;br /&gt;
    js/src/jsopcode.cpp:1867: Assign(75,76, return := 0)&lt;br /&gt;
    js/src/jsopcode.cpp:1867: Call(76,77, ed.~ExpressionDecompiler())&lt;br /&gt;
GC Function: uint8 ExpressionDecompiler::decompilePC(uint8*)&lt;br /&gt;
    JSString* js::ValueToSource(JSContext*, class JS::Handle&amp;lt;JS::Value&amp;gt;)&lt;br /&gt;
    uint8 js::Invoke(JSContext*, JS::Value*, JS::Value*, uint32, JS::Value*, class JS::MutableHandle&amp;lt;JS::Value&amp;gt;)&lt;br /&gt;
    uint8 js::Invoke(JSContext*, JS::CallArgs, uint32)&lt;br /&gt;
    JSScript* JSFunction::getOrCreateScript(JSContext*)&lt;br /&gt;
    uint8 JSFunction::createScriptForLazilyInterpretedFunction(JSContext*, class JS::Handle&amp;lt;JSFunction*&amp;gt;)&lt;br /&gt;
    uint8 JSRuntime::cloneSelfHostedFunctionScript(JSContext*, class JS::Handle&amp;lt;js::PropertyName*&amp;gt;, class JS::Handle&amp;lt;JSFunction*&amp;gt;)&lt;br /&gt;
    JSScript* js::CloneScript(JSContext*, class JS::Handle&amp;lt;JSObject*&amp;gt;, class JS::Handle&amp;lt;JSFunction*&amp;gt;, const class JS::Handle&amp;lt;JSScript*&amp;gt;, uint32)&lt;br /&gt;
    JSObject* js::CloneStaticBlockObject(JSContext*, class JS::Handle&amp;lt;JSObject*&amp;gt;, class JS::Handle&amp;lt;js::StaticBlockObject*&amp;gt;)&lt;br /&gt;
    js::StaticBlockObject* js::StaticBlockObject::create(js::ExclusiveContext*)&lt;br /&gt;
    js::Shape* js::EmptyShape::getInitialShape(js::ExclusiveContext*, js::Class*, js::TaggedProto, JSObject*, JSObject*, uint32, uint32)&lt;br /&gt;
    js::Shape* js::EmptyShape::getInitialShape(js::ExclusiveContext*, js::Class*, js::TaggedProto, JSObject*, JSObject*, uint64, uint32)&lt;br /&gt;
    js::UnownedBaseShape* js::BaseShape::getUnowned(js::ExclusiveContext*, js::StackBaseShape*)&lt;br /&gt;
    js::BaseShape* js_NewGCBaseShape(js::ThreadSafeContext*) [with js::AllowGC allowGC = (js::AllowGC)1u]&lt;br /&gt;
    js::BaseShape* js::gc::NewGCThing(js::ThreadSafeContext*, uint32, uint64, uint32) [with T = js::BaseShape; js::AllowGC allowGC = (js::AllowGC)1u; size_t = long unsigned int]&lt;br /&gt;
    void js::gc::RunDebugGC(JSContext*)&lt;br /&gt;
    void js::MinorGC(JSRuntime*, uint32)&lt;br /&gt;
    GC&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This means that a rooting hazard was discovered at &amp;lt;code&amp;gt;js/src/jsopcode.cpp&amp;lt;/code&amp;gt; line 1866, in the function &amp;lt;code&amp;gt;DecompileExpressionFromStack&amp;lt;/code&amp;gt; (it is prefixed with the filename because it&#039;s a static function.) The problem is that they&#039;re an unrooted variable &#039;&amp;lt;code&amp;gt;ed&amp;lt;/code&amp;gt;&#039; that holds an &amp;lt;code&amp;gt;ExpressionDecompiler&amp;lt;/code&amp;gt; live across a call to &amp;lt;code&amp;gt;decompilePC&amp;lt;/code&amp;gt;. &amp;quot;Live&amp;quot; means that the variable is used after the call to &amp;lt;code&amp;gt;decompilePC&amp;lt;/code&amp;gt; returns. &amp;lt;code&amp;gt;decompilePC&amp;lt;/code&amp;gt; may trigger a GC according to the static call stack given starting from the line beginning with &amp;quot;GC Function:&amp;quot;. The hazard itself has some barely comprehensible Assume(...) and Call(...) gibberish that describes the exact path of the variable into the function call. That stuff is rarely useful -- usually, you&#039;ll only need to look at it if it&#039;s complaining about a temporary and you want to know where the temporary came from. The type &#039;&amp;lt;code&amp;gt;ExpressionDecompiler&amp;lt;/code&amp;gt;&#039; is believed to hold pointers to GC-controlled objects of some sort. The analysis currently does not describe the exact field it is worried about.&lt;br /&gt;
&lt;br /&gt;
To unpack this a little, the analysis is saying the following can happen:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;ExpressionDecompiler&amp;lt;/code&amp;gt; contains some pointer to a GC thing. For example, it might have a field &#039;&amp;lt;code&amp;gt;obj&amp;lt;/code&amp;gt;&#039; of type &#039;&amp;lt;code&amp;gt;JSObject*&amp;lt;/code&amp;gt;&#039;.&lt;br /&gt;
* &amp;lt;code&amp;gt;DecompileExpressionFromStack&amp;lt;/code&amp;gt; is called.&lt;br /&gt;
* A pointer is stored in that field of the &#039;&amp;lt;code&amp;gt;ed&amp;lt;/code&amp;gt;&#039; variable.&lt;br /&gt;
* &amp;lt;code&amp;gt;decompilePC&amp;lt;/code&amp;gt; is invoked, which calls &amp;lt;code&amp;gt;ValueToSource&amp;lt;/code&amp;gt;, which calls &amp;lt;code&amp;gt;Invoke&amp;lt;/code&amp;gt;, which eventually calls &amp;lt;code&amp;gt;js::MinorGC&amp;lt;/code&amp;gt;&lt;br /&gt;
* during the resulting garbage collection, the object pointed to by &amp;lt;code&amp;gt;ed.obj&amp;lt;/code&amp;gt; is moved to a different location. All pointers stored in the JS heap are updated automatically, as are all rooted pointers. &amp;lt;code&amp;gt;ed.obj&amp;lt;/code&amp;gt; is not, because the GC doesn&#039;t know about it.&lt;br /&gt;
* after &amp;lt;code&amp;gt;decompilePC&amp;lt;/code&amp;gt; returns, something accesses &amp;lt;code&amp;gt;ed.obj&amp;lt;/code&amp;gt;. This is now a stale pointer, and may refer to just about anything -- the wrong object, an invalid object, or whatever. Badness 10000, as TeX would say.&lt;br /&gt;
&lt;br /&gt;
=== Diagnosing a heap write hazard failure ===&lt;br /&gt;
&lt;br /&gt;
For the thread unsafe heap write analysis, a hazard means that some Gecko_* function calls, directly or indirectly, code that writes to something on the heap, or calls an unknown function that *might* write to something on the heap. The analysis requires quite a few annotations to describe things that are actually safe. This section will be expanded as we gain more experience with the analysis, but here are some common issues:&lt;br /&gt;
&lt;br /&gt;
* Adding a new Gecko_* function: often, you will need to annotate any outparams or owned (thread-local) parameters in the &amp;lt;code&amp;gt;treatAsSafeArgument&amp;lt;/code&amp;gt; function in &amp;lt;code&amp;gt;js/src/devtools/rootAnalysis/analyzeHeapWrites.js&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Calling some libc function: if you add a call to some random libc function (eg sin() or floor() or ceil(), though the latter two are already annotated), the analysis will report an &amp;quot;External Function&amp;quot;. Add it to &amp;lt;code&amp;gt;checkExternalFunction&amp;lt;/code&amp;gt;, assuming it *doesn&#039;t* have the possibility of writing to shared heap memory.&lt;br /&gt;
* If you call some non-returning (crashing) function that the analysis doesn&#039;t know about, you&#039;ll need to add it to &amp;lt;code&amp;gt;ignoreContents&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
On the other hand, you might have a real thread safety issue on your hands. Shared caches are common problems. Fix it.&lt;br /&gt;
&lt;br /&gt;
=== Analysis implementation ===&lt;br /&gt;
&lt;br /&gt;
These builds are performed as follows:&lt;br /&gt;
&lt;br /&gt;
* run the script testing/taskcluster/scripts/builder/build-haz-linux.sh, which sets up a build environment and runs the analysis within it, then uploads the resulting files&lt;br /&gt;
** compile an optimized JS shell to later run the analysis&lt;br /&gt;
** compile the browser with gcc, using a slightly modified version of the sixgill (http://svn.sixgill.org) gcc plugin, producing a set of .xdb files describing everything encountered during the compilation&lt;br /&gt;
** analyze the .xdb files with scripts in js/src/devtools/rootAnalysis&lt;br /&gt;
&lt;br /&gt;
=== Running the analysis ===&lt;br /&gt;
&lt;br /&gt;
==== Pushing to try ====&lt;br /&gt;
&lt;br /&gt;
The easiest way to run an analysis is to push to try with the trychooser line |try: -b do -p linux64-haz| (or, if the hazards of interest are contained entirely within js/src, use |try: -b do -p linux64-shell-haz| for a much faster result). The expected turnaround time for linux64-haz is just under 2 hours.&lt;br /&gt;
&lt;br /&gt;
The output will be uploaded and a link named &amp;quot;results&amp;quot; will be placed into the &amp;quot;job details&amp;quot; info pane on treeherder. If the analysis fails, you will see the number of failures. Navigate to the hazards.txt.gz file.&lt;br /&gt;
&lt;br /&gt;
==== Running locally ====&lt;br /&gt;
&lt;br /&gt;
To run the browser analysis, you must be on a Fedora/RedHat/CentOS linux64 machine. See js/src/devtools/rootAnalysis/README.md.&lt;br /&gt;
&lt;br /&gt;
If you are running Debian or Ubuntu, then there is currently a problem running the full browser analysis. You can coerce the shell-only build to work by doing something like:&lt;br /&gt;
&lt;br /&gt;
  sudo apt-get install autoconf2.13 libnspr4 libnspr4-dev&lt;br /&gt;
  sudo ln -s autoconf2.13 /usr/bin/autoconf-2.13&lt;br /&gt;
  export CFLAGS=&amp;quot;-B/usr/lib/x86_64-linux-gnu -I/usr/include/x86_64-linux-gnu&amp;quot;&lt;br /&gt;
  export CXXFLAGS=&amp;quot;-B/usr/lib/x86_64-linux-gnu -I/usr/include/x86_64-linux-gnu&amp;quot;&lt;br /&gt;
&lt;br /&gt;
before running the script.&lt;br /&gt;
&lt;br /&gt;
=== So you broke the analysis by adding a hazard. Now what? ===&lt;br /&gt;
&lt;br /&gt;
Backout, fix the hazard, or (final resort) update the expected number of hazards in js/src/devtools/rootAnalysis/expect.browser.json (but don&#039;t do that).&lt;br /&gt;
&lt;br /&gt;
The most common way to fix a hazard is to change the variable to be a Rooted type, as described in http://dxr.mozilla.org/mozilla-central/source/js/public/RootingAPI.h#l21&lt;br /&gt;
&lt;br /&gt;
For more complicated cases, ask on #jsapi. If you don&#039;t get a response, ping sfink or jonco for rooting hazards, bholley or sfink for heap write hazards. Or if it&#039;s a deeper issue with the analysis logic, try bhackett (the author of both analyses.)&lt;/div&gt;</summary>
		<author><name>Sfink</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=Template:OutdatedSpiderMonkey&amp;diff=1235334</id>
		<title>Template:OutdatedSpiderMonkey</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=Template:OutdatedSpiderMonkey&amp;diff=1235334"/>
		<updated>2021-04-28T18:20:48Z</updated>

		<summary type="html">&lt;p&gt;Sfink: First attempt at making a soft redirect (adding a `replacement` parameter.)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{| class=&amp;quot;messagebox standard-talk&amp;quot; style=&amp;quot;margin-bottom: 1em; width:100%; border:5px solid #B0C4DE; background-color:#f6f4ec;&amp;quot;&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; style=&amp;quot;padding:0px 10px 0px;&amp;quot; | [[File:Ambox outdated.png|65px|link=]]&lt;br /&gt;
| style=&amp;quot;padding:0px 40px 0px 10px; font-size: large; text-align:center;&amp;quot; | &#039;&#039;&#039;THIS {{#if:{{{section|}}}|SECTION|PAGE}} IS OBSOLETE&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding:0px 40px 0px 10px; text-align:left;&amp;quot; | This {{#if:{{{section|}}}|section|article}} is in parts, or in its entirety, outdated. {{#if:{{{replacement|}}}|The current version is at {{{replacement}}}.|}} Hence, the information presented {{#if:{{{section|}}}|under it|on this page}} may be incorrect, and should be treated with due caution. Visit [https://spidermonkey.dev/ SpiderMonkey.dev] for more up to date information.&lt;br /&gt;
|}&amp;lt;includeonly&amp;gt;[[Category:Outdated articles|{{PAGENAME}}]]&amp;lt;/includeonly&amp;gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{documentation}}&lt;br /&gt;
&amp;lt;!-- Add categories to the /doc sub-page --&amp;gt;&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Sfink</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=ES6_plans&amp;diff=1235305</id>
		<title>ES6 plans</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=ES6_plans&amp;diff=1235305"/>
		<updated>2021-04-27T22:16:11Z</updated>

		<summary type="html">&lt;p&gt;Sfink: caroline marked obsolete&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{OutdatedSpiderMonkey}} &lt;br /&gt;
&lt;br /&gt;
== New and improved builtin APIs ==&lt;br /&gt;
&lt;br /&gt;
Most of this stuff does not need to touch a lot of code. None of it requires a Harmony opt-in. This is great stuff for new contributors to start work on.&lt;br /&gt;
&lt;br /&gt;
* [http://wiki.ecmascript.org/doku.php?id=harmony:simple_maps_and_sets Simple Maps and Sets] - The spec is incomplete but I will be landing what&#039;s there now in [https://bugzilla.mozilla.org/show_bug.cgi?id=697479 bug 697479].&lt;br /&gt;
* [http://wiki.ecmascript.org/doku.php?id=harmony:binary_data Binary data] - [https://bugzilla.mozilla.org/show_bug.cgi?id=578700 bug 578700]&lt;br /&gt;
* New reflection methods [http://wiki.ecmascript.org/doku.php?id=harmony:extended_object_api Object.getPropertyDescriptor, Object.getPropertyNames]&lt;br /&gt;
* Number.[http://wiki.ecmascript.org/doku.php?id=harmony:number.isfinite isFinite], [http://wiki.ecmascript.org/doku.php?id=harmony:number.isnan isNaN], [http://wiki.ecmascript.org/doku.php?id=harmony:number.isinteger isInteger], and [http://wiki.ecmascript.org/doku.php?id=harmony:number.tointeger toInteger]&lt;br /&gt;
* String.prototype.[http://wiki.ecmascript.org/doku.php?id=harmony:string.prototype.repeat repeat], [http://wiki.ecmascript.org/doku.php?id=harmony:string_extras startsWith, endsWith, contains, toArray]&lt;br /&gt;
* New reflection API that complements proxies: [http://wiki.ecmascript.org/doku.php?id=harmony:reflect_api harmony:reflect_api]&lt;br /&gt;
* [http://wiki.ecmascript.org/doku.php?id=harmony:egal Object.is]&lt;br /&gt;
* [http://wiki.ecmascript.org/doku.php?id=harmony:more_math_functions More math functions] - Proposed are: Math.log10, log2, log1p, expm1, cosh, sinh, tanh, acosh, asinh, atanh, hypot, trunc, sign; perhaps gamma and erf; and perhaps randomInt(n). See [https://bugzilla.mozilla.org/show_bug.cgi?id=717379 bug 717379].&lt;br /&gt;
* ES6 will spec that [http://wiki.ecmascript.org/doku.php?id=harmony:random-er Math.random] does not share state across multiple globals.&lt;br /&gt;
&lt;br /&gt;
== New syntax (stuff that affects the front end and/or bytecode) ==&lt;br /&gt;
&lt;br /&gt;
This stuff isn&#039;t terribly hard either, for the most part.&lt;br /&gt;
&lt;br /&gt;
* [http://wiki.ecmascript.org/doku.php?id=harmony:iterators for-of loops] - [https://bugzilla.mozilla.org/show_bug.cgi?id=699565 bug 699565] - This is I&#039;d say better than half done. It was easy. XPConnect must be updated so that arraylike XPCOM objects cooperate with for-of.&lt;br /&gt;
* [http://wiki.ecmascript.org/doku.php?id=harmony:parameter_default_values Parameter default values]&lt;br /&gt;
* [http://wiki.ecmascript.org/doku.php?id=harmony:rest_parameters Rest parameters] - [https://bugzilla.mozilla.org/show_bug.cgi?id=574132 bug 574132]&lt;br /&gt;
* [http://wiki.ecmascript.org/doku.php?id=harmony:spread Spread operator] - [https://bugzilla.mozilla.org/show_bug.cgi?id=574130 bug 574130] - The operator can appear in two places: function calls and array literals. Maybe two bugs would make sense.&lt;br /&gt;
* [http://wiki.ecmascript.org/doku.php?id=harmony:proper_tail_calls Proper tail calls]&lt;br /&gt;
* [http://wiki.ecmascript.org/doku.php?id=harmony:object_literals Extensions to object literal syntax]&lt;br /&gt;
* [http://wiki.ecmascript.org/doku.php?id=harmony:classes Classes]&lt;br /&gt;
* [http://wiki.ecmascript.org/doku.php?id=harmony:quasis Quasi-literals] [https://bugzilla.mozilla.org/show_bug.cgi?id=688857 Bug 688857]&lt;br /&gt;
* [http://wiki.ecmascript.org/doku.php?id=harmony:pragmas Pragmas]&lt;br /&gt;
&lt;br /&gt;
== Updating SpiderMonkey extensions to the ES6 spec ==&lt;br /&gt;
&lt;br /&gt;
We&#039;ve implemented a ton of stuff, dating back years, that is going to be in ES6 but in a slightly different form.&lt;br /&gt;
&lt;br /&gt;
=== Direct proxies ===&lt;br /&gt;
&lt;br /&gt;
There is a ton of verbiage here and it is still under active development. Still, I think it should be pretty easy to implement. We already have the forwarding code. We can keep &amp;lt;code&amp;gt;Proxy.create&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;createFunction&amp;lt;/code&amp;gt; without a lot of extra effort.&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.mozilla.org/show_bug.cgi?id=703537 Bug 703537].&lt;br /&gt;
&lt;br /&gt;
* http://wiki.ecmascript.org/doku.php?id=harmony:direct_proxies&lt;br /&gt;
* http://wiki.ecmascript.org/doku.php?id=harmony:proxies_spec&lt;br /&gt;
* http://wiki.ecmascript.org/doku.php?id=harmony:proto_climbing_refactoring&lt;br /&gt;
* http://wiki.ecmascript.org/doku.php?id=harmony:virtual_object_api&lt;br /&gt;
&lt;br /&gt;
=== Generators and comprehensions ===&lt;br /&gt;
&lt;br /&gt;
* Certain scoping details in [http://wiki.ecmascript.org/doku.php?id=harmony:array_comprehensions array comprehensions] and [http://wiki.ecmascript.org/doku.php?id=harmony:generator_expressions generator expressions] are probably different from what we have implemented.&lt;br /&gt;
* [http://wiki.ecmascript.org/doku.php?id=harmony:generators &amp;lt;code&amp;gt;function*&amp;lt;/code&amp;gt; syntax] - [https://bugzilla.mozilla.org/show_bug.cgi?id=666399 bug 666399]&lt;br /&gt;
* Allow returning a value from a generator - [https://bugzilla.mozilla.org/show_bug.cgi?id=666404 bug 666404]&lt;br /&gt;
* There are probably one or two other minor details - details of StopIteration, that kind of thing.&lt;br /&gt;
&lt;br /&gt;
=== let, const, and block functions ===&lt;br /&gt;
&lt;br /&gt;
[http://wiki.ecmascript.org/doku.php?id=harmony:block_scoped_bindings Block scoped bindings]&lt;br /&gt;
&lt;br /&gt;
* Top-level let shouldn&#039;t be the same thing as var, per dherman: [https://bugzilla.mozilla.org/show_bug.cgi?id=589199 bug 589199]&lt;br /&gt;
* TC39 is specifying that reading a let-variable before it is initialized is an error, which will be a separate bug.&lt;br /&gt;
* &amp;lt;code&amp;gt;const&amp;lt;/code&amp;gt; - [https://bugzilla.mozilla.org/show_bug.cgi?id=611388 bug 611388]&lt;br /&gt;
* Block functions - [https://bugzilla.mozilla.org/show_bug.cgi?id=585536 bug 585536] (note - opt-in only, still banned in ES5 strict mode)&lt;br /&gt;
* [http://wiki.ecmascript.org/doku.php?id=harmony:destructuring Destructuring]&lt;br /&gt;
* Per loop iteration binding of let/const.&lt;br /&gt;
&lt;br /&gt;
== Harmony infrastructure ==&lt;br /&gt;
&lt;br /&gt;
Some minimal steps here are a prerequisite to doing the features that require a Harmony opt-in: modules and import, block-scoped functions, &amp;lt;code&amp;gt;typeof null&amp;lt;/code&amp;gt;, and lexical scoping of names declared at toplevel.&lt;br /&gt;
&lt;br /&gt;
* New SM version number - This is enough to get started on harmony features with only shell tests.&lt;br /&gt;
* Opt-in via type=&amp;quot;text/ecmascript;version=6&amp;quot; or whatever - [https://bugzilla.mozilla.org/show_bug.cgi?id=694107 bug 694107]&lt;br /&gt;
* Per-script opt-in syntax (&#039;use harmony;&#039; or whatever)&lt;br /&gt;
* Opt-in via HTTP header?&lt;br /&gt;
* Whole-page opt-in via HTML feature?&lt;br /&gt;
&lt;br /&gt;
== Modules ==&lt;br /&gt;
&lt;br /&gt;
[http://wiki.ecmascript.org/doku.php?id=harmony:modules harmony:modules]&lt;br /&gt;
&lt;br /&gt;
Modules are [https://bugzilla.mozilla.org/show_bug.cgi?id=568953 bug 568953].&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;module&amp;lt;/code&amp;gt; syntax, scoping semantics, module objects&lt;br /&gt;
* &amp;lt;code&amp;gt;import&amp;lt;/code&amp;gt; syntax&lt;br /&gt;
* &amp;lt;code&amp;gt;from &amp;quot;url&amp;quot;&amp;lt;/code&amp;gt; syntax&lt;br /&gt;
* Hook up &amp;lt;code&amp;gt;from &amp;quot;url&amp;quot;&amp;lt;/code&amp;gt; and async module loading to Gecko&lt;br /&gt;
* [http://wiki.ecmascript.org/doku.php?id=harmony:module_loaders Module loaders]&lt;br /&gt;
&lt;br /&gt;
With a Harmony opt-in, programs get very different global binding behavior. The bindings are no longer shared with the global object&#039;s properties. This is a major change.&lt;br /&gt;
&lt;br /&gt;
== New APIs that are in modules ==&lt;br /&gt;
* [http://wiki.ecmascript.org/doku.php?id=harmony:modules_standard Reorganize the standard library into modules]&lt;br /&gt;
* [http://wiki.ecmascript.org/doku.php?id=harmony:private_name_objects Private name objects] - [https://bugzilla.mozilla.org/show_bug.cgi?id=645416 bug 645416]&lt;br /&gt;
* A few functions for [http://wiki.ecmascript.org/doku.php?id=harmony:iterators iterating over object properties]&lt;br /&gt;
&lt;br /&gt;
== Incompatible changes ==&lt;br /&gt;
Harmony may change some ES1-5 behavior, if it empirically turns out to be doable without breaking the Web.&lt;br /&gt;
* [http://wiki.ecmascript.org/doku.php?id=harmony:completion_reform Change how eval decides which value to return]&lt;br /&gt;
* typeof null == &amp;quot;null&amp;quot; with Harmony opt-in - [https://bugzilla.mozilla.org/show_bug.cgi?id=651251 bug 651251]&lt;br /&gt;
&lt;br /&gt;
== Proposals that should not create any work for us ==&lt;br /&gt;
* [http://wiki.ecmascript.org/doku.php?id=harmony:multiple_globals Multiple globals]&lt;br /&gt;
* [http://wiki.ecmascript.org/doku.php?id=harmony:regexp_y_flag RegExp y (sticky) flag]&lt;br /&gt;
* [http://wiki.ecmascript.org/doku.php?id=harmony:regexp_match_web_reality RegExp match web reality]&lt;br /&gt;
* [http://wiki.ecmascript.org/doku.php?id=harmony:function_to_string Function.prototype.toString spec tweaks]&lt;/div&gt;</summary>
		<author><name>Sfink</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=Javascript:SpiderMonkey:ES6_Testing&amp;diff=1235304</id>
		<title>Javascript:SpiderMonkey:ES6 Testing</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=Javascript:SpiderMonkey:ES6_Testing&amp;diff=1235304"/>
		<updated>2021-04-27T22:10:14Z</updated>

		<summary type="html">&lt;p&gt;Sfink: mark obsolete&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{OutdatedSpiderMonkey}} &lt;br /&gt;
&lt;br /&gt;
= Objective =&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Summary&#039;&#039;&#039;: Properly test all new features and aspects of ES6.&lt;br /&gt;
&lt;br /&gt;
ES6, the next iteration of ECMAScript, introduces many new features, new methods, new algorithms, and occasionally makes changes to existing methods and algorithms.  Implementing these changes correctly will require a considerable number of tests for all additions and changes.&lt;br /&gt;
&lt;br /&gt;
Historically most Mozilla JS tests have been self-written and work only in SpiderMonkey test harnesses.  There is an effort at ECMA, test262, to introduce a standardized test format, harness, and so on, so that tests that are written can be run by any browser/engine.  We should make an effort to write more tests in standardized format, so that tests we write can be used by other engines, improving the web for everyone -- even if they don&#039;t use SpiderMonkey or a Mozilla-based browser.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Accountable&#039;&#039;&#039;: Naveed&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Responsible&#039;&#039;&#039;: Waldo, jorendorff&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Consulted&#039;&#039;&#039;: &amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Informed&#039;&#039;&#039;: Product Marketing&lt;br /&gt;
&lt;br /&gt;
= Milestones =&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table border&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;th&amp;gt;Status&amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;th&amp;gt;Task&amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;th&amp;gt;Deliverable&amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;th&amp;gt;Assigned&amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;th&amp;gt;Estimate&amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;th&amp;gt;Expected&amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;th&amp;gt;Actual&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;done&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Get test262 running on Tinderbox&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Test262 import script works, imports test262 tests, manually run periodically to get updates&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Waldo&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;in progress&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Implement &amp;lt;code&amp;gt;@negative&amp;lt;/code&amp;gt; support for imported test262 tests, {{bug|496923}}&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Most of the test262 skips in {{source|js/src/tests/jstests.list}} are removed&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Waldo&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;1 week&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;20130823&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;in progress&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Import the ch15 test262 tests&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;{{source|js/src/tests/test262/ch15}} exists, the tests are run on Tinderbox&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Waldo&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;1 week&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;20130823&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;in progress&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Process for upstreaming test262 contributions&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Have at least one test262 contribution in {{source|js/src/tests/test262/to-upstream/}} from someone not involved in the test262 harness work&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Waldo&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;3 days&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;in progress&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Fix remaining issues preventing us from running any test262 tests&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Only actually-failing tests skipped&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Waldo&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;1 week&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;20130823&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;pending&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Evaluate potential [http://wiki.ecmascript.org/doku.php?id=test262:test_case_format test262 format] changes, simplifications to ease contributions&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Iron out test-format concerns we have that make it hard to run the tests with our shell or in the browser; scope unknown, but synchronous script inclusion from script really should go&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Waldo&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;1 week&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;in progress&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Draw up a list of the ES6 features/changes to be tested&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Spec fully run through, all new portions listed with points of interest called out&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Waldo&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;1 week&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;not started&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Write tests for new ES6 changes&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;All areas listed below implemented&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;various&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;see below&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;see below&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;in progress&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Get test262 running on Tinderbox&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;All tests imported, only actually-failing tests skipped&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Waldo&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;1 week&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;20130619&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;actual&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Import the test262 suite into Mozilla, and run it on tinderbox ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Owner&#039;&#039;: jwalden&lt;br /&gt;
&#039;&#039;Status&#039;&#039;: &#039;&#039;&#039;done&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
There&#039;s relatively little impetus for us to write test262 tests if we can&#039;t run them as often as we run all our existing tests.  It should be a high priority to set up a process through which test262 tests are imported into our tree, run on each new change, and regressions flagged so that the relevant patches can be reverted.&lt;br /&gt;
&lt;br /&gt;
== Fix remaining issues preventing us from running any test262 tests ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Owner&#039;&#039;: jwalden&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Status&#039;&#039;: in progress&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Estimate&#039;&#039;: 1 week&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The initial test262 import was relatively brain-dead: import everything, skip tests that fail (validly or not).  We need to go back and fix up our test harnesses, or the test262 import script, to run those additional tests.&lt;br /&gt;
&lt;br /&gt;
Issues to fix:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;@negative&amp;lt;/code&amp;gt; support&lt;br /&gt;
* others?&lt;br /&gt;
&lt;br /&gt;
== Examine the test262 test format/harness to identify any limitations in it ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Owner&#039;&#039;: jwalden&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Status&#039;&#039;: incomplete&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Estimate&#039;&#039;: 1 week&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We frequently add new features and functionality to the JS shell for testing purposes.  We add methods to help verify implementation internals, where adding directly to the shell makes obvious sense.  But we also add functionality to make it easier to test particular bits of entirely-standard functionality -- to permit evaluating multiple global scripts in a single test, for example.  We&#039;ve added these features because, in our harness, this was the easiest way to test a feature.  test262 doubtless has similar limitations, and as these tests must be cross-engine, it won&#039;t be possible to use Mozilla-specific helper functions.&lt;br /&gt;
&lt;br /&gt;
We need to examine the test262 harness and test format and identify these limitations, and consider how they might be resolved or worked around.  Note that as test262 is a shared resource, any changes we request will have to be discussed with and reviewed by non-Mozilla people to consider their effects on others, an extra bit of process that may make this take longer than it would if it were totally under our control.&lt;br /&gt;
&lt;br /&gt;
== Process for upstreaming test262 contributions ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Owner&#039;&#039;: jwalden&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Status&#039;&#039;: not started&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Estimate&#039;&#039;: 3 days&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Contributions to test262, going through test262, probably have too much friction to get developers to make them in the course of usual bug-fixing/regression-fixing.  We should set up a {{source|js/src/tests/test262/to-upstream/}} directory into which test262-format tests can be dumped.  Then whoever runs the update script can be responsible for moving them to a reasonable location, etc. and contributing them to test262.  When they&#039;re landed upstream (which could be later than we want to land the patch and test in our tree), we can run the update script, pick up the new tests, and remove the to-upstream ones.&lt;br /&gt;
&lt;br /&gt;
This mostly requires adding the new to-upstream directory and writing and disseminating documentation about how to write test262 tests.&lt;br /&gt;
&lt;br /&gt;
== Enumerate the features/details/changes in ES6 ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Owner&#039;&#039;: jwalden&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Status&#039;&#039;: incomplete&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Estimate&#039;&#039;: 4 days&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This simply requires running through ES6 drafts, as they&#039;re published, and noting things that will need testing.  The following list was produced by a read-through of the ES6 spec, so it likely misses systemic interactions that need testing.&lt;br /&gt;
&lt;br /&gt;
=== Ordinary/exotic objects ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Owner&#039;&#039;: unowned&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Status&#039;&#039;: incomplete&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Estimate&#039;&#039;: 2 days&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* need to run through 8.4/8.5 with a fine-toothed comb looking for all the various differences&lt;br /&gt;
* some differences should already be tested, because they were implicit (or explicit in different form) in ES5 and earlier&lt;br /&gt;
&lt;br /&gt;
=== Template literals ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Owner&#039;&#039;: unowned&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Status&#039;&#039;: not started&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Estimate&#039;&#039;: unknown; depends on their being implemented, and on the implementation complexities encountered, to know what needs the most test work&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* the InputElementTemplateTail goal symbol has interesting interactions with ASI, that must be investigated&lt;br /&gt;
* template literals generally need to be implemented, and basic semantics tested&lt;br /&gt;
* testing for specific interesting characters in template literals&lt;br /&gt;
** Unicode format-control characters within template literals&lt;br /&gt;
** line terminators (Unicode and non-Unicode both)&lt;br /&gt;
* templates with zero or more substitution parts need particular testing&lt;br /&gt;
&lt;br /&gt;
=== Binary/octal numeric literals ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Owner&#039;&#039;: jwalden&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Status&#039;&#039;: incomplete (tested, but not in test262)&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Estimate&#039;&#039;: 1 day&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* implemented and tested in {{bug|894026}}&lt;br /&gt;
* tests need to be ported to test262 format and upstreamed&lt;br /&gt;
&lt;br /&gt;
=== Non-BMP Unicode escapes ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Owner&#039;&#039;: unowned&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Status&#039;&#039;: not started&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Estimate&#039;&#039;: 1 day&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;\u{}&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;\u{HexDigits}&amp;lt;/code&amp;gt; is a syntax error if HexDigits &amp;gt; 1114111 (0x10FFFF)&lt;br /&gt;
* &amp;lt;code&amp;gt;\u{}&amp;lt;/code&amp;gt; with a surrogate-pair number&lt;br /&gt;
* &amp;lt;code&amp;gt;\u{}&amp;lt;/code&amp;gt; with other reserved and special code points (BOM, the reserved bits around U+FFE0 or so)&lt;br /&gt;
&lt;br /&gt;
=== Identifier syntax changes ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Owner&#039;&#039;: unowned&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Status&#039;&#039;: not started&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Estimate&#039;&#039;: 1 day&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* identifier goal symbols seem to have changed some -- to use the Unicode properties ID_Start and ID_Continue (and also _/$/&amp;lt;ZWJ&amp;gt;/&amp;lt;ZWNJ&amp;gt;)&lt;br /&gt;
* implementation may require changes to our Unicode update script, but once those changes are done, implementation should be a breeze&lt;br /&gt;
&lt;br /&gt;
=== New keywords ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Owner&#039;&#039;: unowned&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Status&#039;&#039;: not started&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Estimate&#039;&#039;: 1 day&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* new keywords: class, continue, const, export, import, super (possibly all reserved before, tests needed for their new semantics, and places that still forbid them)&lt;br /&gt;
* &amp;lt;code&amp;gt;yield&amp;lt;/code&amp;gt; contextual keyword (being worked on by wingo)&lt;br /&gt;
* we already have tests to which keyword-checking stuff can be added (although they&#039;re not in test262 format)&lt;br /&gt;
&lt;br /&gt;
=== Regular expression syntax ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Owner&#039;&#039;: unowned&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Status&#039;&#039;: not started&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Estimate&#039;&#039;: unknown, depends on complexity of syntax changes&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* apparent changes here -- unclear at a glance what needs doing here&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;this&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Owner&#039;&#039;: unowned&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Status&#039;&#039;: incomplete&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Estimate&#039;&#039;: 1 day, appears relatively short&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* 8.2.4.3 GetThisValue(V): how is this used, where, maybe needs tests (if not just some sort of refactoring of &amp;lt;code&amp;gt;this&amp;lt;/code&amp;gt; keyword handling, not sure yet)&lt;br /&gt;
&lt;br /&gt;
=== Property descriptors ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Owner&#039;&#039;: unowned&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Status&#039;&#039;: not started&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Estimate&#039;&#039;: unknown&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* the Property Descriptor type now has an optional &amp;lt;nowiki&amp;gt;[[Origin]]&amp;lt;/nowiki&amp;gt; field -- possibly/likely used for property descriptors returned from proxy hooks -- needs testing&lt;br /&gt;
* implementing this has interactions with the ongoing MOP refactoring work; &amp;lt;code&amp;gt;JSPropertyDescriptor&amp;lt;/code&amp;gt; and/or &amp;lt;code&amp;gt;PropDesc&amp;lt;/code&amp;gt; need changes for this&lt;br /&gt;
&lt;br /&gt;
=== New &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;[[HasOwnProperty]]&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; hook ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Owner&#039;&#039;: jwalden&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Status&#039;&#039;: incomplete&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Estimate&#039;&#039;: unknown&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* previously this was implicitly derived from &amp;lt;nowiki&amp;gt;[[GetOwnProperty]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* implementing this has interactions with MOP refactoring&lt;br /&gt;
* jwalden has partial patch for that refactoring, {{bug|826587}}&lt;br /&gt;
* jwalden also has partial patch for the has-own-property hook, {{bug|862848}} and/or {{bug|905168}}&lt;br /&gt;
&lt;br /&gt;
=== New inheritance hooks ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Owner&#039;&#039;: jwalden&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Status&#039;&#039;: incomplete&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Estimate&#039;&#039;: 2 days, plus implementation time&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* needed for prototype-setting and getting to work with proxies&lt;br /&gt;
* we have some of this implemented already, but we don&#039;t use/respect it universally yet&lt;br /&gt;
&lt;br /&gt;
=== Enumeration changes ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Owner&#039;&#039;: unowned&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Status&#039;&#039;: not started&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Estimate&#039;&#039;: 1 week&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* new &amp;lt;nowiki&amp;gt;[[Enumerate]]&amp;lt;/nowiki&amp;gt; and &amp;lt;nowiki&amp;gt;[[OwnPropertyKeys]]&amp;lt;/nowiki&amp;gt; hooks with well-defined semantics for for(var i in o) and Object.getOwnPropertyNames/keys -- visible in proxies&lt;br /&gt;
* enumeration affects practically everything, so a bit of work necessary here&lt;br /&gt;
&lt;br /&gt;
=== Function internal properties ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Owner&#039;&#039;: unowned&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Status&#039;&#039;: not started&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Estimate&#039;&#039;: unknown&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* functions (ordinary function objects, 8.3.15.1) have a bunch more internal data properties to track -- affecting semantics in various ways; realms are perhaps the most important one (corresponding to the multiple-globals problem in web browsers)&lt;br /&gt;
* |new| on a function whose &amp;lt;nowiki&amp;gt;[[Prototype]]&amp;lt;/nowiki&amp;gt; has been changed to null/undefined -- semantics of this are still partially up in the air&lt;br /&gt;
* there seems to be a requirement that &amp;lt;code&amp;gt;(function() { &amp;quot;use strict&amp;quot;; }).caller === null&amp;lt;/code&amp;gt; per 8.3.15.3 which might be a change from ES5 -- needs investigation, testing, possible bug-reporting&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;[[BuiltinBrand]]&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Owner&#039;&#039;: unowned&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Status&#039;&#039;: not started&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Estimate&#039;&#039;: unknown&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* used for exact-class checks from ES5 and before&lt;br /&gt;
* likely affects every place that currently does exact-class checks (or exact-class-modulo-other-globals checks)&lt;br /&gt;
* most recent ES6 draft doesn&#039;t discuss this anywhere except in overview documentation: highly under-specified right now&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;String&amp;lt;/code&amp;gt; objects ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Owner&#039;&#039;: unowned&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Status&#039;&#039;: incomplete&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Estimate&#039;&#039;: unknown&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* String exotic objects: new internal ops defined for them, may require more testing for out-of-range -- also for negative indexes, which in the current spec seem to be passed through &amp;lt;code&amp;gt;abs()&amp;lt;/code&amp;gt; (!, may be a bug)&lt;br /&gt;
&lt;br /&gt;
=== Symbol exotic objects ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Owner&#039;&#039;: unowned&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Status&#039;&#039;: not started&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Estimate&#039;&#039;: unknown&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* spec still in flux&lt;br /&gt;
* specific testing needed for &amp;quot;8.1.6.4 Well-Known Symbols and Intrinsics&amp;quot;: are these directly observable, or only indirectly through spec algorithms&#039; uses of them?&lt;br /&gt;
* all the hooks in 8.4.4 must be exercised, probably most simply through the &amp;lt;code&amp;gt;Reflect.*&amp;lt;/code&amp;gt; methods that were (are?) mooted at one time for ES6&lt;br /&gt;
&lt;br /&gt;
=== Integer Indexed exotic objects ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Owner&#039;&#039;: unowned&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Status&#039;&#039;: incomplete&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Estimate&#039;&#039;: unknown&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* looks like a catch-all for typed array views, approximately&lt;br /&gt;
&lt;br /&gt;
=== Declaration binding ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Owner&#039;&#039;: unowned&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Status&#039;&#039;: not started&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Estimate&#039;&#039;: unknown, semantics not well-understood yet&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* addition of &amp;lt;code&amp;gt;let&amp;lt;/code&amp;gt; must be accounted for&lt;br /&gt;
* needs careful consideration of how &amp;lt;code&amp;gt;let&amp;lt;/code&amp;gt; and lexically-scoped variables interact with all this -- and also for any cases where &amp;quot;lexically-scoped&amp;quot; doesn&#039;t mean &#039;&#039;just&#039;&#039; &amp;lt;code&amp;gt;let&amp;lt;/code&amp;gt; (but perhaps other things like &amp;lt;code&amp;gt;catch&amp;lt;/code&amp;gt;, possibly top-level vars inside functions, function arguments, other things maybe?  or not?)&lt;br /&gt;
&lt;br /&gt;
=== The &amp;lt;code&amp;gt;super&amp;lt;/code&amp;gt; keyword ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Owner&#039;&#039;: unowned&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Status&#039;&#039;: not started&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Estimate&#039;&#039;: unknown, semantics not well-understood yet&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* used to implement &amp;quot;Super References (8.2.4)&amp;quot; -- something to do with calling superclass methods, and similar things&lt;br /&gt;
* will need extensive testing with all our various function/generator syntaxes&lt;br /&gt;
* will need testing with various methods of calling functions&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;BinaryData&amp;lt;/code&amp;gt; proposal ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Owner&#039;&#039;: unowned&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Status&#039;&#039;: incomplete&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Estimate&#039;&#039;: unknown&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* implemented in {{bug|578700}}, ongoing bugfixing/fuzz-testing work before it&#039;ll be fully enabled&lt;br /&gt;
** data block type&lt;br /&gt;
* need to loop in nsm on this&lt;br /&gt;
&lt;br /&gt;
=== Scriptable proxies ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Owner&#039;&#039;: unowned&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Status&#039;&#039;: incomplete&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Estimate&#039;&#039;: unknown&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* possibly done a bit by ejpbruel?&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;ToPrimitive&amp;lt;/code&amp;gt; is user-hookable now ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Owner&#039;&#039;: unowned&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Status&#039;&#039;: not started&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Estimate&#039;&#039;: 2 days, depends on its being implemented (which further depends on symbols)&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* ToPrimitive is now explicitly hookable in objects (doesn&#039;t use toString/valueOf properties), using a well-known symbol/intrinsic&lt;br /&gt;
&lt;br /&gt;
== Other things ==&lt;br /&gt;
&lt;br /&gt;
Rest of ES6 still needs to be summarized here...&lt;br /&gt;
&lt;br /&gt;
= Issues =&lt;br /&gt;
&lt;br /&gt;
Importing third-party tests into our tree, that we don&#039;t necessarily pass (particularly as tests for new features are introduced), requires a mechanism for marking third-party tests as failing.  Ideally, this must be possible without editing the imported tests, or at least with as few edits to the imported tests as possible.  It&#039;s not clear what this mechanism will look like, but it&#039;s critical that we have it.&lt;br /&gt;
&lt;br /&gt;
= Risks =&lt;br /&gt;
&lt;br /&gt;
test262&#039;s test format may be inadequate to test all behavior required by ES6.  Tests that must run in global code, for example, may not necessarily fit into the test262 format.  (This is purely my recollection from having looked into this a few years ago -- things may have changed since.)  Tests which require executing multiple JS scripts (that is, through multiple &amp;lt;code&amp;gt;&amp;amp;lt;script&amp;amp;gt;&amp;lt;/code&amp;gt; elements in the browser) also may pose issues.  Other instances may arise over time.  Dealing with these harness limitations will require adding new functionality to the harness, and may delay properly testing some new features.&lt;br /&gt;
&lt;br /&gt;
ES6 is a moving target: specified features may be removed, new features may be added, changes may be made at any time.  Keeping tests atop the latest spec revisions will be an ongoing challenge until ES6 is finalized (currently targeted at the end of 2014).&lt;br /&gt;
&lt;br /&gt;
The test262 suite is quite large.  Simply adding all test262 tests to the &amp;quot;J&amp;quot; test runs on Tinderbox will make &amp;quot;J&amp;quot; builds take a lot longer to run.  It may be necessary to split test262 into its own set of builds, so that test262 can be run in parallel with the existing &amp;quot;J&amp;quot; tests.  (The goal is to minimize changeset-push-to-results latency.  Historically this has been accomplished mostly by running tests in parallel.)  It currently appears we can import a substantial number of tests into the existing &amp;quot;J&amp;quot; builds, without unduly lengthening the time it takes to run them, so this challenge doesn&#039;t need to be immediately faced to make progress toward running test262 tests.&lt;br /&gt;
&lt;br /&gt;
= Resources =&lt;br /&gt;
&lt;br /&gt;
* [http://hg.ecmascript.org/tests/test262 test262 repository] (tests, harnesses, etc.)&lt;br /&gt;
* [http://wiki.ecmascript.org/doku.php?id=test262:test_case_format test262 test format]&lt;br /&gt;
* etc.&lt;br /&gt;
* ...&lt;/div&gt;</summary>
		<author><name>Sfink</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=JavaScript:%3FMonkey&amp;diff=1235303</id>
		<title>JavaScript:?Monkey</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=JavaScript:%3FMonkey&amp;diff=1235303"/>
		<updated>2021-04-27T22:09:47Z</updated>

		<summary type="html">&lt;p&gt;Sfink: mark obsolete&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{OutdatedSpiderMonkey}} &lt;br /&gt;
&lt;br /&gt;
This is a list of specific aspects of the current TraceMonkey JIT that could be improved to reduce overall JIT complexity and allow better optimization. This list (in its current form) does not determine a single specific new design but does have high-level design implications.&lt;br /&gt;
&lt;br /&gt;
# Do not interleave compilation and execution&lt;br /&gt;
## There is a [https://bugzilla.mozilla.org/show_bug.cgi?id=561954 significant] challenge in keeping the VM state and what the compiler thinks the VM state is coherent.&lt;br /&gt;
## When compilation straddles execution of an op, this forces us to use the gross &amp;quot;pending X&amp;quot; pattern which makes logic non-local (e.g., bug 622318).&lt;br /&gt;
# Trace in terms of micro-ops instead of (current) fat-ops&lt;br /&gt;
## Macro-ops cause code duplication or complex factored-out helper functions&lt;br /&gt;
### (njn) Can you give an example?  Nanojit&#039;s CSE pass removes a lot of code duplication.&lt;br /&gt;
#### (luke) I mean in the compiler, not in the generated code.&lt;br /&gt;
## Conflict: the interp/JM compiler want fat ops for performance/optimization&lt;br /&gt;
# Remove the &amp;quot;deep bail&amp;quot; possibility&lt;br /&gt;
## Deep bailing requires the programmer to maintain subtle invariants in mind at all times, especially in the presence [https://bugzilla.mozilla.org/show_bug.cgi?id=592069 macro] [https://bugzilla.mozilla.org/show_bug.cgi?id=612523 ops].&lt;br /&gt;
## (dvander) the problem isn&#039;t that deep bails can happen, but that they&#039;re a bad solution with a complex implementation. deep bails happen for two reasons:&lt;br /&gt;
### the engine has broken an invariant, and now we want to recompile, despecialize, and replace on-stack. type inference already has to do both this and maintaining the tricky sanity invariants that deep bailing did, like catching writes to properties.&lt;br /&gt;
### the engine wants to know something about the interpreter state. well, that&#039;s just a silly reason to deep bail :) we have to be able to reify state anyway.&lt;br /&gt;
# No nested trace trees: compile multiple loops&lt;br /&gt;
## The process of recording the call from an inner tree to outer is very delicate. Inner/outer tree reasoning is [http://hg.mozilla.org/tracemonkey/file/2b9d805d77a1/js/src/jstracer.cpp#l5236 complex].&lt;br /&gt;
# Compile with knowledge of multiple iterations and selectively despecialize to avoid trace explosion&lt;br /&gt;
## Specifically, support despecializing:&lt;br /&gt;
### callee (e.g., for polymorphic raytrace);&lt;br /&gt;
### type (e.g., for untyped data shuffling);&lt;br /&gt;
### shape (want ICs); and&lt;br /&gt;
### control flow (want non-linear traces).&lt;br /&gt;
## It is hard to [https://bugzilla.mozilla.org/show_bug.cgi?id=516264 simulate] with always-linear traces and knowledge of only what is happening right now.&lt;br /&gt;
## (dvander) despecializing types would seem to defeat the point of tracing. for data shuffling, we have to box values anyway. it might make more sense to just have a system that can hold onto boxes, and only guard on their type when the value is used by some type-dependent operation.&lt;br /&gt;
### The intention of the phrase &amp;quot;selectively despecialize&amp;quot; was that despecialization only occurs sometimes, so most slots/ops stay remain typed.  &amp;quot;just have a system that can hold onto boxes&amp;quot; is exactly what is being called for (just not said so clearly :).&lt;br /&gt;
&lt;br /&gt;
This list below is a more speculative collection of potential design decisions that address the above concerns:&lt;br /&gt;
* Split recording into a profiling phase followed by a more traditional compilation phase.  The compilation phase consumes a data structure built by the profiling phase.&lt;br /&gt;
** Addresses 1 and 5&lt;br /&gt;
** If we want to take advantage of multi-core, this allows a clean shared-nothing hand-off of profile data from the main thread to a compilation thread.&lt;br /&gt;
* Keep the existing bytecode/IR; define a new micro-op IR and a decomposition function that maps a single fato-ops into a set of micro-ops.&lt;br /&gt;
** Resolves conflict 2.2&lt;br /&gt;
** Don&#039;t have to rewrite parser, decompiler, mjit, type inference, etc.&lt;br /&gt;
** May be slow if profiling was done from an interpreter; perhaps let the mjit compiler or a special profiling compiler compile functions with profiling instrumentation.&lt;br /&gt;
*** (dmandelin) I don&#039;t understand the above point. I think the sentence wants to say &amp;quot;let the mjit compiler or a special profiling compiler compile functions with profiling instrumentation&amp;quot;, but I&#039;m not sure. Anyway, I&#039;m not sure about that. We know that we can do 100-400 iters in an interpreter in the time it takes to compile, so if profiling requires fewer runs than that, we should just do it in the interpreter, or a special profiling interpreter.&lt;br /&gt;
**** (luke) Good point; this was written before the 100-400 figure which certainly seems to indicate that we can profile for a while.&lt;br /&gt;
** Can define simple &amp;quot;definitional interpreter&amp;quot; for micro-ops that would (1) help new hackers (2) help isolate bugs in other execution modes.&lt;br /&gt;
** (dmandelin) I think we should think about long-term goals too. Ideally, I would shoot for a &amp;quot;primary&amp;quot; bytecode that helps simplify the compilers as much as possible. I think that would be a thin-op bytecode with an unlimited number of virtual registers. (That may be too far, though--the interpreter would certainly require a register-assignment lowering pass on top of such a thing and we need to keep startup cheap.)&lt;br /&gt;
*** Now, we can&#039;t take the time to overhaul that right now, so for next year I&#039;m with you.&lt;br /&gt;
*** But we should at least have a viable path there, and make what steps we can in that direction.&lt;br /&gt;
* To avoid deep bails:&lt;br /&gt;
** Have the tracer execute in-place instead of in TraceNativeStorage ([https://bugzilla.mozilla.org/show_bug.cgi?id=590871 bug 590871])&lt;br /&gt;
*** (dmandelin) I think this means &amp;quot;do it like the mjit does&amp;quot;, i.e., hold stuff in registers and so on, but know how to save out to the canonical representation at safe points.&lt;br /&gt;
**** Not exactly; more like &amp;quot;do it like the tjit, just on the VM stack, using the VM layout instead of on some separate hunk o&#039; memory (TraceNativeStorage) with a custom layout (VistFrameSlots)&amp;quot;&lt;br /&gt;
** Assume every native called from jit code clobbers globals and visible upvars except those explicitly annotated not to do so in their JSNativeTraceInfo.&lt;br /&gt;
*** Thus, if VM reenters or VM state is modified during call from trace, no assumptions are broken.&lt;br /&gt;
*** Rely on (1) type inference results and (2) redundant-guard elimination to keep computational kernels fast and unfettered.&lt;/div&gt;</summary>
		<author><name>Sfink</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=JavaScript:Projects&amp;diff=1235302</id>
		<title>JavaScript:Projects</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=JavaScript:Projects&amp;diff=1235302"/>
		<updated>2021-04-27T22:09:28Z</updated>

		<summary type="html">&lt;p&gt;Sfink: mark obsolete&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{OutdatedSpiderMonkey}} &lt;br /&gt;
&lt;br /&gt;
This list of active JS projects was compiled from older lists of [https://wiki.mozilla.org/JavaScript:Home_Page#Tracked_Projects tracked projects] and [https://wiki.mozilla.org/Javascript:SpiderMonkey:2013Projects 2013 projects].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= JavaScript Language =&lt;br /&gt;
&lt;br /&gt;
== Parallel JS ==&lt;br /&gt;
* &#039;&#039;&#039;Goal:&#039;&#039;&#039; Expose finer-grain parallelism to JavaScript.&lt;br /&gt;
* &#039;&#039;&#039;Team:&#039;&#039;&#039; sstangl, luke, niko, shu?&lt;br /&gt;
* &#039;&#039;&#039;Tracking bug:&#039;&#039;&#039; {{bug|891877}}&lt;br /&gt;
* &#039;&#039;&#039;More info:&#039;&#039;&#039; Work includes a parallel subset of JS ({{bug|891877}}), RiverTrail/ParallelArray ({{bug|801869}}), and prototyping Shared ArrayBuffers.&lt;br /&gt;
&lt;br /&gt;
== ECMA-402 i18n ==&lt;br /&gt;
* &#039;&#039;&#039;Goal:&#039;&#039;&#039; Implement ECMA-402, the ECMAScript Internationalization API.&lt;br /&gt;
* &#039;&#039;&#039;Developer:&#039;&#039;&#039; jwalden&lt;br /&gt;
* &#039;&#039;&#039;Tracking bug:&#039;&#039;&#039; {{bug|837963}}&lt;br /&gt;
* &#039;&#039;&#039;More info:&#039;&#039;&#039; https://wiki.mozilla.org/User:Waldo/Internationalization_API&lt;br /&gt;
&lt;br /&gt;
== Test262 ==&lt;br /&gt;
* &#039;&#039;&#039;Goal:&#039;&#039;&#039; Integrate test262, ECMA&#039;s ECMAScript conformance test suite, into Mozilla&#039;s tests ({{bug|496923}}) and fix failures ({{bug|652780}}).&lt;br /&gt;
* &#039;&#039;&#039;Developer:&#039;&#039;&#039; jwalden&lt;br /&gt;
* &#039;&#039;&#039;Tracking bug:&#039;&#039;&#039; {{bug|496923}}&lt;br /&gt;
* &#039;&#039;&#039;More info:&#039;&#039;&#039; https://wiki.mozilla.org/User:Waldo/ES6_testing and http://test262.ecmascript.org/&lt;br /&gt;
&lt;br /&gt;
== ES6 ==&lt;br /&gt;
* &#039;&#039;&#039;Goal:&#039;&#039;&#039; Implement ES6 language support.&lt;br /&gt;
* &#039;&#039;&#039;Team:&#039;&#039;&#039; &lt;br /&gt;
* &#039;&#039;&#039;Tracking bug:&#039;&#039;&#039; {{bug|694100}}&lt;br /&gt;
* &#039;&#039;&#039;More info:&#039;&#039;&#039; https://wiki.mozilla.org/ES6_plans&lt;br /&gt;
&lt;br /&gt;
=== Classes ===&lt;br /&gt;
* &#039;&#039;&#039;Goal:&#039;&#039;&#039; Implement classes.&lt;br /&gt;
* &#039;&#039;&#039;Team:&#039;&#039;&#039; &lt;br /&gt;
* &#039;&#039;&#039;Tracking bug:&#039;&#039;&#039; {{bug|837314}}&lt;br /&gt;
* &#039;&#039;&#039;More info:&#039;&#039;&#039; http://wiki.ecmascript.org/doku.php?id=harmony:classes&lt;br /&gt;
&lt;br /&gt;
=== Modules ===&lt;br /&gt;
* &#039;&#039;&#039;Goal:&#039;&#039;&#039; Implement modules.&lt;br /&gt;
* &#039;&#039;&#039;Team:&#039;&#039;&#039; Eddy and Jason?&lt;br /&gt;
* &#039;&#039;&#039;Tracking bug:&#039;&#039;&#039; {{bug|568953}}&lt;br /&gt;
* &#039;&#039;&#039;More info:&#039;&#039;&#039; http://wiki.ecmascript.org/doku.php?id=harmony:modules&lt;br /&gt;
&lt;br /&gt;
=== Symbols ===&lt;br /&gt;
* &#039;&#039;&#039;Goal:&#039;&#039;&#039; Implement symbols (formerly private name objects).&lt;br /&gt;
* &#039;&#039;&#039;Team:&#039;&#039;&#039; Eddy&lt;br /&gt;
* &#039;&#039;&#039;Tracking bug:&#039;&#039;&#039; {{bug|645416}}&lt;br /&gt;
* &#039;&#039;&#039;More info:&#039;&#039;&#039; http://wiki.ecmascript.org/doku.php?id=harmony:private_name_objects&lt;br /&gt;
&lt;br /&gt;
=== Typed Objects ===&lt;br /&gt;
* &#039;&#039;&#039;Goal:&#039;&#039;&#039; Implement typed objects (formerly binary objects) for efficient, structured access to contiguously allocated data.&lt;br /&gt;
* &#039;&#039;&#039;Team:&#039;&#039;&#039; Nikhil, Niko?&lt;br /&gt;
* &#039;&#039;&#039;Tracking bug:&#039;&#039;&#039; {{bug|578700}}&lt;br /&gt;
* &#039;&#039;&#039;More info:&#039;&#039;&#039; http://wiki.ecmascript.org/doku.php?id=harmony:typed_objects&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= GC =&lt;br /&gt;
&lt;br /&gt;
== Generational GC ==&lt;br /&gt;
* &#039;&#039;&#039;Goal:&#039;&#039;&#039; Implement generational garbage collector (GGC) and exactly root Firefox.&lt;br /&gt;
* &#039;&#039;&#039;Team:&#039;&#039;&#039; terrence, sfink, jonco&lt;br /&gt;
* &#039;&#039;&#039;Tracking bug:&#039;&#039;&#039; GGC {{bug|619558}} and Exact Stack Rooting {{bug|753203}}&lt;br /&gt;
* &#039;&#039;&#039;More info:&#039;&#039;&#039; https://wiki.mozilla.org/Javascript:SpiderMonkey:ProjectGenerationGarbageCollection and [https://people.mozilla.org/~sfink/analysis/ rooting hazard burndown chart]&lt;br /&gt;
&lt;br /&gt;
== Memory-dependent GC Configuration ==&lt;br /&gt;
* &#039;&#039;&#039;Goal:&#039;&#039;&#039; &lt;br /&gt;
* &#039;&#039;&#039;Team:&#039;&#039;&#039; TBD&lt;br /&gt;
* &#039;&#039;&#039;Tracking bug:&#039;&#039;&#039; TBD&lt;br /&gt;
* &#039;&#039;&#039;More info:&#039;&#039;&#039; Currently the GC settings are configured for Unagi devices with 256 MB, and even if this is our current target in terms of Market, but we would need to generalize our GC settings to perform best on all devices (see Bug 898556). Even with GGC, we might still have frequenct GCs if we overflow the nursery before the next minor GC.&lt;br /&gt;
&lt;br /&gt;
== Future ==&lt;br /&gt;
* Incremental Browser Marking&lt;br /&gt;
* Compacting GC&lt;br /&gt;
* Nursery allocation of JSStrings&lt;br /&gt;
* G1: The Good Parts {{bug|902174}}&lt;br /&gt;
* Concurrent GC&lt;br /&gt;
&lt;br /&gt;
= Performance =&lt;br /&gt;
&lt;br /&gt;
== ARM/B2G ==&lt;br /&gt;
* &#039;&#039;&#039;Goal:&#039;&#039;&#039; Optimize ARM performance for Firefox OS and Android.&lt;br /&gt;
* &#039;&#039;&#039;Team:&#039;&#039;&#039; dcrosher, jcoppeard, mrosenberg&lt;br /&gt;
* &#039;&#039;&#039;Tracking bug:&#039;&#039;&#039; {{bug|}}&lt;br /&gt;
* &#039;&#039;&#039;More info:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
== AWFY ==&lt;br /&gt;
* &#039;&#039;&#039;Goal:&#039;&#039;&#039; Optimize AWFY benchmarks.&lt;br /&gt;
* &#039;&#039;&#039;Team:&#039;&#039;&#039; &lt;br /&gt;
* &#039;&#039;&#039;Tracking bug:&#039;&#039;&#039; {{bug|}}&lt;br /&gt;
* &#039;&#039;&#039;More info:&#039;&#039;&#039; http://arewefastyet.com/&lt;br /&gt;
&lt;br /&gt;
== OdinMonkey ==&lt;br /&gt;
* &#039;&#039;&#039;Goal:&#039;&#039;&#039; Optimize OdinMonkey and Emscripten.&lt;br /&gt;
* &#039;&#039;&#039;Team:&#039;&#039;&#039; luke, alon&lt;br /&gt;
* &#039;&#039;&#039;More info:&#039;&#039;&#039; https://wiki.mozilla.org/Javascript:SpiderMonkey:OdinMonkey&lt;br /&gt;
** Visual Studio integration with Emscripten - Naveed waiting on contractor SOW&lt;br /&gt;
&lt;br /&gt;
== Web Browser Grand Prix ==&lt;br /&gt;
* &#039;&#039;&#039;Goal:&#039;&#039;&#039; Beat Chrome on Tom&#039;s Hardware&#039;s Web Browser Grand Prix (WBGP). Run Peacekeeper, Browsermark, and JSBench benchmarks in-house.&lt;br /&gt;
* &#039;&#039;&#039;Team:&#039;&#039;&#039; Naveed&lt;br /&gt;
* &#039;&#039;&#039;Tracking bug:&#039;&#039;&#039; {{bug|499198}}, {{bug|851699}}&lt;br /&gt;
* &#039;&#039;&#039;More info:&#039;&#039;&#039; http://browsermark.rightware.com/&lt;br /&gt;
&lt;br /&gt;
== Selenium Browser Benchmark ==&lt;br /&gt;
* &#039;&#039;&#039;Goal:&#039;&#039;&#039; Create a test framework to browse real websites using Selenium scripts and measure performance regressions. &lt;br /&gt;
* &#039;&#039;&#039;Team:&#039;&#039;&#039; jmaher, bclary, luke&lt;br /&gt;
* &#039;&#039;&#039;Tracking bug:&#039;&#039;&#039; {{bug|}}&lt;br /&gt;
* &#039;&#039;&#039;More info:&#039;&#039;&#039; The A-Team is implementing this test framework with input from Luke. https://etherpad.mozilla.org/js-benchmarking&lt;br /&gt;
&lt;br /&gt;
== Start-up Cache ==&lt;br /&gt;
* &#039;&#039;&#039;Goal:&#039;&#039;&#039; Cache JS bytecode as &amp;quot;extra data&amp;quot; for B2G apps. The target would be to land with support of packaged app for B2G 1.4 / 1.5 (Gecko 30 / 32).&lt;br /&gt;
* &#039;&#039;&#039;Team:&#039;&#039;&#039; npierron&lt;br /&gt;
* &#039;&#039;&#039;Tracking bug:&#039;&#039;&#039; {{bug|900784}}&lt;br /&gt;
* &#039;&#039;&#039;More info:&#039;&#039;&#039; https://wiki.mozilla.org/Javascript:SpiderMonkey:StartupCache&lt;br /&gt;
&lt;br /&gt;
= Dev Tools =&lt;br /&gt;
&lt;br /&gt;
== jsdbg2 ==&lt;br /&gt;
* &#039;&#039;&#039;Goal:&#039;&#039;&#039; Add profiling API ({{bug|797876}}) and JIT stack debugging ({{bug|716647}}) jsdbg2, then remove JSD1 ({{bug|800200}}).&lt;br /&gt;
* &#039;&#039;&#039;Team:&#039;&#039;&#039; TBD&lt;br /&gt;
* &#039;&#039;&#039;Tracking bug:&#039;&#039;&#039; {{bug|800200}}&lt;br /&gt;
* &#039;&#039;&#039;More info:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
= Technical Debt =&lt;br /&gt;
&lt;br /&gt;
== Run TBPL Tests On All Platforms ==&lt;br /&gt;
* &#039;&#039;&#039;Goal:&#039;&#039;&#039; Get our existing test suites running on TBPL in all combinations of the shell and browser on both desktop and ARM.&lt;br /&gt;
* &#039;&#039;&#039;Team:&#039;&#039;&#039; &lt;br /&gt;
* &#039;&#039;&#039;Tracking bug:&#039;&#039;&#039; {{bug|}}&lt;br /&gt;
* &#039;&#039;&#039;More info:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
== Minimize Header Dependencies ==&lt;br /&gt;
* &#039;&#039;&#039;Goal:&#039;&#039;&#039; Reduce header dependencies of jsapi.h and friends to improve rebuild times.&lt;br /&gt;
* &#039;&#039;&#039;Team:&#039;&#039;&#039; njn&lt;br /&gt;
* &#039;&#039;&#039;Tracking bug:&#039;&#039;&#039; {{bug|908050}}&lt;br /&gt;
* &#039;&#039;&#039;More info:&#039;&#039;&#039; {{bug|785103}} tracks header minimization for all of Gecko.&lt;br /&gt;
&lt;br /&gt;
== Refactor MOP ==&lt;br /&gt;
* &#039;&#039;&#039;Goal:&#039;&#039;&#039; Update meta-object protocol to be more ES5/ES6-like.&lt;br /&gt;
* &#039;&#039;&#039;Team:&#039;&#039;&#039; jwalden&lt;br /&gt;
* &#039;&#039;&#039;Tracking bug:&#039;&#039;&#039; MOP {{bug|637378}} and property/element {{bug|586842}}&lt;br /&gt;
* &#039;&#039;&#039;More info:&#039;&#039;&#039; https://wiki.mozilla.org/Javascript:SpiderMonkey:PropertyElementStorage&lt;br /&gt;
&lt;br /&gt;
== Remove JSContext ==&lt;br /&gt;
* &#039;&#039;&#039;Goal:&#039;&#039;&#039; The single-threaded JSRuntime makes JSContext unnecessary, but most of the work is to make Gecko stop depending on them ({{bug|767938}}).&lt;br /&gt;
* &#039;&#039;&#039;Team:&#039;&#039;&#039; &lt;br /&gt;
* &#039;&#039;&#039;Tracking bug:&#039;&#039;&#039; JSContext {{bug|650361}} and Gecko {{bug|767938}}&lt;br /&gt;
* &#039;&#039;&#039;More info:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
= Research =&lt;br /&gt;
&lt;br /&gt;
== Shumway ==&lt;br /&gt;
* &#039;&#039;&#039;Goal:&#039;&#039;&#039; Add built-in SWF support to Firefox with Shumway.&lt;br /&gt;
* &#039;&#039;&#039;Team:&#039;&#039;&#039; mbebenita, shu, till, tobeytailor, ydelendik&lt;br /&gt;
* &#039;&#039;&#039;Tracking bug:&#039;&#039;&#039; {{bug|904346}}&lt;br /&gt;
* &#039;&#039;&#039;More info:&#039;&#039;&#039; http://www.areweflashyet.com/&lt;/div&gt;</summary>
		<author><name>Sfink</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=JavaScript&amp;diff=1235261</id>
		<title>JavaScript</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=JavaScript&amp;diff=1235261"/>
		<updated>2021-04-27T20:46:30Z</updated>

		<summary type="html">&lt;p&gt;Sfink: nuke the old content&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Are you looking for documentation about the JavaScript language? You probably want the [https://developer.mozilla.org/docs/Web/JavaScript Mozilla Developer Network JavaScript site].&lt;br /&gt;
&lt;br /&gt;
For SpiderMonkey, the JavaScript engine that powers Firefox, see [https://spidermonkey.dev/ SpiderMonkey.dev].&lt;/div&gt;</summary>
		<author><name>Sfink</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=JavaScript:SpiderMonkey:Coding_Style&amp;diff=1213556</id>
		<title>JavaScript:SpiderMonkey:Coding Style</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=JavaScript:SpiderMonkey:Coding_Style&amp;diff=1213556"/>
		<updated>2019-06-10T17:33:45Z</updated>

		<summary type="html">&lt;p&gt;Sfink: /* Functions */  namespaces&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Code Organization =&lt;br /&gt;
&lt;br /&gt;
See [[JavaScript:SpiderMonkey:Directories]].&lt;br /&gt;
&lt;br /&gt;
= Functions =&lt;br /&gt;
&lt;br /&gt;
* Public function names go into the JS namespace, with the function name &amp;quot;intercaps&amp;quot;, e.g. JS_NewObject.&lt;br /&gt;
** Older functions may begin with JS_. Use the namespace instead in new code.&lt;br /&gt;
* Extern but library-private function names use the js namespace and mixed case, e.g. js_SearchScope.&lt;br /&gt;
* Most static function names have unprefixed, mixed-case names: GetChar.&lt;br /&gt;
* But static native methods of JS objects have lowercase, underscore-separated or intercaps names, e.g., str_indexOf.&lt;br /&gt;
* Function return types are on a separate line preceding the function name.&lt;br /&gt;
* Function braces go on the line following the function name.&lt;br /&gt;
 void DoThis()           /* bad */&lt;br /&gt;
 {&lt;br /&gt;
     ...&lt;br /&gt;
 }&lt;br /&gt;
 void&lt;br /&gt;
 DoThis()                /* OK */&lt;br /&gt;
 {&lt;br /&gt;
     ...&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
= Other Symbols =&lt;br /&gt;
&lt;br /&gt;
* Library-private and static data use underscores, not intercaps (but library-private data do use a js_ prefix).&lt;br /&gt;
* Scalar type names are lowercase and js-prefixed: jsdouble.&lt;br /&gt;
* Aggregate type names are JS-prefixed and mixed-case: JSObject.&lt;br /&gt;
* Macros are generally ALL_CAPS and underscored, to call out potential side effects, multiple uses of a formal argument, etc.  Line continuation characters should all line up, in column 79 if that exceeds the width of all the macro text.  Macro parameters should be of the form name_ (instead of something like __name).&lt;br /&gt;
&lt;br /&gt;
= Indentation =&lt;br /&gt;
&lt;br /&gt;
* Use spaces, not tabs.  There should be no tabs in source files.&lt;br /&gt;
* Four spaces of indentation per statement nesting level.&lt;br /&gt;
* &amp;quot;&amp;lt;code&amp;gt;case L:&amp;lt;/code&amp;gt;&amp;quot; labels in &amp;lt;code&amp;gt;switch&amp;lt;/code&amp;gt; statements count as half of a nesting level, so indent two spaces, with the labeled statements indenting two more for a standard four spaces indentation from &amp;lt;code&amp;gt;switch&amp;lt;/code&amp;gt; to a case-controlled statement.&lt;br /&gt;
 switch (discriminant) {&lt;br /&gt;
   case L1:&lt;br /&gt;
     DoSomething();&lt;br /&gt;
   . . .&lt;br /&gt;
 }&lt;br /&gt;
* Function arguments that overflow the first line of the call expression should be aligned to underhang the first argument (to start in overflow lines in the column after the opening parenthesis).&lt;br /&gt;
 JS_SetContext(rt,         /* bad */&lt;br /&gt;
              cx);&lt;br /&gt;
 JS_SetContext(rt,         /* OK */&lt;br /&gt;
               cx);&lt;br /&gt;
&lt;br /&gt;
= Whitespace in declarations =&lt;br /&gt;
&lt;br /&gt;
These rules are inconsistently applied.  Be consistent with the code you&#039;re editing rather than adhere too closely to these guidelines!&lt;br /&gt;
&lt;br /&gt;
* In a declaration of a pointer, the &amp;lt;code&amp;gt;*&amp;lt;/code&amp;gt; goes with the type:&lt;br /&gt;
 char *s;                  /* bad */&lt;br /&gt;
 char* s;                  /* OK */&lt;br /&gt;
* In C++ method declarations with default arguments, use spaces and comments like so:&lt;br /&gt;
 static void&lt;br /&gt;
 Frob(JSContext* cx, uint32_t defaultValue = 0);&lt;br /&gt;
 static void&lt;br /&gt;
 Frob(JSContext* cx, uint32_t defaultValue /* = 0 */)&lt;br /&gt;
 {&lt;br /&gt;
     /* ... */&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
= Other whitespace =&lt;br /&gt;
&lt;br /&gt;
* Code should fit within 99 columns; comments should fit within 80 columns; both figures include indentation. Break down lines that are too long by splitting after a binary operator.&lt;br /&gt;
* Exception: in a &amp;lt;code&amp;gt;switch&amp;lt;/code&amp;gt; statement where each case is a trivially-short statement, it&#039;s ok to put the &amp;lt;code&amp;gt;case&amp;lt;/code&amp;gt;, the statement, and the &amp;lt;code&amp;gt;break;&amp;lt;/code&amp;gt; all on one line.&lt;br /&gt;
* Comment &amp;lt;code&amp;gt;/* FALL THROUGH */&amp;lt;/code&amp;gt; in place of missing &amp;lt;code&amp;gt;break&amp;lt;/code&amp;gt; when intentionally falling through from one case-controlled statement sequence into another, or into the &amp;lt;code&amp;gt;default&amp;lt;/code&amp;gt; statements.&lt;br /&gt;
* Do not use spaces between a function name and its arguments list, or between an array name and the square bracket. Also, do no use spaces after a bracket. Use a space after a comma to separate arguments.&lt;br /&gt;
 JS_SetContext ( rt, cx ); /* bad */&lt;br /&gt;
 JS_SetContext(rt, cx);    /* OK */&lt;br /&gt;
* Use a space between a C keyword and parentheses.&lt;br /&gt;
 if(condition) {             /* bad */&lt;br /&gt;
 if (condition) {            /* OK */&lt;br /&gt;
* Always use braces for conditionals, even if the condition and consequent occupy single lines.&lt;br /&gt;
&lt;br /&gt;
 if (!isAwake) {&lt;br /&gt;
     return false;&lt;br /&gt;
 }&lt;br /&gt;
 if (canSwingFromWeb) {&lt;br /&gt;
     p-&amp;gt;swingFromWeb();&lt;br /&gt;
 } else {&lt;br /&gt;
     MOZ_ASSERT(p-&amp;gt;isSpiderPig());&lt;br /&gt;
     p-&amp;gt;doWhateverSpiderPigDoes();&lt;br /&gt;
 }&lt;br /&gt;
 if (hungryForBananas &amp;amp;&amp;amp; // and a comment makes the line long enough for a linebreak&lt;br /&gt;
     wantsAttentionInTheWorstWay)&lt;br /&gt;
 {&lt;br /&gt;
     p-&amp;gt;eatBananasAndPreen();&lt;br /&gt;
 }&lt;br /&gt;
* Conditions with multi-line tests should put the brace on the new line to provide a visual separation between the condition and the body.&lt;br /&gt;
&lt;br /&gt;
   types::TypeSet* types = frame.extra(lhs).types;&lt;br /&gt;
   if (JSOp(*PC) == JSOP_SETPROP &amp;amp;&amp;amp; id == types::MakeTypeId(cx, id) &amp;amp;&amp;amp;&lt;br /&gt;
       types &amp;amp;&amp;amp; !types-&amp;gt;unknownObject() &amp;amp;&amp;amp;&lt;br /&gt;
       types-&amp;gt;getObjectCount() == 1 &amp;amp;&amp;amp;&lt;br /&gt;
       types-&amp;gt;getTypeObject(0) != nullptr &amp;amp;&amp;amp;&lt;br /&gt;
       !types-&amp;gt;getTypeObject(0)-&amp;gt;unknownProperties())&lt;br /&gt;
   {&lt;br /&gt;
       JS_ASSERT(usePropCache);&lt;br /&gt;
       types::TypeObject* object = types-&amp;gt;getTypeObject(0);&lt;br /&gt;
       types::TypeSet* propertyTypes = object-&amp;gt;getProperty(cx, id, false);&lt;br /&gt;
       ...&lt;br /&gt;
   } else {&lt;br /&gt;
       ...&lt;br /&gt;
   }&lt;br /&gt;
However, if there is already a visual separation between the condition and the body, putting the { on a new line isn&#039;t necessary:&lt;br /&gt;
&lt;br /&gt;
   if (forHead-&amp;gt;pn_kid1 &amp;amp;&amp;amp; NewSrcNote2(cx, cg, SRC_DECL,&lt;br /&gt;
                                       (forHead-&amp;gt;pn_kid1-&amp;gt;isOp(JSOP_DEFVAR))&lt;br /&gt;
                                       ? SRC_DECL_VAR&lt;br /&gt;
                                       : SRC_DECL_LET) &amp;lt; 0) {&lt;br /&gt;
       return false;&lt;br /&gt;
   }&lt;br /&gt;
* &amp;lt;code&amp;gt;for&amp;lt;/code&amp;gt; loop heads go on one line where possible; when not possible, initializer part, update, and termination parts each go on separate lines&lt;br /&gt;
 for (int i = 0;&lt;br /&gt;
      i &amp;lt; 5;&lt;br /&gt;
      i++) {                 /* bad, could all fit on one line */&lt;br /&gt;
     doStuff();&lt;br /&gt;
 }&lt;br /&gt;
 for (int i = 0; i &amp;lt; 5; i++) { /* OK */&lt;br /&gt;
     doStuff();&lt;br /&gt;
 }&lt;br /&gt;
 for (size_t ind = JSObject::JSSLOT_DATE_COMPONENTS_START;&lt;br /&gt;
      ind &amp;lt; JSObject::DATE_FIXED_RESERVED_SLOTS; ind++) {   /* bad */&lt;br /&gt;
     obj-&amp;gt;setSlot(ind, DoubleValue(utcTime));&lt;br /&gt;
 }&lt;br /&gt;
 for (size_t ind = JSObject::JSSLOT_DATE_COMPONENTS_START;&lt;br /&gt;
      ind &amp;lt; JSObject::DATE_FIXED_RESERVED_SLOTS;&lt;br /&gt;
      ind++) {                                               /* OK */&lt;br /&gt;
     obj-&amp;gt;setSlot(ind, DoubleValue(utcTime));&lt;br /&gt;
 }&lt;br /&gt;
* In comments, use one space, not two, between sentences and after a colon.&lt;br /&gt;
&lt;br /&gt;
= Control Flow =&lt;br /&gt;
&lt;br /&gt;
* Minimize indentation using return, break, and continue where appropriate.  Prefer return (break, continue) statements to cast out abnormal cases, instead of nesting &amp;quot;if/else&amp;quot; statements and indenting the common cases.&lt;br /&gt;
 void&lt;br /&gt;
 MyFunction(int n)&lt;br /&gt;
 {&lt;br /&gt;
     if (n) {              /* bad */&lt;br /&gt;
         ...&lt;br /&gt;
     }&lt;br /&gt;
 }&lt;br /&gt;
 void&lt;br /&gt;
 MyFunction(int n)&lt;br /&gt;
 {&lt;br /&gt;
     if (!n) {&lt;br /&gt;
         return;           /* OK */&lt;br /&gt;
     }&lt;br /&gt;
     ...&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
* If an &amp;quot;if&amp;quot; statement controls a &amp;quot;then&amp;quot; clause ending in a return statement, do not use &amp;quot;else&amp;quot; after return.&lt;br /&gt;
 if (condition) {          /* bad */&lt;br /&gt;
     DoThis();&lt;br /&gt;
     return;&lt;br /&gt;
 } else {&lt;br /&gt;
     DoThat();&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 if (condition) {          /* OK */&lt;br /&gt;
     DoThis();&lt;br /&gt;
     return;&lt;br /&gt;
 }&lt;br /&gt;
 DoThat();&lt;br /&gt;
&lt;br /&gt;
* Avoid similar arbitrary patterns and non-sequiturs:&lt;br /&gt;
 if (condition) {          /* bad */&lt;br /&gt;
     DoThis();&lt;br /&gt;
     DoThat();&lt;br /&gt;
 } else {&lt;br /&gt;
     CleanUp();&lt;br /&gt;
     return;&lt;br /&gt;
 }&lt;br /&gt;
 DoTheOther();&lt;br /&gt;
 if (!condition) {         /* OK */&lt;br /&gt;
     CleanUp();&lt;br /&gt;
     return;&lt;br /&gt;
 }&lt;br /&gt;
 DoThis();&lt;br /&gt;
 DoThat();&lt;br /&gt;
 DoTheOther();&lt;br /&gt;
&lt;br /&gt;
* Avoid using &amp;amp;&amp;amp; or || to mix deciding-whether-to-do-something with error-checking.&lt;br /&gt;
&lt;br /&gt;
 if (obj-&amp;gt;hasProblems() &amp;amp;&amp;amp; !obj-&amp;gt;rectify()) {   /* bad */&lt;br /&gt;
     return false;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 if (obj-&amp;gt;hasProblems()) {                      /* OK */&lt;br /&gt;
     if (!obj-&amp;gt;rectify()) {&lt;br /&gt;
         return false;&lt;br /&gt;
     }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
= Comments =&lt;br /&gt;
&lt;br /&gt;
* In C files, always use C style comments.  C++ comments are ok otherwise.&lt;br /&gt;
* Terminate a comment with a period (so try to make comments be complete sentences).&lt;br /&gt;
 /* This is a good comment. */&lt;br /&gt;
 // This is also a good comment.&lt;br /&gt;
* For C-style multiline comments, align with any indentation, and start every line with an asterisk. Asterisks stack in the same column. Precede the multiline comment with one empty line unless the prior line ends in a left brace. The first line of the comment contains only leading space followed by &amp;lt;code&amp;gt;/*&amp;lt;/code&amp;gt;. Multiline comments should also be bracketed.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if (condition) {&lt;br /&gt;
    /*&lt;br /&gt;
     * This is a lengthy C-style&lt;br /&gt;
     * multiline comment.&lt;br /&gt;
     */&lt;br /&gt;
    // This is a length&lt;br /&gt;
    // C++-style comment&lt;br /&gt;
    DoYourStuff();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Entry Points and Callbacks =&lt;br /&gt;
&lt;br /&gt;
* DLL entry points have their return type expanded within a JS_PUBLIC_API() macro call, to get the right Windows secret type qualifiers in the right places for all build variants.&lt;br /&gt;
* Callback functions that might be called from a DLL are similarly macroized with JS_STATIC_DLL_CALLBACK (if the function otherwise would be static to hide its name) or JS_DLL_CALLBACK (this macro takes no type argument; it should be used after the return type and before the function name).&lt;br /&gt;
&lt;br /&gt;
= Data Types and Alignments =&lt;br /&gt;
&lt;br /&gt;
* As with all Mozilla code, SpiderMonkey needs to compile and execute correctly on many platforms, including 64-bits systems.&lt;br /&gt;
* JS and NSPR have common roots in the dawn of time (Netscape 2), and the &amp;lt;code&amp;gt;JS_THREADSAFE&amp;lt;/code&amp;gt; mode of building SpiderMonkey depends on NSPR, so reading the [http://www.mozilla.org/projects/nspr/reference/html/ NSPR documentation] is well worth your while.&lt;br /&gt;
* Not all 64-bit systems use the same integer type model: some are &amp;quot;LP64&amp;quot; (long and pointer are 64 bits, int is 32 bits), while others are &amp;quot;LLP64&amp;quot; (only long long and pointer are 64 bits; long and int are 32 bits).&lt;br /&gt;
* Use size_t for unsigned number of bytes variables, ptrdiff_t for signed pointer subtraction results.  In particular, do not use uintN, which is just shorthand for unsigned int, and so may not be big enough.&lt;br /&gt;
&lt;br /&gt;
= Header files =&lt;br /&gt;
&lt;br /&gt;
== #ifndef wrappers ==&lt;br /&gt;
&lt;br /&gt;
Use this exact form for #ifndef wrappers in header files:&lt;br /&gt;
&lt;br /&gt;
  #ifndef &amp;lt;guard&amp;gt;&lt;br /&gt;
  #define &amp;lt;guard&amp;gt;&lt;br /&gt;
  ...&lt;br /&gt;
  #endif // &amp;lt;guard&amp;gt;&lt;br /&gt;
&lt;br /&gt;
GCC and clang recognize this idiom and avoid re-reading headers that use it.  Don&#039;t put any code before the #ifndef or after the #endif, and don&#039;t put anything else in the #ifndef, otherwise the optimization will be thwarted and the file will be multiply-included.  (Check with the -H option if you want to be sure.)&lt;br /&gt;
&lt;br /&gt;
Include guards should be named by determining the fully-qualified include path,&lt;br /&gt;
then substituting _ for &#039;/&#039; and &#039;.&#039; and &#039;-&#039; in it.  For example, js/src/vm/Stack-inl.h&#039;s guard is vm_Stack_inl_h_, and js/public/Vector.h&#039;s guard is js_Vector_h (because its include path is js/Vector.h).&lt;br /&gt;
&lt;br /&gt;
== #include paths ==&lt;br /&gt;
&lt;br /&gt;
All #include statements should use a fully-qualified (within SpiderMonkey) path, even if it&#039;s not necessary.  For example, this:&lt;br /&gt;
&lt;br /&gt;
  #include &amp;quot;vm/Stack.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
not:&lt;br /&gt;
&lt;br /&gt;
  #include &amp;quot;Stack.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
This keeps things consistent and helps with the ordering.&lt;br /&gt;
&lt;br /&gt;
For headers in js/public/, the prefix is &amp;quot;js/&amp;quot;, e.g.:&lt;br /&gt;
&lt;br /&gt;
  #include &amp;quot;js/Vector.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
For headers in mfbt/, the prefix is &amp;quot;mozilla/&amp;quot;, e.g.:&lt;br /&gt;
&lt;br /&gt;
  #include &amp;quot;mozilla/Assertions.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== #include ordering ==&lt;br /&gt;
&lt;br /&gt;
The following order is used for module X:  &lt;br /&gt;
* If X-inl.h exists, it goes first.  (And X-inl.h&#039;s first #include should be X.h.) Otherwise, X.h goes first.  This rule ensures that X.h and X-inl.h both #include all the headers that they need themselves.&lt;br /&gt;
* mozilla/*.h&lt;br /&gt;
* &amp;lt;*.h&amp;gt;&lt;br /&gt;
* js*.h&lt;br /&gt;
* */*.h (this includes the public JSAPI headers in js/public/*.h which should be included using the form js/*.h)&lt;br /&gt;
* js*inlines.h&lt;br /&gt;
* */*-inl.h.&lt;br /&gt;
&lt;br /&gt;
Keep (case-insensitive) lexicographic order with each section.&lt;br /&gt;
&lt;br /&gt;
The presence of conditionally-compiled #include statements complicates thing.  If you have a single #include statement within a #if/#ifdef/#ifndef block, placing the block in the appropriate section is straightforward.  If you have multiple #include statements within a block, use your judgment as to where the best place for it is.&lt;br /&gt;
&lt;br /&gt;
Example for X.cpp:&lt;br /&gt;
&lt;br /&gt;
 #include &amp;quot;X.h&amp;quot;    // put &amp;quot;X-inl.h&amp;quot; instead, if it exists&lt;br /&gt;
 &lt;br /&gt;
 #include &amp;quot;mozilla/HashFunctions.h&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #include &amp;lt;string.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 #include &amp;quot;jsbar.h&amp;quot;&lt;br /&gt;
 #ifdef BAZ&lt;br /&gt;
 # include &amp;quot;jsbaz.h&amp;quot;&lt;br /&gt;
 #endif&lt;br /&gt;
 #include &amp;quot;jscaz.h&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #include &amp;quot;ds/Baz.h&amp;quot;&lt;br /&gt;
 #include &amp;quot;js/Bar.h&amp;quot;&lt;br /&gt;
 #include &amp;quot;vm/Bat.h&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #include &amp;quot;jssqueeinlines.h&amp;quot;&lt;br /&gt;
 #include &amp;quot;jswoot-inl.h&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #include &amp;quot;frontend/Thingamabob-inl.h&amp;quot;&lt;br /&gt;
 #include &amp;quot;vm/VirtualReality-inl.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
= C++ =&lt;br /&gt;
&lt;br /&gt;
== Namespaces ==&lt;br /&gt;
&lt;br /&gt;
* Public functions and types should be in the JS:: namespace, in preference to the old JS/JS_ name prefixes.&lt;br /&gt;
* Library-private and friend functions should be in the js:: namespace, in preference to the old js_ name prefix.&lt;br /&gt;
* Compile-time-evaluated functions (i.e., template meta-functions) should be in &#039;js::tl::&#039;, the &amp;quot;template library&amp;quot; namespace, to avoid collision with their runtime counterparts.&lt;br /&gt;
* In SpiderMonkey .cpp files, it is okay to have &#039;using namespace js;&#039;, but it is not okay to do the same with any other namespace, like JS:: or mozilla::. These can introduce ambiguities that come and go depending on which .cpp files the build system decides to unify.&lt;br /&gt;
* If you do have names in JS:: that should be readily available throughout SpiderMonkey, you may add a &#039;using&#039; declaration to js/src/NamespaceImports.h.&lt;br /&gt;
* Avoid unnamed namespaces unless they are necessary to give a class&#039;s members internal linkage.  Although the C++ standard officially deprecates &#039;static&#039; on  functions, &#039;static&#039; has the following advantages over unnamed namespaces:&lt;br /&gt;
** It is difficult to name functions in unnamed namespaces in gdb.&lt;br /&gt;
** Static says &amp;quot;this is a translation-unit-local helper function&amp;quot; on the function, without having to look around for an enclosing &amp;quot;namespace {&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Enums ==&lt;br /&gt;
&lt;br /&gt;
Older code uses SHOUT_REALLY_LOUD for enum values, newer code uses InterCaps. Enums should be preferred to boolean arguments for ease of understanding at the invocation site.&lt;br /&gt;
&lt;br /&gt;
== Classes ==&lt;br /&gt;
&lt;br /&gt;
* For reasonable-sized classes, put all the fields together, at the top, immediately after any necessary typedefs. For unreasonably large classes, do whatever seems best (but let&#039;s try to avoid making more of these).&lt;br /&gt;
* Align the braces of a class/struct/enum definition like this:&lt;br /&gt;
 class JSObject&lt;br /&gt;
 {&lt;br /&gt;
      ...&lt;br /&gt;
 };&lt;br /&gt;
* Member variable names, private or public, should be decorated with a trailing &#039;_&#039;.&lt;br /&gt;
 class Fail&lt;br /&gt;
 {&lt;br /&gt;
     size_t capacity;  // common&lt;br /&gt;
     T* begin_;        // better, gravitate toward this&lt;br /&gt;
 };&lt;br /&gt;
Sometimes a canonical argument name may conflict with a member name.  In this case, one can disambiguate with &amp;quot;this-&amp;gt;&amp;quot;, although such explicit qualification should only be added when necessary:&lt;br /&gt;
 class C&lt;br /&gt;
 {&lt;br /&gt;
   public:&lt;br /&gt;
     size_t count;&lt;br /&gt;
     bool fresh;&lt;br /&gt;
     void change(size_t count) {&lt;br /&gt;
         this-&amp;gt;count = count;&lt;br /&gt;
         this-&amp;gt;fresh = false;  // verbose and unnecessary&lt;br /&gt;
     }&lt;br /&gt;
 };&lt;br /&gt;
* Prefer inline functions to macros.&lt;br /&gt;
* We build with C++ exceptions disabled, so most of the &amp;lt;code&amp;gt;std&amp;lt;/code&amp;gt; namespace is off-limits, including STL containers. The exception is &amp;lt;code&amp;gt;&amp;amp;lt;algorithm&amp;amp;gt;&amp;lt;/code&amp;gt;, which is mostly OK to use. You can use MFBT. We have some STL-like containers that are used basically everywhere (see js::Vector, js::HashMap, etc.)&lt;br /&gt;
&lt;br /&gt;
=== Initializer lists ===&lt;br /&gt;
&lt;br /&gt;
Initializer lists can break in one of two ways. The first may be preferable when constructors take few arguments:&lt;br /&gt;
&lt;br /&gt;
 class Ninja : public WeaponWeilder, public Camouflagible,&lt;br /&gt;
               public Assassinatable, public ShapeShiftable&lt;br /&gt;
 {&lt;br /&gt;
     Ninja() : WeaponWeilder(Weapons::SHURIKEN),&lt;br /&gt;
               Camouflagible(Garments::SHINOBI_SHOZOKU),&lt;br /&gt;
               Assassinatable(AssassinationDifficulty::HIGHLY_DIFFICULT),&lt;br /&gt;
               ShapeShiftable(MPCost(512)) {}&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
The other permitted style mitigates longer-identifiers-squishing-text-against-the-right-side-of-the-screen-syndrome by using a half-indented colon:&lt;br /&gt;
&lt;br /&gt;
 class Ninja&lt;br /&gt;
   : public WeaponWeilder, public Camouflagible, public Assassinatable,&lt;br /&gt;
     public ShapeShiftable&lt;br /&gt;
 {&lt;br /&gt;
     Ninja()&lt;br /&gt;
       : WeaponWeilder(Weapons::SHURIKEN),&lt;br /&gt;
         Camouflagible(Garments::SHINOBI_SHOZOKU),&lt;br /&gt;
         Assassinatable(AssassinationDifficulty::HIGHLY_DIFFICULT),&lt;br /&gt;
         ShapeShiftable(MPCost(512)) {}&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== Inline methods ===&lt;br /&gt;
&lt;br /&gt;
If the method in question fits on one line and is branch free, do a one liner:&lt;br /&gt;
&lt;br /&gt;
 class Eater&lt;br /&gt;
 {&lt;br /&gt;
     void eat(Eaten &amp;amp;other) { other.setConsumed(); }&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
If it&#039;s too long, put the type, declarator including formals (unless they overflow), and left brace all on the first line:&lt;br /&gt;
&lt;br /&gt;
 class Eater&lt;br /&gt;
 {&lt;br /&gt;
     Food* obtainFoodFromEatery(Eatery&amp;amp; eatery) {&lt;br /&gt;
         if (!eatery.hasFood()) {&lt;br /&gt;
             return nullptr;&lt;br /&gt;
         }&lt;br /&gt;
         return eatery.purchaseFood();&lt;br /&gt;
     }&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
For out-of-line inlines (when the definitions are too unwieldy to place in the class definition) use the inline keyword as an indicator that there&#039;s an out-of-line inline definition:&lt;br /&gt;
&lt;br /&gt;
 class SpaceGoo&lt;br /&gt;
 {&lt;br /&gt;
     inline BlobbyWrapper* enblob(Entity&amp;amp; other);&lt;br /&gt;
 };&lt;br /&gt;
 &lt;br /&gt;
 inline BlobbyWrapper*&lt;br /&gt;
 SpaceGoo::enblob(Entity &amp;amp;other)&lt;br /&gt;
 {&lt;br /&gt;
     /* ... */&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* [https://developer.mozilla.org/en/Mozilla_Coding_Style_Guide Mozilla&#039;s coding style guide].&lt;br /&gt;
* [http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml Google&#039;s C++ coding style guide].&lt;br /&gt;
&lt;br /&gt;
= Exceptions to this coding style =&lt;br /&gt;
&lt;br /&gt;
SpiderMonkey contains some code imported from other projects, e.g. ctypes/libffi/, that is minimally modified.  Such code does not have to follow SpiderMonkey style.&lt;/div&gt;</summary>
		<author><name>Sfink</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=WeeklyUpdates&amp;diff=1213114</id>
		<title>WeeklyUpdates</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=WeeklyUpdates&amp;diff=1213114"/>
		<updated>2019-05-31T20:58:24Z</updated>

		<summary type="html">&lt;p&gt;Sfink: /* Meeting Notes */ added next mtg&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;:&#039;&#039;Mozilla weekly all-hands meetings. For the semi-annual meetings see [[All Hands]]. These updates concern Mozilla as a whole. For the weekly Firefox meetings, see [[Firefox/DeliveryMeetings]], for Gecko progress, see [[Platform#Meeting_Notes]].&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
==Meeting Details==&lt;br /&gt;
*Every Monday @ 11:00am Pacific Time (18:00 UTC) &lt;br /&gt;
*Mozilla HQ, Ten Forward commons area &lt;br /&gt;
{{conf|8600}}&lt;br /&gt;
*http://air.mozilla.org/ to watch and listen &lt;br /&gt;
*join #weekly-project-call on irc.mozilla.org or Slack for backchannel discussion&lt;br /&gt;
*&#039;&#039;&#039;Presenters only&#039;&#039;&#039;: Vidyo room &amp;quot;Brownbags&amp;quot;.  Do &#039;&#039;not&#039;&#039; use this room if you&#039;re not planning to speak.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Agenda:&#039;&#039;&#039; [[WeeklyUpdates/{{#time: Y-m-d | monday}}|Next Week&#039;s Agenda]]&lt;br /&gt;
&lt;br /&gt;
When you call in, you&#039;ll be muted by default, to keep phone noise doMwn. Use &amp;quot;*1&amp;quot; (including the star) to unmute yourself if you want to say something. &lt;br /&gt;
&lt;br /&gt;
Full notes below. &amp;lt;!-- See https://wiki.mozilla.org/WeeklyUpdates/Template for create new page --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Meeting Notes==&lt;br /&gt;
[[Template:WeeklyUpdates]] - &amp;lt;nowiki&amp;gt;{{subst:WeeklyUpdates}}&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;!--*[[WeeklyUpdates/Template]]--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Create a new weekly agenda from the [[Template:WeeklyUpdates|template]]:&lt;br /&gt;
&amp;lt;createbox&amp;gt;&lt;br /&gt;
align=left&lt;br /&gt;
type=create&lt;br /&gt;
preload=Template:WeeklyUpdates&lt;br /&gt;
default={{#time: Y-m-d | monday}}&lt;br /&gt;
prefix=WeeklyUpdates&lt;br /&gt;
&amp;lt;/createbox&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable collapsible collapsed&amp;quot; style=&amp;quot;width: 100%&amp;quot;&lt;br /&gt;
! 2019&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
* [[WeeklyUpdates/2019-06-03|June 3rd, 2019]]&lt;br /&gt;
* May 27th, 2019 (No Meeting Due to Memorial Day US Holiday)&lt;br /&gt;
* [[WeeklyUpdates/2019-05-20|May 20th, 2019]]&lt;br /&gt;
* [[WeeklyUpdates/2019-05-13|May 13th, 2019]]&lt;br /&gt;
* [[WeeklyUpdates/2019-05-06|May 6th, 2019]]&lt;br /&gt;
* [[WeeklyUpdates/2019-04-29|April 29nd, 2019]]&lt;br /&gt;
* [[WeeklyUpdates/2019-04-22|April 22nd, 2019]]&lt;br /&gt;
* [[WeeklyUpdates/2019-04-15|April 15th, 2019]]&lt;br /&gt;
* [[WeeklyUpdates/2019-04-08|April 8th, 2019]]&lt;br /&gt;
* [[WeeklyUpdates/2019-04-01|April 1st, 2019]]&lt;br /&gt;
* [[WeeklyUpdates/2019-03-25|March 25th, 2019]]&lt;br /&gt;
* [[WeeklyUpdates/2019-03-18|March 18th, 2019]]&lt;br /&gt;
* [[WeeklyUpdates/2019-03-11|March 11th, 2019]]&lt;br /&gt;
* [[WeeklyUpdates/2019-03-04|March 4th, 2019]]&lt;br /&gt;
* [[WeeklyUpdates/2019-02-25|February 25th, 2019]]&lt;br /&gt;
* February 18th, 2019 (No meeting due to Washington&#039;s Birthday US Holiday)&lt;br /&gt;
* [[WeeklyUpdates/2019-02-11|February 11th, 2019]]&lt;br /&gt;
* [[WeeklyUpdates/2019-02-04|February 4th, 2019]]&lt;br /&gt;
* [[WeeklyUpdates/2019-01-28|January 28th, 2019]]&lt;br /&gt;
* January 21th, 2019 (No meeting due to Martin Luther King Jr. Day in the US)&lt;br /&gt;
* [[WeeklyUpdates/2019-01-14|January 14th, 2019]]&lt;br /&gt;
* [[WeeklyUpdates/2019-01-07|January 7th, 2019]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable collapsible collapsed&amp;quot; style=&amp;quot;width: 100%&amp;quot;&lt;br /&gt;
! 2018&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
* [[WeeklyUpdates/2018-12-17|December 17th, 2018]] &lt;br /&gt;
* [[WeeklyUpdates/2018-12-10|December 10th, 2018]] (no meeting, people flying home from [[All_Hands/Orlando2018|Mozlando2018]]!)&lt;br /&gt;
* [[WeeklyUpdates/2018-12-03|December 3rd, 2018]] (no meeting, see you at [[All_Hands/Orlando2018|Mozlando2018]]!)&lt;br /&gt;
* [[WeeklyUpdates/2018-11-26|November 26th, 2018]]&lt;br /&gt;
* [[WeeklyUpdates/2018-11-19|November 19th, 2018]]&lt;br /&gt;
* [[WeeklyUpdates/2018-11-12|November 12th, 2018]]&lt;br /&gt;
* [[WeeklyUpdates/2018-11-05|November 5th, 2018]]&lt;br /&gt;
* [[WeeklyUpdates/2018-10-29|October 29nd, 2018]]&lt;br /&gt;
* [[WeeklyUpdates/2018-10-22|October 22nd, 2018]]&lt;br /&gt;
* [[WeeklyUpdates/2018-10-15|October 15th, 2018]]&lt;br /&gt;
* [[WeeklyUpdates/2018-10-08|October 8th, 2018]]&lt;br /&gt;
* [[WeeklyUpdates/2018-10-01|October 1st, 2018]]&lt;br /&gt;
* [[WeeklyUpdates/2018-09-24|September 24th, 2018]]&lt;br /&gt;
* [[WeeklyUpdates/2018-09-17|September 17th, 2018]]&lt;br /&gt;
* [[WeeklyUpdates/2018-09-10|September 10th, 2018]]&lt;br /&gt;
* [[WeeklyUpdates/2018-09-03|September 3rd, 2018]] (no meeting, US Holiday)&lt;br /&gt;
* [[WeeklyUpdates/2018-08-27|August 27th, 2018]]&lt;br /&gt;
* [[WeeklyUpdates/2018-08-20|August 20th, 2018]]&lt;br /&gt;
* [[WeeklyUpdates/2018-08-13|August 13th, 2018]]&lt;br /&gt;
* [[WeeklyUpdates/2018-08-06|August 6th, 2018]]&lt;br /&gt;
* [[WeeklyUpdates/2018-07-30|July 30th, 2018]]&lt;br /&gt;
* [[WeeklyUpdates/2018-07-23|July 23rd, 2018]]&lt;br /&gt;
* [[WeeklyUpdates/2018-07-16|July 16th, 2018]]&lt;br /&gt;
* [[WeeklyUpdates/2018-07-09|July 9th, 2018]]&lt;br /&gt;
* [[WeeklyUpdates/2018-07-02|July 2nd, 2018]]&lt;br /&gt;
* [[WeeklyUpdates/2018-06-25|June 25th, 2018]]&lt;br /&gt;
* June 18th, 2018 - no meeting (post-All Hands San Francisco)&lt;br /&gt;
* June 11th, 2018 - no meeting (All Hands San Francisco)&lt;br /&gt;
* [[WeeklyUpdates/2018-06-04|June 4th, 2018]]&lt;br /&gt;
* May 28th, 2018 - no meeting (US holiday)&lt;br /&gt;
* [[WeeklyUpdates/2018-05-21|May 21st, 2018]]&lt;br /&gt;
* [[WeeklyUpdates/2018-05-14|May 14th, 2018]]&lt;br /&gt;
* [[WeeklyUpdates/2018-05-07|May 7th, 2018]]&lt;br /&gt;
* [[WeeklyUpdates/2018-04-30|April 30th, 2018]]&lt;br /&gt;
* [[WeeklyUpdates/2018-04-23|April 23rd, 2018]]&lt;br /&gt;
* [[WeeklyUpdates/2018-04-16|April 16th, 2018]]&lt;br /&gt;
* [[WeeklyUpdates/2018-04-09|April 9th, 2018]]&lt;br /&gt;
* [[WeeklyUpdates/2018-04-02|April 2nd, 2018]]&lt;br /&gt;
* [[WeeklyUpdates/2018-03-26|March 26th, 2018]]&lt;br /&gt;
* [[WeeklyUpdates/2018-03-19|March 19th, 2018]]&lt;br /&gt;
* [[WeeklyUpdates/2018-03-12|March 12th, 2018]]&lt;br /&gt;
* [[WeeklyUpdates/2018-03-05|March 5th, 2018]]&lt;br /&gt;
* [[WeeklyUpdates/2018-02-26|February 26th, 2018]]&lt;br /&gt;
* [[WeeklyUpdates/2018-02-12|February 12th, 2018]]&lt;br /&gt;
* [[WeeklyUpdates/2018-02-05|February 5th, 2018]]&lt;br /&gt;
* [[WeeklyUpdates/2018-01-29|January 29th, 2018]]&lt;br /&gt;
* [[WeeklyUpdates/2018-01-22|January 22nd, 2018]]&lt;br /&gt;
* January 15th, 2018 (No meeting due to Martin Luther King Jr. Day in the US)&lt;br /&gt;
* [[WeeklyUpdates/2018-01-08|January 8th, 2018]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable collapsible&amp;quot; style=&amp;quot;width: 100%&amp;quot;&lt;br /&gt;
! 2017&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
* [[WeeklyUpdates/2017-12-04|December 4th, 2017]]&lt;br /&gt;
* [[WeeklyUpdates/2017-11-27|November 27th, 2017]]&lt;br /&gt;
* [[WeeklyUpdates/2017-11-20|November 20th, 2017]]&lt;br /&gt;
* [[WeeklyUpdates/2017-11-13|November 13th, 2017]]&lt;br /&gt;
* [[WeeklyUpdates/2017-11-06|November 6th, 2017]]&lt;br /&gt;
* [[WeeklyUpdates/2017-10-30|October 30th, 2017]]&lt;br /&gt;
* [[WeeklyUpdates/2017-10-23|October 23th, 2017]]&lt;br /&gt;
* [[WeeklyUpdates/2017-10-16|October 16th, 2017]]&lt;br /&gt;
* [[WeeklyUpdates/2017-10-09|October 9th, 2017]]&lt;br /&gt;
* [[WeeklyUpdates/2017-10-02|October 2nd, 2017]]&lt;br /&gt;
* [[WeeklyUpdates/2017-09-25|September 25th, 2017]]&lt;br /&gt;
* [[WeeklyUpdates/2017-09-18|September 18th, 2017]]&lt;br /&gt;
* [[WeeklyUpdates/2017-09-11|September 11th, 2017]]&lt;br /&gt;
* [[WeeklyUpdates/2017-08-28|August 28th, 2017]]&lt;br /&gt;
* [[WeeklyUpdates/2017-08-21|August 21th, 2017]]&lt;br /&gt;
* [[WeeklyUpdates/2017-08-14|August 14th, 2017]]&lt;br /&gt;
* [[WeeklyUpdates/2017-08-07|August 7th, 2017]]&lt;br /&gt;
* [[WeeklyUpdates/2017-07-31|July 31st, 2017]]&lt;br /&gt;
* [[WeeklyUpdates/2017-07-24|July 24th, 2017]]&lt;br /&gt;
* [[WeeklyUpdates/2017-07-17|July 17th, 2017]]&lt;br /&gt;
* [[WeeklyUpdates/2017-07-10|July 10th, 2017]]&lt;br /&gt;
* July 3rd, 2017 (No meeting due to All-Hands SF Recovery)&lt;br /&gt;
* June 26th, 2017 (No meeting due to All-Hands SF)&lt;br /&gt;
* [[WeeklyUpdates/2017-06-19|June 19th, 2017]]&lt;br /&gt;
* [[WeeklyUpdates/2017-06-12|June 12th, 2017]]&lt;br /&gt;
* [[WeeklyUpdates/2017-06-05|June 5th, 2017]]&lt;br /&gt;
* May 29th, 2017 (No meeting due to US holiday for Memorial Day)&lt;br /&gt;
* [[WeeklyUpdates/2017-05-22|May 22nd, 2017]]&lt;br /&gt;
* [[WeeklyUpdates/2017-05-15|May 15th, 2017]]&lt;br /&gt;
* [[WeeklyUpdates/2017-05-08|May 8th, 2017]]&lt;br /&gt;
* [[WeeklyUpdates/2017-05-01|May 1st, 2017]]&lt;br /&gt;
* [[WeeklyUpdates/2017-04-24|April 24th, 2017]]&lt;br /&gt;
* [[WeeklyUpdates/2017-04-17|April 17th, 2017]]&lt;br /&gt;
* [[WeeklyUpdates/2017-04-10|April 10th, 2017]]&lt;br /&gt;
* [[WeeklyUpdates/2017-04-03|April 3rd, 2017]]&lt;br /&gt;
* [[WeeklyUpdates/2017-03-27|March 27th, 2017]]&lt;br /&gt;
* [[WeeklyUpdates/2017-03-20|March 20th, 2017]]&lt;br /&gt;
* [[WeeklyUpdates/2017-03-13|March 13th, 2017]]&lt;br /&gt;
* [[WeeklyUpdates/2017-03-06|March 6th, 2017]]&lt;br /&gt;
* [[WeeklyUpdates/2017-02-27|February 27th, 2017]]&lt;br /&gt;
* [[WeeklyUpdates/2017-02-13|February 13th, 2017]]&lt;br /&gt;
* [[WeeklyUpdates/2017-02-06|February 6th, 2017]]&lt;br /&gt;
* [[WeeklyUpdates/2017-01-30|January 30th, 2017]]&lt;br /&gt;
* [[WeeklyUpdates/2017-01-23|January 23rd, 2017]]&lt;br /&gt;
* January 16th, 2017 (no meeting due to US holiday)&lt;br /&gt;
* [[WeeklyUpdates/2017-01-09|January 9th, 2017]]&lt;br /&gt;
* January 2nd, 2017 (no meeting due to US New Year&#039;s Day holiday)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable collapsible collapsed&amp;quot; style=&amp;quot;width: 100%&amp;quot;&lt;br /&gt;
! 2016   &lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
* [[WeeklyUpdates/2016-12-26|December 26th, 2016]] (silent updates only. no meeting due to US Holiday observed)&lt;br /&gt;
* [[WeeklyUpdates/2016-12-19|December 19th, 2016]]&lt;br /&gt;
* [[WeeklyUpdates/2016-12-12|December 12th, 2016]]&lt;br /&gt;
* December 5th, 2016 (no meeting due to All-Hands travel)&lt;br /&gt;
* [[WeeklyUpdates/2016-11-28|November 28th, 2016]]&lt;br /&gt;
* [[WeeklyUpdates/2016-11-21|November 21st, 2016]]&lt;br /&gt;
* [[WeeklyUpdates/2016-11-21|November 21th, 2016]]&lt;br /&gt;
* [[WeeklyUpdates/2016-11-14|November 14th, 2016]]&lt;br /&gt;
* [[WeeklyUpdates/2016-11-07|November 7th, 2016]]&lt;br /&gt;
* [[WeeklyUpdates/2016-10-31|October 31st, 2016]]&lt;br /&gt;
* [[WeeklyUpdates/2016-10-24|October 24th, 2016]]&lt;br /&gt;
* [[WeeklyUpdates/2016-10-17|October 17th, 2016]]&lt;br /&gt;
* [[WeeklyUpdates/2016-10-10|October 10th, 2016]]&lt;br /&gt;
* [[WeeklyUpdates/2016-09-26|September 26th, 2016]]&lt;br /&gt;
* [[WeeklyUpdates/2016-09-19|September 19th, 2016]]&lt;br /&gt;
* [[WeeklyUpdates/2016-09-12|September 12th, 2016]]&lt;br /&gt;
* There was no meeting on September 5 because of the US Labor Day holiday.&lt;br /&gt;
* [[WeeklyUpdates/2016-08-29|August 29nd, 2016]]&lt;br /&gt;
* [[WeeklyUpdates/2016-08-22|August 22nd, 2016]]&lt;br /&gt;
* [[WeeklyUpdates/2016-08-15|August 15th, 2016]]&lt;br /&gt;
* [[WeeklyUpdates/2016-08-08|August 8th, 2016]]&lt;br /&gt;
* [[WeeklyUpdates/2016-08-01|August 1st, 2016]]&lt;br /&gt;
* [[WeeklyUpdates/2016-07-25|July 25th, 2016]]&lt;br /&gt;
* [[WeeklyUpdates/2016-07-18|July 18th, 2016]]&lt;br /&gt;
* [[WeeklyUpdates/2016-07-11|July 11th, 2016]]&lt;br /&gt;
* [[WeeklyUpdates/2016-06-27|June 27th, 2016]]&lt;br /&gt;
* [[WeeklyUpdates/2016-06-20|June 20th, 2016]]&lt;br /&gt;
* [[WeeklyUpdates/2016-06-06|June 6th, 2016]]&lt;br /&gt;
* [[WeeklyUpdates/2016-05-23|May 23rd, 2016]]&lt;br /&gt;
* [[WeeklyUpdates/2016-05-16|May 16th, 2016]]&lt;br /&gt;
* [[WeeklyUpdates/2016-05-09|May 9th, 2016]]&lt;br /&gt;
* [[WeeklyUpdates/2016-05-02|May 2nd, 2016]]&lt;br /&gt;
* [[WeeklyUpdates/2016-04-25|April 25th, 2016]]&lt;br /&gt;
* [[WeeklyUpdates/2016-04-18|April 18th, 2016]]&lt;br /&gt;
* [[WeeklyUpdates/2016-04-11|April 11th, 2016]]&lt;br /&gt;
* [[WeeklyUpdates/2016-04-04|April 4th, 2016]]&lt;br /&gt;
* [[WeeklyUpdates/2016-03-28|March 28th, 2016]]&lt;br /&gt;
* [[WeeklyUpdates/2016-03-21|March 21st, 2016]]&lt;br /&gt;
* [[WeeklyUpdates/2016-03-14|March 14th, 2016]]&lt;br /&gt;
* [[WeeklyUpdates/2016-03-07|March 7th, 2016]]&lt;br /&gt;
* [[WeeklyUpdates/2016-02-29|February 29th, 2016]]&lt;br /&gt;
* [[WeeklyUpdates/2016-02-22|February 22nd, 2016]]&lt;br /&gt;
* [[WeeklyUpdates/2016-02-15|February 15th, 2016]] (no live meeting due to [https://en.wikipedia.org/wiki/Washington&#039;s_Birthday Washington&#039;s Birthday] Holiday in the US.)&lt;br /&gt;
* [[WeeklyUpdates/2016-02-08|February 8th, 2016]]&lt;br /&gt;
* [[WeeklyUpdates/2016-02-01|February 1st, 2016]]&lt;br /&gt;
* [[WeeklyUpdates/2016-01-25|January 25th, 2016]]&lt;br /&gt;
* [[WeeklyUpdates/2016-01-11|January 11th, 2016]]&lt;br /&gt;
* [[WeeklyUpdates/2016-01-04|January 4th, 2016]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable collapsible collapsed&amp;quot; style=&amp;quot;width: 100%&amp;quot;&lt;br /&gt;
! 2015   &lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
* [[WeeklyUpdates/2015-12-28|December 28th, 2015]] (no meeting, just announcements)&lt;br /&gt;
* December 21st (no meeting)&lt;br /&gt;
* [[WeeklyUpdates/2015-12-14|December 14th, 2015]] (no live meeting due to All Hands recovery)&lt;br /&gt;
* December 7th (no meeting due to All Hands)&lt;br /&gt;
* [[WeeklyUpdates/2015-11-30|November 30th, 2015]]&lt;br /&gt;
* [[WeeklyUpdates/2015-11-23|November 23rd, 2015]]&lt;br /&gt;
* [[WeeklyUpdates/2015-11-16|November 16th, 2015]]&lt;br /&gt;
* [[WeeklyUpdates/2015-11-09|November 9th, 2015]]&lt;br /&gt;
* [[WeeklyUpdates/2015-11-02|November 2nd, 2015]]&lt;br /&gt;
* [[WeeklyUpdates/2015-10-26|October 26th, 2015]]&lt;br /&gt;
* [[WeeklyUpdates/2015-10-19|October 19th, 2015]]&lt;br /&gt;
* [[WeeklyUpdates/2015-10-12|October 12th, 2015]]&lt;br /&gt;
* [[WeeklyUpdates/2015-10-05|October 5th, 2015]]&lt;br /&gt;
* [[WeeklyUpdates/2015-09-28|September 28th, 2015]]&lt;br /&gt;
* [[WeeklyUpdates/2015-09-21|September 21st, 2015]]&lt;br /&gt;
* [[WeeklyUpdates/2015-09-14|September 14th, 2015]]&lt;br /&gt;
* September 7th (No meeting due to Labor Day)&lt;br /&gt;
* [[WeeklyUpdates/2015-08-31|August 31st, 2015]]&lt;br /&gt;
* [[WeeklyUpdates/2015-08-24|August 24th, 2015]]&lt;br /&gt;
* [[WeeklyUpdates/2015-08-17|August 17th, 2015]]&lt;br /&gt;
* [[WeeklyUpdates/2015-08-10|August 10th, 2015]]&lt;br /&gt;
* [[WeeklyUpdates/2015-08-03|August 3rd, 2015]]&lt;br /&gt;
* [[WeeklyUpdates/2015-07-27|July 27th, 2015]]&lt;br /&gt;
* [[WeeklyUpdates/2015-07-20|July 20th, 2015]]&lt;br /&gt;
* [[WeeklyUpdates/2015-07-13|July 13th, 2015]]&lt;br /&gt;
* [[WeeklyUpdates/2015-07-06|July 6th, 2015]]&lt;br /&gt;
* [[WeeklyUpdates/2015-06-29|June 29th, 2015]]&lt;br /&gt;
* June 22nd, 2015 (no meeting due to All-Hands travel)&lt;br /&gt;
* [[WeeklyUpdates/2015-06-15|June 15th, 2015]]&lt;br /&gt;
* [[WeeklyUpdates/2015-06-08|June 8th, 2015]]&lt;br /&gt;
* [[WeeklyUpdates/2015-06-01|June 1st, 2015]]&lt;br /&gt;
* May 25th, 2015 (no meeting due to US Holiday)&lt;br /&gt;
* [[WeeklyUpdates/2015-05-18|May 18th, 2015]]&lt;br /&gt;
* [[WeeklyUpdates/2015-05-11|May 11th, 2015]]&lt;br /&gt;
* [[WeeklyUpdates/2015-05-04|May 4th, 2015]]&lt;br /&gt;
* [[WeeklyUpdates/2015-04-27|April 27th, 2015]]&lt;br /&gt;
* [[WeeklyUpdates/2015-04-20|April 20th, 2015]]&lt;br /&gt;
* [[WeeklyUpdates/2015-04-13|April 13th, 2015]]&lt;br /&gt;
* [[WeeklyUpdates/2015-04-06|April 6th, 2015]]&lt;br /&gt;
* [[WeeklyUpdates/2015-03-30|March 30th, 2015]]&lt;br /&gt;
* [[WeeklyUpdates/2015-03-23|March 23rd, 2015]]&lt;br /&gt;
* [[WeeklyUpdates/2015-03-16|March 16th, 2015]]&lt;br /&gt;
* [[WeeklyUpdates/2015-03-09|March 9th, 2015]]&lt;br /&gt;
* [[WeeklyUpdates/2015-03-02|March 2nd, 2015]]&lt;br /&gt;
* [[WeeklyUpdates/2015-02-23|February 23rd, 2015]]&lt;br /&gt;
* Feb 16th No meeting due to US Holiday&lt;br /&gt;
* [[WeeklyUpdates/2015-02-09|February 9nd, 2015]]&lt;br /&gt;
* [[WeeklyUpdates/2015-02-02|February 2nd, 2015]]&lt;br /&gt;
* [[WeeklyUpdates/2015-01-26|January 26th, 2015]]&lt;br /&gt;
* [[WeeklyUpdates/2015-01-19|January 19th, 2015]]&lt;br /&gt;
* [[WeeklyUpdates/2015-01-12|January 12th, 2015]]&lt;br /&gt;
* [[WeeklyUpdates/2015-01-05|January 5th, 2015]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable collapsible collapsed&amp;quot; style=&amp;quot;width: 100%&amp;quot;&lt;br /&gt;
! 2014&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
*[[WeeklyUpdates/2014-12-29|December 29th, 2014]]&lt;br /&gt;
*[[WeeklyUpdates/2014-12-15|December 15th, 2014]]&lt;br /&gt;
*[[WeeklyUpdates/2014-12-08|December 8th, 2014]]&lt;br /&gt;
*[[WeeklyUpdates/2014-11-24|November 24th, 2014]]&lt;br /&gt;
*[[WeeklyUpdates/2014-11-17|November 17th, 2014]]&lt;br /&gt;
*[[WeeklyUpdates/2014-11-10|November 10th, 2014]]&lt;br /&gt;
*[[WeeklyUpdates/2014-11-03|November 3rd, 2014]]&lt;br /&gt;
*[[WeeklyUpdates/2014-10-27|October 27th, 2014]]&lt;br /&gt;
*[[WeeklyUpdates/2014-10-20|October 20th, 2014]]&lt;br /&gt;
*[[WeeklyUpdates/2014-10-13|October 13th, 2014]]&lt;br /&gt;
*[[WeeklyUpdates/2014-10-06|October 6th, 2014]]&lt;br /&gt;
*[[WeeklyUpdates/2014-09-29|September 29th, 2014]]&lt;br /&gt;
*[[WeeklyUpdates/2014-09-22|September 22th, 2014]]&lt;br /&gt;
*[[WeeklyUpdates/2014-09-15|September 15th, 2014]]&lt;br /&gt;
*[[WeeklyUpdates/2014-09-08|September 8th, 2014]]&lt;br /&gt;
*[[WeeklyUpdates/2014-09-01|September 1st, 2014]]&lt;br /&gt;
*[[WeeklyUpdates/2014-08-25|August 25, 2014]]&lt;br /&gt;
*[[WeeklyUpdates/2014-08-18|August 18, 2014]]&lt;br /&gt;
*[[WeeklyUpdates/2014-08-11|August 11, 2014]]&lt;br /&gt;
*[[WeeklyUpdates/2014-08-04|August 4, 2014]]&lt;br /&gt;
*[[WeeklyUpdates/2014-07-28|July 28, 2014]]&lt;br /&gt;
*[[WeeklyUpdates/2014-07-21|July 21, 2014]]&lt;br /&gt;
*[[WeeklyUpdates/2014-07-14|July 14, 2014]]&lt;br /&gt;
*[[WeeklyUpdates/2014-07-07|July 7, 2014]]&lt;br /&gt;
*[[WeeklyUpdates/2014-06-30|June 30, 2014]]&lt;br /&gt;
*[[WeeklyUpdates/2014-06-23|June 23, 2014]]&lt;br /&gt;
*[[WeeklyUpdates/2014-06-16|June 16, 2014]]&lt;br /&gt;
*[[WeeklyUpdates/2014-06-09|June 09, 2014]]&lt;br /&gt;
*[[WeeklyUpdates/2014-06-02|June 02, 2014]]&lt;br /&gt;
*[[WeeklyUpdates/2014-05-26|May 26, 2014]]&lt;br /&gt;
*[[WeeklyUpdates/2014-05-19|May 19, 2014]]&lt;br /&gt;
*[[WeeklyUpdates/2014-05-12|May 12, 2014]]&lt;br /&gt;
*[[WeeklyUpdates/2014-05-05|May 05, 2014]]&lt;br /&gt;
*[[WeeklyUpdates/2014-04-28|April 28, 2014]]&lt;br /&gt;
*[[WeeklyUpdates/2014-04-21|April 21, 2014]]&lt;br /&gt;
*[[WeeklyUpdates/2014-04-14|April 14, 2014]]&lt;br /&gt;
*[[WeeklyUpdates/2014-04-07|April 7, 2014]]&lt;br /&gt;
*[[WeeklyUpdates/2014-03-31|March 31, 2014]]&lt;br /&gt;
*[[WeeklyUpdates/2014-03-24|March 24, 2014]]&lt;br /&gt;
*[[WeeklyUpdates/2014-03-17|March 17, 2014]]&lt;br /&gt;
*[[WeeklyUpdates/2014-03-10|March 10, 2014]]&lt;br /&gt;
*[[WeeklyUpdates/2014-03-03|March 3, 2014]]&lt;br /&gt;
*[[WeeklyUpdates/2014-02-24|February 24, 2014]]&lt;br /&gt;
*[[WeeklyUpdates/2014-02-10|February 10, 2014]]&lt;br /&gt;
*[[WeeklyUpdates/2014-02-03|February 3, 2014]]&lt;br /&gt;
*[[WeeklyUpdates/2014-01-27|January 27, 2014]]&lt;br /&gt;
*[[WeeklyUpdates/2014-01-20|January 20, 2014]]&lt;br /&gt;
*[[WeeklyUpdates/2014-01-13|January 13, 2014]]&lt;br /&gt;
*[[WeeklyUpdates/2014-01-06|January 6, 2014]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable collapsible collapsed&amp;quot; style=&amp;quot;width: 100%&amp;quot;&lt;br /&gt;
! 2013   &lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
*[[WeeklyUpdates/2013-12-16|December 16, 2013]]&lt;br /&gt;
*[[WeeklyUpdates/2013-12-09|December 9, 2013]]&lt;br /&gt;
*[[WeeklyUpdates/2013-12-02|December 2, 2013]]&lt;br /&gt;
*[[WeeklyUpdates/2013-11-25|November 25, 2013]]&lt;br /&gt;
*[[WeeklyUpdates/2013-11-18|November 18, 2013]]&lt;br /&gt;
*[[WeeklyUpdates/2013-11-11|November 11, 2013]]&lt;br /&gt;
*[[WeeklyUpdates/2013-11-04|November 4, 2013]]&lt;br /&gt;
*[[WeeklyUpdates/2013-10-28|October 28, 2013]]&lt;br /&gt;
*[[WeeklyUpdates/2013-10-21|October 21, 2013]]&lt;br /&gt;
*[[WeeklyUpdates/2013-10-14|October 14, 2013]]&lt;br /&gt;
*[[WeeklyUpdates/2013-10-07|October 7, 2013]]&lt;br /&gt;
*[[WeeklyUpdates/2013-09-30|September 30, 2013]]&lt;br /&gt;
*[[WeeklyUpdates/2013-09-23|September 23, 2013]]&lt;br /&gt;
*[[WeeklyUpdates/2013-09-16|September 16, 2013]]&lt;br /&gt;
*[[WeeklyUpdates/2013-09-09|September 9, 2013]]&lt;br /&gt;
*[[WeeklyUpdates/2013-09-02|September 2, 2013]]&lt;br /&gt;
*[[WeeklyUpdates/2013-08-26|August 26, 2013]]&lt;br /&gt;
*[[WeeklyUpdates/2013-08-19|August 19, 2013]]&lt;br /&gt;
*[[WeeklyUpdates/2013-08-12|August 12, 2013]]&lt;br /&gt;
*[[WeeklyUpdates/2013-08-05|August 5, 2013]]&lt;br /&gt;
*[[WeeklyUpdates/2013-07-29|July 29, 2013]]&lt;br /&gt;
*[[WeeklyUpdates/2013-07-22|July 22, 2013]]&lt;br /&gt;
*[[WeeklyUpdates/2013-07-15|July 15, 2013]]&lt;br /&gt;
*[[WeeklyUpdates/2013-07-08|July 8, 2013]]&lt;br /&gt;
*[[WeeklyUpdates/2013-07-01|July 1, 2013]]&lt;br /&gt;
*[[WeeklyUpdates/2013-06-24|June 24, 2013]]&lt;br /&gt;
*[[WeeklyUpdates/2013-06-17|June 17, 2013]]&lt;br /&gt;
*[[WeeklyUpdates/2013-06-10|June 10, 2013]]&lt;br /&gt;
*[[WeeklyUpdates/2013-06-03|June 3, 2013]]&lt;br /&gt;
*[[WeeklyUpdates/2013-05-20|May 20, 2013]]&lt;br /&gt;
*[[WeeklyUpdates/2013-05-13|May 13, 2013]]&lt;br /&gt;
*[[WeeklyUpdates/2013-05-06|May 6, 2013]]&lt;br /&gt;
*[[WeeklyUpdates/2013-04-29|April 29, 2013]]&lt;br /&gt;
*[[WeeklyUpdates/2013-04-22|April 22, 2013]]&lt;br /&gt;
*[[WeeklyUpdates/2013-04-15|April 15, 2013]]&lt;br /&gt;
*[[WeeklyUpdates/2013-04-08|April 8, 2013]]&lt;br /&gt;
*[[WeeklyUpdates/2013-04-01|April 1, 2013]]&lt;br /&gt;
*[[WeeklyUpdates/2013-03-25|March 25, 2013]]&lt;br /&gt;
*[[WeeklyUpdates/2013-03-18|March 18, 2013]]&lt;br /&gt;
*[[WeeklyUpdates/2013-03-11|March 11, 2013]]&lt;br /&gt;
*[[WeeklyUpdates/2013-03-04|March 4, 2013]]&lt;br /&gt;
*[[WeeklyUpdates/2013-02-25|February 25, 2013]]&lt;br /&gt;
*February 18, 2013 - &#039;&#039;No meeting.&#039;&#039; &lt;br /&gt;
*[[WeeklyUpdates/2013-02-11|February 11, 2013]]&lt;br /&gt;
*[[WeeklyUpdates/2013-02-04|February 04, 2013]]&lt;br /&gt;
*[[WeeklyUpdates/2013-01-28|January 28, 2013]]&lt;br /&gt;
*[[WeeklyUpdates/2013-01-21|January 21, 2013]]&lt;br /&gt;
*[[WeeklyUpdates/2013-01-14|January 14, 2013]]&lt;br /&gt;
*[[WeeklyUpdates/2013-01-07|January 7, 2013]]&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable collapsible collapsed&amp;quot; style=&amp;quot;width: 100%&amp;quot;&lt;br /&gt;
! 2012   &lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
*December 31, 2012 - &#039;&#039;No meeting.&#039;&#039;&lt;br /&gt;
*December 24, 2012 - &#039;&#039;No meeting.&#039;&#039;&lt;br /&gt;
*[[WeeklyUpdates/2012-12-17|December 17, 2012]]&lt;br /&gt;
*[[WeeklyUpdates/2012-12-10|December 10, 2012]]&lt;br /&gt;
*[[WeeklyUpdates/2012-12-03|December 03, 2012]]&lt;br /&gt;
*[[WeeklyUpdates/2012-11-26|November 26, 2012]]&lt;br /&gt;
*[[WeeklyUpdates/2012-11-19|November 19, 2012]]&lt;br /&gt;
*[[WeeklyUpdates/2012-11-12|November 12, 2012]]&lt;br /&gt;
*[[WeeklyUpdates/2012-11-05|November 5, 2012]]&lt;br /&gt;
*[[WeeklyUpdates/2012-10-29|October 29, 2012]]&lt;br /&gt;
*[[WeeklyUpdates/2012-10-22|October 22, 2012]]&lt;br /&gt;
*[[WeeklyUpdates/2012-10-15|October 15, 2012]]&lt;br /&gt;
*[[WeeklyUpdates/2012-10-08|October 8, 2012]]&lt;br /&gt;
*[[WeeklyUpdates/2012-10-01|October 1, 2012]]&lt;br /&gt;
*[[WeeklyUpdates/2012-09-24|September 24, 2012]]&lt;br /&gt;
*[[WeeklyUpdates/2012-09-17|September 17, 2012]]&lt;br /&gt;
*[[WeeklyUpdates/2012-09-10|September 10, 2012]]&lt;br /&gt;
*[[WeeklyUpdates/2012-08-27|August 27, 2012]]&lt;br /&gt;
*[[WeeklyUpdates/2012-08-20|August 20, 2012]]&lt;br /&gt;
*[[WeeklyUpdates/2012-08-13|August 13, 2012]]&lt;br /&gt;
*[[WeeklyUpdates/2012-08-06|August 06, 2012]]&lt;br /&gt;
*[[WeeklyUpdates/2012-07-30|July 30, 2012]]&lt;br /&gt;
*[[WeeklyUpdates/2012-07-23|July 23, 2012]]&lt;br /&gt;
*[[WeeklyUpdates/2012-07-16|July 16, 2012]]&lt;br /&gt;
*[[WeeklyUpdates/2012-07-09|July 9, 2012]]&lt;br /&gt;
*[[WeeklyUpdates/2012-07-02|July 2, 2012]]&lt;br /&gt;
*[[WeeklyUpdates/2012-06-25|June 25, 2012]]&lt;br /&gt;
*[[WeeklyUpdates/2012-06-18|June 18, 2012]]&lt;br /&gt;
*[[WeeklyUpdates/2012-06-11|June 11, 2012]]&lt;br /&gt;
*[[WeeklyUpdates/2012-06-04|June 4, 2012]]&lt;br /&gt;
*[[WeeklyUpdates/2012-05-28|May 28, 2012]]&lt;br /&gt;
*[[WeeklyUpdates/2012-05-21|May 21, 2012]]&lt;br /&gt;
*[[WeeklyUpdates/2012-05-14|May 14, 2012]]&lt;br /&gt;
*[[WeeklyUpdates/2012-05-07|May 7, 2012]]&lt;br /&gt;
*[[WeeklyUpdates/2012-04-30|April 30, 2012]]&lt;br /&gt;
*[[WeeklyUpdates/2012-04-23|April 23, 2012]]&lt;br /&gt;
*[[WeeklyUpdates/2012-04-16|April 16, 2012]]&lt;br /&gt;
*[[WeeklyUpdates/2012-04-09|April 9, 2012]]&lt;br /&gt;
*[[WeeklyUpdates/2012-04-02|April 2, 2012]]&lt;br /&gt;
*[[WeeklyUpdates/2012-03-26|March 26, 2012]]&lt;br /&gt;
*[[WeeklyUpdates/2012-03-19|March 19, 2012]]&lt;br /&gt;
*[[WeeklyUpdates/2012-03-12|March 12, 2012]]&lt;br /&gt;
*[[WeeklyUpdates/2012-03-05|March 5, 2012]]&lt;br /&gt;
*[[WeeklyUpdates/2012-02-27|February 27, 2012]]&lt;br /&gt;
*February 20, 2012 - &#039;&#039;No meeting.&#039;&#039;&lt;br /&gt;
*[[WeeklyUpdates/2012-02-13|February 13, 2012]]&lt;br /&gt;
*[[WeeklyUpdates/2012-02-06|February 6, 2012]]&lt;br /&gt;
*[[WeeklyUpdates/2012-01-30|January 30, 2012]]&lt;br /&gt;
*[[WeeklyUpdates/2012-01-23|January 23, 2012]]&lt;br /&gt;
*January 16, 2012 - &#039;&#039;No meeting.&#039;&#039;&lt;br /&gt;
*[[WeeklyUpdates/2012-01-09|January 9, 2012]]&lt;br /&gt;
*January 2, 2012 - &#039;&#039;No meeting.&#039;&#039;&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable collapsible collapsed&amp;quot; style=&amp;quot;width: 100%&amp;quot;&lt;br /&gt;
! 2011   &lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
*December 26, 2011 - &#039;&#039;No meeting.&#039;&#039;&lt;br /&gt;
*[[WeeklyUpdates/2011-12-19|December 19, 2011]]&lt;br /&gt;
*[[WeeklyUpdates/2011-12-12|December 12, 2011]]&lt;br /&gt;
*[[WeeklyUpdates/2011-12-05|December 5, 2011]]&lt;br /&gt;
*[[WeeklyUpdates/2011-11-28|November 28, 2011]]&lt;br /&gt;
*[[WeeklyUpdates/2011-11-21|November 21, 2011]]&lt;br /&gt;
*[[WeeklyUpdates/2011-11-14|November 14, 2011]]&lt;br /&gt;
*[[WeeklyUpdates/2011-11-07|November 7, 2011]]&lt;br /&gt;
*[[WeeklyUpdates/2011-10-31|October 31, 2011]]&lt;br /&gt;
*[[WeeklyUpdates/2011-10-24|October 24, 2011]]&lt;br /&gt;
*[[WeeklyUpdates/2011-10-17|October 17, 2011]]&lt;br /&gt;
*[[WeeklyUpdates/2011-10-10|October 10, 2011]]&lt;br /&gt;
*[[WeeklyUpdates/2011-10-03|October 3, 2011]]&lt;br /&gt;
*[[WeeklyUpdates/2011-09-27|September 26, 2011]]&lt;br /&gt;
*[[WeeklyUpdates/2011-09-19|September 19, 2011]]&lt;br /&gt;
*September 12, 2011 - &#039;&#039;No meeting due to All-Hands week.&#039;&#039;&lt;br /&gt;
*September 5, 2011 - &#039;&#039;No meeting due to US holiday.&#039;&#039;&lt;br /&gt;
*[[WeeklyUpdates/2011-08-29|August 29, 2011]]&lt;br /&gt;
*[[WeeklyUpdates/2011-08-22|August 22, 2011]]&lt;br /&gt;
*[[WeeklyUpdates/2011-08-15|August 15, 2011]]&lt;br /&gt;
*[[WeeklyUpdates/2011-08-08|August 8, 2011]]&lt;br /&gt;
*[[WeeklyUpdates/2011-08-01|August 1, 2011]]&lt;br /&gt;
*[[WeeklyUpdates/2011-07-25|July 25, 2011]]&lt;br /&gt;
*[[WeeklyUpdates/2011-07-18|July 18, 2011]]&lt;br /&gt;
*[[WeeklyUpdates/2011-07-11|July 11, 2011]]&lt;br /&gt;
*July 4, 2011 - &#039;&#039;No meeting due to US holiday.&#039;&#039;&lt;br /&gt;
*[[WeeklyUpdates/2011-06-27|June 27, 2011]]&lt;br /&gt;
*[[WeeklyUpdates/2011-06-20|June 20, 2011]]&lt;br /&gt;
*[[WeeklyUpdates/2011-06-13|June 13, 2011]]&lt;br /&gt;
*[[WeeklyUpdates/2011-06-06|June 6, 2011]]&lt;br /&gt;
*May 30, 2011 - &#039;&#039;No meeting due to US holiday.&#039;&#039;&lt;br /&gt;
*[[WeeklyUpdates/2011-05-23|May 23, 2011]]&lt;br /&gt;
*[[WeeklyUpdates/2011-05-16|May 16, 2011]]&lt;br /&gt;
*[[WeeklyUpdates/2011-05-09|May 9, 2011]]&lt;br /&gt;
*[[WeeklyUpdates/2011-05-02|May 2, 2011]]&lt;br /&gt;
*[[WeeklyUpdates/2011-04-25|April 25, 2011]]&lt;br /&gt;
*[[WeeklyUpdates/2011-04-18|April 18, 2011]]&lt;br /&gt;
*[[WeeklyUpdates/2011-04-11|April 11, 2011]]&lt;br /&gt;
*April 4, 2011 - &#039;&#039;No meeting due to All-Hands week.&#039;&#039;&lt;br /&gt;
*[[WeeklyUpdates/2011-03-28|March 28, 2011]]&lt;br /&gt;
*[[WeeklyUpdates/2011-03-21|March 21, 2011]]&lt;br /&gt;
*[[WeeklyUpdates/2011-03-14|March 14, 2011]]&lt;br /&gt;
*[[WeeklyUpdates/2011-03-07|March 7, 2011]]&lt;br /&gt;
*[[WeeklyUpdates/2011-02-28|February 28, 2011]]&lt;br /&gt;
*February 21, 2011 - &#039;&#039;No meeting due to US holiday.&#039;&#039;&lt;br /&gt;
*[[WeeklyUpdates/2011-02-14|February 14, 2011]]&lt;br /&gt;
*[[WeeklyUpdates/2011-02-07|February 07, 2011]]&lt;br /&gt;
*[[WeeklyUpdates/2011-01-31|January 31, 2011]]&lt;br /&gt;
*[[WeeklyUpdates/2011-01-24|January 24, 2011]]&lt;br /&gt;
*January 17, 2011 - &#039;&#039;No meeting due to US holiday.&#039;&#039;&lt;br /&gt;
*[[WeeklyUpdates/2011-01-10|January 10, 2011]]&lt;br /&gt;
*[[WeeklyUpdates/2011-01-03|January 3, 2011]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable collapsible collapsed&amp;quot; style=&amp;quot;width: 100%&amp;quot;&lt;br /&gt;
! 2010   &lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
*December 27, 2010 - &#039;&#039;No meeting due to holiday season.&#039;&#039;&lt;br /&gt;
*[[WeeklyUpdates/2010-12-20|December 20, 2010]]&lt;br /&gt;
*December 13, 2010 - &#039;&#039;No meeting due to Work Week&#039;&#039;&lt;br /&gt;
*[[WeeklyUpdates/2010-12-06|December 6, 2010]]&lt;br /&gt;
*[[WeeklyUpdates/2010-11-29|November 29, 2010]]&lt;br /&gt;
*[[WeeklyUpdates/2010-11-22|November 22, 2010]]&lt;br /&gt;
*[[WeeklyUpdates/2010-11-15|November 15, 2010]]&lt;br /&gt;
*[[WeeklyUpdates/2010-11-08|November 08, 2010]]&lt;br /&gt;
*[[WeeklyUpdates/2010-11-01|November 01, 2010]]&lt;br /&gt;
*[[WeeklyUpdates/2010-10-25|October 25, 2010]]&lt;br /&gt;
*[[WeeklyUpdates/2010-10-18|October 18, 2010]]&lt;br /&gt;
*[[WeeklyUpdates/2010-10-11|October 11, 2010]]&lt;br /&gt;
*[[WeeklyUpdates/2010-10-04|October 4, 2010]]&lt;br /&gt;
*[[WeeklyUpdates/2010-09-27|September 27, 2010]]&lt;br /&gt;
*[[WeeklyUpdates/2010-09-20|September 20, 2010]]&lt;br /&gt;
*[[WeeklyUpdates/2010-09-13|September 13, 2010]]&lt;br /&gt;
*September 6, 2010 - &#039;&#039;No meeting due to US holiday&#039;&#039;&lt;br /&gt;
*[[WeeklyUpdates/2010-08-30|August 30, 2010]]&lt;br /&gt;
*[[WeeklyUpdates/2010-08-23|August 23, 2010]]&lt;br /&gt;
*[[WeeklyUpdates/2010-08-16|August 16, 2010]]&lt;br /&gt;
*[[WeeklyUpdates/2010-08-09|August 9, 2010]]&lt;br /&gt;
*[[WeeklyUpdates/2010-08-02|August 2, 2010]]&lt;br /&gt;
*[[WeeklyUpdates/2010-07-26|July 26, 2010]]&lt;br /&gt;
*[[WeeklyUpdates/2010-07-19|July 19, 2010]]&lt;br /&gt;
*[[WeeklyUpdates/2010-07-12|July 12, 2010]]&lt;br /&gt;
*July 5, 2010 - &#039;&#039;No meeting due to summit&#039;&#039;&lt;br /&gt;
*[[WeeklyUpdates/2010-06-28|June 28, 2010]]&lt;br /&gt;
*[[WeeklyUpdates/2010-06-21|June 21, 2010]]&lt;br /&gt;
*[[WeeklyUpdates/2010-06-14|June 14, 2010]]&lt;br /&gt;
*[[WeeklyUpdates/2010-06-07|June 7, 2010]]&lt;br /&gt;
*May 31, 2010 - &#039;&#039;No meeting due to US holiday&#039;&#039;&lt;br /&gt;
*[[WeeklyUpdates/2010-05-24|May 24, 2010]]&lt;br /&gt;
*[[WeeklyUpdates/2010-05-17|May 17, 2010]]&lt;br /&gt;
*[[WeeklyUpdates/2010-05-10|May 10, 2010]]&lt;br /&gt;
*[[WeeklyUpdates/2010-05-03|May 03, 2010]]&lt;br /&gt;
*[[WeeklyUpdates/2010-04-26|April 26, 2010]]&lt;br /&gt;
*[[WeeklyUpdates/2010-04-19|April 19, 2010]]&lt;br /&gt;
*[[WeeklyUpdates/2010-04-12|April 12, 2010]]&lt;br /&gt;
*[[WeeklyUpdates/2010-04-05|April 5, 2010]]&lt;br /&gt;
*[[WeeklyUpdates/2010-03-29|March 29, 2010]]&lt;br /&gt;
*[[WeeklyUpdates/2010-03-22|March 22, 2010]]&lt;br /&gt;
*[[WeeklyUpdates/2010-03-15|March 15, 2010]]&lt;br /&gt;
*[[WeeklyUpdates/2010-03-08|March 8, 2010]]&lt;br /&gt;
*[[WeeklyUpdates/2010-03-01|March 1, 2010]]&lt;br /&gt;
*[[WeeklyUpdates/2010-02-22|February 22, 2010]] &lt;br /&gt;
*[[WeeklyUpdates/2010-02-15|February 15, 2010]]- No meeting due to holiday, please leave updates in the wiki.&lt;br /&gt;
*[[WeeklyUpdates/2010-02-08|February 8, 2010]] &lt;br /&gt;
*[[WeeklyUpdates/2010-02-01|February 1, 2010]]&lt;br /&gt;
*[[WeeklyUpdates/2010-01-25|January 25, 2010]]&lt;br /&gt;
*[[WeeklyUpdates/2010-01-18|January 18, 2010]]- No meeting due to US holiday, please leaves updates in the wiki.&lt;br /&gt;
*[[WeeklyUpdates/2010-01-11|January 11, 2010]]- First meeting using [[WeeklyUpdates/Guidance|new procedures]].&lt;br /&gt;
*[[WeeklyUpdates/2010-01-04|January 04, 2010]] &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable collapsible collapsed&amp;quot; style=&amp;quot;width: 100%&amp;quot;&lt;br /&gt;
! 2009   &lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
*[[WeeklyUpdates/2009-12-28|December 28, 2009]]- No meeting due to holiday. Feel free to leave updates in the Wiki. &lt;br /&gt;
*[[WeeklyUpdates/2009-12-21|December 21, 2009]] &lt;br /&gt;
*[[WeeklyUpdates/2009-12-14|December 14, 2009]] &lt;br /&gt;
*[[WeeklyUpdates/2009-12-07|December 07, 2009]]- No meeting due to all day Mozilla Corp meetings. Feel free to leave updates in the Wiki. &lt;br /&gt;
*[[WeeklyUpdates/2009-11-30|November 30, 2009]] &lt;br /&gt;
*[[WeeklyUpdates/2009-11-23|November 23, 2009]] &lt;br /&gt;
*[[WeeklyUpdates/2009-11-16|November 16, 2009]] &lt;br /&gt;
*[[WeeklyUpdates/2009-11-09|November 09, 2009]] &lt;br /&gt;
*[[WeeklyUpdates/2009-11-02|November 02, 2009]] - Time Change! 19:00 UTC (11am PST) &lt;br /&gt;
*[[WeeklyUpdates/2009-10-26|October 26, 2009]] &lt;br /&gt;
*[[WeeklyUpdates/2009-10-19|October 19, 2009]] &lt;br /&gt;
*[[WeeklyUpdates/2009-10-12|October 12, 2009]] &lt;br /&gt;
*[[WeeklyUpdates/2009-10-05|October 05, 2009]] &lt;br /&gt;
*[[WeeklyUpdates/2009-09-28|September 28, 2009]] &lt;br /&gt;
*[[WeeklyUpdates/2009-09-21|September 21, 2009]] &lt;br /&gt;
*[[WeeklyUpdates/2009-09-14|September 14, 2009]] &lt;br /&gt;
*[[WeeklyUpdates/2009-09-07|September 07, 2009]] - No Meeting due to [http://en.wikipedia.org/wiki/Labor_Day Labor Day] Holiday &lt;br /&gt;
*[[WeeklyUpdates/2009-08-31|August 31, 2009]] &lt;br /&gt;
*[[WeeklyUpdates/2009-08-24|August 24, 2009]] &lt;br /&gt;
*[[WeeklyUpdates/2009-08-17|August 17, 2009]] &lt;br /&gt;
*[[WeeklyUpdates/2009-08-10|August 10, 2009]] &lt;br /&gt;
*[[WeeklyUpdates/2009-08-03|August 03, 2009]] &lt;br /&gt;
*[[WeeklyUpdates/2009-07-27|July 27, 2009]] &lt;br /&gt;
*[[WeeklyUpdates/2009-07-20|July 20, 2009]] &lt;br /&gt;
*[[WeeklyUpdates/2009-07-13|July 13, 2009]] &lt;br /&gt;
*[[WeeklyUpdates/2009-07-06|July 06, 2009]] &lt;br /&gt;
*[[WeeklyUpdates/2009-06-29|June 29, 2009]] &lt;br /&gt;
*[[WeeklyUpdates/2009-06-22|June 22, 2009]] &lt;br /&gt;
*[[WeeklyUpdates/2009-06-15|June 15, 2009]] &lt;br /&gt;
*[[WeeklyUpdates/2009-06-08|June 08, 2009]] &lt;br /&gt;
*[[WeeklyUpdates/2009-06-01|June 01, 2009]] &lt;br /&gt;
*[[WeeklyUpdates/2009-05-25|May 25, 2009]] - No meeting due to US Holiday: [http://en.wikipedia.org/wiki/Memorial_day Memorial Day]. Feel free to leave status! &lt;br /&gt;
*[[WeeklyUpdates/2009-05-18|May 18, 2009]] &lt;br /&gt;
*[[WeeklyUpdates/2009-05-11|May 11, 2009]] &lt;br /&gt;
*[[WeeklyUpdates/2009-05-04|May 04, 2009]] &lt;br /&gt;
*April 27, 2009 - no update meeting this week due to on-site event &lt;br /&gt;
*[[WeeklyUpdates/2009-04-20|April 20, 2009]] &lt;br /&gt;
*[[WeeklyUpdates/2009-04-13|April 13, 2009]] &lt;br /&gt;
*[[WeeklyUpdates/2009-04-06|April 06, 2009]] &lt;br /&gt;
*[[WeeklyUpdates/2009-03-30|March 30, 2009]] &lt;br /&gt;
*[[WeeklyUpdates/2009-03-23|March 23, 2009]] &lt;br /&gt;
*[[WeeklyUpdates/2009-03-16|March 16, 2009]] &lt;br /&gt;
*[[WeeklyUpdates/2009-03-09|March 09, 2009]] &lt;br /&gt;
*[[WeeklyUpdates/2009-03-02|March 02, 2009]] &lt;br /&gt;
*[[WeeklyUpdates/2009-02-23|February 23, 2009]] &lt;br /&gt;
*February 16, 2009 - No Meeting due to US Holiday &lt;br /&gt;
*[[WeeklyUpdates/2009-02-09|February 09, 2009]] &lt;br /&gt;
*[[WeeklyUpdates/2009-02-02|February 02, 2009]] &lt;br /&gt;
*[[WeeklyUpdates/2009-01-26|January 26, 2009]] &lt;br /&gt;
*January 19, 2009 - No Meeting due to US Holiday &lt;br /&gt;
*[[WeeklyUpdates/2009-01-12|January 12, 2009]] &lt;br /&gt;
*[[WeeklyUpdates/2009-01-05|January 05, 2009]] &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable collapsible collapsed&amp;quot; style=&amp;quot;width: 100%&amp;quot;&lt;br /&gt;
! 2008   &lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
*[[WeeklyUpdates/2008-12-29|December 29, 2008]] &lt;br /&gt;
*[[WeeklyUpdates/2008-12-22|December 22, 2008]] &lt;br /&gt;
*[[WeeklyUpdates/2008-12-15|December 15, 2008]] &lt;br /&gt;
*[[WeeklyUpdates/2008-12-08|December 08, 2008]] &lt;br /&gt;
*[[WeeklyUpdates/2008-12-01|December 01, 2008]] &lt;br /&gt;
*[[WeeklyUpdates/2008-11-24|November 24, 2008]] &lt;br /&gt;
*[[WeeklyUpdates/2008-11-17|November 17, 2008]] &lt;br /&gt;
*[[WeeklyUpdates/2008-11-10|November 10, 2008]] &lt;br /&gt;
*[[WeeklyUpdates/2008-11-03|November 03, 2008]] &lt;br /&gt;
*[[WeeklyUpdates/2008-10-27|October 27, 2008]] &lt;br /&gt;
*[[WeeklyUpdates/2008-10-20|October 20, 2008]] &lt;br /&gt;
*[[WeeklyUpdates/2008-10-13|October 13, 2008]] &lt;br /&gt;
*[[WeeklyUpdates/2008-10-06|October 06, 2008]] &lt;br /&gt;
*[[WeeklyUpdates/2008-09-29|September 29, 2008]] &lt;br /&gt;
*[[WeeklyUpdates/2008-09-22|September 22, 2008]] &lt;br /&gt;
*[[WeeklyUpdates/2008-09-15|September 15, 2008]] &lt;br /&gt;
*[[WeeklyUpdates/2008-09-08|September 08, 2008]] &lt;br /&gt;
*September 01, 2008 - No Meeting due to US Holiday &lt;br /&gt;
*[[WeeklyUpdates/2008-08-25|August 25, 2008]] &lt;br /&gt;
*[[WeeklyUpdates/2008-08-18|August 18, 2008]] &lt;br /&gt;
*[[WeeklyUpdates/2008-08-11|August 11, 2008]] &lt;br /&gt;
*[[WeeklyUpdates/2008-08-04|August 04, 2008]] &lt;br /&gt;
*July 28, 2008 - No Meeting due to Summit &lt;br /&gt;
*[[WeeklyUpdates/2008-07-21|July 21, 2008]] &lt;br /&gt;
*[[WeeklyUpdates/2008-07-14|July 14, 2008]] &lt;br /&gt;
*[[WeeklyUpdates/2008-07-07|July 07, 2008]] &lt;br /&gt;
*[[WeeklyUpdates/2008-06-30|June 30, 2008]] &lt;br /&gt;
*[[WeeklyUpdates/2008-06-23|June 23, 2008]] &lt;br /&gt;
*[[WeeklyUpdates/2008-06-16|June 16, 2008]] &lt;br /&gt;
*[[WeeklyUpdates/2008-06-09|June 09, 2008]] &lt;br /&gt;
*[[WeeklyUpdates/2008-06-02|June 02, 2008]] &lt;br /&gt;
*May 26, 2008 - No Meeting due to US Holiday &lt;br /&gt;
*[[WeeklyUpdates/2008-05-19|May 19, 2008]] &lt;br /&gt;
*[[WeeklyUpdates/2008-05-12|May 12, 2008]] &lt;br /&gt;
*[[WeeklyUpdates/2008-05-05|May 05, 2008]] &lt;br /&gt;
*[[WeeklyUpdates/2008-04-28|April 28, 2008]] &lt;br /&gt;
*[[WeeklyUpdates/2008-04-21|April 21, 2008]] &lt;br /&gt;
*[[WeeklyUpdates/2008-04-14|April 14, 2008]] &lt;br /&gt;
*[[WeeklyUpdates/2008-04-07|April 07, 2008]] &lt;br /&gt;
*[[WeeklyUpdates/2008-03-31|March 31, 2008]] &lt;br /&gt;
*[[WeeklyUpdates/2008-03-24|March 24, 2008]] &lt;br /&gt;
*[[WeeklyUpdates/2008-03-17|March 17, 2008]] &lt;br /&gt;
*[[WeeklyUpdates/2008-03-10|March 10, 2008]] &lt;br /&gt;
*[[WeeklyUpdates/2008-03-03|March 03, 2008]] &lt;br /&gt;
*[[WeeklyUpdates/2008-02-25|February 25, 2008]] &lt;br /&gt;
*February 18, 2008 - No Meeting due to US Holiday &lt;br /&gt;
*[[WeeklyUpdates/2008-02-11|February 11, 2008]] &lt;br /&gt;
*[[WeeklyUpdates/2008-02-04|February 04, 2008]] &lt;br /&gt;
*[[WeeklyUpdates/2008-01-28|January 28, 2008]] &lt;br /&gt;
*January 21, 2008 - No Meeting due to US Holiday &lt;br /&gt;
*[[WeeklyUpdates/2008-01-14|January 14, 2008]] &lt;br /&gt;
*[[WeeklyUpdates/2008-01-07|January 07, 2008]] &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable collapsible collapsed&amp;quot; style=&amp;quot;width: 100%&amp;quot;&lt;br /&gt;
! 2007   &lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
*December 31, 2007 - No Meeting due to US holiday season &lt;br /&gt;
*December 24, 2007 - No Meeting due to US holiday season &lt;br /&gt;
*[[WeeklyUpdates/2007-12-17|December 17, 2007]] &lt;br /&gt;
*[[WeeklyUpdates/2007-12-10|December 10, 2007]] &lt;br /&gt;
*[[WeeklyUpdates/2007-12-03|December 03, 2007]] &lt;br /&gt;
*[[WeeklyUpdates/2007-11-26|November 26, 2007]] &lt;br /&gt;
*[[WeeklyUpdates/2007-11-19|November 19, 2007]] &lt;br /&gt;
*November 12, 2007 - No Meeting due to US Holiday &lt;br /&gt;
*[[WeeklyUpdates/2007-11-05|November 05, 2007]] &lt;br /&gt;
*[[WeeklyUpdates/2007-10-29|October 29, 2007]] &lt;br /&gt;
*[[WeeklyUpdates/2007-10-22|October 22, 2007]] &lt;br /&gt;
*[[WeeklyUpdates/2007-10-15|October 15, 2007]] &lt;br /&gt;
*[[WeeklyUpdates/2007-10-08|October 08, 2007]] &lt;br /&gt;
*[[WeeklyUpdates/2007-10-01|October 01, 2007]] &lt;br /&gt;
*[[WeeklyUpdates/2007-09-24|September 24, 2007]] &lt;br /&gt;
*[[WeeklyUpdates/2007-09-17|September 17, 2007]] &lt;br /&gt;
*[[WeeklyUpdates/2007-09-10|September 10, 2007]] &lt;br /&gt;
*[[WeeklyUpdates/2007-08-27|August 27, 2007]] &lt;br /&gt;
*[[WeeklyUpdates/2007-08-20|August 20, 2007]] &lt;br /&gt;
*[[WeeklyUpdates/2007-08-13|August 13, 2007]] &lt;br /&gt;
*[[WeeklyUpdates/2007-08-06|August 6, 2007]] &lt;br /&gt;
*[[WeeklyUpdates/2007-07-30|July 30, 2007]] &lt;br /&gt;
*[[WeeklyUpdates/2007-07-23|July 23, 2007]] &lt;br /&gt;
*[[WeeklyUpdates/2007-07-16|July 16, 2007]] &lt;br /&gt;
*[[WeeklyUpdates/2007-07-09|July 9, 2007]] &lt;br /&gt;
*[[WeeklyUpdates/2007-07-02|July 2, 2007]] &lt;br /&gt;
*[[WeeklyUpdates/2007-06-25|June 25, 2007]] &lt;br /&gt;
*[[WeeklyUpdates/2007-06-18|June 18, 2007]] &lt;br /&gt;
*[[WeeklyUpdates/2007-06-11|June 11, 2007]] &lt;br /&gt;
*[[WeeklyUpdates/2007-06-04|June 4, 2007]] &lt;br /&gt;
*[[WeeklyUpdates/2007-05-21|May 21, 2007]] &lt;br /&gt;
*[[WeeklyUpdates/2007-05-14|May 14, 2007]] &lt;br /&gt;
*[[WeeklyUpdates/2007-05-07|May 7, 2007]] &lt;br /&gt;
*[[WeeklyUpdates/2007-04-30|April 30, 2007]] &lt;br /&gt;
*[[WeeklyUpdates/2007-04-23|April 23, 2007]] &lt;br /&gt;
*[[WeeklyUpdates/2007-04-16|April 16, 2007]] &lt;br /&gt;
*[[WeeklyUpdates/2007-04-09|April 9, 2007]] &lt;br /&gt;
*[[WeeklyUpdates/2007-04-02|April 2, 2007]] &lt;br /&gt;
*[[WeeklyUpdates/2007-03-26|March 26, 2007]] &lt;br /&gt;
*[[WeeklyUpdates/2007-03-19|March 19, 2007]] &lt;br /&gt;
*[[WeeklyUpdates/2007-03-12|March 12, 2007]] &lt;br /&gt;
*[[WeeklyUpdates/2007-03-05|March 5, 2007]] &lt;br /&gt;
*[[WeeklyUpdates/2007-02-26|February 26, 2007]] &lt;br /&gt;
*[[WeeklyUpdates/2007-02-12|February 12, 2007]] &lt;br /&gt;
*[[WeeklyUpdates/2007-02-05|February 5, 2007]] &lt;br /&gt;
*[[WeeklyUpdates/2007-01-29|January 29, 2007]] &lt;br /&gt;
*[[WeeklyUpdates/2007-01-22|January 22, 2007]] &lt;br /&gt;
*[[WeeklyUpdates/2007-01-08|January 08, 2007]] &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable collapsible collapsed&amp;quot; style=&amp;quot;width: 100%&amp;quot;&lt;br /&gt;
! 2006   &lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
*[[WeeklyUpdates/2006-12-18|December 18, 2006]] &lt;br /&gt;
*[[WeeklyUpdates/2006-12-11|December 11, 2006]] &lt;br /&gt;
*[[WeeklyUpdates/2006-12-04|December 4, 2006]] &lt;br /&gt;
*[[WeeklyUpdates/2006-11-27|November 27, 2006]] &lt;br /&gt;
*[[WeeklyUpdates/2006-11-13|November 13, 2006]] &lt;br /&gt;
*[[WeeklyUpdates/2006-11-06|November 6, 2006]] &lt;br /&gt;
*[[WeeklyUpdates/2006-10-30|October 30, 2006]] &lt;br /&gt;
*[[WeeklyUpdates/2006-10-23|October 23, 2006]] &lt;br /&gt;
*[[WeeklyUpdates/2006-10-16|October 16, 2006]] &lt;br /&gt;
*[[WeeklyUpdates/2006-10-09|October 9, 2006]] &lt;br /&gt;
*[[WeeklyUpdates/2006-10-02|October 2, 2006]] &lt;br /&gt;
*[[WeeklyUpdates/2006-09-25|September 25, 2006]] &lt;br /&gt;
*[[WeeklyUpdates/2006-09-18|September 18, 2006]] &lt;br /&gt;
*[[WeeklyUpdates/2006-09-11|September 11, 2006]] &lt;br /&gt;
*September 4, 2006 - No Meeting due to US and Canadian Holiday &lt;br /&gt;
*[[WeeklyUpdates/2006-08-28|August 28, 2006]] &lt;br /&gt;
*[[WeeklyUpdates/2006-08-21|August 21, 2006]] &lt;br /&gt;
*[[WeeklyUpdates/2006-08-14|August 14, 2006]] &lt;br /&gt;
*[[WeeklyUpdates/2006-08-07|August 07, 2006]] &lt;br /&gt;
*[[WeeklyUpdates/2006-07-31|July 31, 2006]] &lt;br /&gt;
*[[WeeklyUpdates/2006-07-24|July 24, 2006]] &lt;br /&gt;
*[[WeeklyUpdates/2006-07-17|July 17, 2006]] &lt;br /&gt;
*[[WeeklyUpdates/2006-07-10|July 10, 2006]] &lt;br /&gt;
*July 3, 2006 - No Meeting due to US Holiday &lt;br /&gt;
*June 26, 2006 - No Meeting &lt;br /&gt;
*[[WeeklyUpdates/2006-06-19|June 19, 2006]] &lt;br /&gt;
*[[WeeklyUpdates/2006-06-12|June 12, 2006]] &lt;br /&gt;
*[[WeeklyUpdates/2006-06-05|June 05, 2006]] &lt;br /&gt;
*May 29, 2006 -- No Meeting due to US Holiday &lt;br /&gt;
*[[WeeklyUpdates/2006-05-22|May 22, 2006]] &lt;br /&gt;
*May 15, 2006 -- No Meeting due to XTech 2006 Conference &lt;br /&gt;
*[[WeeklyUpdates/2006-05-08|May 08, 2006]] &lt;br /&gt;
*[[WeeklyUpdates/2006-05-01|May 01, 2006]] &lt;br /&gt;
*[[WeeklyUpdates/2006-04-24|April 24, 2006]] &lt;br /&gt;
*[[WeeklyUpdates/2006-04-17|April 17, 2006]] &lt;br /&gt;
*[[WeeklyUpdates/2006-04-10|April 10, 2006]] &lt;br /&gt;
*[[WeeklyUpdates/2006-04-03|April 03, 2006]] &lt;br /&gt;
*[[WeeklyUpdates/2006-03-27|March 27, 2006]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note: Older [http://www-archive.mozilla.org/status/minutes.html meeting minutes] and [http://www-archive.mozilla.org/status/ status updates] are available on the www.mozilla.org archive site.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[Category:Weekly Updates]]&lt;br /&gt;
[[Category:Meeting Notes]]&lt;/div&gt;</summary>
		<author><name>Sfink</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=WeeklyUpdates/2019-06-03&amp;diff=1213112</id>
		<title>WeeklyUpdates/2019-06-03</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=WeeklyUpdates/2019-06-03&amp;diff=1213112"/>
		<updated>2019-05-31T20:21:19Z</updated>

		<summary type="html">&lt;p&gt;Sfink: /* Welcome! */  added Krystal&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
{{WeeklyUpdateNav}}&lt;br /&gt;
* Every Monday @ 11:00am Pacific Time (19:00 UTC) &lt;br /&gt;
* Watch at https://mzl.la/project-meeting-2019-06-03 or anonymously at https://air.mozilla.org. You can also watch on the Mozilla YouTube channel at https://www.youtube.com/watch?v=uMa8nehFv40&lt;br /&gt;
* join #weekly-project-call on irc.mozilla.org or Slack for backchannel discussion&lt;br /&gt;
* If you plan on presenting, please join the Zoom video chat 20 minutes prior to the start of the meeting and announce to the A/V Technicians that you will be speaking so that they can confirm your Audio and Video.&lt;br /&gt;
* &#039;&#039;&#039;Presenters only:&#039;&#039;&#039; Zoom Meeting ID: 828 817 988  [https://mozilla.zoom.us/j/828817988 https://mozilla.zoom.us/j/828817988.] Do &#039;&#039;&#039;not&#039;&#039;&#039; use this room if you&#039;re not planning to speak. &lt;br /&gt;
* One-tap mobile&lt;br /&gt;
** +16465588656,,828817988# US (New York)&lt;br /&gt;
** +17207072699,,828817988# US&lt;br /&gt;
* Dial-in by your location&lt;br /&gt;
** +1 646 558 8656 US (New York)&lt;br /&gt;
** +1 720 707 2699 US&lt;br /&gt;
** 877 853 5257 US Toll-free&lt;br /&gt;
** +61 2 8015 2088 Australia&lt;br /&gt;
** +61 8 7150 1149 Australia&lt;br /&gt;
** 1800 893 423 Australia Toll-free&lt;br /&gt;
** +1 647 558 0588 Canada&lt;br /&gt;
** +33 1 8288 0188 France&lt;br /&gt;
** +33 7 5678 4048 France&lt;br /&gt;
** 0 805 082 588 France Toll-free&lt;br /&gt;
** +49 30 5679 5800 Germany&lt;br /&gt;
** +49 69 8088 3899 Germany&lt;br /&gt;
** +49 30 3080 6188 Germany&lt;br /&gt;
** 800 724 3138 Germany Toll-free&lt;br /&gt;
** +852 5808 6088 Hong Kong, China&lt;br /&gt;
** +44 203 695 0088 United Kingdom&lt;br /&gt;
** +44 203 966 3809 United Kingdom&lt;br /&gt;
** +44 203 051 2874 United Kingdom&lt;br /&gt;
** 0 800 031 5717 United Kingdom Toll-free&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Weekly Project Status Meeting Agenda =&lt;br /&gt;
&lt;br /&gt;
Items in this section will be shared during the live status meeting.&lt;br /&gt;
&lt;br /&gt;
== Friends of Mozilla [[Image:Tree.gif|Friends of Mozilla]] ==&lt;br /&gt;
&lt;br /&gt;
== Upcoming Events ==&lt;br /&gt;
&lt;br /&gt;
=== This Week ===&lt;br /&gt;
&lt;br /&gt;
=== Monday, {{#time:d F|{{SUBPAGENAME}}}} ===&lt;br /&gt;
&lt;br /&gt;
=== Tuesday, {{#time:d F|{{SUBPAGENAME}} +1 day}} ===&lt;br /&gt;
&lt;br /&gt;
=== Wednesday, {{#time:d F|{{SUBPAGENAME}} +2 days}} ===&lt;br /&gt;
&lt;br /&gt;
=== Thursday, {{#time:d F|{{SUBPAGENAME}} +3 days}} ===&lt;br /&gt;
&lt;br /&gt;
=== Friday, {{#time:d F|{{SUBPAGENAME}} +4 days}} ===&lt;br /&gt;
&lt;br /&gt;
=== Saturday, {{#time:d F|{{SUBPAGENAME}} +5 days}} ===&lt;br /&gt;
&lt;br /&gt;
=== Sunday, {{#time:d F|{{SUBPAGENAME}} +6 days}} ===&lt;br /&gt;
&lt;br /&gt;
=== Next Week ===&lt;br /&gt;
&lt;br /&gt;
=== Later Events and Available Tickets ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Mozilla DevRel Complimentary Tickets&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Our DevRel Sponsorship team sometimes receives complimentary tickets to share with Mozillians interested in attending the following events. Please reach out to Sandra Persing at spersing@mozilla.com for more details. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039; Mozilla Sponsored Developer Events&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Mozilla sponsored developer events around the globe: &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Speakers ==&lt;br /&gt;
&lt;br /&gt;
The limit is &#039;&#039;&#039;3 minutes per topic&#039;&#039;&#039;.  It&#039;s like a lightning talk, but don&#039;t feel that you have to have slides in order to make a presentation.  If you plan on showing a video, you need to contact the Air Mozilla team before the day of the meeting or you will be deferred to the next week. The meeting is streamed in a 4:3 format in order to allow for split screen. If your slides are 16:9 &amp;quot;widescreen&amp;quot; format, please indicate in the &amp;quot;Sharing&amp;quot; column below.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;fullwidth-table wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!  [https://mozillians.org/u/USERNAME Presenter]&lt;br /&gt;
!  Title&lt;br /&gt;
!  Topic&lt;br /&gt;
!  Location&lt;br /&gt;
!  Sharing&lt;br /&gt;
!  Media&lt;br /&gt;
!  More Details&lt;br /&gt;
|-&lt;br /&gt;
| Who Are You?&lt;br /&gt;
| What Do You Do?&lt;br /&gt;
| What are you going to talk about?&lt;br /&gt;
| Where are you presenting from? (Moz Space, your house, space)&lt;br /&gt;
| Will you be sharing your screen? (yes/no, 4:3 or 16:9)&lt;br /&gt;
| Links to slides or images you want displayed on screen&lt;br /&gt;
| Link to where audience can find out more information&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Welcome! =&lt;br /&gt;
&lt;br /&gt;
Let&#039;s say hello to some new Mozillians! If you are not able to join the meeting live, you can add a link to a short video introducing yourself.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;fullwidth-table wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! &#039;&#039;Who is being introduced?&#039;&#039;&lt;br /&gt;
! &#039;&#039;Who are you? (the introducer)&#039;&#039;&lt;br /&gt;
! &#039;&#039;Where are you doing the introduction?&#039;&#039;&lt;br /&gt;
! &#039;&#039;Where are they from?&#039;&#039;&lt;br /&gt;
! &#039;&#039;How will they be part of Mozilla?&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
&amp;lt;!-- Insert new rows here --&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Their Name&lt;br /&gt;
| Your Name&lt;br /&gt;
| Intro location&lt;br /&gt;
| Their Location&lt;br /&gt;
| Their Role&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
| Jeane Carlos&lt;br /&gt;
| Punam Dahiya&lt;br /&gt;
| MTV&lt;br /&gt;
| MTV&lt;br /&gt;
| Intern - User Journey Engineering&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
| Alvina Waseem&lt;br /&gt;
| David Bolter&lt;br /&gt;
| Toronto&lt;br /&gt;
| Toronto&lt;br /&gt;
| Intern - GeckoView Engineering&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
| Krystal Yang&lt;br /&gt;
| Steve Fink&lt;br /&gt;
| MTV&lt;br /&gt;
| MTV&lt;br /&gt;
| Intern - SpiderMonkey GC&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Weekly Updates]]&lt;br /&gt;
[[Category:Meeting Notes]]&lt;/div&gt;</summary>
		<author><name>Sfink</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=Mrgiggles&amp;diff=1209726</id>
		<title>Mrgiggles</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=Mrgiggles&amp;diff=1209726"/>
		<updated>2019-03-29T23:31:09Z</updated>

		<summary type="html">&lt;p&gt;Sfink: /* Areas of Functionality (aka Plugins) */ histoire, demangle&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Mr. Giggles =&lt;br /&gt;
&lt;br /&gt;
mrgiggles is an IRC bot originally created for monitoring and reporting on the results of a static analysis for GC (garbage collection) rooting hazards. It has grown beyond this original purpose, as such things often do.&lt;br /&gt;
&lt;br /&gt;
== Usage ==&lt;br /&gt;
&lt;br /&gt;
For now, just ask him.&lt;br /&gt;
&lt;br /&gt;
  /msg mrgiggles help&lt;br /&gt;
&lt;br /&gt;
== Areas of Functionality (aka Plugins) ==&lt;br /&gt;
&lt;br /&gt;
* analysis: Reporting on static rooting hazard analysis results for SpiderMonkey engine (mrgiggles: help analysis)&lt;br /&gt;
* treewatch: Watching the tree for openings/closures (mrgiggles: tell me when inbound opens or mrgiggles: help treewatch)&lt;br /&gt;
* pun: Telling puns (mrgiggles: pun)&lt;br /&gt;
* map: Timezone lookup (mrgiggles: what time is it in Perth?)&lt;br /&gt;
* mqext: Suggest reviewers or bug components for patches to a given file (mrgiggles: who has reviewed nsJSEnvironment.cpp?)&lt;br /&gt;
* knowledge: Return information about the interpretation of hex values as nsresult codes, JS::Values, or poison patterns (mrgiggles: what is 0xe5e5e5e5e5f7?)&lt;br /&gt;
* histoire: keep a record of what you have been working on (confession: wrote patch for bug 5432100)&lt;br /&gt;
* demangle: demangle C++ symbols for *nix or Windows; no Rust yet, sorry (mrgiggles: demangle _ZZN2js3jit11X86Encoding6CCNameENS1_9ConditionEE5names)&lt;br /&gt;
&lt;br /&gt;
== Source ==&lt;br /&gt;
&lt;br /&gt;
The source code may be found at https://bitbucket.org/sfink/mrgiggles&lt;br /&gt;
&lt;br /&gt;
Note that you will almost certainly want a mrgiggles_config.py file. (I&#039;m not sure if it still works without one, but probably not.) Not so basic example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
  config = {&lt;br /&gt;
    &#039;nick&#039;: &#039;drchuckles&#039;,&lt;br /&gt;
    &#039;server&#039;: &amp;quot;irc.mozilla.org&amp;quot;,&lt;br /&gt;
    &#039;port&#039;: 6667,&lt;br /&gt;
    &#039;password&#039;: &amp;quot;...&amp;quot;,&lt;br /&gt;
    &#039;bitly_token&#039;: &#039;e4718deadbeefdeadbeef2422078f51d2cc41a4c&#039;,&lt;br /&gt;
    &#039;poll-interval&#039;: 10, # Seconds&lt;br /&gt;
    &#039;debug-channel&#039;: &#039;#my-debug-channel&#039;,&lt;br /&gt;
    &#039;report-channels&#039;: [ &#039;#my-debug-channel&#039;, &#039;#mychannel&#039; ],&lt;br /&gt;
    &#039;nondebug-channels&#039;: [ &#039;#mychannel&#039;, &#039;#theirchannel&#039; ],&lt;br /&gt;
    &#039;var-path&#039;: &amp;quot;/home/tweety/var/{nick}&amp;quot;,&lt;br /&gt;
    &lt;br /&gt;
    &#039;plugins&#039;: {&lt;br /&gt;
        &#039;treewatch&#039;: { &#039;class&#039;: &#039;TreeWatchPlugin&#039;,&lt;br /&gt;
                       &#039;poll-interval&#039;: 180 },&lt;br /&gt;
        &#039;mqext&#039;: { &#039;class&#039;: &#039;MQExtPlugin&#039; },&lt;br /&gt;
        &#039;pulse&#039;: {&lt;br /&gt;
            &#039;class&#039;: &#039;PulsePlugin&#039;,&lt;br /&gt;
            &#039;server&#039;: &#039;pulse.mozilla.org&#039;,&lt;br /&gt;
            &#039;port&#039;: 5672,&lt;br /&gt;
            &#039;user&#039;: &#039;mrgiggles&#039;,&lt;br /&gt;
            &#039;password&#039;: &#039;...&#039;,&lt;br /&gt;
            &#039;exchanges&#039;: {&lt;br /&gt;
                &#039;build&#039;: &#039;exchange/build&#039;,&lt;br /&gt;
            },&lt;br /&gt;
            &#039;queues&#039;: {&lt;br /&gt;
                &#039;build&#039;: &#039;queue/{user}/builds&#039;,&lt;br /&gt;
            },&lt;br /&gt;
        },&lt;br /&gt;
                   &lt;br /&gt;
        &#039;pun&#039;: { &#039;class&#039;: &#039;PunPlugin&#039; },&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Sfink</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=Mrgiggles&amp;diff=1209725</id>
		<title>Mrgiggles</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=Mrgiggles&amp;diff=1209725"/>
		<updated>2019-03-29T23:27:12Z</updated>

		<summary type="html">&lt;p&gt;Sfink: /* Areas of Functionality (aka Plugins) */ knowledge example&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Mr. Giggles =&lt;br /&gt;
&lt;br /&gt;
mrgiggles is an IRC bot originally created for monitoring and reporting on the results of a static analysis for GC (garbage collection) rooting hazards. It has grown beyond this original purpose, as such things often do.&lt;br /&gt;
&lt;br /&gt;
== Usage ==&lt;br /&gt;
&lt;br /&gt;
For now, just ask him.&lt;br /&gt;
&lt;br /&gt;
  /msg mrgiggles help&lt;br /&gt;
&lt;br /&gt;
== Areas of Functionality (aka Plugins) ==&lt;br /&gt;
&lt;br /&gt;
* analysis: Reporting on static rooting hazard analysis results for SpiderMonkey engine (mrgiggles: help analysis)&lt;br /&gt;
* treewatch: Watching the tree for openings/closures (mrgiggles: tell me when inbound opens or mrgiggles: help treewatch)&lt;br /&gt;
* pun: Telling puns (mrgiggles: pun)&lt;br /&gt;
* map: Timezone lookup (mrgiggles: what time is it in Perth?)&lt;br /&gt;
* mqext: Suggest reviewers or bug components for patches to a given file (mrgiggles: who has reviewed nsJSEnvironment.cpp?)&lt;br /&gt;
* knowledge: Return information about the interpretation of hex values as nsresult codes, JS::Values, or poison patterns (mrgiggles: what is 0xe5e5e5e5e5f7?)&lt;br /&gt;
&lt;br /&gt;
== Source ==&lt;br /&gt;
&lt;br /&gt;
The source code may be found at https://bitbucket.org/sfink/mrgiggles&lt;br /&gt;
&lt;br /&gt;
Note that you will almost certainly want a mrgiggles_config.py file. (I&#039;m not sure if it still works without one, but probably not.) Not so basic example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
  config = {&lt;br /&gt;
    &#039;nick&#039;: &#039;drchuckles&#039;,&lt;br /&gt;
    &#039;server&#039;: &amp;quot;irc.mozilla.org&amp;quot;,&lt;br /&gt;
    &#039;port&#039;: 6667,&lt;br /&gt;
    &#039;password&#039;: &amp;quot;...&amp;quot;,&lt;br /&gt;
    &#039;bitly_token&#039;: &#039;e4718deadbeefdeadbeef2422078f51d2cc41a4c&#039;,&lt;br /&gt;
    &#039;poll-interval&#039;: 10, # Seconds&lt;br /&gt;
    &#039;debug-channel&#039;: &#039;#my-debug-channel&#039;,&lt;br /&gt;
    &#039;report-channels&#039;: [ &#039;#my-debug-channel&#039;, &#039;#mychannel&#039; ],&lt;br /&gt;
    &#039;nondebug-channels&#039;: [ &#039;#mychannel&#039;, &#039;#theirchannel&#039; ],&lt;br /&gt;
    &#039;var-path&#039;: &amp;quot;/home/tweety/var/{nick}&amp;quot;,&lt;br /&gt;
    &lt;br /&gt;
    &#039;plugins&#039;: {&lt;br /&gt;
        &#039;treewatch&#039;: { &#039;class&#039;: &#039;TreeWatchPlugin&#039;,&lt;br /&gt;
                       &#039;poll-interval&#039;: 180 },&lt;br /&gt;
        &#039;mqext&#039;: { &#039;class&#039;: &#039;MQExtPlugin&#039; },&lt;br /&gt;
        &#039;pulse&#039;: {&lt;br /&gt;
            &#039;class&#039;: &#039;PulsePlugin&#039;,&lt;br /&gt;
            &#039;server&#039;: &#039;pulse.mozilla.org&#039;,&lt;br /&gt;
            &#039;port&#039;: 5672,&lt;br /&gt;
            &#039;user&#039;: &#039;mrgiggles&#039;,&lt;br /&gt;
            &#039;password&#039;: &#039;...&#039;,&lt;br /&gt;
            &#039;exchanges&#039;: {&lt;br /&gt;
                &#039;build&#039;: &#039;exchange/build&#039;,&lt;br /&gt;
            },&lt;br /&gt;
            &#039;queues&#039;: {&lt;br /&gt;
                &#039;build&#039;: &#039;queue/{user}/builds&#039;,&lt;br /&gt;
            },&lt;br /&gt;
        },&lt;br /&gt;
                   &lt;br /&gt;
        &#039;pun&#039;: { &#039;class&#039;: &#039;PunPlugin&#039; },&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Sfink</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=Mrgiggles&amp;diff=1209724</id>
		<title>Mrgiggles</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=Mrgiggles&amp;diff=1209724"/>
		<updated>2019-03-29T23:26:19Z</updated>

		<summary type="html">&lt;p&gt;Sfink: /* Areas of Functionality (aka Plugins) */ knowledge plugin&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Mr. Giggles =&lt;br /&gt;
&lt;br /&gt;
mrgiggles is an IRC bot originally created for monitoring and reporting on the results of a static analysis for GC (garbage collection) rooting hazards. It has grown beyond this original purpose, as such things often do.&lt;br /&gt;
&lt;br /&gt;
== Usage ==&lt;br /&gt;
&lt;br /&gt;
For now, just ask him.&lt;br /&gt;
&lt;br /&gt;
  /msg mrgiggles help&lt;br /&gt;
&lt;br /&gt;
== Areas of Functionality (aka Plugins) ==&lt;br /&gt;
&lt;br /&gt;
* analysis: Reporting on static rooting hazard analysis results for SpiderMonkey engine (mrgiggles: help analysis)&lt;br /&gt;
* treewatch: Watching the tree for openings/closures (mrgiggles: tell me when inbound opens or mrgiggles: help treewatch)&lt;br /&gt;
* pun: Telling puns (mrgiggles: pun)&lt;br /&gt;
* map: Timezone lookup (mrgiggles: what time is it in Perth?)&lt;br /&gt;
* mqext: Suggest reviewers or bug components for patches to a given file (mrgiggles: who has reviewed nsJSEnvironment.cpp?)&lt;br /&gt;
* knowledge: Return information about the interpretation of hex values as nsresult codes, JS::Values, or poison patterns&lt;br /&gt;
&lt;br /&gt;
== Source ==&lt;br /&gt;
&lt;br /&gt;
The source code may be found at https://bitbucket.org/sfink/mrgiggles&lt;br /&gt;
&lt;br /&gt;
Note that you will almost certainly want a mrgiggles_config.py file. (I&#039;m not sure if it still works without one, but probably not.) Not so basic example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
  config = {&lt;br /&gt;
    &#039;nick&#039;: &#039;drchuckles&#039;,&lt;br /&gt;
    &#039;server&#039;: &amp;quot;irc.mozilla.org&amp;quot;,&lt;br /&gt;
    &#039;port&#039;: 6667,&lt;br /&gt;
    &#039;password&#039;: &amp;quot;...&amp;quot;,&lt;br /&gt;
    &#039;bitly_token&#039;: &#039;e4718deadbeefdeadbeef2422078f51d2cc41a4c&#039;,&lt;br /&gt;
    &#039;poll-interval&#039;: 10, # Seconds&lt;br /&gt;
    &#039;debug-channel&#039;: &#039;#my-debug-channel&#039;,&lt;br /&gt;
    &#039;report-channels&#039;: [ &#039;#my-debug-channel&#039;, &#039;#mychannel&#039; ],&lt;br /&gt;
    &#039;nondebug-channels&#039;: [ &#039;#mychannel&#039;, &#039;#theirchannel&#039; ],&lt;br /&gt;
    &#039;var-path&#039;: &amp;quot;/home/tweety/var/{nick}&amp;quot;,&lt;br /&gt;
    &lt;br /&gt;
    &#039;plugins&#039;: {&lt;br /&gt;
        &#039;treewatch&#039;: { &#039;class&#039;: &#039;TreeWatchPlugin&#039;,&lt;br /&gt;
                       &#039;poll-interval&#039;: 180 },&lt;br /&gt;
        &#039;mqext&#039;: { &#039;class&#039;: &#039;MQExtPlugin&#039; },&lt;br /&gt;
        &#039;pulse&#039;: {&lt;br /&gt;
            &#039;class&#039;: &#039;PulsePlugin&#039;,&lt;br /&gt;
            &#039;server&#039;: &#039;pulse.mozilla.org&#039;,&lt;br /&gt;
            &#039;port&#039;: 5672,&lt;br /&gt;
            &#039;user&#039;: &#039;mrgiggles&#039;,&lt;br /&gt;
            &#039;password&#039;: &#039;...&#039;,&lt;br /&gt;
            &#039;exchanges&#039;: {&lt;br /&gt;
                &#039;build&#039;: &#039;exchange/build&#039;,&lt;br /&gt;
            },&lt;br /&gt;
            &#039;queues&#039;: {&lt;br /&gt;
                &#039;build&#039;: &#039;queue/{user}/builds&#039;,&lt;br /&gt;
            },&lt;br /&gt;
        },&lt;br /&gt;
                   &lt;br /&gt;
        &#039;pun&#039;: { &#039;class&#039;: &#039;PunPlugin&#039; },&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Sfink</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=Sfink/Static_Rooting_Analysis&amp;diff=1206171</id>
		<title>Sfink/Static Rooting Analysis</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=Sfink/Static_Rooting_Analysis&amp;diff=1206171"/>
		<updated>2019-01-14T20:59:25Z</updated>

		<summary type="html">&lt;p&gt;Sfink: removed 90% of this doc; outdated. Did not update to current status.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;If you want to implement a new analysis, then probably the easiest way is to skip all of the nasty hairy bits of compiling the tree with the plugin installed, and instead copy over some .xdb files from a try push (try: -b do -p linux64-haz --upload-xdbs) and just run the rest of it. Everything else is implemented with JS source files from js/src/devtools/rootAnalysis/. The xdb files are enormous uncompressed, but not too horrible compressed.&lt;/div&gt;</summary>
		<author><name>Sfink</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=Javascript:Automation_Builds&amp;diff=1194087</id>
		<title>Javascript:Automation Builds</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=Javascript:Automation_Builds&amp;diff=1194087"/>
		<updated>2018-05-18T16:38:27Z</updated>

		<summary type="html">&lt;p&gt;Sfink: /* SM(tsan) */ make this a little scarier&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= The Builds =&lt;br /&gt;
&lt;br /&gt;
All of the &#039;&#039;&#039;SM(...)&#039;&#039;&#039; builds appearing on Treeherder are JS shell-only builds. Currently, they all&lt;br /&gt;
* Checkout the source&lt;br /&gt;
* Configure using a set of options appropriate to the specific build&lt;br /&gt;
* Build (by simply invoking make)&lt;br /&gt;
* Run tests, possibly differently depending on the specific build&lt;br /&gt;
&lt;br /&gt;
All of this is done by running the shell script js/src/devtools/automation/autospider.sh &amp;lt;variant&amp;gt;, where &amp;lt;variant&amp;gt; is one of the filenames in js/src/devtools/automation/variants/.&lt;br /&gt;
&lt;br /&gt;
= Reproducing a build =&lt;br /&gt;
&lt;br /&gt;
You should be able to closely replicate a TH build by running autospider.sh yourself. For example, to replicate &#039;&#039;&#039;SM(cgc)&#039;&#039;&#039;, you could be anywhere within your checkout, and run&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;gecko-root&amp;gt;/js/src/devtools/automation/autospider.sh --clobber compacting&lt;br /&gt;
&lt;br /&gt;
The default objdir is &amp;lt;gecko-root&amp;gt;/obj-spider. You can change it by setting the $OBJDIR environment variable.&lt;br /&gt;
&lt;br /&gt;
To narrow the test down, delete some of the lines at the end of autospider.sh that run the various tests.&lt;br /&gt;
&lt;br /&gt;
== Mapping variants to SM(...) names ==&lt;br /&gt;
&lt;br /&gt;
There is no good way. They&#039;re hardcoded in the Treeherder code. Many of them even show up in multiple repos. Here&#039;s a snapshot:&lt;br /&gt;
&lt;br /&gt;
* SM(cgc) - compacting&lt;br /&gt;
* SM(p) - plain or plaindebug&lt;br /&gt;
* SM(arm) - arm-sim or arm-sim-osx&lt;br /&gt;
* SM(arm64) - arm64-sim&lt;br /&gt;
* SM(exr) - exactrooting&lt;br /&gt;
* SM(r) - rootanalysis&lt;br /&gt;
* SM(pkg) - Standalone SpiderMonkey package.&lt;br /&gt;
* SM(tsan) - tsan&lt;br /&gt;
&lt;br /&gt;
= Specific Build Information =&lt;br /&gt;
&lt;br /&gt;
== SM(pkg) ==&lt;br /&gt;
&lt;br /&gt;
The SM(pkg) builds create a tarball of all the sources used to make a standalone SpiderMonkey library and shell, untar it somewhere else, and then runs the autospider command listed above. To reproduce this packaging and unpackaging behavior, you can run this command:&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;gecko-root&amp;gt;/testing/taskcluster/scripts/builder/build-sm-package.sh&lt;br /&gt;
&lt;br /&gt;
== SM(tsan) ==&lt;br /&gt;
&lt;br /&gt;
sm-tsan uses the clang ThreadSanitizer dynamic thread safety checker. Since this is a dynamic analysis, any given run may report only a subset of issues based on the exact timing of that run. One thing that means is that failures in this job may well be intermittent, and thus may not be due to the immediately preceding push. You may consider retriggering a failure a few times to see what to blame it on.&lt;br /&gt;
&lt;br /&gt;
ThreadSanitizer failures are generally not security sensitive, though they can be. The usual rules apply -- eg if it&#039;s in GC code, it should be assumed to be sensitive until investigated.&lt;/div&gt;</summary>
		<author><name>Sfink</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=Javascript:Automation_Builds&amp;diff=1194086</id>
		<title>Javascript:Automation Builds</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=Javascript:Automation_Builds&amp;diff=1194086"/>
		<updated>2018-05-18T16:30:57Z</updated>

		<summary type="html">&lt;p&gt;Sfink: /* SM(tsan) */  replace old tsan info&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= The Builds =&lt;br /&gt;
&lt;br /&gt;
All of the &#039;&#039;&#039;SM(...)&#039;&#039;&#039; builds appearing on Treeherder are JS shell-only builds. Currently, they all&lt;br /&gt;
* Checkout the source&lt;br /&gt;
* Configure using a set of options appropriate to the specific build&lt;br /&gt;
* Build (by simply invoking make)&lt;br /&gt;
* Run tests, possibly differently depending on the specific build&lt;br /&gt;
&lt;br /&gt;
All of this is done by running the shell script js/src/devtools/automation/autospider.sh &amp;lt;variant&amp;gt;, where &amp;lt;variant&amp;gt; is one of the filenames in js/src/devtools/automation/variants/.&lt;br /&gt;
&lt;br /&gt;
= Reproducing a build =&lt;br /&gt;
&lt;br /&gt;
You should be able to closely replicate a TH build by running autospider.sh yourself. For example, to replicate &#039;&#039;&#039;SM(cgc)&#039;&#039;&#039;, you could be anywhere within your checkout, and run&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;gecko-root&amp;gt;/js/src/devtools/automation/autospider.sh --clobber compacting&lt;br /&gt;
&lt;br /&gt;
The default objdir is &amp;lt;gecko-root&amp;gt;/obj-spider. You can change it by setting the $OBJDIR environment variable.&lt;br /&gt;
&lt;br /&gt;
To narrow the test down, delete some of the lines at the end of autospider.sh that run the various tests.&lt;br /&gt;
&lt;br /&gt;
== Mapping variants to SM(...) names ==&lt;br /&gt;
&lt;br /&gt;
There is no good way. They&#039;re hardcoded in the Treeherder code. Many of them even show up in multiple repos. Here&#039;s a snapshot:&lt;br /&gt;
&lt;br /&gt;
* SM(cgc) - compacting&lt;br /&gt;
* SM(p) - plain or plaindebug&lt;br /&gt;
* SM(arm) - arm-sim or arm-sim-osx&lt;br /&gt;
* SM(arm64) - arm64-sim&lt;br /&gt;
* SM(exr) - exactrooting&lt;br /&gt;
* SM(r) - rootanalysis&lt;br /&gt;
* SM(pkg) - Standalone SpiderMonkey package.&lt;br /&gt;
* SM(tsan) - tsan&lt;br /&gt;
&lt;br /&gt;
= Specific Build Information =&lt;br /&gt;
&lt;br /&gt;
== SM(pkg) ==&lt;br /&gt;
&lt;br /&gt;
The SM(pkg) builds create a tarball of all the sources used to make a standalone SpiderMonkey library and shell, untar it somewhere else, and then runs the autospider command listed above. To reproduce this packaging and unpackaging behavior, you can run this command:&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;gecko-root&amp;gt;/testing/taskcluster/scripts/builder/build-sm-package.sh&lt;br /&gt;
&lt;br /&gt;
== SM(tsan) ==&lt;br /&gt;
&lt;br /&gt;
sm-tsan uses the clang ThreadSanitizer dynamic thread safety checker. Since this is a dynamic analysis, any given run may report only a subset of issues based on the exact timing of that run. One thing that means is that failures in this job may well be intermittent, and thus may not be due to the immediately preceding push. You may consider retriggering a failure a few times to see what to blame it on.&lt;br /&gt;
&lt;br /&gt;
ThreadSanitizer failures are generally not security-critical, though they can be.&lt;/div&gt;</summary>
		<author><name>Sfink</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=Javascript:Automation_Builds&amp;diff=1171658</id>
		<title>Javascript:Automation Builds</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=Javascript:Automation_Builds&amp;diff=1171658"/>
		<updated>2017-05-20T01:17:18Z</updated>

		<summary type="html">&lt;p&gt;Sfink: headers&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= The Builds =&lt;br /&gt;
&lt;br /&gt;
All of the &#039;&#039;&#039;SM(...)&#039;&#039;&#039; builds appearing on Treeherder are JS shell-only builds. Currently, they all&lt;br /&gt;
* Checkout the source&lt;br /&gt;
* Configure using a set of options appropriate to the specific build&lt;br /&gt;
* Build (by simply invoking make)&lt;br /&gt;
* Run tests, possibly differently depending on the specific build&lt;br /&gt;
&lt;br /&gt;
All of this is done by running the shell script js/src/devtools/automation/autospider.sh &amp;lt;variant&amp;gt;, where &amp;lt;variant&amp;gt; is one of the filenames in js/src/devtools/automation/variants/.&lt;br /&gt;
&lt;br /&gt;
= Reproducing a build =&lt;br /&gt;
&lt;br /&gt;
You should be able to closely replicate a TH build by running autospider.sh yourself. For example, to replicate &#039;&#039;&#039;SM(cgc)&#039;&#039;&#039;, you could be anywhere within your checkout, and run&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;gecko-root&amp;gt;/js/src/devtools/automation/autospider.sh --clobber compacting&lt;br /&gt;
&lt;br /&gt;
The default objdir is &amp;lt;gecko-root&amp;gt;/obj-spider. You can change it by setting the $OBJDIR environment variable.&lt;br /&gt;
&lt;br /&gt;
To narrow the test down, delete some of the lines at the end of autospider.sh that run the various tests.&lt;br /&gt;
&lt;br /&gt;
== Mapping variants to SM(...) names ==&lt;br /&gt;
&lt;br /&gt;
There is no good way. They&#039;re hardcoded in the Treeherder code. Many of them even show up in multiple repos. Here&#039;s a snapshot:&lt;br /&gt;
&lt;br /&gt;
* SM(cgc) - compacting&lt;br /&gt;
* SM(p) - plain or plaindebug&lt;br /&gt;
* SM(arm) - arm-sim or arm-sim-osx&lt;br /&gt;
* SM(arm64) - arm64-sim&lt;br /&gt;
* SM(exr) - exactrooting&lt;br /&gt;
* SM(r) - rootanalysis&lt;br /&gt;
* SM(pkg) - Standalone SpiderMonkey package.&lt;br /&gt;
* SM(tsan) - tsan&lt;br /&gt;
&lt;br /&gt;
= Specific Build Information =&lt;br /&gt;
&lt;br /&gt;
== SM(pkg) ==&lt;br /&gt;
&lt;br /&gt;
The SM(pkg) builds create a tarball of all the sources used to make a standalone SpiderMonkey library and shell, untar it somewhere else, and then runs the autospider command listed above. To reproduce this packaging and unpackaging behavior, you can run this command:&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;gecko-root&amp;gt;/testing/taskcluster/scripts/builder/build-sm-package.sh&lt;br /&gt;
&lt;br /&gt;
== SM(tsan) ==&lt;br /&gt;
&lt;br /&gt;
sm-tsan is a dynamic thread safety checker, which means that any given run will only report a subset of issues. Also, we have a number of errors currently in the codebase that it will allow through without turning the build red. These are listed in&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;gecko-root&amp;gt;/js/src/devtools/automation/variants/tsan&lt;br /&gt;
&lt;br /&gt;
under the &#039;expect-errors&#039; key. These are a list of filename,function pairs. (We cannot use a line number because it would change whenever lines are added/removed.) For a given build, errors are summarized in a tsan_summary.txt artifact, and the detailed stack information produced by tsan will be bundled up in a tsan.tar.gz file containing per-pid outputs.&lt;br /&gt;
&lt;br /&gt;
The mrgiggles server is running a script that downloads and categorizes the observed failures, but it isn&#039;t done yet (it misses some pushes), and it does not yet expose the information it collects. If you&#039;re looking into a specific failure, you can either dig it out of tsan.tar.gz, or ask sfink for the detailed failure information. (mrgiggles watches for job completions, downloads tsan.tar.gz, and records the failure stacks in a file named after the filename, line number, and function name.)&lt;/div&gt;</summary>
		<author><name>Sfink</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=Javascript:Automation_Builds&amp;diff=1171657</id>
		<title>Javascript:Automation Builds</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=Javascript:Automation_Builds&amp;diff=1171657"/>
		<updated>2017-05-20T01:13:16Z</updated>

		<summary type="html">&lt;p&gt;Sfink: tsan info&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= The Builds =&lt;br /&gt;
&lt;br /&gt;
All of the &#039;&#039;&#039;SM(...)&#039;&#039;&#039; builds appearing on Treeherder are JS shell-only builds. Currently, they all&lt;br /&gt;
* Checkout the source&lt;br /&gt;
* Configure using a set of options appropriate to the specific build&lt;br /&gt;
* Build (by simply invoking make)&lt;br /&gt;
* Run tests, possibly differently depending on the specific build&lt;br /&gt;
&lt;br /&gt;
All of this is done by running the shell script js/src/devtools/automation/autospider.sh &amp;lt;variant&amp;gt;, where &amp;lt;variant&amp;gt; is one of the filenames in js/src/devtools/automation/variants/.&lt;br /&gt;
&lt;br /&gt;
= Reproducing a build =&lt;br /&gt;
&lt;br /&gt;
You should be able to closely replicate a TH build by running autospider.sh yourself. For example, to replicate &#039;&#039;&#039;SM(cgc)&#039;&#039;&#039;, you could be anywhere within your checkout, and run&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;gecko-root&amp;gt;/js/src/devtools/automation/autospider.sh --clobber compacting&lt;br /&gt;
&lt;br /&gt;
The default objdir is &amp;lt;gecko-root&amp;gt;/obj-spider. You can change it by setting the $OBJDIR environment variable.&lt;br /&gt;
&lt;br /&gt;
To narrow the test down, delete some of the lines at the end of autospider.sh that run the various tests.&lt;br /&gt;
&lt;br /&gt;
== Mapping variants to SM(...) names ==&lt;br /&gt;
&lt;br /&gt;
There is no good way. They&#039;re hardcoded in the Treeherder code. Many of them even show up in multiple repos. Here&#039;s a snapshot:&lt;br /&gt;
&lt;br /&gt;
* SM(cgc) - compacting&lt;br /&gt;
* SM(p) - plain or plaindebug&lt;br /&gt;
* SM(arm) - arm-sim or arm-sim-osx&lt;br /&gt;
* SM(arm64) - arm64-sim&lt;br /&gt;
* SM(exr) - exactrooting&lt;br /&gt;
* SM(r) - rootanalysis&lt;br /&gt;
* SM(pkg) - Standalone SpiderMonkey package.&lt;br /&gt;
* SM(tsan) - tsan&lt;br /&gt;
&lt;br /&gt;
== Specific Builds ==&lt;br /&gt;
&lt;br /&gt;
=== SM(pkg) ===&lt;br /&gt;
&lt;br /&gt;
The SM(pkg) builds create a tarball of all the sources used to make a standalone SpiderMonkey library and shell, untar it somewhere else, and then runs the autospider command listed above. To reproduce this packaging and unpackaging behavior, you can run this command:&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;gecko-root&amp;gt;/testing/taskcluster/scripts/builder/build-sm-package.sh&lt;br /&gt;
&lt;br /&gt;
=== SM(tsan) ===&lt;br /&gt;
&lt;br /&gt;
sm-tsan is a dynamic thread safety checker, which means that any given run will only report a subset of issues. Also, we have a number of errors currently in the codebase that it will allow through without turning the build red. These are listed in&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;gecko-root&amp;gt;/js/src/devtools/automation/variants/tsan&lt;br /&gt;
&lt;br /&gt;
under the &#039;expect-errors&#039; key. These are a list of filename,function pairs. (We cannot use a line number because it would change whenever lines are added/removed.) For a given build, errors are summarized in a tsan_summary.txt artifact, and the detailed stack information produced by tsan will be bundled up in a tsan.tar.gz file containing per-pid outputs.&lt;br /&gt;
&lt;br /&gt;
The mrgiggles server is running a script that downloads and categorizes the observed failures, but it isn&#039;t done yet (it misses some pushes), and it does not yet expose the information it collects. If you&#039;re looking into a specific failure, you can either dig it out of tsan.tar.gz, or ask sfink for the detailed failure information. (mrgiggles watches for job completions, downloads tsan.tar.gz, and records the failure stacks in a file named after the filename, line number, and function name.)&lt;/div&gt;</summary>
		<author><name>Sfink</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=Javascript:Automation_Builds&amp;diff=1171656</id>
		<title>Javascript:Automation Builds</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=Javascript:Automation_Builds&amp;diff=1171656"/>
		<updated>2017-05-20T01:00:33Z</updated>

		<summary type="html">&lt;p&gt;Sfink: /* Mapping variants to SM(...) names */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= The Builds =&lt;br /&gt;
&lt;br /&gt;
All of the &#039;&#039;&#039;SM(...)&#039;&#039;&#039; builds appearing on Treeherder are JS shell-only builds. Currently, they all&lt;br /&gt;
* Checkout the source&lt;br /&gt;
* Configure using a set of options appropriate to the specific build&lt;br /&gt;
* Build (by simply invoking make)&lt;br /&gt;
* Run tests, possibly differently depending on the specific build&lt;br /&gt;
&lt;br /&gt;
All of this is done by running the shell script js/src/devtools/automation/autospider.sh &amp;lt;variant&amp;gt;, where &amp;lt;variant&amp;gt; is one of the filenames in js/src/devtools/automation/variants/.&lt;br /&gt;
&lt;br /&gt;
= Reproducing a build =&lt;br /&gt;
&lt;br /&gt;
You should be able to closely replicate a TH build by running autospider.sh yourself. For example, to replicate &#039;&#039;&#039;SM(cgc)&#039;&#039;&#039;, you could be anywhere within your checkout, and run&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;gecko-root&amp;gt;/js/src/devtools/automation/autospider.sh --clobber compacting&lt;br /&gt;
&lt;br /&gt;
The default objdir is &amp;lt;gecko-root&amp;gt;/obj-spider. You can change it by setting the $OBJDIR environment variable.&lt;br /&gt;
&lt;br /&gt;
To narrow the test down, delete some of the lines at the end of autospider.sh that run the various tests.&lt;br /&gt;
&lt;br /&gt;
== Mapping variants to SM(...) names ==&lt;br /&gt;
&lt;br /&gt;
There is no good way. They&#039;re hardcoded in the Treeherder code. Many of them even show up in multiple repos. Here&#039;s a snapshot:&lt;br /&gt;
&lt;br /&gt;
* SM(cgc) - compacting&lt;br /&gt;
* SM(p) - plain or plaindebug&lt;br /&gt;
* SM(arm) - arm-sim or arm-sim-osx&lt;br /&gt;
* SM(arm64) - arm64-sim&lt;br /&gt;
* SM(exr) - exactrooting&lt;br /&gt;
* SM(r) - rootanalysis&lt;br /&gt;
* SM(pkg) - Standalone SpiderMonkey package.&lt;br /&gt;
* SM(tsan) - tsan&lt;br /&gt;
&lt;br /&gt;
== Aside on SM(pkg) ==&lt;br /&gt;
&lt;br /&gt;
The SM(pkg) builds create a tarball of all the sources used to make a standalone SpiderMonkey library and shell, untar it somewhere else, and then runs the autospider command listed above. To reproduce this packaging and unpackaging behavior, you can run this command:&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;gecko-root&amp;gt;/testing/taskcluster/scripts/builder/build-sm-package.sh&lt;/div&gt;</summary>
		<author><name>Sfink</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=Sfink/Moving_GC&amp;diff=1170537</id>
		<title>Sfink/Moving GC</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=Sfink/Moving_GC&amp;diff=1170537"/>
		<updated>2017-05-06T16:47:47Z</updated>

		<summary type="html">&lt;p&gt;Sfink: minor fixups&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;All garbage collection requires a way to find the set of objects that are&lt;br /&gt;
currently reachable. This requires knowing about all pointers into the JS heap&lt;br /&gt;
(&amp;quot;roots&amp;quot;), as well as all pointers within the JS heap (the &amp;quot;heap graph&amp;quot;). GC&lt;br /&gt;
will do a graph traversal starting from the roots and visiting everything&lt;br /&gt;
reachable. This requires being able to find all roots during a GC.&lt;br /&gt;
&lt;br /&gt;
A generational garbage collector (GGC) defines a subset of the JS heap as the&lt;br /&gt;
&amp;quot;nursery&amp;quot;, and allocates most objects out of this nursery in the expectation&lt;br /&gt;
that many of them will die quickly (become unused and unreferenced). The&lt;br /&gt;
collector periodically sweeps through the nursery, packing only the live&lt;br /&gt;
objects into another area so that the nursery is empty and available for new&lt;br /&gt;
allocations again. It is important that this nursery sweep (a &amp;quot;minor&lt;br /&gt;
collection&amp;quot;) only need to look at the *live* objects (plus some bookkeeping&lt;br /&gt;
information), NOT the full heap (or even a percentage of it) -- you want the&lt;br /&gt;
cost of minor collections to be proportional only to the amount of live data in&lt;br /&gt;
the nursery, and independent of the amount of garbage.&lt;br /&gt;
&lt;br /&gt;
This requires two main capabilities: (1) the ability to move objects around,&lt;br /&gt;
and (2) a record of all external pointers into the nursery.&lt;br /&gt;
&lt;br /&gt;
Incremental garbage collection (IGC) adds an additional requirement: at the&lt;br /&gt;
beginning of an incremental collection, all roots (external pointers) into the&lt;br /&gt;
heap are recorded, then the main program is allowed to continue running but is&lt;br /&gt;
interrupted periodically so the incremental collector can gradually trace the&lt;br /&gt;
whole heap graph. Because the graph can change during this sweep, any&lt;br /&gt;
intra-heap reference that is deleted must be marked (treated as live): such&lt;br /&gt;
references usually are either dead or reachable from somewhere else, but it&#039;s also possible that the main program&lt;br /&gt;
moved a reference from a part of the heap that has not yet been scanned to a&lt;br /&gt;
part that has already been scanned, and so it will not get marked during the&lt;br /&gt;
rest of the incremental collection. This adds a required capability (3): a&lt;br /&gt;
record of all pointers within the heap that were deleted while incremental GC&lt;br /&gt;
was active. Note that this is actually accomplished by putting them on the same mark stack as is used to record the current state of the incremental GC.&lt;br /&gt;
&lt;br /&gt;
Capability #1 means that we need to be able to find and update all pointers&lt;br /&gt;
from outside the JS heap into the JS heap. (Intra-heap pointers can be found&lt;br /&gt;
and updated by scanning, so they don&#039;t need any special handling.) The embedding uses APIs to register certain data structures as part of the root set, as well as callbacks to record other root pointers during the GC. For pointers on the stack, we use the Stack Rooting API; see js/public/RootingAPI.h.&lt;br /&gt;
&lt;br /&gt;
Capabilities #2 and #3 mean that we need &amp;quot;write barriers&amp;quot; for all JS heap&lt;br /&gt;
pointers stored within the C++ heap, which is a fancy way of saying that if you&lt;br /&gt;
modify a pointer into the heap, you may need to do something before and/or after&lt;br /&gt;
the write to update bookkeeping information. Capability #2 requires a&lt;br /&gt;
&amp;quot;post-barrier&amp;quot;, an action taken after the write occurs (or at least, using the written value), to store a record of&lt;br /&gt;
any new pointer value that points (or might point) into the nursery. Capability #3&lt;br /&gt;
requires a &amp;quot;pre-barrier&amp;quot;, an action taken before the write occurs, so it can&lt;br /&gt;
mark the overwritten value as live (before it is lost from the&lt;br /&gt;
graph).&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
You can divide memory into 4 partitions: the stack, the non-JS (C++) heap, the&lt;br /&gt;
JS nursery, and the JS tenured area. (Or you could say there&#039;s the stack and&lt;br /&gt;
the heap, and the heap is divided into JS and non-JS parts, and the JS part is&lt;br /&gt;
separated into a nursery and a tenured area, but it&#039;s the pointers between&lt;br /&gt;
these areas that matter so we&#039;ll keep them separate.)&lt;br /&gt;
&lt;br /&gt;
Pointers from the stack to either part of the JS heap must be findable and&lt;br /&gt;
updatable during a moving GC. This is usually accomplished with Rooted&amp;lt;T&amp;gt;,&lt;br /&gt;
Handle&amp;lt;T&amp;gt;, and MutableHandle&amp;lt;T&amp;gt;, though aggregates of various sorts will also&lt;br /&gt;
use the Auto*Rooter classes as well. Pointers from the stack to either the&lt;br /&gt;
stack or the C++ heap don&#039;t matter.&lt;br /&gt;
&lt;br /&gt;
Pointers from the C++ heap to the JS heap must be findable and updatable, and&lt;br /&gt;
writes must be barriered. Pointers from the C++ heap to the C++ heap don&#039;t matter to the GC. Pointers&lt;br /&gt;
from the C++ heap to the stack are kind of funky but don&#039;t matter to the GC.&lt;br /&gt;
&lt;br /&gt;
Pointers from the tenured area to anywhere in the JS heap are automatically&lt;br /&gt;
findable and updatable, since you can scan the JS heap. Writes do need to be&lt;br /&gt;
barriered, in case they change to point to the nursery (for GGC) or move an&lt;br /&gt;
unscanned subgraph into the already-scanned region (for IGC). Pointers from&lt;br /&gt;
tenured to the stack (?!) or the C++ heap don&#039;t matter.&lt;br /&gt;
&lt;br /&gt;
Pointers from the nursery are the same as those from tenured, except it doesn&#039;t&lt;br /&gt;
matter for GGC if a nursery pointer points to the nursery vs tenured. So the&lt;br /&gt;
post barrier is not needed. The pre barrier is not needed because incremental GC does a nursery collection before each slice.&lt;/div&gt;</summary>
		<author><name>Sfink</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=Javascript:Hazard_Builds&amp;diff=1168189</id>
		<title>Javascript:Hazard Builds</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=Javascript:Hazard_Builds&amp;diff=1168189"/>
		<updated>2017-04-12T22:52:56Z</updated>

		<summary type="html">&lt;p&gt;Sfink: /* Diagnosing a rooting hazards failure */ added &amp;lt;code&amp;gt; tags&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Static Analysis for Rooting and Heap Write Hazards ==&lt;br /&gt;
&lt;br /&gt;
Treeherder can run two static analysis builds: the full browser (linux64-haz), just the JS shell (linux64-shell-haz). They show up on treeherder as &#039;&#039;&#039;H&#039;&#039;&#039; and &#039;&#039;&#039;SM(H)&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Diagnosing a hazard failure ===&lt;br /&gt;
&lt;br /&gt;
The first step is to look at what sort of hazard is being reported. There are two types that cause the job to fail: stack rooting hazards for garbage collection, and heap write thread safety hazards for stylo.&lt;br /&gt;
&lt;br /&gt;
The summary output will include either the string &amp;quot;&amp;lt;N&amp;gt; rooting hazards detected&amp;quot; or &amp;quot;&amp;lt;N&amp;gt; heap write hazards detected out of &amp;lt;M&amp;gt; allowed&amp;quot;. See the appropriate section below for each.&lt;br /&gt;
&lt;br /&gt;
=== Diagnosing a rooting hazards failure ===&lt;br /&gt;
&lt;br /&gt;
Click on the &#039;&#039;&#039;H&#039;&#039;&#039; build link, select the &amp;quot;Job details&amp;quot; pane on the bottom right, follow the &amp;quot;Inspect Task&amp;quot; link, and download the &amp;quot;&amp;lt;code&amp;gt;public/build/hazards.txt.gz&amp;lt;/code&amp;gt;&amp;quot; file.&lt;br /&gt;
&lt;br /&gt;
Example snippet:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Function &#039;jsopcode.cpp:uint8 DecompileExpressionFromStack(JSContext*, int32, int32, class JS::Handle&amp;lt;JS::Value&amp;gt;, int8**)&#039; has unrooted &#039;ed&#039; of type &#039;ExpressionDecompiler&#039; live across GC call &#039;uint8 ExpressionDecompiler::decompilePC(uint8*)&#039; at js/src/jsopcode.cpp:1866&lt;br /&gt;
    js/src/jsopcode.cpp:1866: Assume(74,75, !__temp_23*, true)&lt;br /&gt;
    js/src/jsopcode.cpp:1867: Assign(75,76, return := 0)&lt;br /&gt;
    js/src/jsopcode.cpp:1867: Call(76,77, ed.~ExpressionDecompiler())&lt;br /&gt;
GC Function: uint8 ExpressionDecompiler::decompilePC(uint8*)&lt;br /&gt;
    JSString* js::ValueToSource(JSContext*, class JS::Handle&amp;lt;JS::Value&amp;gt;)&lt;br /&gt;
    uint8 js::Invoke(JSContext*, JS::Value*, JS::Value*, uint32, JS::Value*, class JS::MutableHandle&amp;lt;JS::Value&amp;gt;)&lt;br /&gt;
    uint8 js::Invoke(JSContext*, JS::CallArgs, uint32)&lt;br /&gt;
    JSScript* JSFunction::getOrCreateScript(JSContext*)&lt;br /&gt;
    uint8 JSFunction::createScriptForLazilyInterpretedFunction(JSContext*, class JS::Handle&amp;lt;JSFunction*&amp;gt;)&lt;br /&gt;
    uint8 JSRuntime::cloneSelfHostedFunctionScript(JSContext*, class JS::Handle&amp;lt;js::PropertyName*&amp;gt;, class JS::Handle&amp;lt;JSFunction*&amp;gt;)&lt;br /&gt;
    JSScript* js::CloneScript(JSContext*, class JS::Handle&amp;lt;JSObject*&amp;gt;, class JS::Handle&amp;lt;JSFunction*&amp;gt;, const class JS::Handle&amp;lt;JSScript*&amp;gt;, uint32)&lt;br /&gt;
    JSObject* js::CloneStaticBlockObject(JSContext*, class JS::Handle&amp;lt;JSObject*&amp;gt;, class JS::Handle&amp;lt;js::StaticBlockObject*&amp;gt;)&lt;br /&gt;
    js::StaticBlockObject* js::StaticBlockObject::create(js::ExclusiveContext*)&lt;br /&gt;
    js::Shape* js::EmptyShape::getInitialShape(js::ExclusiveContext*, js::Class*, js::TaggedProto, JSObject*, JSObject*, uint32, uint32)&lt;br /&gt;
    js::Shape* js::EmptyShape::getInitialShape(js::ExclusiveContext*, js::Class*, js::TaggedProto, JSObject*, JSObject*, uint64, uint32)&lt;br /&gt;
    js::UnownedBaseShape* js::BaseShape::getUnowned(js::ExclusiveContext*, js::StackBaseShape*)&lt;br /&gt;
    js::BaseShape* js_NewGCBaseShape(js::ThreadSafeContext*) [with js::AllowGC allowGC = (js::AllowGC)1u]&lt;br /&gt;
    js::BaseShape* js::gc::NewGCThing(js::ThreadSafeContext*, uint32, uint64, uint32) [with T = js::BaseShape; js::AllowGC allowGC = (js::AllowGC)1u; size_t = long unsigned int]&lt;br /&gt;
    void js::gc::RunDebugGC(JSContext*)&lt;br /&gt;
    void js::MinorGC(JSRuntime*, uint32)&lt;br /&gt;
    GC&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This means that a rooting hazard was discovered at &amp;lt;code&amp;gt;js/src/jsopcode.cpp&amp;lt;/code&amp;gt; line 1866, in the function &amp;lt;code&amp;gt;DecompileExpressionFromStack&amp;lt;/code&amp;gt; (it is prefixed with the filename because it&#039;s a static function.) The problem is that they&#039;re an unrooted variable &#039;&amp;lt;code&amp;gt;ed&amp;lt;/code&amp;gt;&#039; that holds an &amp;lt;code&amp;gt;ExpressionDecompiler&amp;lt;/code&amp;gt; live across a call to &amp;lt;code&amp;gt;decompilePC&amp;lt;/code&amp;gt;. &amp;quot;Live&amp;quot; means that the variable is used after the call to &amp;lt;code&amp;gt;decompilePC&amp;lt;/code&amp;gt; returns. &amp;lt;code&amp;gt;decompilePC&amp;lt;/code&amp;gt; may trigger a GC according to the static call stack given starting from the line beginning with &amp;quot;GC Function:&amp;quot;. The hazard itself has some barely comprehensible Assume(...) and Call(...) gibberish that describes the exact path of the variable into the function call. That stuff is rarely useful -- usually, you&#039;ll only need to look at it if it&#039;s complaining about a temporary and you want to know where the temporary came from. The type &#039;&amp;lt;code&amp;gt;ExpressionDecompiler&amp;lt;/code&amp;gt;&#039; is believed to hold pointers to GC-controlled objects of some sort. The analysis currently does not describe the exact field it is worried about.&lt;br /&gt;
&lt;br /&gt;
To unpack this a little, the analysis is saying the following can happen:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;ExpressionDecompiler&amp;lt;/code&amp;gt; contains some pointer to a GC thing. For example, it might have a field &#039;&amp;lt;code&amp;gt;obj&amp;lt;/code&amp;gt;&#039; of type &#039;&amp;lt;code&amp;gt;JSObject*&amp;lt;/code&amp;gt;&#039;.&lt;br /&gt;
* &amp;lt;code&amp;gt;DecompileExpressionFromStack&amp;lt;/code&amp;gt; is called.&lt;br /&gt;
* A pointer is stored in that field of the &#039;&amp;lt;code&amp;gt;ed&amp;lt;/code&amp;gt;&#039; variable.&lt;br /&gt;
* &amp;lt;code&amp;gt;decompilePC&amp;lt;/code&amp;gt; is invoked, which calls &amp;lt;code&amp;gt;ValueToSource&amp;lt;/code&amp;gt;, which calls &amp;lt;code&amp;gt;Invoke&amp;lt;/code&amp;gt;, which eventually calls &amp;lt;code&amp;gt;js::MinorGC&amp;lt;/code&amp;gt;&lt;br /&gt;
* during the resulting garbage collection, the object pointed to by &amp;lt;code&amp;gt;ed.obj&amp;lt;/code&amp;gt; is moved to a different location. All pointers stored in the JS heap are updated automatically, as are all rooted pointers. &amp;lt;code&amp;gt;ed.obj&amp;lt;/code&amp;gt; is not, because the GC doesn&#039;t know about it.&lt;br /&gt;
* after &amp;lt;code&amp;gt;decompilePC&amp;lt;/code&amp;gt; returns, something accesses &amp;lt;code&amp;gt;ed.obj&amp;lt;/code&amp;gt;. This is now a stale pointer, and may refer to just about anything -- the wrong object, an invalid object, or whatever. Badness 10000, as TeX would say.&lt;br /&gt;
&lt;br /&gt;
=== Diagnosing a heap write hazard failure ===&lt;br /&gt;
&lt;br /&gt;
For the thread unsafe heap write analysis, a hazard means that some Gecko_* function calls, directly or indirectly, code that writes to something on the heap, or calls an unknown function that *might* write to something on the heap. The analysis requires quite a few annotations to describe things that are actually safe. This section will be expanded as we gain more experience with the analysis, but here are some common issues:&lt;br /&gt;
&lt;br /&gt;
* Adding a new Gecko_* function: often, you will need to annotate any outparams or owned (thread-local) parameters in the &amp;lt;code&amp;gt;treatAsSafeArgument&amp;lt;/code&amp;gt; function in &amp;lt;code&amp;gt;js/src/devtools/rootAnalysis/analyzeHeapWrites.js&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Calling some libc function: if you add a call to some random libc function (eg sin() or floor() or ceil(), though the latter two are already annotated), the analysis will report an &amp;quot;External Function&amp;quot;. Add it to &amp;lt;code&amp;gt;checkExternalFunction&amp;lt;/code&amp;gt;, assuming it *doesn&#039;t* have the possibility of writing to shared heap memory.&lt;br /&gt;
* If you call some non-returning (crashing) function that the analysis doesn&#039;t know about, you&#039;ll need to add it to &amp;lt;code&amp;gt;ignoreContents&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
On the other hand, you might have a real thread safety issue on your hands. Shared caches are common problems. Fix it.&lt;br /&gt;
&lt;br /&gt;
=== Analysis implementation ===&lt;br /&gt;
&lt;br /&gt;
These builds are performed as follows:&lt;br /&gt;
&lt;br /&gt;
* run the script testing/taskcluster/scripts/builder/build-haz-linux.sh, which sets up a build environment and runs the analysis within it, then uploads the resulting files&lt;br /&gt;
** compile an optimized JS shell to later run the analysis&lt;br /&gt;
** compile the browser with gcc, using a slightly modified version of the sixgill (http://svn.sixgill.org) gcc plugin, producing a set of .xdb files describing everything encountered during the compilation&lt;br /&gt;
** analyze the .xdb files with scripts in js/src/devtools/rootAnalysis&lt;br /&gt;
&lt;br /&gt;
=== Running the analysis ===&lt;br /&gt;
&lt;br /&gt;
==== Pushing to try ====&lt;br /&gt;
&lt;br /&gt;
The easiest way to run an analysis is to push to try with the trychooser line |try: -b do -p linux64-haz| (or, if the hazards of interest are contained entirely within js/src, use |try: -b do -p linux64-shell-haz| for a much faster result). The expected turnaround time for linux64-haz is just under 2 hours.&lt;br /&gt;
&lt;br /&gt;
The output will be uploaded and a link named &amp;quot;results&amp;quot; will be placed into the &amp;quot;job details&amp;quot; info pane on treeherder. If the analysis fails, you will see the number of failures. Navigate to the hazards.txt.gz file.&lt;br /&gt;
&lt;br /&gt;
==== Running locally ====&lt;br /&gt;
&lt;br /&gt;
To run the browser analysis, you must be on a Fedora/RedHat/CentOS linux64 machine. See js/src/devtools/rootAnalysis/README.md.&lt;br /&gt;
&lt;br /&gt;
If you are running Debian or Ubuntu, then there is currently a problem running the full browser analysis. You can coerce the shell-only build to work by doing something like:&lt;br /&gt;
&lt;br /&gt;
  sudo apt-get install autoconf2.13 libnspr4 libnspr4-dev&lt;br /&gt;
  sudo ln -s autoconf2.13 /usr/bin/autoconf-2.13&lt;br /&gt;
  export CFLAGS=&amp;quot;-B/usr/lib/x86_64-linux-gnu -I/usr/include/x86_64-linux-gnu&amp;quot;&lt;br /&gt;
  export CXXFLAGS=&amp;quot;-B/usr/lib/x86_64-linux-gnu -I/usr/include/x86_64-linux-gnu&amp;quot;&lt;br /&gt;
&lt;br /&gt;
before running the script.&lt;br /&gt;
&lt;br /&gt;
=== So you broke the analysis by adding a hazard. Now what? ===&lt;br /&gt;
&lt;br /&gt;
Backout, fix the hazard, or (final resort) update the expected number of hazards in js/src/devtools/rootAnalysis/expect.browser.json (but don&#039;t do that).&lt;br /&gt;
&lt;br /&gt;
The most common way to fix a hazard is to change the variable to be a Rooted type, as described in http://dxr.mozilla.org/mozilla-central/source/js/public/RootingAPI.h#l21&lt;br /&gt;
&lt;br /&gt;
For more complicated cases, ask on #jsapi. If you don&#039;t get a response, ping sfink or jonco for rooting hazards, bholley or sfink for heap write hazards. Or if it&#039;s a deeper issue with the analysis logic, try bhackett (the author of both analyses.)&lt;/div&gt;</summary>
		<author><name>Sfink</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=Javascript:Hazard_Builds&amp;diff=1168185</id>
		<title>Javascript:Hazard Builds</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=Javascript:Hazard_Builds&amp;diff=1168185"/>
		<updated>2017-04-12T22:42:15Z</updated>

		<summary type="html">&lt;p&gt;Sfink: /* Static Analysis for Rooting Hazards */ stuff about heap writes&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Static Analysis for Rooting and Heap Write Hazards ==&lt;br /&gt;
&lt;br /&gt;
Treeherder can run two static analysis builds: the full browser (linux64-haz), just the JS shell (linux64-shell-haz). They show up on treeherder as &#039;&#039;&#039;H&#039;&#039;&#039; and &#039;&#039;&#039;SM(H)&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Diagnosing a hazard failure ===&lt;br /&gt;
&lt;br /&gt;
The first step is to look at what sort of hazard is being reported. There are two types that cause the job to fail: stack rooting hazards for garbage collection, and heap write thread safety hazards for stylo.&lt;br /&gt;
&lt;br /&gt;
The summary output will include either the string &amp;quot;&amp;lt;N&amp;gt; rooting hazards detected&amp;quot; or &amp;quot;&amp;lt;N&amp;gt; heap write hazards detected out of &amp;lt;M&amp;gt; allowed&amp;quot;. See the appropriate section below for each.&lt;br /&gt;
&lt;br /&gt;
=== Diagnosing a rooting hazards failure ===&lt;br /&gt;
&lt;br /&gt;
Click on the &#039;&#039;&#039;H&#039;&#039;&#039; build link, select the &amp;quot;Job details&amp;quot; pane on the bottom right, follow the &amp;quot;Inspect Task&amp;quot; link, and download the &amp;quot;public/build/hazards.txt.gz&amp;quot; file.&lt;br /&gt;
&lt;br /&gt;
Example snippet:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Function &#039;jsopcode.cpp:uint8 DecompileExpressionFromStack(JSContext*, int32, int32, class JS::Handle&amp;lt;JS::Value&amp;gt;, int8**)&#039; has unrooted &#039;ed&#039; of type &#039;ExpressionDecompiler&#039; live across GC call &#039;uint8 ExpressionDecompiler::decompilePC(uint8*)&#039; at js/src/jsopcode.cpp:1866&lt;br /&gt;
    js/src/jsopcode.cpp:1866: Assume(74,75, !__temp_23*, true)&lt;br /&gt;
    js/src/jsopcode.cpp:1867: Assign(75,76, return := 0)&lt;br /&gt;
    js/src/jsopcode.cpp:1867: Call(76,77, ed.~ExpressionDecompiler())&lt;br /&gt;
GC Function: uint8 ExpressionDecompiler::decompilePC(uint8*)&lt;br /&gt;
    JSString* js::ValueToSource(JSContext*, class JS::Handle&amp;lt;JS::Value&amp;gt;)&lt;br /&gt;
    uint8 js::Invoke(JSContext*, JS::Value*, JS::Value*, uint32, JS::Value*, class JS::MutableHandle&amp;lt;JS::Value&amp;gt;)&lt;br /&gt;
    uint8 js::Invoke(JSContext*, JS::CallArgs, uint32)&lt;br /&gt;
    JSScript* JSFunction::getOrCreateScript(JSContext*)&lt;br /&gt;
    uint8 JSFunction::createScriptForLazilyInterpretedFunction(JSContext*, class JS::Handle&amp;lt;JSFunction*&amp;gt;)&lt;br /&gt;
    uint8 JSRuntime::cloneSelfHostedFunctionScript(JSContext*, class JS::Handle&amp;lt;js::PropertyName*&amp;gt;, class JS::Handle&amp;lt;JSFunction*&amp;gt;)&lt;br /&gt;
    JSScript* js::CloneScript(JSContext*, class JS::Handle&amp;lt;JSObject*&amp;gt;, class JS::Handle&amp;lt;JSFunction*&amp;gt;, const class JS::Handle&amp;lt;JSScript*&amp;gt;, uint32)&lt;br /&gt;
    JSObject* js::CloneStaticBlockObject(JSContext*, class JS::Handle&amp;lt;JSObject*&amp;gt;, class JS::Handle&amp;lt;js::StaticBlockObject*&amp;gt;)&lt;br /&gt;
    js::StaticBlockObject* js::StaticBlockObject::create(js::ExclusiveContext*)&lt;br /&gt;
    js::Shape* js::EmptyShape::getInitialShape(js::ExclusiveContext*, js::Class*, js::TaggedProto, JSObject*, JSObject*, uint32, uint32)&lt;br /&gt;
    js::Shape* js::EmptyShape::getInitialShape(js::ExclusiveContext*, js::Class*, js::TaggedProto, JSObject*, JSObject*, uint64, uint32)&lt;br /&gt;
    js::UnownedBaseShape* js::BaseShape::getUnowned(js::ExclusiveContext*, js::StackBaseShape*)&lt;br /&gt;
    js::BaseShape* js_NewGCBaseShape(js::ThreadSafeContext*) [with js::AllowGC allowGC = (js::AllowGC)1u]&lt;br /&gt;
    js::BaseShape* js::gc::NewGCThing(js::ThreadSafeContext*, uint32, uint64, uint32) [with T = js::BaseShape; js::AllowGC allowGC = (js::AllowGC)1u; size_t = long unsigned int]&lt;br /&gt;
    void js::gc::RunDebugGC(JSContext*)&lt;br /&gt;
    void js::MinorGC(JSRuntime*, uint32)&lt;br /&gt;
    GC&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This means that a rooting hazard was discovered at js/src/jsopcode.cpp line 1866, in the function DecompileExpressionFromStack (it is prefixed with the filename because it&#039;s a static function.) The problem is that they&#039;re an unrooted variable &#039;ed&#039; that holds an ExpressionDecompiler live across a call to decompilePC. &amp;quot;Live&amp;quot; means that the variable is used after the call to decompilePC returns. decompilePC may trigger a GC according to the static call stack given starting from the line beginning with &amp;quot;GC Function:&amp;quot;. The hazard itself has some barely comprehensible Assume(...) and Call(...) gibberish that describes the exact path of the variable into the function call. That stuff is rarely useful -- usually, you&#039;ll only need to look at it if it&#039;s complaining about a temporary and you want to know where the temporary came from. The type &#039;ExpressionDecompiler&#039; is believed to hold pointers to GC-controlled objects of some sort. The analysis currently does not describe the exact field it is worried about.&lt;br /&gt;
&lt;br /&gt;
To unpack this a little, the analysis is saying the following can happen:&lt;br /&gt;
&lt;br /&gt;
* ExpressionDecompiler contains some pointer to a GC thing. For example, it might have a field &#039;obj&#039; of type &#039;JSObject*&#039;.&lt;br /&gt;
* DecompileExpressionFromStack is called.&lt;br /&gt;
* A pointer is stored in that field of the &#039;ed&#039; variable.&lt;br /&gt;
* decompilePC is invoked, which calls ValueToSource, which calls Invoke, which eventually calls js::MinorGC&lt;br /&gt;
* during the resulting garbage collection, the object pointed to by ed.obj is moved to a different location. All pointers stored in the JS heap are updated automatically, as are all rooted pointers. ed.obj is not, because the GC doesn&#039;t know about it.&lt;br /&gt;
* after decompilePC returns, something accesses ed.obj. This is now a stale pointer, and may refer to just about anything -- the wrong object, an invalid object, or whatever. Badness 10000, as TeX would say.&lt;br /&gt;
&lt;br /&gt;
=== Diagnosing a heap write hazard failure ===&lt;br /&gt;
&lt;br /&gt;
For the thread unsafe heap write analysis, a hazard means that some Gecko_* function calls, directly or indirectly, code that writes to something on the heap, or calls an unknown function that *might* write to something on the heap. The analysis requires quite a few annotations to describe things that are actually safe. This section will be expanded as we gain more experience with the analysis, but here are some common issues:&lt;br /&gt;
&lt;br /&gt;
* Adding a new Gecko_* function: often, you will need to annotate any outparams or owned (thread-local) parameters in the &amp;lt;code&amp;gt;treatAsSafeArgument&amp;lt;/code&amp;gt; function in &amp;lt;code&amp;gt;js/src/devtools/rootAnalysis/analyzeHeapWrites.js&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Calling some libc function: if you add a call to some random libc function (eg sin() or floor() or ceil(), though the latter two are already annotated), the analysis will report an &amp;quot;External Function&amp;quot;. Add it to &amp;lt;code&amp;gt;checkExternalFunction&amp;lt;/code&amp;gt;, assuming it *doesn&#039;t* have the possibility of writing to shared heap memory.&lt;br /&gt;
* If you call some non-returning (crashing) function that the analysis doesn&#039;t know about, you&#039;ll need to add it to &amp;lt;code&amp;gt;ignoreContents&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
On the other hand, you might have a real thread safety issue on your hands. Shared caches are common problems. Fix it.&lt;br /&gt;
&lt;br /&gt;
=== Analysis implementation ===&lt;br /&gt;
&lt;br /&gt;
These builds are performed as follows:&lt;br /&gt;
&lt;br /&gt;
* run the script testing/taskcluster/scripts/builder/build-haz-linux.sh, which sets up a build environment and runs the analysis within it, then uploads the resulting files&lt;br /&gt;
** compile an optimized JS shell to later run the analysis&lt;br /&gt;
** compile the browser with gcc, using a slightly modified version of the sixgill (http://svn.sixgill.org) gcc plugin, producing a set of .xdb files describing everything encountered during the compilation&lt;br /&gt;
** analyze the .xdb files with scripts in js/src/devtools/rootAnalysis&lt;br /&gt;
&lt;br /&gt;
=== Running the analysis ===&lt;br /&gt;
&lt;br /&gt;
==== Pushing to try ====&lt;br /&gt;
&lt;br /&gt;
The easiest way to run an analysis is to push to try with the trychooser line |try: -b do -p linux64-haz| (or, if the hazards of interest are contained entirely within js/src, use |try: -b do -p linux64-shell-haz| for a much faster result). The expected turnaround time for linux64-haz is just under 2 hours.&lt;br /&gt;
&lt;br /&gt;
The output will be uploaded and a link named &amp;quot;results&amp;quot; will be placed into the &amp;quot;job details&amp;quot; info pane on treeherder. If the analysis fails, you will see the number of failures. Navigate to the hazards.txt.gz file.&lt;br /&gt;
&lt;br /&gt;
==== Running locally ====&lt;br /&gt;
&lt;br /&gt;
To run the browser analysis, you must be on a Fedora/RedHat/CentOS linux64 machine. See js/src/devtools/rootAnalysis/README.md.&lt;br /&gt;
&lt;br /&gt;
If you are running Debian or Ubuntu, then there is currently a problem running the full browser analysis. You can coerce the shell-only build to work by doing something like:&lt;br /&gt;
&lt;br /&gt;
  sudo apt-get install autoconf2.13 libnspr4 libnspr4-dev&lt;br /&gt;
  sudo ln -s autoconf2.13 /usr/bin/autoconf-2.13&lt;br /&gt;
  export CFLAGS=&amp;quot;-B/usr/lib/x86_64-linux-gnu -I/usr/include/x86_64-linux-gnu&amp;quot;&lt;br /&gt;
  export CXXFLAGS=&amp;quot;-B/usr/lib/x86_64-linux-gnu -I/usr/include/x86_64-linux-gnu&amp;quot;&lt;br /&gt;
&lt;br /&gt;
before running the script.&lt;br /&gt;
&lt;br /&gt;
=== So you broke the analysis by adding a hazard. Now what? ===&lt;br /&gt;
&lt;br /&gt;
Backout, fix the hazard, or (final resort) update the expected number of hazards in js/src/devtools/rootAnalysis/expect.browser.json (but don&#039;t do that).&lt;br /&gt;
&lt;br /&gt;
The most common way to fix a hazard is to change the variable to be a Rooted type, as described in http://dxr.mozilla.org/mozilla-central/source/js/public/RootingAPI.h#l21&lt;br /&gt;
&lt;br /&gt;
For more complicated cases, ask on #jsapi. If you don&#039;t get a response, ping sfink or jonco for rooting hazards, bholley or sfink for heap write hazards. Or if it&#039;s a deeper issue with the analysis logic, try bhackett (the author of both analyses.)&lt;/div&gt;</summary>
		<author><name>Sfink</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=Javascript:Hazard_Builds&amp;diff=1158184</id>
		<title>Javascript:Hazard Builds</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=Javascript:Hazard_Builds&amp;diff=1158184"/>
		<updated>2016-12-29T22:29:28Z</updated>

		<summary type="html">&lt;p&gt;Sfink: terrence gone.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Static Analysis for Rooting Hazards ==&lt;br /&gt;
&lt;br /&gt;
Treeherder can run two static analysis builds: the full browser (linux64-haz), just the JS shell (linux64-shell-haz). They show up on treeherder as &#039;&#039;&#039;H&#039;&#039;&#039; and &#039;&#039;&#039;SM(H)&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Diagnosing a hazard failure ===&lt;br /&gt;
&lt;br /&gt;
Click on the &#039;&#039;&#039;H&#039;&#039;&#039; build link, select the &amp;quot;Job details&amp;quot; pane on the bottom right, follow the &amp;quot;Inspect Task&amp;quot; link, and download the &amp;quot;public/build/hazards.txt.gz&amp;quot; file.&lt;br /&gt;
&lt;br /&gt;
Example snippet:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Function &#039;jsopcode.cpp:uint8 DecompileExpressionFromStack(JSContext*, int32, int32, class JS::Handle&amp;lt;JS::Value&amp;gt;, int8**)&#039; has unrooted &#039;ed&#039; of type &#039;ExpressionDecompiler&#039; live across GC call &#039;uint8 ExpressionDecompiler::decompilePC(uint8*)&#039; at js/src/jsopcode.cpp:1866&lt;br /&gt;
    js/src/jsopcode.cpp:1866: Assume(74,75, !__temp_23*, true)&lt;br /&gt;
    js/src/jsopcode.cpp:1867: Assign(75,76, return := 0)&lt;br /&gt;
    js/src/jsopcode.cpp:1867: Call(76,77, ed.~ExpressionDecompiler())&lt;br /&gt;
GC Function: uint8 ExpressionDecompiler::decompilePC(uint8*)&lt;br /&gt;
    JSString* js::ValueToSource(JSContext*, class JS::Handle&amp;lt;JS::Value&amp;gt;)&lt;br /&gt;
    uint8 js::Invoke(JSContext*, JS::Value*, JS::Value*, uint32, JS::Value*, class JS::MutableHandle&amp;lt;JS::Value&amp;gt;)&lt;br /&gt;
    uint8 js::Invoke(JSContext*, JS::CallArgs, uint32)&lt;br /&gt;
    JSScript* JSFunction::getOrCreateScript(JSContext*)&lt;br /&gt;
    uint8 JSFunction::createScriptForLazilyInterpretedFunction(JSContext*, class JS::Handle&amp;lt;JSFunction*&amp;gt;)&lt;br /&gt;
    uint8 JSRuntime::cloneSelfHostedFunctionScript(JSContext*, class JS::Handle&amp;lt;js::PropertyName*&amp;gt;, class JS::Handle&amp;lt;JSFunction*&amp;gt;)&lt;br /&gt;
    JSScript* js::CloneScript(JSContext*, class JS::Handle&amp;lt;JSObject*&amp;gt;, class JS::Handle&amp;lt;JSFunction*&amp;gt;, const class JS::Handle&amp;lt;JSScript*&amp;gt;, uint32)&lt;br /&gt;
    JSObject* js::CloneStaticBlockObject(JSContext*, class JS::Handle&amp;lt;JSObject*&amp;gt;, class JS::Handle&amp;lt;js::StaticBlockObject*&amp;gt;)&lt;br /&gt;
    js::StaticBlockObject* js::StaticBlockObject::create(js::ExclusiveContext*)&lt;br /&gt;
    js::Shape* js::EmptyShape::getInitialShape(js::ExclusiveContext*, js::Class*, js::TaggedProto, JSObject*, JSObject*, uint32, uint32)&lt;br /&gt;
    js::Shape* js::EmptyShape::getInitialShape(js::ExclusiveContext*, js::Class*, js::TaggedProto, JSObject*, JSObject*, uint64, uint32)&lt;br /&gt;
    js::UnownedBaseShape* js::BaseShape::getUnowned(js::ExclusiveContext*, js::StackBaseShape*)&lt;br /&gt;
    js::BaseShape* js_NewGCBaseShape(js::ThreadSafeContext*) [with js::AllowGC allowGC = (js::AllowGC)1u]&lt;br /&gt;
    js::BaseShape* js::gc::NewGCThing(js::ThreadSafeContext*, uint32, uint64, uint32) [with T = js::BaseShape; js::AllowGC allowGC = (js::AllowGC)1u; size_t = long unsigned int]&lt;br /&gt;
    void js::gc::RunDebugGC(JSContext*)&lt;br /&gt;
    void js::MinorGC(JSRuntime*, uint32)&lt;br /&gt;
    GC&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This means that a rooting hazard was discovered at js/src/jsopcode.cpp line 1866, in the function DecompileExpressionFromStack (it is prefixed with the filename because it&#039;s a static function.) The problem is that they&#039;re an unrooted variable &#039;ed&#039; that holds an ExpressionDecompiler live across a call to decompilePC. &amp;quot;Live&amp;quot; means that the variable is used after the call to decompilePC returns. decompilePC may trigger a GC according to the static call stack given starting from the line beginning with &amp;quot;GC Function:&amp;quot;. The hazard itself has some barely comprehensible Assume(...) and Call(...) gibberish that describes the exact path of the variable into the function call. That stuff is rarely useful -- usually, you&#039;ll only need to look at it if it&#039;s complaining about a temporary and you want to know where the temporary came from. The type &#039;ExpressionDecompiler&#039; is believed to hold pointers to GC-controlled objects of some sort. The analysis currently does not describe the exact field it is worried about.&lt;br /&gt;
&lt;br /&gt;
To unpack this a little, the analysis is saying the following can happen:&lt;br /&gt;
&lt;br /&gt;
* ExpressionDecompiler contains some pointer to a GC thing. For example, it might have a field &#039;obj&#039; of type &#039;JSObject*&#039;.&lt;br /&gt;
* DecompileExpressionFromStack is called.&lt;br /&gt;
* A pointer is stored in that field of the &#039;ed&#039; variable.&lt;br /&gt;
* decompilePC is invoked, which calls ValueToSource, which calls Invoke, which eventually calls js::MinorGC&lt;br /&gt;
* during the resulting garbage collection, the object pointed to by ed.obj is moved to a different location. All pointers stored in the JS heap are updated automatically, as are all rooted pointers. ed.obj is not, because the GC doesn&#039;t know about it.&lt;br /&gt;
* after decompilePC returns, something accesses ed.obj. This is now a stale pointer, and may refer to just about anything -- the wrong object, an invalid object, or whatever. Badness 10000, as TeX would say.&lt;br /&gt;
&lt;br /&gt;
=== Analysis implementation ===&lt;br /&gt;
&lt;br /&gt;
These builds are performed as follows:&lt;br /&gt;
&lt;br /&gt;
* run the script testing/taskcluster/scripts/builder/build-haz-linux.sh, which sets up a build environment and runs the analysis within it, then uploads the resulting files&lt;br /&gt;
** compile an optimized JS shell to later run the analysis&lt;br /&gt;
** compile the browser with gcc, using a slightly modified version of the sixgill (http://svn.sixgill.org) gcc plugin, producing a set of .xdb files describing everything encountered during the compilation&lt;br /&gt;
** analyze the .xdb files with scripts in js/src/devtools/rootAnalysis&lt;br /&gt;
&lt;br /&gt;
=== Running the analysis ===&lt;br /&gt;
&lt;br /&gt;
==== Pushing to try ====&lt;br /&gt;
&lt;br /&gt;
The easiest way to run an analysis is to push to try with the trychooser line |try: -b do -p linux64-haz| (or, if the hazards of interest are contained entirely within js/src, use |try: -b do -p linux64-shell-haz| for a much faster result). The expected turnaround time for linux64-haz is just under 2 hours.&lt;br /&gt;
&lt;br /&gt;
The output will be uploaded and a link named &amp;quot;results&amp;quot; will be placed into the &amp;quot;job details&amp;quot; info pane on treeherder. If the analysis fails, you will see the number of failures. Navigate to the hazards.txt.gz file.&lt;br /&gt;
&lt;br /&gt;
==== Running locally ====&lt;br /&gt;
&lt;br /&gt;
To run the browser analysis, you must be on a Fedora/RedHat/CentOS linux64 machine. See js/src/devtools/rootAnalysis/README.md.&lt;br /&gt;
&lt;br /&gt;
If you are running Debian or Ubuntu, then there is currently a problem running the full browser analysis. You can coerce the shell-only build to work by doing something like:&lt;br /&gt;
&lt;br /&gt;
  sudo apt-get install autoconf2.13 libnspr4 libnspr4-dev&lt;br /&gt;
  sudo ln -s autoconf2.13 /usr/bin/autoconf-2.13&lt;br /&gt;
  export CFLAGS=&amp;quot;-B/usr/lib/x86_64-linux-gnu -I/usr/include/x86_64-linux-gnu&amp;quot;&lt;br /&gt;
  export CXXFLAGS=&amp;quot;-B/usr/lib/x86_64-linux-gnu -I/usr/include/x86_64-linux-gnu&amp;quot;&lt;br /&gt;
&lt;br /&gt;
before running the script.&lt;br /&gt;
&lt;br /&gt;
=== So you broke the analysis by adding a hazard. Now what? ===&lt;br /&gt;
&lt;br /&gt;
Backout, fix the hazard, or (final resort) update the expected number of hazards in js/src/devtools/rootAnalysis/expect.browser.json (but don&#039;t do that).&lt;br /&gt;
&lt;br /&gt;
The most common way to fix a hazard is to change the variable to be a Rooted type, as described in http://dxr.mozilla.org/mozilla-central/source/js/public/RootingAPI.h#l21&lt;br /&gt;
&lt;br /&gt;
For more complicated cases, ask on #jsapi. If you don&#039;t get a response, ping sfink or jonco.&lt;/div&gt;</summary>
		<author><name>Sfink</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=JavaScript:New_to_SpiderMonkey&amp;diff=1150971</id>
		<title>JavaScript:New to SpiderMonkey</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=JavaScript:New_to_SpiderMonkey&amp;diff=1150971"/>
		<updated>2016-10-11T16:20:01Z</updated>

		<summary type="html">&lt;p&gt;Sfink: /* Try server */ tbpl -&amp;gt; th&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Tutorial: your first patch  ==&lt;br /&gt;
&lt;br /&gt;
The first step to getting involved with SpiderMonkey is to make your first patch. This guides you through it, and at the end you should have learnt a lot of the procedures and formalisms involved in getting things done here.&lt;br /&gt;
&lt;br /&gt;
We&#039;ll assume you&#039;re on a Unix-y platform, and that you know what you&#039;re doing. We&#039;ll ignore nearly all details. &lt;br /&gt;
&lt;br /&gt;
=== Get the code ===&lt;br /&gt;
&lt;br /&gt;
Spidermonkey development happens in the &amp;quot;mozilla-central&amp;quot; mercurial repository:&lt;br /&gt;
&lt;br /&gt;
 hg clone http://hg.mozilla.org/mozilla-central spidermonkey&lt;br /&gt;
&lt;br /&gt;
=== Build the js shell ===&lt;br /&gt;
&lt;br /&gt;
Most of the time, you&#039;ll be working with the Javascript shell, instead of the full Firefox browser. So build the shell: &lt;br /&gt;
&lt;br /&gt;
 cd spidermonkey/js/src&lt;br /&gt;
 cp configure.in configure &amp;amp;&amp;amp; chmod +x configure # or autoconf2.13 or autoconf-2.13&lt;br /&gt;
 mkdir build_DBG.OBJ &lt;br /&gt;
 cd build_DBG.OBJ &lt;br /&gt;
 ../configure --enable-debug --disable-optimize&lt;br /&gt;
 make # or make -j8&lt;br /&gt;
 cd ..&lt;br /&gt;
&lt;br /&gt;
If you&#039;re having trouble or are missing dependencies, refer to [https://developer.mozilla.org/en/SpiderMonkey/Build_Documentation#Building_SpiderMonkey_tip Building SpiderMonkey Tip].&lt;br /&gt;
&lt;br /&gt;
=== Fix something ===&lt;br /&gt;
&lt;br /&gt;
At this point, you&#039;re ready to make your first fix. &lt;br /&gt;
&lt;br /&gt;
 TODO: something useless. Maybe adding a datemicrosecond function.&lt;br /&gt;
&lt;br /&gt;
==== Building your changes ====&lt;br /&gt;
&lt;br /&gt;
Having made the change, build the shell again. &lt;br /&gt;
&lt;br /&gt;
 make -C build_DBG.OBJ&lt;br /&gt;
&lt;br /&gt;
==== Testing your changes ====&lt;br /&gt;
&lt;br /&gt;
It builds. Hurray. Time to run the tests to check you haven&#039;t broken anything. &lt;br /&gt;
&lt;br /&gt;
 jit-test/jit_test.py build_DBG.OBJ/dist/bin/js&lt;br /&gt;
(The location of the shell has changed, it used to be build_DBG.OBJ/js)&lt;br /&gt;
&lt;br /&gt;
The jit-tests are pretty quick, and should give you an idea if you&#039;ve gotten something wrong. Assuming nothing goes wrong, try the ref-tests: &lt;br /&gt;
&lt;br /&gt;
 tests/jstests.py build_DBG.OBJ/dist/bin/js&lt;br /&gt;
&lt;br /&gt;
Note that some of these tests fail depending on the timezone and locale they&#039;re run in, so if you get any errors that don&#039;t seem related to your changes, re-run the tests with a shell build without your changes applied and compare the results.&lt;br /&gt;
&lt;br /&gt;
==== Benchmark your changes ====&lt;br /&gt;
&lt;br /&gt;
Tests all pass. Congrats, you didn&#039;t break anything. Now, did you make it faster or slower? We benchmark using the v8 and SunSpider benchmarks. Get the benchmarks: &lt;br /&gt;
&lt;br /&gt;
 svn checkout http://svn.webkit.org/repository/webkit/trunk/PerformanceTests/SunSpider&lt;br /&gt;
&lt;br /&gt;
And now run them: &lt;br /&gt;
&lt;br /&gt;
 cd SunSpider &lt;br /&gt;
 ./sunspider --shell=../build_DBG.OBJ/dist/bin/js --run=30 --suite=sunspider-0.9.1 &lt;br /&gt;
 cd ..&lt;br /&gt;
&lt;br /&gt;
===== Optimized build =====&lt;br /&gt;
&lt;br /&gt;
Whoops, we benchmarked the debug version. Let&#039;s make an optimized build to test instead.&lt;br /&gt;
&lt;br /&gt;
 mkdir build_OPT.OBJ &lt;br /&gt;
 cd build_OPT.OBJ &lt;br /&gt;
 ../configure --disable-debug --enable-optimize&lt;br /&gt;
 make &lt;br /&gt;
 cd ..&lt;br /&gt;
&lt;br /&gt;
Repeat the sunspider steps above, and take note of the line that looks like: &lt;br /&gt;
&lt;br /&gt;
 Results are located at sunspider-0.9.1-results/sunspider-results-2010-08-07-17.56.48.js&lt;br /&gt;
&lt;br /&gt;
You&#039;ll need that later. &lt;br /&gt;
&lt;br /&gt;
===== Baseline version / Mercurial Queues =====&lt;br /&gt;
&lt;br /&gt;
We need to time our optimized version against the baseline version. This calls for a brief introduction to mercurial queues, which used to be the way most people managed their SpiderMonkey workflow (though these days many people use native hg, native hg + evolution, or git):&lt;br /&gt;
&lt;br /&gt;
 hg qinit&lt;br /&gt;
 hg qnew my_first_patch -f&lt;br /&gt;
 hg qrefresh&lt;br /&gt;
&lt;br /&gt;
This puts your current work into a patch, managed by Mercurial, symbolically called my_first_patch. To pop the patch off: &lt;br /&gt;
&lt;br /&gt;
 hg qpop&lt;br /&gt;
&lt;br /&gt;
And we&#039;re back to our pristine version.&lt;br /&gt;
&lt;br /&gt;
===== Compare =====&lt;br /&gt;
&lt;br /&gt;
Build again and rerun SunSpider again. You should now have two files like: &lt;br /&gt;
&lt;br /&gt;
 sunspider-0.9.1-results/sunspider-results-2010-08-07-17.56.48.js&lt;br /&gt;
&lt;br /&gt;
Compare them using the compare script: &lt;br /&gt;
&lt;br /&gt;
 cd SunSpider &lt;br /&gt;
 ./sunspider-compare-results --shell=../build_DBG.OBJ/js --suite=sunspider-0.9.1 FILE1-withoutPatch FILE2-withPatch&lt;br /&gt;
&lt;br /&gt;
=== Get a real bug  ===&lt;br /&gt;
&lt;br /&gt;
At this point, you&#039;ve seen nearly everything you need to do hack on SpiderMonkey. So it&#039;s time to get a real bug to work on. You can get a bug on [http://www.joshmatthews.net/bugsahoy/?jseng=1&amp;amp;unowned=1 Bugs Ahoy].&lt;br /&gt;
&lt;br /&gt;
Fix the bug, updating the bug report with your progress, and asking questions as you go (either in the bug comments, or in [irc://irc.mozilla.org/#jsapi #jsapi]). When it&#039;s done, repeat all the steps above. Then it&#039;s time to get your patch into the tree.&lt;br /&gt;
&lt;br /&gt;
=== Submit a patch  ===&lt;br /&gt;
&lt;br /&gt;
To get the patch from mercurial, use: &lt;br /&gt;
&lt;br /&gt;
 hg qdiff # if you&#039;re using queues or&lt;br /&gt;
 hg diff  # if you&#039;re not&lt;br /&gt;
&lt;br /&gt;
Add it to the bug as an attachment. &lt;br /&gt;
&lt;br /&gt;
=== Get a review ===&lt;br /&gt;
&lt;br /&gt;
Nothing gets into the tree without a review, so you&#039;ll need one. The [[JavaScript:Hackers|SpiderMonkey hackers list]] is a good place to start: if your patch changes something listed as an area of expertise for someone there, that&#039;s a good person to ask for a review.&lt;br /&gt;
&lt;br /&gt;
Alternatively run &amp;lt;code&amp;gt;hg blame&amp;lt;/code&amp;gt; on the files you&#039;ve changed, and check who has been changing related code recently. They&#039;re likely to be good candidates. An irc bot can automate this process for a single file if you enter &amp;quot;/msg mrgiggles who can review something.cpp?&amp;quot; into your irc client.&lt;br /&gt;
&lt;br /&gt;
The review will consist of comments on your changes, suggesting or requesting alternative ways to do something and asking you to make changes where needed. They might also request additional changes, for example tests. Fix what they ask, resubmit the patch to bugzilla, and ask for another review. After you repeat this step a few times, they will mark the patch as &amp;quot;&amp;lt;code&amp;gt;r+&amp;lt;/code&amp;gt;&amp;quot; meaning it&#039;s now good to commit.&lt;br /&gt;
&lt;br /&gt;
=== Commit ===&lt;br /&gt;
&lt;br /&gt;
You can&#039;t commit to mozilla-central / mozilla-inbound until you have &amp;quot;level 3&amp;quot; access, so you&#039;ll need someone to do this for you. Try asking in [irc://irc.mozilla.org/#jsapi #jsapi], or add the &amp;lt;code&amp;gt;checkin-needed&amp;lt;/code&amp;gt; keyword to the bug. After you have been contributing for a while, you can get level 3 access by [https://www.mozilla.org/hacking/commit-access-policy/ applying for it].&lt;br /&gt;
&lt;br /&gt;
After committing, a large series of tests will be run to make sure you didn&#039;t break anything. You will need to hang around to make sure you didn&#039;t break something. It is difficult to determine what failures are real and what are what we call &amp;quot;intermittent oranges&amp;quot; (&amp;quot;orange&amp;quot; because that is the color used on our continuous integration dashboard for test failures). If you do break something, a sheriff will probably let you know via IRC and will probably back your patch out. You can always ask [irc://irc.mozilla.org/#jsapi for help] determining what is going on. (Over time you&#039;ll get a feel for figuring out when breakage is real on your own.)&lt;br /&gt;
&lt;br /&gt;
== Overview of the JS engine ==&lt;br /&gt;
&lt;br /&gt;
The JS engine is a swiftly moving target. The most detailed information is available at https://developer.mozilla.org/en/SpiderMonkey. Here are some particularly interesting, mostly up-to-date resources:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== High level overviews ===&lt;br /&gt;
&lt;br /&gt;
(Outdated) http://hacks.mozilla.org/2010/03/a-quick-note-on-javascript-engine-components/&lt;br /&gt;
&lt;br /&gt;
https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Internals&lt;br /&gt;
&lt;br /&gt;
=== Medium level documentation ===&lt;br /&gt;
&lt;br /&gt;
jsapi.h: http://hg.mozilla.org/mozilla-central/file/tip/js/src/jsapi.h and the files in http://hg.mozilla.org/mozilla-central/file/tip/js/public&lt;br /&gt;
&lt;br /&gt;
Frequently used coding recipes and mappings from JS idioms to SpiderMonkey code: https://developer.mozilla.org/En/SpiderMonkey/JSAPI_Cookbook&lt;br /&gt;
&lt;br /&gt;
=== Detailed documentation ===&lt;br /&gt;
&lt;br /&gt;
Build: https://developer.mozilla.org/en/SpiderMonkey/Build_Documentation&lt;br /&gt;
&lt;br /&gt;
Testing: https://developer.mozilla.org/en/SpiderMonkey/Running_Automated_JavaScript_Tests&lt;br /&gt;
&lt;br /&gt;
Shell: https://developer.mozilla.org/En/SpiderMonkey/Introduction_to_the_JavaScript_shell&lt;br /&gt;
&lt;br /&gt;
Function reference: https://developer.mozilla.org/en/SpiderMonkey/JSAPI_Reference&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Collaboration and teamwork ==&lt;br /&gt;
&lt;br /&gt;
=== Communication (in descending order of information content) ===&lt;br /&gt;
&lt;br /&gt;
Nearly all communication is handled through [https://bugzilla.mozilla.org Bugzilla]. All bugs, feature requests, issues, enhancements, etc, are all referred to as bugs. No code may enter the Mozilla repository without being a patch attached to a bugzilla bug first. To follow all SpiderMonkey related bugs:&lt;br /&gt;
&lt;br /&gt;
 Go to [https://bugzilla.mozilla.org/userprefs.cgi?tab=email email preferences]&lt;br /&gt;
 Watch the user general@spidermonkey.bugs&lt;br /&gt;
 Or watch one of the JS components in the Core product: JavaScript Engine, JavaScript Engine: JIT, JavaScript: GC, or JavaScript: Standard Library&lt;br /&gt;
&lt;br /&gt;
SpiderMonkey contributors generally hang out in the very active [irc://irc.mozilla.org/jsapi #jsapi IRC channel].&lt;br /&gt;
&lt;br /&gt;
The [https://www.mozilla.org/about/forums/#dev-tech-js-engine-internals js-internals mailing list] is used for communicating with other SpiderMonkey hackers. (&amp;lt;i&amp;gt;Internals&amp;lt;/i&amp;gt; as in discussing the internals of the SpiderMonkey engine. All are welcome on the list.).&lt;br /&gt;
&lt;br /&gt;
Reading Planet Mozilla is the best way to keep up with the Mozilla project, which includes some SpiderMonkey related blogs:&lt;br /&gt;
&lt;br /&gt;
 [https://blog.mozilla.org/javascript General JavaScript blog]&lt;br /&gt;
 [http://blog.mozilla.com/jorendorff Jason Orendorff]&lt;br /&gt;
 [http://blog.mozilla.com/nnethercote/ Nicholas Nethercote]&lt;br /&gt;
 [http://whereswalden.com/ Jeff Walden]&lt;br /&gt;
 [https://itcouldbesomuchbetter.wordpress.com Jim Blandy]&lt;br /&gt;
 [https://jandemooij.nl/ Jan de Mooij]&lt;br /&gt;
 [https://h4writer.com/ Hannes Verschore]&lt;br /&gt;
 [http://rfrn.org/~shu/ Shu-yu Guo]&lt;br /&gt;
 [https://blog.benj.me/tag/mozilla.html Benjamin Bouvier]&lt;br /&gt;
&lt;br /&gt;
The [https://developer.mozilla.org/en/SpiderMonkey#Community js-engine mailing list] is generally used for communicating with people who embed SpiderMonkey, such as asking questions and announcing API changes. No actual development happens on the list.&lt;br /&gt;
&lt;br /&gt;
== Code considerations ==&lt;br /&gt;
&lt;br /&gt;
=== Repository ===&lt;br /&gt;
&lt;br /&gt;
Most active work on SpiderMonkey is done in the [http://hg.mozilla.org/mozilla-central mozilla-central] branch of the mozilla repository.&lt;br /&gt;
&lt;br /&gt;
=== Coding Style ===&lt;br /&gt;
&lt;br /&gt;
For many years, SpiderMonkey was written in C, and is gradually moving to C++. We still avoid many features such as run-time type information and exceptions, and generally avoid virtual functions for core data, but have come around to the glory of templates and namespaces relatively recently. Read the [[JavaScript:SpiderMonkey:C++ Coding Style|Coding Style]]. Do NOT read the portability guidelines, which I will not link to, since they are very out of date.&lt;br /&gt;
&lt;br /&gt;
=== Workflow ===&lt;br /&gt;
&lt;br /&gt;
Everything goes through bugzilla. We find a bug or have an idea, then submit it to bugzilla, then file patches to solve it. When it is solved, the patch is reviewed by team members, and is then committed to the [http://hg.mozilla.org/integration/mozilla-inbound mozilla-inbound repository]. A link to the commit is then automatically added as a comment to the bug. mozilla-inbound is periodically merged to mozilla-central by a Sheriff. This exempts us from watching [https://treeherder.mozilla.org/#/jobs?repo=mozilla-inbound treeherder] to check for failures caused by our patches, and commits are automatically backed out if errors are found.&lt;br /&gt;
&lt;br /&gt;
==== Sample Workflows ====&lt;br /&gt;
&lt;br /&gt;
(Outdated) [http://blog.mozilla.com/nnethercote/2009/07/27/how-i-work-on-tracemonkey/ Nicholas Nethercote: How I work on Tracemonkey]&lt;br /&gt;
&lt;br /&gt;
=== Policy ===&lt;br /&gt;
&lt;br /&gt;
The following docs are for the Mozilla project, and differ ever so slightly from what you should do for SpiderMonkey. For example, you should find reviewers in #jsapi rather than #developers.&lt;br /&gt;
&lt;br /&gt;
[http://www.mozilla.org/hacking/committer/ How to get commit access]&lt;br /&gt;
&lt;br /&gt;
[https://developer.mozilla.org/en/Creating_a_patch How to make patches]&lt;br /&gt;
&lt;br /&gt;
[https://developer.mozilla.org/En/Developer_Guide/How_to_Submit_a_Patch Submitting a patch]&lt;br /&gt;
&lt;br /&gt;
[https://developer.mozilla.org/en/Supported_build_configurations Supported Platforms]&lt;br /&gt;
&lt;br /&gt;
==== .hgrc file ====&lt;br /&gt;
&lt;br /&gt;
This .hgrc file contains a lot of the wisdom distilled through the wiki:&lt;br /&gt;
&lt;br /&gt;
 [extensions]&lt;br /&gt;
 mq =&lt;br /&gt;
 &lt;br /&gt;
 [ui]&lt;br /&gt;
 username = First Last &amp;lt;email@domain.tld&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
 [alias]&lt;br /&gt;
 qfulldiff = diff --rev qparent:.&lt;br /&gt;
 &lt;br /&gt;
 [defaults]&lt;br /&gt;
 diff = -p -U 8&lt;br /&gt;
 qdiff = -p -U 8&lt;br /&gt;
 qnew = -U&lt;br /&gt;
 commit = -v&lt;br /&gt;
 &lt;br /&gt;
 [diff]&lt;br /&gt;
 git = true&lt;br /&gt;
 showfunc = true&lt;br /&gt;
 unified = 8&lt;br /&gt;
 &lt;br /&gt;
 [paths]&lt;br /&gt;
 try = ssh://email@domain.tld@hg.mozilla.org/try/&lt;br /&gt;
&lt;br /&gt;
=== Try server  ===&lt;br /&gt;
&lt;br /&gt;
Often, you may be a little wary of breaking things. Mozilla has a [[Build:TryServer|Try Server]] where you can send a patch, and it&#039;ll be built and tested on tons of machines, which report to [https://treeherder.mozilla.org/#/jobs?repo=try TreeHerder]. Although you don&#039;t have [https://www.mozilla.org/hacking/commit-access-policy/ access] to TryServer just yet, you can get someone else to push it there for you. Just attach a patch to your bug, and ask in a comment, or on [irc://irc.mozilla.org/#jsapi #jsapi]. To be able to push to try-server yourself, you will need &amp;quot;level 1&amp;quot; access, which you can [https://www.mozilla.org/hacking/commit-access-policy/ request] once you&#039;ve contributed a patch or two.&lt;br /&gt;
&lt;br /&gt;
=== Mercurial Queues ===&lt;br /&gt;
&lt;br /&gt;
Since most of our lives revolve around patches, and we use Mercurial, nearly everybody uses Mercurial queues.&lt;br /&gt;
&lt;br /&gt;
Queues are based on the idea of patch management. Each queue consists of a series of patches, applied sequentially. The aim of the game is to split potential commits into simple, bite-sized chunks which are easy to review. This also makes it simple to experiment without polluting your existing work on a bug, to spin parts off into new bugs, and to rapidly apply and unapply patches (as demonstrated in the tutorial above).&lt;br /&gt;
&lt;br /&gt;
==== Enabling ====&lt;br /&gt;
&lt;br /&gt;
Add the following snippet to your .hgrc file to enable MQ&lt;br /&gt;
&lt;br /&gt;
 [extensions]&lt;br /&gt;
 mq =&lt;br /&gt;
&lt;br /&gt;
==== Example MQ workflow ====&lt;br /&gt;
&lt;br /&gt;
Clone the repository to deal with a bug:&lt;br /&gt;
&lt;br /&gt;
  hg clone http://hg.mozilla.org/mozilla-central&lt;br /&gt;
&lt;br /&gt;
Initialize your queue:&lt;br /&gt;
&lt;br /&gt;
  hg qinit -c&lt;br /&gt;
&lt;br /&gt;
Create a new patch, with some name:&lt;br /&gt;
&lt;br /&gt;
  hg qnew first_attempt&lt;br /&gt;
&lt;br /&gt;
Work on the patch, try to fix the bug, test, compile, etc.&lt;br /&gt;
&lt;br /&gt;
Refresh (save your work into the patch):&lt;br /&gt;
&lt;br /&gt;
 hg qrefresh&lt;br /&gt;
&lt;br /&gt;
Repeat a few times.&lt;br /&gt;
&lt;br /&gt;
Rename the patch (because your first name wasn&#039;t appliable):&lt;br /&gt;
&lt;br /&gt;
 hg qrename refactor_the_whatsit&lt;br /&gt;
&lt;br /&gt;
Create a new patch to try a logically separate part of the same bug:&lt;br /&gt;
&lt;br /&gt;
 hg qnew rip_out_the_old_thing&lt;br /&gt;
&lt;br /&gt;
Repeat the process a few times, until you have solved the problem. During this time, it can often be useful to go back and forth between patches:&lt;br /&gt;
&lt;br /&gt;
 hg qpop # unapply a patch&lt;br /&gt;
 hg qpush # reapply a patch&lt;br /&gt;
 hg qpop -a # unapply all patches&lt;br /&gt;
 hg qpush -a # reapply all patches&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Combine all the patches into a single patch, which you submit to bugzilla:&lt;br /&gt;
&lt;br /&gt;
 hg qpush -a&lt;br /&gt;
 hg qdiff --rev qparent:. &amp;gt; my_wonderful_patch.patch&lt;br /&gt;
&lt;br /&gt;
Commit the patches to your local patch repository, in case you make a mistake (You might do this periodically):&lt;br /&gt;
&lt;br /&gt;
 hg qcommit -m &amp;quot;Some message. Doesn&#039;t have to be good, this won&#039;t be committed to the repository, it&#039;s just for you&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Go back to the old patches and fiddle with them based on feedback:&lt;br /&gt;
&lt;br /&gt;
 hg qpop&lt;br /&gt;
 hg qrefresh&lt;br /&gt;
 etc&lt;br /&gt;
&lt;br /&gt;
There are some more complex techniques that we won&#039;t go into in detail. You can enable only some patches using qguard and qselect, and you can reorder the patches by manually editing the .hg/patches/series file. But be careful!&lt;br /&gt;
&lt;br /&gt;
[[Category:New Contributor Landing Page]]&lt;/div&gt;</summary>
		<author><name>Sfink</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=JavaScript:New_to_SpiderMonkey&amp;diff=1150970</id>
		<title>JavaScript:New to SpiderMonkey</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=JavaScript:New_to_SpiderMonkey&amp;diff=1150970"/>
		<updated>2016-10-11T16:19:15Z</updated>

		<summary type="html">&lt;p&gt;Sfink: /* Workflow */ treeherder, inbound&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Tutorial: your first patch  ==&lt;br /&gt;
&lt;br /&gt;
The first step to getting involved with SpiderMonkey is to make your first patch. This guides you through it, and at the end you should have learnt a lot of the procedures and formalisms involved in getting things done here.&lt;br /&gt;
&lt;br /&gt;
We&#039;ll assume you&#039;re on a Unix-y platform, and that you know what you&#039;re doing. We&#039;ll ignore nearly all details. &lt;br /&gt;
&lt;br /&gt;
=== Get the code ===&lt;br /&gt;
&lt;br /&gt;
Spidermonkey development happens in the &amp;quot;mozilla-central&amp;quot; mercurial repository:&lt;br /&gt;
&lt;br /&gt;
 hg clone http://hg.mozilla.org/mozilla-central spidermonkey&lt;br /&gt;
&lt;br /&gt;
=== Build the js shell ===&lt;br /&gt;
&lt;br /&gt;
Most of the time, you&#039;ll be working with the Javascript shell, instead of the full Firefox browser. So build the shell: &lt;br /&gt;
&lt;br /&gt;
 cd spidermonkey/js/src&lt;br /&gt;
 cp configure.in configure &amp;amp;&amp;amp; chmod +x configure # or autoconf2.13 or autoconf-2.13&lt;br /&gt;
 mkdir build_DBG.OBJ &lt;br /&gt;
 cd build_DBG.OBJ &lt;br /&gt;
 ../configure --enable-debug --disable-optimize&lt;br /&gt;
 make # or make -j8&lt;br /&gt;
 cd ..&lt;br /&gt;
&lt;br /&gt;
If you&#039;re having trouble or are missing dependencies, refer to [https://developer.mozilla.org/en/SpiderMonkey/Build_Documentation#Building_SpiderMonkey_tip Building SpiderMonkey Tip].&lt;br /&gt;
&lt;br /&gt;
=== Fix something ===&lt;br /&gt;
&lt;br /&gt;
At this point, you&#039;re ready to make your first fix. &lt;br /&gt;
&lt;br /&gt;
 TODO: something useless. Maybe adding a datemicrosecond function.&lt;br /&gt;
&lt;br /&gt;
==== Building your changes ====&lt;br /&gt;
&lt;br /&gt;
Having made the change, build the shell again. &lt;br /&gt;
&lt;br /&gt;
 make -C build_DBG.OBJ&lt;br /&gt;
&lt;br /&gt;
==== Testing your changes ====&lt;br /&gt;
&lt;br /&gt;
It builds. Hurray. Time to run the tests to check you haven&#039;t broken anything. &lt;br /&gt;
&lt;br /&gt;
 jit-test/jit_test.py build_DBG.OBJ/dist/bin/js&lt;br /&gt;
(The location of the shell has changed, it used to be build_DBG.OBJ/js)&lt;br /&gt;
&lt;br /&gt;
The jit-tests are pretty quick, and should give you an idea if you&#039;ve gotten something wrong. Assuming nothing goes wrong, try the ref-tests: &lt;br /&gt;
&lt;br /&gt;
 tests/jstests.py build_DBG.OBJ/dist/bin/js&lt;br /&gt;
&lt;br /&gt;
Note that some of these tests fail depending on the timezone and locale they&#039;re run in, so if you get any errors that don&#039;t seem related to your changes, re-run the tests with a shell build without your changes applied and compare the results.&lt;br /&gt;
&lt;br /&gt;
==== Benchmark your changes ====&lt;br /&gt;
&lt;br /&gt;
Tests all pass. Congrats, you didn&#039;t break anything. Now, did you make it faster or slower? We benchmark using the v8 and SunSpider benchmarks. Get the benchmarks: &lt;br /&gt;
&lt;br /&gt;
 svn checkout http://svn.webkit.org/repository/webkit/trunk/PerformanceTests/SunSpider&lt;br /&gt;
&lt;br /&gt;
And now run them: &lt;br /&gt;
&lt;br /&gt;
 cd SunSpider &lt;br /&gt;
 ./sunspider --shell=../build_DBG.OBJ/dist/bin/js --run=30 --suite=sunspider-0.9.1 &lt;br /&gt;
 cd ..&lt;br /&gt;
&lt;br /&gt;
===== Optimized build =====&lt;br /&gt;
&lt;br /&gt;
Whoops, we benchmarked the debug version. Let&#039;s make an optimized build to test instead.&lt;br /&gt;
&lt;br /&gt;
 mkdir build_OPT.OBJ &lt;br /&gt;
 cd build_OPT.OBJ &lt;br /&gt;
 ../configure --disable-debug --enable-optimize&lt;br /&gt;
 make &lt;br /&gt;
 cd ..&lt;br /&gt;
&lt;br /&gt;
Repeat the sunspider steps above, and take note of the line that looks like: &lt;br /&gt;
&lt;br /&gt;
 Results are located at sunspider-0.9.1-results/sunspider-results-2010-08-07-17.56.48.js&lt;br /&gt;
&lt;br /&gt;
You&#039;ll need that later. &lt;br /&gt;
&lt;br /&gt;
===== Baseline version / Mercurial Queues =====&lt;br /&gt;
&lt;br /&gt;
We need to time our optimized version against the baseline version. This calls for a brief introduction to mercurial queues, which used to be the way most people managed their SpiderMonkey workflow (though these days many people use native hg, native hg + evolution, or git):&lt;br /&gt;
&lt;br /&gt;
 hg qinit&lt;br /&gt;
 hg qnew my_first_patch -f&lt;br /&gt;
 hg qrefresh&lt;br /&gt;
&lt;br /&gt;
This puts your current work into a patch, managed by Mercurial, symbolically called my_first_patch. To pop the patch off: &lt;br /&gt;
&lt;br /&gt;
 hg qpop&lt;br /&gt;
&lt;br /&gt;
And we&#039;re back to our pristine version.&lt;br /&gt;
&lt;br /&gt;
===== Compare =====&lt;br /&gt;
&lt;br /&gt;
Build again and rerun SunSpider again. You should now have two files like: &lt;br /&gt;
&lt;br /&gt;
 sunspider-0.9.1-results/sunspider-results-2010-08-07-17.56.48.js&lt;br /&gt;
&lt;br /&gt;
Compare them using the compare script: &lt;br /&gt;
&lt;br /&gt;
 cd SunSpider &lt;br /&gt;
 ./sunspider-compare-results --shell=../build_DBG.OBJ/js --suite=sunspider-0.9.1 FILE1-withoutPatch FILE2-withPatch&lt;br /&gt;
&lt;br /&gt;
=== Get a real bug  ===&lt;br /&gt;
&lt;br /&gt;
At this point, you&#039;ve seen nearly everything you need to do hack on SpiderMonkey. So it&#039;s time to get a real bug to work on. You can get a bug on [http://www.joshmatthews.net/bugsahoy/?jseng=1&amp;amp;unowned=1 Bugs Ahoy].&lt;br /&gt;
&lt;br /&gt;
Fix the bug, updating the bug report with your progress, and asking questions as you go (either in the bug comments, or in [irc://irc.mozilla.org/#jsapi #jsapi]). When it&#039;s done, repeat all the steps above. Then it&#039;s time to get your patch into the tree.&lt;br /&gt;
&lt;br /&gt;
=== Submit a patch  ===&lt;br /&gt;
&lt;br /&gt;
To get the patch from mercurial, use: &lt;br /&gt;
&lt;br /&gt;
 hg qdiff # if you&#039;re using queues or&lt;br /&gt;
 hg diff  # if you&#039;re not&lt;br /&gt;
&lt;br /&gt;
Add it to the bug as an attachment. &lt;br /&gt;
&lt;br /&gt;
=== Get a review ===&lt;br /&gt;
&lt;br /&gt;
Nothing gets into the tree without a review, so you&#039;ll need one. The [[JavaScript:Hackers|SpiderMonkey hackers list]] is a good place to start: if your patch changes something listed as an area of expertise for someone there, that&#039;s a good person to ask for a review.&lt;br /&gt;
&lt;br /&gt;
Alternatively run &amp;lt;code&amp;gt;hg blame&amp;lt;/code&amp;gt; on the files you&#039;ve changed, and check who has been changing related code recently. They&#039;re likely to be good candidates. An irc bot can automate this process for a single file if you enter &amp;quot;/msg mrgiggles who can review something.cpp?&amp;quot; into your irc client.&lt;br /&gt;
&lt;br /&gt;
The review will consist of comments on your changes, suggesting or requesting alternative ways to do something and asking you to make changes where needed. They might also request additional changes, for example tests. Fix what they ask, resubmit the patch to bugzilla, and ask for another review. After you repeat this step a few times, they will mark the patch as &amp;quot;&amp;lt;code&amp;gt;r+&amp;lt;/code&amp;gt;&amp;quot; meaning it&#039;s now good to commit.&lt;br /&gt;
&lt;br /&gt;
=== Commit ===&lt;br /&gt;
&lt;br /&gt;
You can&#039;t commit to mozilla-central / mozilla-inbound until you have &amp;quot;level 3&amp;quot; access, so you&#039;ll need someone to do this for you. Try asking in [irc://irc.mozilla.org/#jsapi #jsapi], or add the &amp;lt;code&amp;gt;checkin-needed&amp;lt;/code&amp;gt; keyword to the bug. After you have been contributing for a while, you can get level 3 access by [https://www.mozilla.org/hacking/commit-access-policy/ applying for it].&lt;br /&gt;
&lt;br /&gt;
After committing, a large series of tests will be run to make sure you didn&#039;t break anything. You will need to hang around to make sure you didn&#039;t break something. It is difficult to determine what failures are real and what are what we call &amp;quot;intermittent oranges&amp;quot; (&amp;quot;orange&amp;quot; because that is the color used on our continuous integration dashboard for test failures). If you do break something, a sheriff will probably let you know via IRC and will probably back your patch out. You can always ask [irc://irc.mozilla.org/#jsapi for help] determining what is going on. (Over time you&#039;ll get a feel for figuring out when breakage is real on your own.)&lt;br /&gt;
&lt;br /&gt;
== Overview of the JS engine ==&lt;br /&gt;
&lt;br /&gt;
The JS engine is a swiftly moving target. The most detailed information is available at https://developer.mozilla.org/en/SpiderMonkey. Here are some particularly interesting, mostly up-to-date resources:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== High level overviews ===&lt;br /&gt;
&lt;br /&gt;
(Outdated) http://hacks.mozilla.org/2010/03/a-quick-note-on-javascript-engine-components/&lt;br /&gt;
&lt;br /&gt;
https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Internals&lt;br /&gt;
&lt;br /&gt;
=== Medium level documentation ===&lt;br /&gt;
&lt;br /&gt;
jsapi.h: http://hg.mozilla.org/mozilla-central/file/tip/js/src/jsapi.h and the files in http://hg.mozilla.org/mozilla-central/file/tip/js/public&lt;br /&gt;
&lt;br /&gt;
Frequently used coding recipes and mappings from JS idioms to SpiderMonkey code: https://developer.mozilla.org/En/SpiderMonkey/JSAPI_Cookbook&lt;br /&gt;
&lt;br /&gt;
=== Detailed documentation ===&lt;br /&gt;
&lt;br /&gt;
Build: https://developer.mozilla.org/en/SpiderMonkey/Build_Documentation&lt;br /&gt;
&lt;br /&gt;
Testing: https://developer.mozilla.org/en/SpiderMonkey/Running_Automated_JavaScript_Tests&lt;br /&gt;
&lt;br /&gt;
Shell: https://developer.mozilla.org/En/SpiderMonkey/Introduction_to_the_JavaScript_shell&lt;br /&gt;
&lt;br /&gt;
Function reference: https://developer.mozilla.org/en/SpiderMonkey/JSAPI_Reference&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Collaboration and teamwork ==&lt;br /&gt;
&lt;br /&gt;
=== Communication (in descending order of information content) ===&lt;br /&gt;
&lt;br /&gt;
Nearly all communication is handled through [https://bugzilla.mozilla.org Bugzilla]. All bugs, feature requests, issues, enhancements, etc, are all referred to as bugs. No code may enter the Mozilla repository without being a patch attached to a bugzilla bug first. To follow all SpiderMonkey related bugs:&lt;br /&gt;
&lt;br /&gt;
 Go to [https://bugzilla.mozilla.org/userprefs.cgi?tab=email email preferences]&lt;br /&gt;
 Watch the user general@spidermonkey.bugs&lt;br /&gt;
 Or watch one of the JS components in the Core product: JavaScript Engine, JavaScript Engine: JIT, JavaScript: GC, or JavaScript: Standard Library&lt;br /&gt;
&lt;br /&gt;
SpiderMonkey contributors generally hang out in the very active [irc://irc.mozilla.org/jsapi #jsapi IRC channel].&lt;br /&gt;
&lt;br /&gt;
The [https://www.mozilla.org/about/forums/#dev-tech-js-engine-internals js-internals mailing list] is used for communicating with other SpiderMonkey hackers. (&amp;lt;i&amp;gt;Internals&amp;lt;/i&amp;gt; as in discussing the internals of the SpiderMonkey engine. All are welcome on the list.).&lt;br /&gt;
&lt;br /&gt;
Reading Planet Mozilla is the best way to keep up with the Mozilla project, which includes some SpiderMonkey related blogs:&lt;br /&gt;
&lt;br /&gt;
 [https://blog.mozilla.org/javascript General JavaScript blog]&lt;br /&gt;
 [http://blog.mozilla.com/jorendorff Jason Orendorff]&lt;br /&gt;
 [http://blog.mozilla.com/nnethercote/ Nicholas Nethercote]&lt;br /&gt;
 [http://whereswalden.com/ Jeff Walden]&lt;br /&gt;
 [https://itcouldbesomuchbetter.wordpress.com Jim Blandy]&lt;br /&gt;
 [https://jandemooij.nl/ Jan de Mooij]&lt;br /&gt;
 [https://h4writer.com/ Hannes Verschore]&lt;br /&gt;
 [http://rfrn.org/~shu/ Shu-yu Guo]&lt;br /&gt;
 [https://blog.benj.me/tag/mozilla.html Benjamin Bouvier]&lt;br /&gt;
&lt;br /&gt;
The [https://developer.mozilla.org/en/SpiderMonkey#Community js-engine mailing list] is generally used for communicating with people who embed SpiderMonkey, such as asking questions and announcing API changes. No actual development happens on the list.&lt;br /&gt;
&lt;br /&gt;
== Code considerations ==&lt;br /&gt;
&lt;br /&gt;
=== Repository ===&lt;br /&gt;
&lt;br /&gt;
Most active work on SpiderMonkey is done in the [http://hg.mozilla.org/mozilla-central mozilla-central] branch of the mozilla repository.&lt;br /&gt;
&lt;br /&gt;
=== Coding Style ===&lt;br /&gt;
&lt;br /&gt;
For many years, SpiderMonkey was written in C, and is gradually moving to C++. We still avoid many features such as run-time type information and exceptions, and generally avoid virtual functions for core data, but have come around to the glory of templates and namespaces relatively recently. Read the [[JavaScript:SpiderMonkey:C++ Coding Style|Coding Style]]. Do NOT read the portability guidelines, which I will not link to, since they are very out of date.&lt;br /&gt;
&lt;br /&gt;
=== Workflow ===&lt;br /&gt;
&lt;br /&gt;
Everything goes through bugzilla. We find a bug or have an idea, then submit it to bugzilla, then file patches to solve it. When it is solved, the patch is reviewed by team members, and is then committed to the [http://hg.mozilla.org/integration/mozilla-inbound mozilla-inbound repository]. A link to the commit is then automatically added as a comment to the bug. mozilla-inbound is periodically merged to mozilla-central by a Sheriff. This exempts us from watching [https://treeherder.mozilla.org/#/jobs?repo=mozilla-inbound treeherder] to check for failures caused by our patches, and commits are automatically backed out if errors are found.&lt;br /&gt;
&lt;br /&gt;
==== Sample Workflows ====&lt;br /&gt;
&lt;br /&gt;
(Outdated) [http://blog.mozilla.com/nnethercote/2009/07/27/how-i-work-on-tracemonkey/ Nicholas Nethercote: How I work on Tracemonkey]&lt;br /&gt;
&lt;br /&gt;
=== Policy ===&lt;br /&gt;
&lt;br /&gt;
The following docs are for the Mozilla project, and differ ever so slightly from what you should do for SpiderMonkey. For example, you should find reviewers in #jsapi rather than #developers.&lt;br /&gt;
&lt;br /&gt;
[http://www.mozilla.org/hacking/committer/ How to get commit access]&lt;br /&gt;
&lt;br /&gt;
[https://developer.mozilla.org/en/Creating_a_patch How to make patches]&lt;br /&gt;
&lt;br /&gt;
[https://developer.mozilla.org/En/Developer_Guide/How_to_Submit_a_Patch Submitting a patch]&lt;br /&gt;
&lt;br /&gt;
[https://developer.mozilla.org/en/Supported_build_configurations Supported Platforms]&lt;br /&gt;
&lt;br /&gt;
==== .hgrc file ====&lt;br /&gt;
&lt;br /&gt;
This .hgrc file contains a lot of the wisdom distilled through the wiki:&lt;br /&gt;
&lt;br /&gt;
 [extensions]&lt;br /&gt;
 mq =&lt;br /&gt;
 &lt;br /&gt;
 [ui]&lt;br /&gt;
 username = First Last &amp;lt;email@domain.tld&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
 [alias]&lt;br /&gt;
 qfulldiff = diff --rev qparent:.&lt;br /&gt;
 &lt;br /&gt;
 [defaults]&lt;br /&gt;
 diff = -p -U 8&lt;br /&gt;
 qdiff = -p -U 8&lt;br /&gt;
 qnew = -U&lt;br /&gt;
 commit = -v&lt;br /&gt;
 &lt;br /&gt;
 [diff]&lt;br /&gt;
 git = true&lt;br /&gt;
 showfunc = true&lt;br /&gt;
 unified = 8&lt;br /&gt;
 &lt;br /&gt;
 [paths]&lt;br /&gt;
 try = ssh://email@domain.tld@hg.mozilla.org/try/&lt;br /&gt;
&lt;br /&gt;
=== Try server  ===&lt;br /&gt;
&lt;br /&gt;
Often, you may be a little wary of breaking things. Mozilla has a [[Build:TryServer|Try Server]] where you can send a patch, and it&#039;ll be built and tested on tons of machines, which report to [http://tbpl.mozilla.org/?tree=Try TBPL]. Although you don&#039;t have [https://www.mozilla.org/hacking/commit-access-policy/ access] to TryServer just yet, you can get someone else to push it there for you. Just attach a patch to your bug, and ask in a comment, or on [irc://irc.mozilla.org/#jsapi #jsapi]. To be able to push to try-server yourself, you will need &amp;quot;level 1&amp;quot; access, which you can [https://www.mozilla.org/hacking/commit-access-policy/ request] once you&#039;ve contributed a patch or two.&lt;br /&gt;
&lt;br /&gt;
=== Mercurial Queues ===&lt;br /&gt;
&lt;br /&gt;
Since most of our lives revolve around patches, and we use Mercurial, nearly everybody uses Mercurial queues.&lt;br /&gt;
&lt;br /&gt;
Queues are based on the idea of patch management. Each queue consists of a series of patches, applied sequentially. The aim of the game is to split potential commits into simple, bite-sized chunks which are easy to review. This also makes it simple to experiment without polluting your existing work on a bug, to spin parts off into new bugs, and to rapidly apply and unapply patches (as demonstrated in the tutorial above).&lt;br /&gt;
&lt;br /&gt;
==== Enabling ====&lt;br /&gt;
&lt;br /&gt;
Add the following snippet to your .hgrc file to enable MQ&lt;br /&gt;
&lt;br /&gt;
 [extensions]&lt;br /&gt;
 mq =&lt;br /&gt;
&lt;br /&gt;
==== Example MQ workflow ====&lt;br /&gt;
&lt;br /&gt;
Clone the repository to deal with a bug:&lt;br /&gt;
&lt;br /&gt;
  hg clone http://hg.mozilla.org/mozilla-central&lt;br /&gt;
&lt;br /&gt;
Initialize your queue:&lt;br /&gt;
&lt;br /&gt;
  hg qinit -c&lt;br /&gt;
&lt;br /&gt;
Create a new patch, with some name:&lt;br /&gt;
&lt;br /&gt;
  hg qnew first_attempt&lt;br /&gt;
&lt;br /&gt;
Work on the patch, try to fix the bug, test, compile, etc.&lt;br /&gt;
&lt;br /&gt;
Refresh (save your work into the patch):&lt;br /&gt;
&lt;br /&gt;
 hg qrefresh&lt;br /&gt;
&lt;br /&gt;
Repeat a few times.&lt;br /&gt;
&lt;br /&gt;
Rename the patch (because your first name wasn&#039;t appliable):&lt;br /&gt;
&lt;br /&gt;
 hg qrename refactor_the_whatsit&lt;br /&gt;
&lt;br /&gt;
Create a new patch to try a logically separate part of the same bug:&lt;br /&gt;
&lt;br /&gt;
 hg qnew rip_out_the_old_thing&lt;br /&gt;
&lt;br /&gt;
Repeat the process a few times, until you have solved the problem. During this time, it can often be useful to go back and forth between patches:&lt;br /&gt;
&lt;br /&gt;
 hg qpop # unapply a patch&lt;br /&gt;
 hg qpush # reapply a patch&lt;br /&gt;
 hg qpop -a # unapply all patches&lt;br /&gt;
 hg qpush -a # reapply all patches&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Combine all the patches into a single patch, which you submit to bugzilla:&lt;br /&gt;
&lt;br /&gt;
 hg qpush -a&lt;br /&gt;
 hg qdiff --rev qparent:. &amp;gt; my_wonderful_patch.patch&lt;br /&gt;
&lt;br /&gt;
Commit the patches to your local patch repository, in case you make a mistake (You might do this periodically):&lt;br /&gt;
&lt;br /&gt;
 hg qcommit -m &amp;quot;Some message. Doesn&#039;t have to be good, this won&#039;t be committed to the repository, it&#039;s just for you&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Go back to the old patches and fiddle with them based on feedback:&lt;br /&gt;
&lt;br /&gt;
 hg qpop&lt;br /&gt;
 hg qrefresh&lt;br /&gt;
 etc&lt;br /&gt;
&lt;br /&gt;
There are some more complex techniques that we won&#039;t go into in detail. You can enable only some patches using qguard and qselect, and you can reorder the patches by manually editing the .hg/patches/series file. But be careful!&lt;br /&gt;
&lt;br /&gt;
[[Category:New Contributor Landing Page]]&lt;/div&gt;</summary>
		<author><name>Sfink</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=JavaScript:New_to_SpiderMonkey&amp;diff=1150969</id>
		<title>JavaScript:New to SpiderMonkey</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=JavaScript:New_to_SpiderMonkey&amp;diff=1150969"/>
		<updated>2016-10-11T16:17:12Z</updated>

		<summary type="html">&lt;p&gt;Sfink: /* Coding Style */ virtual functions are ok for random stuff, which isn&amp;#039;t in the JS heap&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Tutorial: your first patch  ==&lt;br /&gt;
&lt;br /&gt;
The first step to getting involved with SpiderMonkey is to make your first patch. This guides you through it, and at the end you should have learnt a lot of the procedures and formalisms involved in getting things done here.&lt;br /&gt;
&lt;br /&gt;
We&#039;ll assume you&#039;re on a Unix-y platform, and that you know what you&#039;re doing. We&#039;ll ignore nearly all details. &lt;br /&gt;
&lt;br /&gt;
=== Get the code ===&lt;br /&gt;
&lt;br /&gt;
Spidermonkey development happens in the &amp;quot;mozilla-central&amp;quot; mercurial repository:&lt;br /&gt;
&lt;br /&gt;
 hg clone http://hg.mozilla.org/mozilla-central spidermonkey&lt;br /&gt;
&lt;br /&gt;
=== Build the js shell ===&lt;br /&gt;
&lt;br /&gt;
Most of the time, you&#039;ll be working with the Javascript shell, instead of the full Firefox browser. So build the shell: &lt;br /&gt;
&lt;br /&gt;
 cd spidermonkey/js/src&lt;br /&gt;
 cp configure.in configure &amp;amp;&amp;amp; chmod +x configure # or autoconf2.13 or autoconf-2.13&lt;br /&gt;
 mkdir build_DBG.OBJ &lt;br /&gt;
 cd build_DBG.OBJ &lt;br /&gt;
 ../configure --enable-debug --disable-optimize&lt;br /&gt;
 make # or make -j8&lt;br /&gt;
 cd ..&lt;br /&gt;
&lt;br /&gt;
If you&#039;re having trouble or are missing dependencies, refer to [https://developer.mozilla.org/en/SpiderMonkey/Build_Documentation#Building_SpiderMonkey_tip Building SpiderMonkey Tip].&lt;br /&gt;
&lt;br /&gt;
=== Fix something ===&lt;br /&gt;
&lt;br /&gt;
At this point, you&#039;re ready to make your first fix. &lt;br /&gt;
&lt;br /&gt;
 TODO: something useless. Maybe adding a datemicrosecond function.&lt;br /&gt;
&lt;br /&gt;
==== Building your changes ====&lt;br /&gt;
&lt;br /&gt;
Having made the change, build the shell again. &lt;br /&gt;
&lt;br /&gt;
 make -C build_DBG.OBJ&lt;br /&gt;
&lt;br /&gt;
==== Testing your changes ====&lt;br /&gt;
&lt;br /&gt;
It builds. Hurray. Time to run the tests to check you haven&#039;t broken anything. &lt;br /&gt;
&lt;br /&gt;
 jit-test/jit_test.py build_DBG.OBJ/dist/bin/js&lt;br /&gt;
(The location of the shell has changed, it used to be build_DBG.OBJ/js)&lt;br /&gt;
&lt;br /&gt;
The jit-tests are pretty quick, and should give you an idea if you&#039;ve gotten something wrong. Assuming nothing goes wrong, try the ref-tests: &lt;br /&gt;
&lt;br /&gt;
 tests/jstests.py build_DBG.OBJ/dist/bin/js&lt;br /&gt;
&lt;br /&gt;
Note that some of these tests fail depending on the timezone and locale they&#039;re run in, so if you get any errors that don&#039;t seem related to your changes, re-run the tests with a shell build without your changes applied and compare the results.&lt;br /&gt;
&lt;br /&gt;
==== Benchmark your changes ====&lt;br /&gt;
&lt;br /&gt;
Tests all pass. Congrats, you didn&#039;t break anything. Now, did you make it faster or slower? We benchmark using the v8 and SunSpider benchmarks. Get the benchmarks: &lt;br /&gt;
&lt;br /&gt;
 svn checkout http://svn.webkit.org/repository/webkit/trunk/PerformanceTests/SunSpider&lt;br /&gt;
&lt;br /&gt;
And now run them: &lt;br /&gt;
&lt;br /&gt;
 cd SunSpider &lt;br /&gt;
 ./sunspider --shell=../build_DBG.OBJ/dist/bin/js --run=30 --suite=sunspider-0.9.1 &lt;br /&gt;
 cd ..&lt;br /&gt;
&lt;br /&gt;
===== Optimized build =====&lt;br /&gt;
&lt;br /&gt;
Whoops, we benchmarked the debug version. Let&#039;s make an optimized build to test instead.&lt;br /&gt;
&lt;br /&gt;
 mkdir build_OPT.OBJ &lt;br /&gt;
 cd build_OPT.OBJ &lt;br /&gt;
 ../configure --disable-debug --enable-optimize&lt;br /&gt;
 make &lt;br /&gt;
 cd ..&lt;br /&gt;
&lt;br /&gt;
Repeat the sunspider steps above, and take note of the line that looks like: &lt;br /&gt;
&lt;br /&gt;
 Results are located at sunspider-0.9.1-results/sunspider-results-2010-08-07-17.56.48.js&lt;br /&gt;
&lt;br /&gt;
You&#039;ll need that later. &lt;br /&gt;
&lt;br /&gt;
===== Baseline version / Mercurial Queues =====&lt;br /&gt;
&lt;br /&gt;
We need to time our optimized version against the baseline version. This calls for a brief introduction to mercurial queues, which used to be the way most people managed their SpiderMonkey workflow (though these days many people use native hg, native hg + evolution, or git):&lt;br /&gt;
&lt;br /&gt;
 hg qinit&lt;br /&gt;
 hg qnew my_first_patch -f&lt;br /&gt;
 hg qrefresh&lt;br /&gt;
&lt;br /&gt;
This puts your current work into a patch, managed by Mercurial, symbolically called my_first_patch. To pop the patch off: &lt;br /&gt;
&lt;br /&gt;
 hg qpop&lt;br /&gt;
&lt;br /&gt;
And we&#039;re back to our pristine version.&lt;br /&gt;
&lt;br /&gt;
===== Compare =====&lt;br /&gt;
&lt;br /&gt;
Build again and rerun SunSpider again. You should now have two files like: &lt;br /&gt;
&lt;br /&gt;
 sunspider-0.9.1-results/sunspider-results-2010-08-07-17.56.48.js&lt;br /&gt;
&lt;br /&gt;
Compare them using the compare script: &lt;br /&gt;
&lt;br /&gt;
 cd SunSpider &lt;br /&gt;
 ./sunspider-compare-results --shell=../build_DBG.OBJ/js --suite=sunspider-0.9.1 FILE1-withoutPatch FILE2-withPatch&lt;br /&gt;
&lt;br /&gt;
=== Get a real bug  ===&lt;br /&gt;
&lt;br /&gt;
At this point, you&#039;ve seen nearly everything you need to do hack on SpiderMonkey. So it&#039;s time to get a real bug to work on. You can get a bug on [http://www.joshmatthews.net/bugsahoy/?jseng=1&amp;amp;unowned=1 Bugs Ahoy].&lt;br /&gt;
&lt;br /&gt;
Fix the bug, updating the bug report with your progress, and asking questions as you go (either in the bug comments, or in [irc://irc.mozilla.org/#jsapi #jsapi]). When it&#039;s done, repeat all the steps above. Then it&#039;s time to get your patch into the tree.&lt;br /&gt;
&lt;br /&gt;
=== Submit a patch  ===&lt;br /&gt;
&lt;br /&gt;
To get the patch from mercurial, use: &lt;br /&gt;
&lt;br /&gt;
 hg qdiff # if you&#039;re using queues or&lt;br /&gt;
 hg diff  # if you&#039;re not&lt;br /&gt;
&lt;br /&gt;
Add it to the bug as an attachment. &lt;br /&gt;
&lt;br /&gt;
=== Get a review ===&lt;br /&gt;
&lt;br /&gt;
Nothing gets into the tree without a review, so you&#039;ll need one. The [[JavaScript:Hackers|SpiderMonkey hackers list]] is a good place to start: if your patch changes something listed as an area of expertise for someone there, that&#039;s a good person to ask for a review.&lt;br /&gt;
&lt;br /&gt;
Alternatively run &amp;lt;code&amp;gt;hg blame&amp;lt;/code&amp;gt; on the files you&#039;ve changed, and check who has been changing related code recently. They&#039;re likely to be good candidates. An irc bot can automate this process for a single file if you enter &amp;quot;/msg mrgiggles who can review something.cpp?&amp;quot; into your irc client.&lt;br /&gt;
&lt;br /&gt;
The review will consist of comments on your changes, suggesting or requesting alternative ways to do something and asking you to make changes where needed. They might also request additional changes, for example tests. Fix what they ask, resubmit the patch to bugzilla, and ask for another review. After you repeat this step a few times, they will mark the patch as &amp;quot;&amp;lt;code&amp;gt;r+&amp;lt;/code&amp;gt;&amp;quot; meaning it&#039;s now good to commit.&lt;br /&gt;
&lt;br /&gt;
=== Commit ===&lt;br /&gt;
&lt;br /&gt;
You can&#039;t commit to mozilla-central / mozilla-inbound until you have &amp;quot;level 3&amp;quot; access, so you&#039;ll need someone to do this for you. Try asking in [irc://irc.mozilla.org/#jsapi #jsapi], or add the &amp;lt;code&amp;gt;checkin-needed&amp;lt;/code&amp;gt; keyword to the bug. After you have been contributing for a while, you can get level 3 access by [https://www.mozilla.org/hacking/commit-access-policy/ applying for it].&lt;br /&gt;
&lt;br /&gt;
After committing, a large series of tests will be run to make sure you didn&#039;t break anything. You will need to hang around to make sure you didn&#039;t break something. It is difficult to determine what failures are real and what are what we call &amp;quot;intermittent oranges&amp;quot; (&amp;quot;orange&amp;quot; because that is the color used on our continuous integration dashboard for test failures). If you do break something, a sheriff will probably let you know via IRC and will probably back your patch out. You can always ask [irc://irc.mozilla.org/#jsapi for help] determining what is going on. (Over time you&#039;ll get a feel for figuring out when breakage is real on your own.)&lt;br /&gt;
&lt;br /&gt;
== Overview of the JS engine ==&lt;br /&gt;
&lt;br /&gt;
The JS engine is a swiftly moving target. The most detailed information is available at https://developer.mozilla.org/en/SpiderMonkey. Here are some particularly interesting, mostly up-to-date resources:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== High level overviews ===&lt;br /&gt;
&lt;br /&gt;
(Outdated) http://hacks.mozilla.org/2010/03/a-quick-note-on-javascript-engine-components/&lt;br /&gt;
&lt;br /&gt;
https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Internals&lt;br /&gt;
&lt;br /&gt;
=== Medium level documentation ===&lt;br /&gt;
&lt;br /&gt;
jsapi.h: http://hg.mozilla.org/mozilla-central/file/tip/js/src/jsapi.h and the files in http://hg.mozilla.org/mozilla-central/file/tip/js/public&lt;br /&gt;
&lt;br /&gt;
Frequently used coding recipes and mappings from JS idioms to SpiderMonkey code: https://developer.mozilla.org/En/SpiderMonkey/JSAPI_Cookbook&lt;br /&gt;
&lt;br /&gt;
=== Detailed documentation ===&lt;br /&gt;
&lt;br /&gt;
Build: https://developer.mozilla.org/en/SpiderMonkey/Build_Documentation&lt;br /&gt;
&lt;br /&gt;
Testing: https://developer.mozilla.org/en/SpiderMonkey/Running_Automated_JavaScript_Tests&lt;br /&gt;
&lt;br /&gt;
Shell: https://developer.mozilla.org/En/SpiderMonkey/Introduction_to_the_JavaScript_shell&lt;br /&gt;
&lt;br /&gt;
Function reference: https://developer.mozilla.org/en/SpiderMonkey/JSAPI_Reference&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Collaboration and teamwork ==&lt;br /&gt;
&lt;br /&gt;
=== Communication (in descending order of information content) ===&lt;br /&gt;
&lt;br /&gt;
Nearly all communication is handled through [https://bugzilla.mozilla.org Bugzilla]. All bugs, feature requests, issues, enhancements, etc, are all referred to as bugs. No code may enter the Mozilla repository without being a patch attached to a bugzilla bug first. To follow all SpiderMonkey related bugs:&lt;br /&gt;
&lt;br /&gt;
 Go to [https://bugzilla.mozilla.org/userprefs.cgi?tab=email email preferences]&lt;br /&gt;
 Watch the user general@spidermonkey.bugs&lt;br /&gt;
 Or watch one of the JS components in the Core product: JavaScript Engine, JavaScript Engine: JIT, JavaScript: GC, or JavaScript: Standard Library&lt;br /&gt;
&lt;br /&gt;
SpiderMonkey contributors generally hang out in the very active [irc://irc.mozilla.org/jsapi #jsapi IRC channel].&lt;br /&gt;
&lt;br /&gt;
The [https://www.mozilla.org/about/forums/#dev-tech-js-engine-internals js-internals mailing list] is used for communicating with other SpiderMonkey hackers. (&amp;lt;i&amp;gt;Internals&amp;lt;/i&amp;gt; as in discussing the internals of the SpiderMonkey engine. All are welcome on the list.).&lt;br /&gt;
&lt;br /&gt;
Reading Planet Mozilla is the best way to keep up with the Mozilla project, which includes some SpiderMonkey related blogs:&lt;br /&gt;
&lt;br /&gt;
 [https://blog.mozilla.org/javascript General JavaScript blog]&lt;br /&gt;
 [http://blog.mozilla.com/jorendorff Jason Orendorff]&lt;br /&gt;
 [http://blog.mozilla.com/nnethercote/ Nicholas Nethercote]&lt;br /&gt;
 [http://whereswalden.com/ Jeff Walden]&lt;br /&gt;
 [https://itcouldbesomuchbetter.wordpress.com Jim Blandy]&lt;br /&gt;
 [https://jandemooij.nl/ Jan de Mooij]&lt;br /&gt;
 [https://h4writer.com/ Hannes Verschore]&lt;br /&gt;
 [http://rfrn.org/~shu/ Shu-yu Guo]&lt;br /&gt;
 [https://blog.benj.me/tag/mozilla.html Benjamin Bouvier]&lt;br /&gt;
&lt;br /&gt;
The [https://developer.mozilla.org/en/SpiderMonkey#Community js-engine mailing list] is generally used for communicating with people who embed SpiderMonkey, such as asking questions and announcing API changes. No actual development happens on the list.&lt;br /&gt;
&lt;br /&gt;
== Code considerations ==&lt;br /&gt;
&lt;br /&gt;
=== Repository ===&lt;br /&gt;
&lt;br /&gt;
Most active work on SpiderMonkey is done in the [http://hg.mozilla.org/mozilla-central mozilla-central] branch of the mozilla repository.&lt;br /&gt;
&lt;br /&gt;
=== Coding Style ===&lt;br /&gt;
&lt;br /&gt;
For many years, SpiderMonkey was written in C, and is gradually moving to C++. We still avoid many features such as run-time type information and exceptions, and generally avoid virtual functions for core data, but have come around to the glory of templates and namespaces relatively recently. Read the [[JavaScript:SpiderMonkey:C++ Coding Style|Coding Style]]. Do NOT read the portability guidelines, which I will not link to, since they are very out of date.&lt;br /&gt;
&lt;br /&gt;
=== Workflow ===&lt;br /&gt;
&lt;br /&gt;
Everything goes through bugzilla. We find a bug or have an idea, then submit it to bugzilla, then file patches to solve it. When it is solved, the patch is reviewed by team members, and is then committed to the [http://hg.mozilla.org/mozilla-central mozilla-central repository]. A link to the commit is then added as a comment to the bug.&lt;br /&gt;
&lt;br /&gt;
As well as committing to [http://hg.mozilla.org/mozilla-central mozilla-central], we also have the option of committing to [http://hg.mozilla.org/integration/mozilla-inbound mozilla-inbound], which is automatically merged to mozilla-central by a Sheriff. This exempts us from watching [http://tbpl.mozilla.org tinderbox] to check for errors in our patches, and commits are automatically backed out if errors are found.&lt;br /&gt;
&lt;br /&gt;
==== Sample Workflows ====&lt;br /&gt;
&lt;br /&gt;
(Outdated) [http://blog.mozilla.com/nnethercote/2009/07/27/how-i-work-on-tracemonkey/ Nicholas Nethercote: How I work on Tracemonkey]&lt;br /&gt;
&lt;br /&gt;
=== Policy ===&lt;br /&gt;
&lt;br /&gt;
The following docs are for the Mozilla project, and differ ever so slightly from what you should do for SpiderMonkey. For example, you should find reviewers in #jsapi rather than #developers.&lt;br /&gt;
&lt;br /&gt;
[http://www.mozilla.org/hacking/committer/ How to get commit access]&lt;br /&gt;
&lt;br /&gt;
[https://developer.mozilla.org/en/Creating_a_patch How to make patches]&lt;br /&gt;
&lt;br /&gt;
[https://developer.mozilla.org/En/Developer_Guide/How_to_Submit_a_Patch Submitting a patch]&lt;br /&gt;
&lt;br /&gt;
[https://developer.mozilla.org/en/Supported_build_configurations Supported Platforms]&lt;br /&gt;
&lt;br /&gt;
==== .hgrc file ====&lt;br /&gt;
&lt;br /&gt;
This .hgrc file contains a lot of the wisdom distilled through the wiki:&lt;br /&gt;
&lt;br /&gt;
 [extensions]&lt;br /&gt;
 mq =&lt;br /&gt;
 &lt;br /&gt;
 [ui]&lt;br /&gt;
 username = First Last &amp;lt;email@domain.tld&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
 [alias]&lt;br /&gt;
 qfulldiff = diff --rev qparent:.&lt;br /&gt;
 &lt;br /&gt;
 [defaults]&lt;br /&gt;
 diff = -p -U 8&lt;br /&gt;
 qdiff = -p -U 8&lt;br /&gt;
 qnew = -U&lt;br /&gt;
 commit = -v&lt;br /&gt;
 &lt;br /&gt;
 [diff]&lt;br /&gt;
 git = true&lt;br /&gt;
 showfunc = true&lt;br /&gt;
 unified = 8&lt;br /&gt;
 &lt;br /&gt;
 [paths]&lt;br /&gt;
 try = ssh://email@domain.tld@hg.mozilla.org/try/&lt;br /&gt;
&lt;br /&gt;
=== Try server  ===&lt;br /&gt;
&lt;br /&gt;
Often, you may be a little wary of breaking things. Mozilla has a [[Build:TryServer|Try Server]] where you can send a patch, and it&#039;ll be built and tested on tons of machines, which report to [http://tbpl.mozilla.org/?tree=Try TBPL]. Although you don&#039;t have [https://www.mozilla.org/hacking/commit-access-policy/ access] to TryServer just yet, you can get someone else to push it there for you. Just attach a patch to your bug, and ask in a comment, or on [irc://irc.mozilla.org/#jsapi #jsapi]. To be able to push to try-server yourself, you will need &amp;quot;level 1&amp;quot; access, which you can [https://www.mozilla.org/hacking/commit-access-policy/ request] once you&#039;ve contributed a patch or two.&lt;br /&gt;
&lt;br /&gt;
=== Mercurial Queues ===&lt;br /&gt;
&lt;br /&gt;
Since most of our lives revolve around patches, and we use Mercurial, nearly everybody uses Mercurial queues.&lt;br /&gt;
&lt;br /&gt;
Queues are based on the idea of patch management. Each queue consists of a series of patches, applied sequentially. The aim of the game is to split potential commits into simple, bite-sized chunks which are easy to review. This also makes it simple to experiment without polluting your existing work on a bug, to spin parts off into new bugs, and to rapidly apply and unapply patches (as demonstrated in the tutorial above).&lt;br /&gt;
&lt;br /&gt;
==== Enabling ====&lt;br /&gt;
&lt;br /&gt;
Add the following snippet to your .hgrc file to enable MQ&lt;br /&gt;
&lt;br /&gt;
 [extensions]&lt;br /&gt;
 mq =&lt;br /&gt;
&lt;br /&gt;
==== Example MQ workflow ====&lt;br /&gt;
&lt;br /&gt;
Clone the repository to deal with a bug:&lt;br /&gt;
&lt;br /&gt;
  hg clone http://hg.mozilla.org/mozilla-central&lt;br /&gt;
&lt;br /&gt;
Initialize your queue:&lt;br /&gt;
&lt;br /&gt;
  hg qinit -c&lt;br /&gt;
&lt;br /&gt;
Create a new patch, with some name:&lt;br /&gt;
&lt;br /&gt;
  hg qnew first_attempt&lt;br /&gt;
&lt;br /&gt;
Work on the patch, try to fix the bug, test, compile, etc.&lt;br /&gt;
&lt;br /&gt;
Refresh (save your work into the patch):&lt;br /&gt;
&lt;br /&gt;
 hg qrefresh&lt;br /&gt;
&lt;br /&gt;
Repeat a few times.&lt;br /&gt;
&lt;br /&gt;
Rename the patch (because your first name wasn&#039;t appliable):&lt;br /&gt;
&lt;br /&gt;
 hg qrename refactor_the_whatsit&lt;br /&gt;
&lt;br /&gt;
Create a new patch to try a logically separate part of the same bug:&lt;br /&gt;
&lt;br /&gt;
 hg qnew rip_out_the_old_thing&lt;br /&gt;
&lt;br /&gt;
Repeat the process a few times, until you have solved the problem. During this time, it can often be useful to go back and forth between patches:&lt;br /&gt;
&lt;br /&gt;
 hg qpop # unapply a patch&lt;br /&gt;
 hg qpush # reapply a patch&lt;br /&gt;
 hg qpop -a # unapply all patches&lt;br /&gt;
 hg qpush -a # reapply all patches&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Combine all the patches into a single patch, which you submit to bugzilla:&lt;br /&gt;
&lt;br /&gt;
 hg qpush -a&lt;br /&gt;
 hg qdiff --rev qparent:. &amp;gt; my_wonderful_patch.patch&lt;br /&gt;
&lt;br /&gt;
Commit the patches to your local patch repository, in case you make a mistake (You might do this periodically):&lt;br /&gt;
&lt;br /&gt;
 hg qcommit -m &amp;quot;Some message. Doesn&#039;t have to be good, this won&#039;t be committed to the repository, it&#039;s just for you&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Go back to the old patches and fiddle with them based on feedback:&lt;br /&gt;
&lt;br /&gt;
 hg qpop&lt;br /&gt;
 hg qrefresh&lt;br /&gt;
 etc&lt;br /&gt;
&lt;br /&gt;
There are some more complex techniques that we won&#039;t go into in detail. You can enable only some patches using qguard and qselect, and you can reorder the patches by manually editing the .hg/patches/series file. But be careful!&lt;br /&gt;
&lt;br /&gt;
[[Category:New Contributor Landing Page]]&lt;/div&gt;</summary>
		<author><name>Sfink</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=JavaScript:New_to_SpiderMonkey&amp;diff=1150958</id>
		<title>JavaScript:New to SpiderMonkey</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=JavaScript:New_to_SpiderMonkey&amp;diff=1150958"/>
		<updated>2016-10-11T15:48:05Z</updated>

		<summary type="html">&lt;p&gt;Sfink: /* Communication (in descending order of information content) */ component watch&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Tutorial: your first patch  ==&lt;br /&gt;
&lt;br /&gt;
The first step to getting involved with SpiderMonkey is to make your first patch. This guides you through it, and at the end you should have learnt a lot of the procedures and formalisms involved in getting things done here.&lt;br /&gt;
&lt;br /&gt;
We&#039;ll assume you&#039;re on a Unix-y platform, and that you know what you&#039;re doing. We&#039;ll ignore nearly all details. &lt;br /&gt;
&lt;br /&gt;
=== Get the code ===&lt;br /&gt;
&lt;br /&gt;
Spidermonkey development happens in the &amp;quot;mozilla-central&amp;quot; mercurial repository:&lt;br /&gt;
&lt;br /&gt;
 hg clone http://hg.mozilla.org/mozilla-central spidermonkey&lt;br /&gt;
&lt;br /&gt;
=== Build the js shell ===&lt;br /&gt;
&lt;br /&gt;
Most of the time, you&#039;ll be working with the Javascript shell, instead of the full Firefox browser. So build the shell: &lt;br /&gt;
&lt;br /&gt;
 cd spidermonkey/js/src&lt;br /&gt;
 cp configure.in configure &amp;amp;&amp;amp; chmod +x configure # or autoconf2.13 or autoconf-2.13&lt;br /&gt;
 mkdir build_DBG.OBJ &lt;br /&gt;
 cd build_DBG.OBJ &lt;br /&gt;
 ../configure --enable-debug --disable-optimize&lt;br /&gt;
 make # or make -j8&lt;br /&gt;
 cd ..&lt;br /&gt;
&lt;br /&gt;
If you&#039;re having trouble or are missing dependencies, refer to [https://developer.mozilla.org/en/SpiderMonkey/Build_Documentation#Building_SpiderMonkey_tip Building SpiderMonkey Tip].&lt;br /&gt;
&lt;br /&gt;
=== Fix something ===&lt;br /&gt;
&lt;br /&gt;
At this point, you&#039;re ready to make your first fix. &lt;br /&gt;
&lt;br /&gt;
 TODO: something useless. Maybe adding a datemicrosecond function.&lt;br /&gt;
&lt;br /&gt;
==== Building your changes ====&lt;br /&gt;
&lt;br /&gt;
Having made the change, build the shell again. &lt;br /&gt;
&lt;br /&gt;
 make -C build_DBG.OBJ&lt;br /&gt;
&lt;br /&gt;
==== Testing your changes ====&lt;br /&gt;
&lt;br /&gt;
It builds. Hurray. Time to run the tests to check you haven&#039;t broken anything. &lt;br /&gt;
&lt;br /&gt;
 jit-test/jit_test.py build_DBG.OBJ/dist/bin/js&lt;br /&gt;
(The location of the shell has changed, it used to be build_DBG.OBJ/js)&lt;br /&gt;
&lt;br /&gt;
The jit-tests are pretty quick, and should give you an idea if you&#039;ve gotten something wrong. Assuming nothing goes wrong, try the ref-tests: &lt;br /&gt;
&lt;br /&gt;
 tests/jstests.py build_DBG.OBJ/dist/bin/js&lt;br /&gt;
&lt;br /&gt;
Note that some of these tests fail depending on the timezone and locale they&#039;re run in, so if you get any errors that don&#039;t seem related to your changes, re-run the tests with a shell build without your changes applied and compare the results.&lt;br /&gt;
&lt;br /&gt;
==== Benchmark your changes ====&lt;br /&gt;
&lt;br /&gt;
Tests all pass. Congrats, you didn&#039;t break anything. Now, did you make it faster or slower? We benchmark using the v8 and SunSpider benchmarks. Get the benchmarks: &lt;br /&gt;
&lt;br /&gt;
 svn checkout http://svn.webkit.org/repository/webkit/trunk/PerformanceTests/SunSpider&lt;br /&gt;
&lt;br /&gt;
And now run them: &lt;br /&gt;
&lt;br /&gt;
 cd SunSpider &lt;br /&gt;
 ./sunspider --shell=../build_DBG.OBJ/dist/bin/js --run=30 --suite=sunspider-0.9.1 &lt;br /&gt;
 cd ..&lt;br /&gt;
&lt;br /&gt;
===== Optimized build =====&lt;br /&gt;
&lt;br /&gt;
Whoops, we benchmarked the debug version. Let&#039;s make an optimized build to test instead.&lt;br /&gt;
&lt;br /&gt;
 mkdir build_OPT.OBJ &lt;br /&gt;
 cd build_OPT.OBJ &lt;br /&gt;
 ../configure --disable-debug --enable-optimize&lt;br /&gt;
 make &lt;br /&gt;
 cd ..&lt;br /&gt;
&lt;br /&gt;
Repeat the sunspider steps above, and take note of the line that looks like: &lt;br /&gt;
&lt;br /&gt;
 Results are located at sunspider-0.9.1-results/sunspider-results-2010-08-07-17.56.48.js&lt;br /&gt;
&lt;br /&gt;
You&#039;ll need that later. &lt;br /&gt;
&lt;br /&gt;
===== Baseline version / Mercurial Queues =====&lt;br /&gt;
&lt;br /&gt;
We need to time our optimized version against the baseline version. This calls for a brief introduction to mercurial queues, which used to be the way most people managed their SpiderMonkey workflow (though these days many people use native hg, native hg + evolution, or git):&lt;br /&gt;
&lt;br /&gt;
 hg qinit&lt;br /&gt;
 hg qnew my_first_patch -f&lt;br /&gt;
 hg qrefresh&lt;br /&gt;
&lt;br /&gt;
This puts your current work into a patch, managed by Mercurial, symbolically called my_first_patch. To pop the patch off: &lt;br /&gt;
&lt;br /&gt;
 hg qpop&lt;br /&gt;
&lt;br /&gt;
And we&#039;re back to our pristine version.&lt;br /&gt;
&lt;br /&gt;
===== Compare =====&lt;br /&gt;
&lt;br /&gt;
Build again and rerun SunSpider again. You should now have two files like: &lt;br /&gt;
&lt;br /&gt;
 sunspider-0.9.1-results/sunspider-results-2010-08-07-17.56.48.js&lt;br /&gt;
&lt;br /&gt;
Compare them using the compare script: &lt;br /&gt;
&lt;br /&gt;
 cd SunSpider &lt;br /&gt;
 ./sunspider-compare-results --shell=../build_DBG.OBJ/js --suite=sunspider-0.9.1 FILE1-withoutPatch FILE2-withPatch&lt;br /&gt;
&lt;br /&gt;
=== Get a real bug  ===&lt;br /&gt;
&lt;br /&gt;
At this point, you&#039;ve seen nearly everything you need to do hack on SpiderMonkey. So it&#039;s time to get a real bug to work on. You can get a bug on [http://www.joshmatthews.net/bugsahoy/?jseng=1&amp;amp;unowned=1 Bugs Ahoy].&lt;br /&gt;
&lt;br /&gt;
Fix the bug, updating the bug report with your progress, and asking questions as you go (either in the bug comments, or in [irc://irc.mozilla.org/#jsapi #jsapi]). When it&#039;s done, repeat all the steps above. Then it&#039;s time to get your patch into the tree.&lt;br /&gt;
&lt;br /&gt;
=== Submit a patch  ===&lt;br /&gt;
&lt;br /&gt;
To get the patch from mercurial, use: &lt;br /&gt;
&lt;br /&gt;
 hg qdiff # if you&#039;re using queues or&lt;br /&gt;
 hg diff  # if you&#039;re not&lt;br /&gt;
&lt;br /&gt;
Add it to the bug as an attachment. &lt;br /&gt;
&lt;br /&gt;
=== Get a review ===&lt;br /&gt;
&lt;br /&gt;
Nothing gets into the tree without a review, so you&#039;ll need one. The [[JavaScript:Hackers|SpiderMonkey hackers list]] is a good place to start: if your patch changes something listed as an area of expertise for someone there, that&#039;s a good person to ask for a review.&lt;br /&gt;
&lt;br /&gt;
Alternatively run &amp;lt;code&amp;gt;hg blame&amp;lt;/code&amp;gt; on the files you&#039;ve changed, and check who has been changing related code recently. They&#039;re likely to be good candidates. An irc bot can automate this process for a single file if you enter &amp;quot;/msg mrgiggles who can review something.cpp?&amp;quot; into your irc client.&lt;br /&gt;
&lt;br /&gt;
The review will consist of comments on your changes, suggesting or requesting alternative ways to do something and asking you to make changes where needed. They might also request additional changes, for example tests. Fix what they ask, resubmit the patch to bugzilla, and ask for another review. After you repeat this step a few times, they will mark the patch as &amp;quot;&amp;lt;code&amp;gt;r+&amp;lt;/code&amp;gt;&amp;quot; meaning it&#039;s now good to commit.&lt;br /&gt;
&lt;br /&gt;
=== Commit ===&lt;br /&gt;
&lt;br /&gt;
You can&#039;t commit to mozilla-central / mozilla-inbound until you have &amp;quot;level 3&amp;quot; access, so you&#039;ll need someone to do this for you. Try asking in [irc://irc.mozilla.org/#jsapi #jsapi], or add the &amp;lt;code&amp;gt;checkin-needed&amp;lt;/code&amp;gt; keyword to the bug. After you have been contributing for a while, you can get level 3 access by [https://www.mozilla.org/hacking/commit-access-policy/ applying for it].&lt;br /&gt;
&lt;br /&gt;
After committing, a large series of tests will be run to make sure you didn&#039;t break anything. You will need to hang around to make sure you didn&#039;t break something. It is difficult to determine what failures are real and what are what we call &amp;quot;intermittent oranges&amp;quot; (&amp;quot;orange&amp;quot; because that is the color used on our continuous integration dashboard for test failures). If you do break something, a sheriff will probably let you know via IRC and will probably back your patch out. You can always ask [irc://irc.mozilla.org/#jsapi for help] determining what is going on. (Over time you&#039;ll get a feel for figuring out when breakage is real on your own.)&lt;br /&gt;
&lt;br /&gt;
== Overview of the JS engine ==&lt;br /&gt;
&lt;br /&gt;
The JS engine is a swiftly moving target. The most detailed information is available at https://developer.mozilla.org/en/SpiderMonkey. Here are some particularly interesting, mostly up-to-date resources:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== High level overviews ===&lt;br /&gt;
&lt;br /&gt;
(Outdated) http://hacks.mozilla.org/2010/03/a-quick-note-on-javascript-engine-components/&lt;br /&gt;
&lt;br /&gt;
https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Internals&lt;br /&gt;
&lt;br /&gt;
=== Medium level documentation ===&lt;br /&gt;
&lt;br /&gt;
jsapi.h: http://hg.mozilla.org/mozilla-central/file/tip/js/src/jsapi.h and the files in http://hg.mozilla.org/mozilla-central/file/tip/js/public&lt;br /&gt;
&lt;br /&gt;
Frequently used coding recipes and mappings from JS idioms to SpiderMonkey code: https://developer.mozilla.org/En/SpiderMonkey/JSAPI_Cookbook&lt;br /&gt;
&lt;br /&gt;
=== Detailed documentation ===&lt;br /&gt;
&lt;br /&gt;
Build: https://developer.mozilla.org/en/SpiderMonkey/Build_Documentation&lt;br /&gt;
&lt;br /&gt;
Testing: https://developer.mozilla.org/en/SpiderMonkey/Running_Automated_JavaScript_Tests&lt;br /&gt;
&lt;br /&gt;
Shell: https://developer.mozilla.org/En/SpiderMonkey/Introduction_to_the_JavaScript_shell&lt;br /&gt;
&lt;br /&gt;
Function reference: https://developer.mozilla.org/en/SpiderMonkey/JSAPI_Reference&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Collaboration and teamwork ==&lt;br /&gt;
&lt;br /&gt;
=== Communication (in descending order of information content) ===&lt;br /&gt;
&lt;br /&gt;
Nearly all communication is handled through [https://bugzilla.mozilla.org Bugzilla]. All bugs, feature requests, issues, enhancements, etc, are all referred to as bugs. No code may enter the Mozilla repository without being a patch attached to a bugzilla bug first. To follow all SpiderMonkey related bugs:&lt;br /&gt;
&lt;br /&gt;
 Go to [https://bugzilla.mozilla.org/userprefs.cgi?tab=email email preferences]&lt;br /&gt;
 Watch the user general@spidermonkey.bugs&lt;br /&gt;
 Or watch one of the JS components in the Core product: JavaScript Engine, JavaScript Engine: JIT, JavaScript: GC, or JavaScript: Standard Library&lt;br /&gt;
&lt;br /&gt;
SpiderMonkey contributors generally hang out in the very active [irc://irc.mozilla.org/jsapi #jsapi IRC channel].&lt;br /&gt;
&lt;br /&gt;
The [https://www.mozilla.org/about/forums/#dev-tech-js-engine-internals js-internals mailing list] is used for communicating with other SpiderMonkey hackers. (&amp;lt;i&amp;gt;Internals&amp;lt;/i&amp;gt; as in discussing the internals of the SpiderMonkey engine. All are welcome on the list.).&lt;br /&gt;
&lt;br /&gt;
Reading Planet Mozilla is the best way to keep up with the Mozilla project, which includes some SpiderMonkey related blogs:&lt;br /&gt;
&lt;br /&gt;
 [https://blog.mozilla.org/javascript General JavaScript blog]&lt;br /&gt;
 [http://blog.mozilla.com/jorendorff Jason Orendorff]&lt;br /&gt;
 [http://blog.mozilla.com/nnethercote/ Nicholas Nethercote]&lt;br /&gt;
 [http://whereswalden.com/ Jeff Walden]&lt;br /&gt;
 [https://itcouldbesomuchbetter.wordpress.com Jim Blandy]&lt;br /&gt;
 [https://jandemooij.nl/ Jan de Mooij]&lt;br /&gt;
 [https://h4writer.com/ Hannes Verschore]&lt;br /&gt;
 [http://rfrn.org/~shu/ Shu-yu Guo]&lt;br /&gt;
 [https://blog.benj.me/tag/mozilla.html Benjamin Bouvier]&lt;br /&gt;
&lt;br /&gt;
The [https://developer.mozilla.org/en/SpiderMonkey#Community js-engine mailing list] is generally used for communicating with people who embed SpiderMonkey, such as asking questions and announcing API changes. No actual development happens on the list.&lt;br /&gt;
&lt;br /&gt;
== Code considerations ==&lt;br /&gt;
&lt;br /&gt;
=== Repository ===&lt;br /&gt;
&lt;br /&gt;
Most active work on SpiderMonkey is done in the [http://hg.mozilla.org/mozilla-central mozilla-central] branch of the mozilla repository.&lt;br /&gt;
&lt;br /&gt;
=== Coding Style ===&lt;br /&gt;
&lt;br /&gt;
For many years, SpiderMonkey was written in C, and is gradually moving to C++. We still avoid many features such as run-time type information and virtual functions, but have come around to the glory of templates and namespaces relatively recently. Read the [[JavaScript:SpiderMonkey:C++ Coding Style|Coding Style]]. Do NOT read the portability guidelines, which I will not link to, since they are very out of date.&lt;br /&gt;
&lt;br /&gt;
=== Workflow ===&lt;br /&gt;
&lt;br /&gt;
Everything goes through bugzilla. We find a bug or have an idea, then submit it to bugzilla, then file patches to solve it. When it is solved, the patch is reviewed by team members, and is then committed to the [http://hg.mozilla.org/mozilla-central mozilla-central repository]. A link to the commit is then added as a comment to the bug.&lt;br /&gt;
&lt;br /&gt;
As well as committing to [http://hg.mozilla.org/mozilla-central mozilla-central], we also have the option of committing to [http://hg.mozilla.org/integration/mozilla-inbound mozilla-inbound], which is automatically merged to mozilla-central by a Sheriff. This exempts us from watching [http://tbpl.mozilla.org tinderbox] to check for errors in our patches, and commits are automatically backed out if errors are found.&lt;br /&gt;
&lt;br /&gt;
==== Sample Workflows ====&lt;br /&gt;
&lt;br /&gt;
(Outdated) [http://blog.mozilla.com/nnethercote/2009/07/27/how-i-work-on-tracemonkey/ Nicholas Nethercote: How I work on Tracemonkey]&lt;br /&gt;
&lt;br /&gt;
=== Policy ===&lt;br /&gt;
&lt;br /&gt;
The following docs are for the Mozilla project, and differ ever so slightly from what you should do for SpiderMonkey. For example, you should find reviewers in #jsapi rather than #developers.&lt;br /&gt;
&lt;br /&gt;
[http://www.mozilla.org/hacking/committer/ How to get commit access]&lt;br /&gt;
&lt;br /&gt;
[https://developer.mozilla.org/en/Creating_a_patch How to make patches]&lt;br /&gt;
&lt;br /&gt;
[https://developer.mozilla.org/En/Developer_Guide/How_to_Submit_a_Patch Submitting a patch]&lt;br /&gt;
&lt;br /&gt;
[https://developer.mozilla.org/en/Supported_build_configurations Supported Platforms]&lt;br /&gt;
&lt;br /&gt;
==== .hgrc file ====&lt;br /&gt;
&lt;br /&gt;
This .hgrc file contains a lot of the wisdom distilled through the wiki:&lt;br /&gt;
&lt;br /&gt;
 [extensions]&lt;br /&gt;
 mq =&lt;br /&gt;
 &lt;br /&gt;
 [ui]&lt;br /&gt;
 username = First Last &amp;lt;email@domain.tld&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
 [alias]&lt;br /&gt;
 qfulldiff = diff --rev qparent:.&lt;br /&gt;
 &lt;br /&gt;
 [defaults]&lt;br /&gt;
 diff = -p -U 8&lt;br /&gt;
 qdiff = -p -U 8&lt;br /&gt;
 qnew = -U&lt;br /&gt;
 commit = -v&lt;br /&gt;
 &lt;br /&gt;
 [diff]&lt;br /&gt;
 git = true&lt;br /&gt;
 showfunc = true&lt;br /&gt;
 unified = 8&lt;br /&gt;
 &lt;br /&gt;
 [paths]&lt;br /&gt;
 try = ssh://email@domain.tld@hg.mozilla.org/try/&lt;br /&gt;
&lt;br /&gt;
=== Try server  ===&lt;br /&gt;
&lt;br /&gt;
Often, you may be a little wary of breaking things. Mozilla has a [[Build:TryServer|Try Server]] where you can send a patch, and it&#039;ll be built and tested on tons of machines, which report to [http://tbpl.mozilla.org/?tree=Try TBPL]. Although you don&#039;t have [https://www.mozilla.org/hacking/commit-access-policy/ access] to TryServer just yet, you can get someone else to push it there for you. Just attach a patch to your bug, and ask in a comment, or on [irc://irc.mozilla.org/#jsapi #jsapi]. To be able to push to try-server yourself, you will need &amp;quot;level 1&amp;quot; access, which you can [https://www.mozilla.org/hacking/commit-access-policy/ request] once you&#039;ve contributed a patch or two.&lt;br /&gt;
&lt;br /&gt;
=== Mercurial Queues ===&lt;br /&gt;
&lt;br /&gt;
Since most of our lives revolve around patches, and we use Mercurial, nearly everybody uses Mercurial queues.&lt;br /&gt;
&lt;br /&gt;
Queues are based on the idea of patch management. Each queue consists of a series of patches, applied sequentially. The aim of the game is to split potential commits into simple, bite-sized chunks which are easy to review. This also makes it simple to experiment without polluting your existing work on a bug, to spin parts off into new bugs, and to rapidly apply and unapply patches (as demonstrated in the tutorial above).&lt;br /&gt;
&lt;br /&gt;
==== Enabling ====&lt;br /&gt;
&lt;br /&gt;
Add the following snippet to your .hgrc file to enable MQ&lt;br /&gt;
&lt;br /&gt;
 [extensions]&lt;br /&gt;
 mq =&lt;br /&gt;
&lt;br /&gt;
==== Example MQ workflow ====&lt;br /&gt;
&lt;br /&gt;
Clone the repository to deal with a bug:&lt;br /&gt;
&lt;br /&gt;
  hg clone http://hg.mozilla.org/mozilla-central&lt;br /&gt;
&lt;br /&gt;
Initialize your queue:&lt;br /&gt;
&lt;br /&gt;
  hg qinit -c&lt;br /&gt;
&lt;br /&gt;
Create a new patch, with some name:&lt;br /&gt;
&lt;br /&gt;
  hg qnew first_attempt&lt;br /&gt;
&lt;br /&gt;
Work on the patch, try to fix the bug, test, compile, etc.&lt;br /&gt;
&lt;br /&gt;
Refresh (save your work into the patch):&lt;br /&gt;
&lt;br /&gt;
 hg qrefresh&lt;br /&gt;
&lt;br /&gt;
Repeat a few times.&lt;br /&gt;
&lt;br /&gt;
Rename the patch (because your first name wasn&#039;t appliable):&lt;br /&gt;
&lt;br /&gt;
 hg qrename refactor_the_whatsit&lt;br /&gt;
&lt;br /&gt;
Create a new patch to try a logically separate part of the same bug:&lt;br /&gt;
&lt;br /&gt;
 hg qnew rip_out_the_old_thing&lt;br /&gt;
&lt;br /&gt;
Repeat the process a few times, until you have solved the problem. During this time, it can often be useful to go back and forth between patches:&lt;br /&gt;
&lt;br /&gt;
 hg qpop # unapply a patch&lt;br /&gt;
 hg qpush # reapply a patch&lt;br /&gt;
 hg qpop -a # unapply all patches&lt;br /&gt;
 hg qpush -a # reapply all patches&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Combine all the patches into a single patch, which you submit to bugzilla:&lt;br /&gt;
&lt;br /&gt;
 hg qpush -a&lt;br /&gt;
 hg qdiff --rev qparent:. &amp;gt; my_wonderful_patch.patch&lt;br /&gt;
&lt;br /&gt;
Commit the patches to your local patch repository, in case you make a mistake (You might do this periodically):&lt;br /&gt;
&lt;br /&gt;
 hg qcommit -m &amp;quot;Some message. Doesn&#039;t have to be good, this won&#039;t be committed to the repository, it&#039;s just for you&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Go back to the old patches and fiddle with them based on feedback:&lt;br /&gt;
&lt;br /&gt;
 hg qpop&lt;br /&gt;
 hg qrefresh&lt;br /&gt;
 etc&lt;br /&gt;
&lt;br /&gt;
There are some more complex techniques that we won&#039;t go into in detail. You can enable only some patches using qguard and qselect, and you can reorder the patches by manually editing the .hg/patches/series file. But be careful!&lt;br /&gt;
&lt;br /&gt;
[[Category:New Contributor Landing Page]]&lt;/div&gt;</summary>
		<author><name>Sfink</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=JavaScript:New_to_SpiderMonkey&amp;diff=1150957</id>
		<title>JavaScript:New to SpiderMonkey</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=JavaScript:New_to_SpiderMonkey&amp;diff=1150957"/>
		<updated>2016-10-11T15:45:20Z</updated>

		<summary type="html">&lt;p&gt;Sfink: /* Medium level documentation */ js/public&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Tutorial: your first patch  ==&lt;br /&gt;
&lt;br /&gt;
The first step to getting involved with SpiderMonkey is to make your first patch. This guides you through it, and at the end you should have learnt a lot of the procedures and formalisms involved in getting things done here.&lt;br /&gt;
&lt;br /&gt;
We&#039;ll assume you&#039;re on a Unix-y platform, and that you know what you&#039;re doing. We&#039;ll ignore nearly all details. &lt;br /&gt;
&lt;br /&gt;
=== Get the code ===&lt;br /&gt;
&lt;br /&gt;
Spidermonkey development happens in the &amp;quot;mozilla-central&amp;quot; mercurial repository:&lt;br /&gt;
&lt;br /&gt;
 hg clone http://hg.mozilla.org/mozilla-central spidermonkey&lt;br /&gt;
&lt;br /&gt;
=== Build the js shell ===&lt;br /&gt;
&lt;br /&gt;
Most of the time, you&#039;ll be working with the Javascript shell, instead of the full Firefox browser. So build the shell: &lt;br /&gt;
&lt;br /&gt;
 cd spidermonkey/js/src&lt;br /&gt;
 cp configure.in configure &amp;amp;&amp;amp; chmod +x configure # or autoconf2.13 or autoconf-2.13&lt;br /&gt;
 mkdir build_DBG.OBJ &lt;br /&gt;
 cd build_DBG.OBJ &lt;br /&gt;
 ../configure --enable-debug --disable-optimize&lt;br /&gt;
 make # or make -j8&lt;br /&gt;
 cd ..&lt;br /&gt;
&lt;br /&gt;
If you&#039;re having trouble or are missing dependencies, refer to [https://developer.mozilla.org/en/SpiderMonkey/Build_Documentation#Building_SpiderMonkey_tip Building SpiderMonkey Tip].&lt;br /&gt;
&lt;br /&gt;
=== Fix something ===&lt;br /&gt;
&lt;br /&gt;
At this point, you&#039;re ready to make your first fix. &lt;br /&gt;
&lt;br /&gt;
 TODO: something useless. Maybe adding a datemicrosecond function.&lt;br /&gt;
&lt;br /&gt;
==== Building your changes ====&lt;br /&gt;
&lt;br /&gt;
Having made the change, build the shell again. &lt;br /&gt;
&lt;br /&gt;
 make -C build_DBG.OBJ&lt;br /&gt;
&lt;br /&gt;
==== Testing your changes ====&lt;br /&gt;
&lt;br /&gt;
It builds. Hurray. Time to run the tests to check you haven&#039;t broken anything. &lt;br /&gt;
&lt;br /&gt;
 jit-test/jit_test.py build_DBG.OBJ/dist/bin/js&lt;br /&gt;
(The location of the shell has changed, it used to be build_DBG.OBJ/js)&lt;br /&gt;
&lt;br /&gt;
The jit-tests are pretty quick, and should give you an idea if you&#039;ve gotten something wrong. Assuming nothing goes wrong, try the ref-tests: &lt;br /&gt;
&lt;br /&gt;
 tests/jstests.py build_DBG.OBJ/dist/bin/js&lt;br /&gt;
&lt;br /&gt;
Note that some of these tests fail depending on the timezone and locale they&#039;re run in, so if you get any errors that don&#039;t seem related to your changes, re-run the tests with a shell build without your changes applied and compare the results.&lt;br /&gt;
&lt;br /&gt;
==== Benchmark your changes ====&lt;br /&gt;
&lt;br /&gt;
Tests all pass. Congrats, you didn&#039;t break anything. Now, did you make it faster or slower? We benchmark using the v8 and SunSpider benchmarks. Get the benchmarks: &lt;br /&gt;
&lt;br /&gt;
 svn checkout http://svn.webkit.org/repository/webkit/trunk/PerformanceTests/SunSpider&lt;br /&gt;
&lt;br /&gt;
And now run them: &lt;br /&gt;
&lt;br /&gt;
 cd SunSpider &lt;br /&gt;
 ./sunspider --shell=../build_DBG.OBJ/dist/bin/js --run=30 --suite=sunspider-0.9.1 &lt;br /&gt;
 cd ..&lt;br /&gt;
&lt;br /&gt;
===== Optimized build =====&lt;br /&gt;
&lt;br /&gt;
Whoops, we benchmarked the debug version. Let&#039;s make an optimized build to test instead.&lt;br /&gt;
&lt;br /&gt;
 mkdir build_OPT.OBJ &lt;br /&gt;
 cd build_OPT.OBJ &lt;br /&gt;
 ../configure --disable-debug --enable-optimize&lt;br /&gt;
 make &lt;br /&gt;
 cd ..&lt;br /&gt;
&lt;br /&gt;
Repeat the sunspider steps above, and take note of the line that looks like: &lt;br /&gt;
&lt;br /&gt;
 Results are located at sunspider-0.9.1-results/sunspider-results-2010-08-07-17.56.48.js&lt;br /&gt;
&lt;br /&gt;
You&#039;ll need that later. &lt;br /&gt;
&lt;br /&gt;
===== Baseline version / Mercurial Queues =====&lt;br /&gt;
&lt;br /&gt;
We need to time our optimized version against the baseline version. This calls for a brief introduction to mercurial queues, which used to be the way most people managed their SpiderMonkey workflow (though these days many people use native hg, native hg + evolution, or git):&lt;br /&gt;
&lt;br /&gt;
 hg qinit&lt;br /&gt;
 hg qnew my_first_patch -f&lt;br /&gt;
 hg qrefresh&lt;br /&gt;
&lt;br /&gt;
This puts your current work into a patch, managed by Mercurial, symbolically called my_first_patch. To pop the patch off: &lt;br /&gt;
&lt;br /&gt;
 hg qpop&lt;br /&gt;
&lt;br /&gt;
And we&#039;re back to our pristine version.&lt;br /&gt;
&lt;br /&gt;
===== Compare =====&lt;br /&gt;
&lt;br /&gt;
Build again and rerun SunSpider again. You should now have two files like: &lt;br /&gt;
&lt;br /&gt;
 sunspider-0.9.1-results/sunspider-results-2010-08-07-17.56.48.js&lt;br /&gt;
&lt;br /&gt;
Compare them using the compare script: &lt;br /&gt;
&lt;br /&gt;
 cd SunSpider &lt;br /&gt;
 ./sunspider-compare-results --shell=../build_DBG.OBJ/js --suite=sunspider-0.9.1 FILE1-withoutPatch FILE2-withPatch&lt;br /&gt;
&lt;br /&gt;
=== Get a real bug  ===&lt;br /&gt;
&lt;br /&gt;
At this point, you&#039;ve seen nearly everything you need to do hack on SpiderMonkey. So it&#039;s time to get a real bug to work on. You can get a bug on [http://www.joshmatthews.net/bugsahoy/?jseng=1&amp;amp;unowned=1 Bugs Ahoy].&lt;br /&gt;
&lt;br /&gt;
Fix the bug, updating the bug report with your progress, and asking questions as you go (either in the bug comments, or in [irc://irc.mozilla.org/#jsapi #jsapi]). When it&#039;s done, repeat all the steps above. Then it&#039;s time to get your patch into the tree.&lt;br /&gt;
&lt;br /&gt;
=== Submit a patch  ===&lt;br /&gt;
&lt;br /&gt;
To get the patch from mercurial, use: &lt;br /&gt;
&lt;br /&gt;
 hg qdiff # if you&#039;re using queues or&lt;br /&gt;
 hg diff  # if you&#039;re not&lt;br /&gt;
&lt;br /&gt;
Add it to the bug as an attachment. &lt;br /&gt;
&lt;br /&gt;
=== Get a review ===&lt;br /&gt;
&lt;br /&gt;
Nothing gets into the tree without a review, so you&#039;ll need one. The [[JavaScript:Hackers|SpiderMonkey hackers list]] is a good place to start: if your patch changes something listed as an area of expertise for someone there, that&#039;s a good person to ask for a review.&lt;br /&gt;
&lt;br /&gt;
Alternatively run &amp;lt;code&amp;gt;hg blame&amp;lt;/code&amp;gt; on the files you&#039;ve changed, and check who has been changing related code recently. They&#039;re likely to be good candidates. An irc bot can automate this process for a single file if you enter &amp;quot;/msg mrgiggles who can review something.cpp?&amp;quot; into your irc client.&lt;br /&gt;
&lt;br /&gt;
The review will consist of comments on your changes, suggesting or requesting alternative ways to do something and asking you to make changes where needed. They might also request additional changes, for example tests. Fix what they ask, resubmit the patch to bugzilla, and ask for another review. After you repeat this step a few times, they will mark the patch as &amp;quot;&amp;lt;code&amp;gt;r+&amp;lt;/code&amp;gt;&amp;quot; meaning it&#039;s now good to commit.&lt;br /&gt;
&lt;br /&gt;
=== Commit ===&lt;br /&gt;
&lt;br /&gt;
You can&#039;t commit to mozilla-central / mozilla-inbound until you have &amp;quot;level 3&amp;quot; access, so you&#039;ll need someone to do this for you. Try asking in [irc://irc.mozilla.org/#jsapi #jsapi], or add the &amp;lt;code&amp;gt;checkin-needed&amp;lt;/code&amp;gt; keyword to the bug. After you have been contributing for a while, you can get level 3 access by [https://www.mozilla.org/hacking/commit-access-policy/ applying for it].&lt;br /&gt;
&lt;br /&gt;
After committing, a large series of tests will be run to make sure you didn&#039;t break anything. You will need to hang around to make sure you didn&#039;t break something. It is difficult to determine what failures are real and what are what we call &amp;quot;intermittent oranges&amp;quot; (&amp;quot;orange&amp;quot; because that is the color used on our continuous integration dashboard for test failures). If you do break something, a sheriff will probably let you know via IRC and will probably back your patch out. You can always ask [irc://irc.mozilla.org/#jsapi for help] determining what is going on. (Over time you&#039;ll get a feel for figuring out when breakage is real on your own.)&lt;br /&gt;
&lt;br /&gt;
== Overview of the JS engine ==&lt;br /&gt;
&lt;br /&gt;
The JS engine is a swiftly moving target. The most detailed information is available at https://developer.mozilla.org/en/SpiderMonkey. Here are some particularly interesting, mostly up-to-date resources:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== High level overviews ===&lt;br /&gt;
&lt;br /&gt;
(Outdated) http://hacks.mozilla.org/2010/03/a-quick-note-on-javascript-engine-components/&lt;br /&gt;
&lt;br /&gt;
https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Internals&lt;br /&gt;
&lt;br /&gt;
=== Medium level documentation ===&lt;br /&gt;
&lt;br /&gt;
jsapi.h: http://hg.mozilla.org/mozilla-central/file/tip/js/src/jsapi.h and the files in http://hg.mozilla.org/mozilla-central/file/tip/js/public&lt;br /&gt;
&lt;br /&gt;
Frequently used coding recipes and mappings from JS idioms to SpiderMonkey code: https://developer.mozilla.org/En/SpiderMonkey/JSAPI_Cookbook&lt;br /&gt;
&lt;br /&gt;
=== Detailed documentation ===&lt;br /&gt;
&lt;br /&gt;
Build: https://developer.mozilla.org/en/SpiderMonkey/Build_Documentation&lt;br /&gt;
&lt;br /&gt;
Testing: https://developer.mozilla.org/en/SpiderMonkey/Running_Automated_JavaScript_Tests&lt;br /&gt;
&lt;br /&gt;
Shell: https://developer.mozilla.org/En/SpiderMonkey/Introduction_to_the_JavaScript_shell&lt;br /&gt;
&lt;br /&gt;
Function reference: https://developer.mozilla.org/en/SpiderMonkey/JSAPI_Reference&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Collaboration and teamwork ==&lt;br /&gt;
&lt;br /&gt;
=== Communication (in descending order of information content) ===&lt;br /&gt;
&lt;br /&gt;
Nearly all communication is handled through [https://bugzilla.mozilla.org Bugzilla]. All bugs, feature requests, issues, enhancements, etc, are all referred to as bugs. No code may enter the Mozilla repository without being a patch attached to a bugzilla bug first. To follow all SpiderMonkey related bugs:&lt;br /&gt;
&lt;br /&gt;
 Go to [https://bugzilla.mozilla.org/userprefs.cgi?tab=email email preferences]&lt;br /&gt;
 Watch the user general@spidermonkey.bugs&lt;br /&gt;
&lt;br /&gt;
SpiderMonkey contributors generally hang out in the very active [irc://irc.mozilla.org/jsapi #jsapi IRC channel].&lt;br /&gt;
&lt;br /&gt;
The [https://www.mozilla.org/about/forums/#dev-tech-js-engine-internals js-internals mailing list] is used for communicating with other SpiderMonkey hackers. (&amp;lt;i&amp;gt;Internals&amp;lt;/i&amp;gt; as in discussing the internals of the SpiderMonkey engine. All are welcome on the list.).&lt;br /&gt;
&lt;br /&gt;
Reading Planet Mozilla is the best way to keep up with the Mozilla project, which includes some SpiderMonkey related blogs:&lt;br /&gt;
&lt;br /&gt;
 [https://blog.mozilla.org/javascript General JavaScript blog]&lt;br /&gt;
 [http://blog.mozilla.com/jorendorff Jason Orendorff]&lt;br /&gt;
 [http://blog.mozilla.com/nnethercote/ Nicholas Nethercote]&lt;br /&gt;
 [http://whereswalden.com/ Jeff Walden]&lt;br /&gt;
 [https://itcouldbesomuchbetter.wordpress.com Jim Blandy]&lt;br /&gt;
 [https://jandemooij.nl/ Jan de Mooij]&lt;br /&gt;
 [https://h4writer.com/ Hannes Verschore]&lt;br /&gt;
 [http://rfrn.org/~shu/ Shu-yu Guo]&lt;br /&gt;
 [https://blog.benj.me/tag/mozilla.html Benjamin Bouvier]&lt;br /&gt;
&lt;br /&gt;
The [https://developer.mozilla.org/en/SpiderMonkey#Community js-engine mailing list] is generally used for communicating with people who embed SpiderMonkey, such as asking questions and announcing API changes. No actual development happens on the list.&lt;br /&gt;
&lt;br /&gt;
== Code considerations ==&lt;br /&gt;
&lt;br /&gt;
=== Repository ===&lt;br /&gt;
&lt;br /&gt;
Most active work on SpiderMonkey is done in the [http://hg.mozilla.org/mozilla-central mozilla-central] branch of the mozilla repository.&lt;br /&gt;
&lt;br /&gt;
=== Coding Style ===&lt;br /&gt;
&lt;br /&gt;
For many years, SpiderMonkey was written in C, and is gradually moving to C++. We still avoid many features such as run-time type information and virtual functions, but have come around to the glory of templates and namespaces relatively recently. Read the [[JavaScript:SpiderMonkey:C++ Coding Style|Coding Style]]. Do NOT read the portability guidelines, which I will not link to, since they are very out of date.&lt;br /&gt;
&lt;br /&gt;
=== Workflow ===&lt;br /&gt;
&lt;br /&gt;
Everything goes through bugzilla. We find a bug or have an idea, then submit it to bugzilla, then file patches to solve it. When it is solved, the patch is reviewed by team members, and is then committed to the [http://hg.mozilla.org/mozilla-central mozilla-central repository]. A link to the commit is then added as a comment to the bug.&lt;br /&gt;
&lt;br /&gt;
As well as committing to [http://hg.mozilla.org/mozilla-central mozilla-central], we also have the option of committing to [http://hg.mozilla.org/integration/mozilla-inbound mozilla-inbound], which is automatically merged to mozilla-central by a Sheriff. This exempts us from watching [http://tbpl.mozilla.org tinderbox] to check for errors in our patches, and commits are automatically backed out if errors are found.&lt;br /&gt;
&lt;br /&gt;
==== Sample Workflows ====&lt;br /&gt;
&lt;br /&gt;
(Outdated) [http://blog.mozilla.com/nnethercote/2009/07/27/how-i-work-on-tracemonkey/ Nicholas Nethercote: How I work on Tracemonkey]&lt;br /&gt;
&lt;br /&gt;
=== Policy ===&lt;br /&gt;
&lt;br /&gt;
The following docs are for the Mozilla project, and differ ever so slightly from what you should do for SpiderMonkey. For example, you should find reviewers in #jsapi rather than #developers.&lt;br /&gt;
&lt;br /&gt;
[http://www.mozilla.org/hacking/committer/ How to get commit access]&lt;br /&gt;
&lt;br /&gt;
[https://developer.mozilla.org/en/Creating_a_patch How to make patches]&lt;br /&gt;
&lt;br /&gt;
[https://developer.mozilla.org/En/Developer_Guide/How_to_Submit_a_Patch Submitting a patch]&lt;br /&gt;
&lt;br /&gt;
[https://developer.mozilla.org/en/Supported_build_configurations Supported Platforms]&lt;br /&gt;
&lt;br /&gt;
==== .hgrc file ====&lt;br /&gt;
&lt;br /&gt;
This .hgrc file contains a lot of the wisdom distilled through the wiki:&lt;br /&gt;
&lt;br /&gt;
 [extensions]&lt;br /&gt;
 mq =&lt;br /&gt;
 &lt;br /&gt;
 [ui]&lt;br /&gt;
 username = First Last &amp;lt;email@domain.tld&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
 [alias]&lt;br /&gt;
 qfulldiff = diff --rev qparent:.&lt;br /&gt;
 &lt;br /&gt;
 [defaults]&lt;br /&gt;
 diff = -p -U 8&lt;br /&gt;
 qdiff = -p -U 8&lt;br /&gt;
 qnew = -U&lt;br /&gt;
 commit = -v&lt;br /&gt;
 &lt;br /&gt;
 [diff]&lt;br /&gt;
 git = true&lt;br /&gt;
 showfunc = true&lt;br /&gt;
 unified = 8&lt;br /&gt;
 &lt;br /&gt;
 [paths]&lt;br /&gt;
 try = ssh://email@domain.tld@hg.mozilla.org/try/&lt;br /&gt;
&lt;br /&gt;
=== Try server  ===&lt;br /&gt;
&lt;br /&gt;
Often, you may be a little wary of breaking things. Mozilla has a [[Build:TryServer|Try Server]] where you can send a patch, and it&#039;ll be built and tested on tons of machines, which report to [http://tbpl.mozilla.org/?tree=Try TBPL]. Although you don&#039;t have [https://www.mozilla.org/hacking/commit-access-policy/ access] to TryServer just yet, you can get someone else to push it there for you. Just attach a patch to your bug, and ask in a comment, or on [irc://irc.mozilla.org/#jsapi #jsapi]. To be able to push to try-server yourself, you will need &amp;quot;level 1&amp;quot; access, which you can [https://www.mozilla.org/hacking/commit-access-policy/ request] once you&#039;ve contributed a patch or two.&lt;br /&gt;
&lt;br /&gt;
=== Mercurial Queues ===&lt;br /&gt;
&lt;br /&gt;
Since most of our lives revolve around patches, and we use Mercurial, nearly everybody uses Mercurial queues.&lt;br /&gt;
&lt;br /&gt;
Queues are based on the idea of patch management. Each queue consists of a series of patches, applied sequentially. The aim of the game is to split potential commits into simple, bite-sized chunks which are easy to review. This also makes it simple to experiment without polluting your existing work on a bug, to spin parts off into new bugs, and to rapidly apply and unapply patches (as demonstrated in the tutorial above).&lt;br /&gt;
&lt;br /&gt;
==== Enabling ====&lt;br /&gt;
&lt;br /&gt;
Add the following snippet to your .hgrc file to enable MQ&lt;br /&gt;
&lt;br /&gt;
 [extensions]&lt;br /&gt;
 mq =&lt;br /&gt;
&lt;br /&gt;
==== Example MQ workflow ====&lt;br /&gt;
&lt;br /&gt;
Clone the repository to deal with a bug:&lt;br /&gt;
&lt;br /&gt;
  hg clone http://hg.mozilla.org/mozilla-central&lt;br /&gt;
&lt;br /&gt;
Initialize your queue:&lt;br /&gt;
&lt;br /&gt;
  hg qinit -c&lt;br /&gt;
&lt;br /&gt;
Create a new patch, with some name:&lt;br /&gt;
&lt;br /&gt;
  hg qnew first_attempt&lt;br /&gt;
&lt;br /&gt;
Work on the patch, try to fix the bug, test, compile, etc.&lt;br /&gt;
&lt;br /&gt;
Refresh (save your work into the patch):&lt;br /&gt;
&lt;br /&gt;
 hg qrefresh&lt;br /&gt;
&lt;br /&gt;
Repeat a few times.&lt;br /&gt;
&lt;br /&gt;
Rename the patch (because your first name wasn&#039;t appliable):&lt;br /&gt;
&lt;br /&gt;
 hg qrename refactor_the_whatsit&lt;br /&gt;
&lt;br /&gt;
Create a new patch to try a logically separate part of the same bug:&lt;br /&gt;
&lt;br /&gt;
 hg qnew rip_out_the_old_thing&lt;br /&gt;
&lt;br /&gt;
Repeat the process a few times, until you have solved the problem. During this time, it can often be useful to go back and forth between patches:&lt;br /&gt;
&lt;br /&gt;
 hg qpop # unapply a patch&lt;br /&gt;
 hg qpush # reapply a patch&lt;br /&gt;
 hg qpop -a # unapply all patches&lt;br /&gt;
 hg qpush -a # reapply all patches&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Combine all the patches into a single patch, which you submit to bugzilla:&lt;br /&gt;
&lt;br /&gt;
 hg qpush -a&lt;br /&gt;
 hg qdiff --rev qparent:. &amp;gt; my_wonderful_patch.patch&lt;br /&gt;
&lt;br /&gt;
Commit the patches to your local patch repository, in case you make a mistake (You might do this periodically):&lt;br /&gt;
&lt;br /&gt;
 hg qcommit -m &amp;quot;Some message. Doesn&#039;t have to be good, this won&#039;t be committed to the repository, it&#039;s just for you&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Go back to the old patches and fiddle with them based on feedback:&lt;br /&gt;
&lt;br /&gt;
 hg qpop&lt;br /&gt;
 hg qrefresh&lt;br /&gt;
 etc&lt;br /&gt;
&lt;br /&gt;
There are some more complex techniques that we won&#039;t go into in detail. You can enable only some patches using qguard and qselect, and you can reorder the patches by manually editing the .hg/patches/series file. But be careful!&lt;br /&gt;
&lt;br /&gt;
[[Category:New Contributor Landing Page]]&lt;/div&gt;</summary>
		<author><name>Sfink</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=JavaScript:New_to_SpiderMonkey&amp;diff=1150955</id>
		<title>JavaScript:New to SpiderMonkey</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=JavaScript:New_to_SpiderMonkey&amp;diff=1150955"/>
		<updated>2016-10-11T15:44:39Z</updated>

		<summary type="html">&lt;p&gt;Sfink: /* Commit */ sheriffs watch our backs&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Tutorial: your first patch  ==&lt;br /&gt;
&lt;br /&gt;
The first step to getting involved with SpiderMonkey is to make your first patch. This guides you through it, and at the end you should have learnt a lot of the procedures and formalisms involved in getting things done here.&lt;br /&gt;
&lt;br /&gt;
We&#039;ll assume you&#039;re on a Unix-y platform, and that you know what you&#039;re doing. We&#039;ll ignore nearly all details. &lt;br /&gt;
&lt;br /&gt;
=== Get the code ===&lt;br /&gt;
&lt;br /&gt;
Spidermonkey development happens in the &amp;quot;mozilla-central&amp;quot; mercurial repository:&lt;br /&gt;
&lt;br /&gt;
 hg clone http://hg.mozilla.org/mozilla-central spidermonkey&lt;br /&gt;
&lt;br /&gt;
=== Build the js shell ===&lt;br /&gt;
&lt;br /&gt;
Most of the time, you&#039;ll be working with the Javascript shell, instead of the full Firefox browser. So build the shell: &lt;br /&gt;
&lt;br /&gt;
 cd spidermonkey/js/src&lt;br /&gt;
 cp configure.in configure &amp;amp;&amp;amp; chmod +x configure # or autoconf2.13 or autoconf-2.13&lt;br /&gt;
 mkdir build_DBG.OBJ &lt;br /&gt;
 cd build_DBG.OBJ &lt;br /&gt;
 ../configure --enable-debug --disable-optimize&lt;br /&gt;
 make # or make -j8&lt;br /&gt;
 cd ..&lt;br /&gt;
&lt;br /&gt;
If you&#039;re having trouble or are missing dependencies, refer to [https://developer.mozilla.org/en/SpiderMonkey/Build_Documentation#Building_SpiderMonkey_tip Building SpiderMonkey Tip].&lt;br /&gt;
&lt;br /&gt;
=== Fix something ===&lt;br /&gt;
&lt;br /&gt;
At this point, you&#039;re ready to make your first fix. &lt;br /&gt;
&lt;br /&gt;
 TODO: something useless. Maybe adding a datemicrosecond function.&lt;br /&gt;
&lt;br /&gt;
==== Building your changes ====&lt;br /&gt;
&lt;br /&gt;
Having made the change, build the shell again. &lt;br /&gt;
&lt;br /&gt;
 make -C build_DBG.OBJ&lt;br /&gt;
&lt;br /&gt;
==== Testing your changes ====&lt;br /&gt;
&lt;br /&gt;
It builds. Hurray. Time to run the tests to check you haven&#039;t broken anything. &lt;br /&gt;
&lt;br /&gt;
 jit-test/jit_test.py build_DBG.OBJ/dist/bin/js&lt;br /&gt;
(The location of the shell has changed, it used to be build_DBG.OBJ/js)&lt;br /&gt;
&lt;br /&gt;
The jit-tests are pretty quick, and should give you an idea if you&#039;ve gotten something wrong. Assuming nothing goes wrong, try the ref-tests: &lt;br /&gt;
&lt;br /&gt;
 tests/jstests.py build_DBG.OBJ/dist/bin/js&lt;br /&gt;
&lt;br /&gt;
Note that some of these tests fail depending on the timezone and locale they&#039;re run in, so if you get any errors that don&#039;t seem related to your changes, re-run the tests with a shell build without your changes applied and compare the results.&lt;br /&gt;
&lt;br /&gt;
==== Benchmark your changes ====&lt;br /&gt;
&lt;br /&gt;
Tests all pass. Congrats, you didn&#039;t break anything. Now, did you make it faster or slower? We benchmark using the v8 and SunSpider benchmarks. Get the benchmarks: &lt;br /&gt;
&lt;br /&gt;
 svn checkout http://svn.webkit.org/repository/webkit/trunk/PerformanceTests/SunSpider&lt;br /&gt;
&lt;br /&gt;
And now run them: &lt;br /&gt;
&lt;br /&gt;
 cd SunSpider &lt;br /&gt;
 ./sunspider --shell=../build_DBG.OBJ/dist/bin/js --run=30 --suite=sunspider-0.9.1 &lt;br /&gt;
 cd ..&lt;br /&gt;
&lt;br /&gt;
===== Optimized build =====&lt;br /&gt;
&lt;br /&gt;
Whoops, we benchmarked the debug version. Let&#039;s make an optimized build to test instead.&lt;br /&gt;
&lt;br /&gt;
 mkdir build_OPT.OBJ &lt;br /&gt;
 cd build_OPT.OBJ &lt;br /&gt;
 ../configure --disable-debug --enable-optimize&lt;br /&gt;
 make &lt;br /&gt;
 cd ..&lt;br /&gt;
&lt;br /&gt;
Repeat the sunspider steps above, and take note of the line that looks like: &lt;br /&gt;
&lt;br /&gt;
 Results are located at sunspider-0.9.1-results/sunspider-results-2010-08-07-17.56.48.js&lt;br /&gt;
&lt;br /&gt;
You&#039;ll need that later. &lt;br /&gt;
&lt;br /&gt;
===== Baseline version / Mercurial Queues =====&lt;br /&gt;
&lt;br /&gt;
We need to time our optimized version against the baseline version. This calls for a brief introduction to mercurial queues, which used to be the way most people managed their SpiderMonkey workflow (though these days many people use native hg, native hg + evolution, or git):&lt;br /&gt;
&lt;br /&gt;
 hg qinit&lt;br /&gt;
 hg qnew my_first_patch -f&lt;br /&gt;
 hg qrefresh&lt;br /&gt;
&lt;br /&gt;
This puts your current work into a patch, managed by Mercurial, symbolically called my_first_patch. To pop the patch off: &lt;br /&gt;
&lt;br /&gt;
 hg qpop&lt;br /&gt;
&lt;br /&gt;
And we&#039;re back to our pristine version.&lt;br /&gt;
&lt;br /&gt;
===== Compare =====&lt;br /&gt;
&lt;br /&gt;
Build again and rerun SunSpider again. You should now have two files like: &lt;br /&gt;
&lt;br /&gt;
 sunspider-0.9.1-results/sunspider-results-2010-08-07-17.56.48.js&lt;br /&gt;
&lt;br /&gt;
Compare them using the compare script: &lt;br /&gt;
&lt;br /&gt;
 cd SunSpider &lt;br /&gt;
 ./sunspider-compare-results --shell=../build_DBG.OBJ/js --suite=sunspider-0.9.1 FILE1-withoutPatch FILE2-withPatch&lt;br /&gt;
&lt;br /&gt;
=== Get a real bug  ===&lt;br /&gt;
&lt;br /&gt;
At this point, you&#039;ve seen nearly everything you need to do hack on SpiderMonkey. So it&#039;s time to get a real bug to work on. You can get a bug on [http://www.joshmatthews.net/bugsahoy/?jseng=1&amp;amp;unowned=1 Bugs Ahoy].&lt;br /&gt;
&lt;br /&gt;
Fix the bug, updating the bug report with your progress, and asking questions as you go (either in the bug comments, or in [irc://irc.mozilla.org/#jsapi #jsapi]). When it&#039;s done, repeat all the steps above. Then it&#039;s time to get your patch into the tree.&lt;br /&gt;
&lt;br /&gt;
=== Submit a patch  ===&lt;br /&gt;
&lt;br /&gt;
To get the patch from mercurial, use: &lt;br /&gt;
&lt;br /&gt;
 hg qdiff # if you&#039;re using queues or&lt;br /&gt;
 hg diff  # if you&#039;re not&lt;br /&gt;
&lt;br /&gt;
Add it to the bug as an attachment. &lt;br /&gt;
&lt;br /&gt;
=== Get a review ===&lt;br /&gt;
&lt;br /&gt;
Nothing gets into the tree without a review, so you&#039;ll need one. The [[JavaScript:Hackers|SpiderMonkey hackers list]] is a good place to start: if your patch changes something listed as an area of expertise for someone there, that&#039;s a good person to ask for a review.&lt;br /&gt;
&lt;br /&gt;
Alternatively run &amp;lt;code&amp;gt;hg blame&amp;lt;/code&amp;gt; on the files you&#039;ve changed, and check who has been changing related code recently. They&#039;re likely to be good candidates. An irc bot can automate this process for a single file if you enter &amp;quot;/msg mrgiggles who can review something.cpp?&amp;quot; into your irc client.&lt;br /&gt;
&lt;br /&gt;
The review will consist of comments on your changes, suggesting or requesting alternative ways to do something and asking you to make changes where needed. They might also request additional changes, for example tests. Fix what they ask, resubmit the patch to bugzilla, and ask for another review. After you repeat this step a few times, they will mark the patch as &amp;quot;&amp;lt;code&amp;gt;r+&amp;lt;/code&amp;gt;&amp;quot; meaning it&#039;s now good to commit.&lt;br /&gt;
&lt;br /&gt;
=== Commit ===&lt;br /&gt;
&lt;br /&gt;
You can&#039;t commit to mozilla-central / mozilla-inbound until you have &amp;quot;level 3&amp;quot; access, so you&#039;ll need someone to do this for you. Try asking in [irc://irc.mozilla.org/#jsapi #jsapi], or add the &amp;lt;code&amp;gt;checkin-needed&amp;lt;/code&amp;gt; keyword to the bug. After you have been contributing for a while, you can get level 3 access by [https://www.mozilla.org/hacking/commit-access-policy/ applying for it].&lt;br /&gt;
&lt;br /&gt;
After committing, a large series of tests will be run to make sure you didn&#039;t break anything. You will need to hang around to make sure you didn&#039;t break something. It is difficult to determine what failures are real and what are what we call &amp;quot;intermittent oranges&amp;quot; (&amp;quot;orange&amp;quot; because that is the color used on our continuous integration dashboard for test failures). If you do break something, a sheriff will probably let you know via IRC and will probably back your patch out. You can always ask [irc://irc.mozilla.org/#jsapi for help] determining what is going on. (Over time you&#039;ll get a feel for figuring out when breakage is real on your own.)&lt;br /&gt;
&lt;br /&gt;
== Overview of the JS engine ==&lt;br /&gt;
&lt;br /&gt;
The JS engine is a swiftly moving target. The most detailed information is available at https://developer.mozilla.org/en/SpiderMonkey. Here are some particularly interesting, mostly up-to-date resources:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== High level overviews ===&lt;br /&gt;
&lt;br /&gt;
(Outdated) http://hacks.mozilla.org/2010/03/a-quick-note-on-javascript-engine-components/&lt;br /&gt;
&lt;br /&gt;
https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Internals&lt;br /&gt;
&lt;br /&gt;
=== Medium level documentation ===&lt;br /&gt;
&lt;br /&gt;
jsapi.h: http://hg.mozilla.org/mozilla-central/file/tip/js/src/jsapi.h&lt;br /&gt;
&lt;br /&gt;
Frequently used coding recipes and mappings from JS idioms to SpiderMonkey code: https://developer.mozilla.org/En/SpiderMonkey/JSAPI_Cookbook&lt;br /&gt;
&lt;br /&gt;
=== Detailed documentation ===&lt;br /&gt;
&lt;br /&gt;
Build: https://developer.mozilla.org/en/SpiderMonkey/Build_Documentation&lt;br /&gt;
&lt;br /&gt;
Testing: https://developer.mozilla.org/en/SpiderMonkey/Running_Automated_JavaScript_Tests&lt;br /&gt;
&lt;br /&gt;
Shell: https://developer.mozilla.org/En/SpiderMonkey/Introduction_to_the_JavaScript_shell&lt;br /&gt;
&lt;br /&gt;
Function reference: https://developer.mozilla.org/en/SpiderMonkey/JSAPI_Reference&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Collaboration and teamwork ==&lt;br /&gt;
&lt;br /&gt;
=== Communication (in descending order of information content) ===&lt;br /&gt;
&lt;br /&gt;
Nearly all communication is handled through [https://bugzilla.mozilla.org Bugzilla]. All bugs, feature requests, issues, enhancements, etc, are all referred to as bugs. No code may enter the Mozilla repository without being a patch attached to a bugzilla bug first. To follow all SpiderMonkey related bugs:&lt;br /&gt;
&lt;br /&gt;
 Go to [https://bugzilla.mozilla.org/userprefs.cgi?tab=email email preferences]&lt;br /&gt;
 Watch the user general@spidermonkey.bugs&lt;br /&gt;
&lt;br /&gt;
SpiderMonkey contributors generally hang out in the very active [irc://irc.mozilla.org/jsapi #jsapi IRC channel].&lt;br /&gt;
&lt;br /&gt;
The [https://www.mozilla.org/about/forums/#dev-tech-js-engine-internals js-internals mailing list] is used for communicating with other SpiderMonkey hackers. (&amp;lt;i&amp;gt;Internals&amp;lt;/i&amp;gt; as in discussing the internals of the SpiderMonkey engine. All are welcome on the list.).&lt;br /&gt;
&lt;br /&gt;
Reading Planet Mozilla is the best way to keep up with the Mozilla project, which includes some SpiderMonkey related blogs:&lt;br /&gt;
&lt;br /&gt;
 [https://blog.mozilla.org/javascript General JavaScript blog]&lt;br /&gt;
 [http://blog.mozilla.com/jorendorff Jason Orendorff]&lt;br /&gt;
 [http://blog.mozilla.com/nnethercote/ Nicholas Nethercote]&lt;br /&gt;
 [http://whereswalden.com/ Jeff Walden]&lt;br /&gt;
 [https://itcouldbesomuchbetter.wordpress.com Jim Blandy]&lt;br /&gt;
 [https://jandemooij.nl/ Jan de Mooij]&lt;br /&gt;
 [https://h4writer.com/ Hannes Verschore]&lt;br /&gt;
 [http://rfrn.org/~shu/ Shu-yu Guo]&lt;br /&gt;
 [https://blog.benj.me/tag/mozilla.html Benjamin Bouvier]&lt;br /&gt;
&lt;br /&gt;
The [https://developer.mozilla.org/en/SpiderMonkey#Community js-engine mailing list] is generally used for communicating with people who embed SpiderMonkey, such as asking questions and announcing API changes. No actual development happens on the list.&lt;br /&gt;
&lt;br /&gt;
== Code considerations ==&lt;br /&gt;
&lt;br /&gt;
=== Repository ===&lt;br /&gt;
&lt;br /&gt;
Most active work on SpiderMonkey is done in the [http://hg.mozilla.org/mozilla-central mozilla-central] branch of the mozilla repository.&lt;br /&gt;
&lt;br /&gt;
=== Coding Style ===&lt;br /&gt;
&lt;br /&gt;
For many years, SpiderMonkey was written in C, and is gradually moving to C++. We still avoid many features such as run-time type information and virtual functions, but have come around to the glory of templates and namespaces relatively recently. Read the [[JavaScript:SpiderMonkey:C++ Coding Style|Coding Style]]. Do NOT read the portability guidelines, which I will not link to, since they are very out of date.&lt;br /&gt;
&lt;br /&gt;
=== Workflow ===&lt;br /&gt;
&lt;br /&gt;
Everything goes through bugzilla. We find a bug or have an idea, then submit it to bugzilla, then file patches to solve it. When it is solved, the patch is reviewed by team members, and is then committed to the [http://hg.mozilla.org/mozilla-central mozilla-central repository]. A link to the commit is then added as a comment to the bug.&lt;br /&gt;
&lt;br /&gt;
As well as committing to [http://hg.mozilla.org/mozilla-central mozilla-central], we also have the option of committing to [http://hg.mozilla.org/integration/mozilla-inbound mozilla-inbound], which is automatically merged to mozilla-central by a Sheriff. This exempts us from watching [http://tbpl.mozilla.org tinderbox] to check for errors in our patches, and commits are automatically backed out if errors are found.&lt;br /&gt;
&lt;br /&gt;
==== Sample Workflows ====&lt;br /&gt;
&lt;br /&gt;
(Outdated) [http://blog.mozilla.com/nnethercote/2009/07/27/how-i-work-on-tracemonkey/ Nicholas Nethercote: How I work on Tracemonkey]&lt;br /&gt;
&lt;br /&gt;
=== Policy ===&lt;br /&gt;
&lt;br /&gt;
The following docs are for the Mozilla project, and differ ever so slightly from what you should do for SpiderMonkey. For example, you should find reviewers in #jsapi rather than #developers.&lt;br /&gt;
&lt;br /&gt;
[http://www.mozilla.org/hacking/committer/ How to get commit access]&lt;br /&gt;
&lt;br /&gt;
[https://developer.mozilla.org/en/Creating_a_patch How to make patches]&lt;br /&gt;
&lt;br /&gt;
[https://developer.mozilla.org/En/Developer_Guide/How_to_Submit_a_Patch Submitting a patch]&lt;br /&gt;
&lt;br /&gt;
[https://developer.mozilla.org/en/Supported_build_configurations Supported Platforms]&lt;br /&gt;
&lt;br /&gt;
==== .hgrc file ====&lt;br /&gt;
&lt;br /&gt;
This .hgrc file contains a lot of the wisdom distilled through the wiki:&lt;br /&gt;
&lt;br /&gt;
 [extensions]&lt;br /&gt;
 mq =&lt;br /&gt;
 &lt;br /&gt;
 [ui]&lt;br /&gt;
 username = First Last &amp;lt;email@domain.tld&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
 [alias]&lt;br /&gt;
 qfulldiff = diff --rev qparent:.&lt;br /&gt;
 &lt;br /&gt;
 [defaults]&lt;br /&gt;
 diff = -p -U 8&lt;br /&gt;
 qdiff = -p -U 8&lt;br /&gt;
 qnew = -U&lt;br /&gt;
 commit = -v&lt;br /&gt;
 &lt;br /&gt;
 [diff]&lt;br /&gt;
 git = true&lt;br /&gt;
 showfunc = true&lt;br /&gt;
 unified = 8&lt;br /&gt;
 &lt;br /&gt;
 [paths]&lt;br /&gt;
 try = ssh://email@domain.tld@hg.mozilla.org/try/&lt;br /&gt;
&lt;br /&gt;
=== Try server  ===&lt;br /&gt;
&lt;br /&gt;
Often, you may be a little wary of breaking things. Mozilla has a [[Build:TryServer|Try Server]] where you can send a patch, and it&#039;ll be built and tested on tons of machines, which report to [http://tbpl.mozilla.org/?tree=Try TBPL]. Although you don&#039;t have [https://www.mozilla.org/hacking/commit-access-policy/ access] to TryServer just yet, you can get someone else to push it there for you. Just attach a patch to your bug, and ask in a comment, or on [irc://irc.mozilla.org/#jsapi #jsapi]. To be able to push to try-server yourself, you will need &amp;quot;level 1&amp;quot; access, which you can [https://www.mozilla.org/hacking/commit-access-policy/ request] once you&#039;ve contributed a patch or two.&lt;br /&gt;
&lt;br /&gt;
=== Mercurial Queues ===&lt;br /&gt;
&lt;br /&gt;
Since most of our lives revolve around patches, and we use Mercurial, nearly everybody uses Mercurial queues.&lt;br /&gt;
&lt;br /&gt;
Queues are based on the idea of patch management. Each queue consists of a series of patches, applied sequentially. The aim of the game is to split potential commits into simple, bite-sized chunks which are easy to review. This also makes it simple to experiment without polluting your existing work on a bug, to spin parts off into new bugs, and to rapidly apply and unapply patches (as demonstrated in the tutorial above).&lt;br /&gt;
&lt;br /&gt;
==== Enabling ====&lt;br /&gt;
&lt;br /&gt;
Add the following snippet to your .hgrc file to enable MQ&lt;br /&gt;
&lt;br /&gt;
 [extensions]&lt;br /&gt;
 mq =&lt;br /&gt;
&lt;br /&gt;
==== Example MQ workflow ====&lt;br /&gt;
&lt;br /&gt;
Clone the repository to deal with a bug:&lt;br /&gt;
&lt;br /&gt;
  hg clone http://hg.mozilla.org/mozilla-central&lt;br /&gt;
&lt;br /&gt;
Initialize your queue:&lt;br /&gt;
&lt;br /&gt;
  hg qinit -c&lt;br /&gt;
&lt;br /&gt;
Create a new patch, with some name:&lt;br /&gt;
&lt;br /&gt;
  hg qnew first_attempt&lt;br /&gt;
&lt;br /&gt;
Work on the patch, try to fix the bug, test, compile, etc.&lt;br /&gt;
&lt;br /&gt;
Refresh (save your work into the patch):&lt;br /&gt;
&lt;br /&gt;
 hg qrefresh&lt;br /&gt;
&lt;br /&gt;
Repeat a few times.&lt;br /&gt;
&lt;br /&gt;
Rename the patch (because your first name wasn&#039;t appliable):&lt;br /&gt;
&lt;br /&gt;
 hg qrename refactor_the_whatsit&lt;br /&gt;
&lt;br /&gt;
Create a new patch to try a logically separate part of the same bug:&lt;br /&gt;
&lt;br /&gt;
 hg qnew rip_out_the_old_thing&lt;br /&gt;
&lt;br /&gt;
Repeat the process a few times, until you have solved the problem. During this time, it can often be useful to go back and forth between patches:&lt;br /&gt;
&lt;br /&gt;
 hg qpop # unapply a patch&lt;br /&gt;
 hg qpush # reapply a patch&lt;br /&gt;
 hg qpop -a # unapply all patches&lt;br /&gt;
 hg qpush -a # reapply all patches&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Combine all the patches into a single patch, which you submit to bugzilla:&lt;br /&gt;
&lt;br /&gt;
 hg qpush -a&lt;br /&gt;
 hg qdiff --rev qparent:. &amp;gt; my_wonderful_patch.patch&lt;br /&gt;
&lt;br /&gt;
Commit the patches to your local patch repository, in case you make a mistake (You might do this periodically):&lt;br /&gt;
&lt;br /&gt;
 hg qcommit -m &amp;quot;Some message. Doesn&#039;t have to be good, this won&#039;t be committed to the repository, it&#039;s just for you&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Go back to the old patches and fiddle with them based on feedback:&lt;br /&gt;
&lt;br /&gt;
 hg qpop&lt;br /&gt;
 hg qrefresh&lt;br /&gt;
 etc&lt;br /&gt;
&lt;br /&gt;
There are some more complex techniques that we won&#039;t go into in detail. You can enable only some patches using qguard and qselect, and you can reorder the patches by manually editing the .hg/patches/series file. But be careful!&lt;br /&gt;
&lt;br /&gt;
[[Category:New Contributor Landing Page]]&lt;/div&gt;</summary>
		<author><name>Sfink</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=JavaScript:New_to_SpiderMonkey&amp;diff=1150954</id>
		<title>JavaScript:New to SpiderMonkey</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=JavaScript:New_to_SpiderMonkey&amp;diff=1150954"/>
		<updated>2016-10-11T15:40:58Z</updated>

		<summary type="html">&lt;p&gt;Sfink: /* Get a review */ mrgiggles&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Tutorial: your first patch  ==&lt;br /&gt;
&lt;br /&gt;
The first step to getting involved with SpiderMonkey is to make your first patch. This guides you through it, and at the end you should have learnt a lot of the procedures and formalisms involved in getting things done here.&lt;br /&gt;
&lt;br /&gt;
We&#039;ll assume you&#039;re on a Unix-y platform, and that you know what you&#039;re doing. We&#039;ll ignore nearly all details. &lt;br /&gt;
&lt;br /&gt;
=== Get the code ===&lt;br /&gt;
&lt;br /&gt;
Spidermonkey development happens in the &amp;quot;mozilla-central&amp;quot; mercurial repository:&lt;br /&gt;
&lt;br /&gt;
 hg clone http://hg.mozilla.org/mozilla-central spidermonkey&lt;br /&gt;
&lt;br /&gt;
=== Build the js shell ===&lt;br /&gt;
&lt;br /&gt;
Most of the time, you&#039;ll be working with the Javascript shell, instead of the full Firefox browser. So build the shell: &lt;br /&gt;
&lt;br /&gt;
 cd spidermonkey/js/src&lt;br /&gt;
 cp configure.in configure &amp;amp;&amp;amp; chmod +x configure # or autoconf2.13 or autoconf-2.13&lt;br /&gt;
 mkdir build_DBG.OBJ &lt;br /&gt;
 cd build_DBG.OBJ &lt;br /&gt;
 ../configure --enable-debug --disable-optimize&lt;br /&gt;
 make # or make -j8&lt;br /&gt;
 cd ..&lt;br /&gt;
&lt;br /&gt;
If you&#039;re having trouble or are missing dependencies, refer to [https://developer.mozilla.org/en/SpiderMonkey/Build_Documentation#Building_SpiderMonkey_tip Building SpiderMonkey Tip].&lt;br /&gt;
&lt;br /&gt;
=== Fix something ===&lt;br /&gt;
&lt;br /&gt;
At this point, you&#039;re ready to make your first fix. &lt;br /&gt;
&lt;br /&gt;
 TODO: something useless. Maybe adding a datemicrosecond function.&lt;br /&gt;
&lt;br /&gt;
==== Building your changes ====&lt;br /&gt;
&lt;br /&gt;
Having made the change, build the shell again. &lt;br /&gt;
&lt;br /&gt;
 make -C build_DBG.OBJ&lt;br /&gt;
&lt;br /&gt;
==== Testing your changes ====&lt;br /&gt;
&lt;br /&gt;
It builds. Hurray. Time to run the tests to check you haven&#039;t broken anything. &lt;br /&gt;
&lt;br /&gt;
 jit-test/jit_test.py build_DBG.OBJ/dist/bin/js&lt;br /&gt;
(The location of the shell has changed, it used to be build_DBG.OBJ/js)&lt;br /&gt;
&lt;br /&gt;
The jit-tests are pretty quick, and should give you an idea if you&#039;ve gotten something wrong. Assuming nothing goes wrong, try the ref-tests: &lt;br /&gt;
&lt;br /&gt;
 tests/jstests.py build_DBG.OBJ/dist/bin/js&lt;br /&gt;
&lt;br /&gt;
Note that some of these tests fail depending on the timezone and locale they&#039;re run in, so if you get any errors that don&#039;t seem related to your changes, re-run the tests with a shell build without your changes applied and compare the results.&lt;br /&gt;
&lt;br /&gt;
==== Benchmark your changes ====&lt;br /&gt;
&lt;br /&gt;
Tests all pass. Congrats, you didn&#039;t break anything. Now, did you make it faster or slower? We benchmark using the v8 and SunSpider benchmarks. Get the benchmarks: &lt;br /&gt;
&lt;br /&gt;
 svn checkout http://svn.webkit.org/repository/webkit/trunk/PerformanceTests/SunSpider&lt;br /&gt;
&lt;br /&gt;
And now run them: &lt;br /&gt;
&lt;br /&gt;
 cd SunSpider &lt;br /&gt;
 ./sunspider --shell=../build_DBG.OBJ/dist/bin/js --run=30 --suite=sunspider-0.9.1 &lt;br /&gt;
 cd ..&lt;br /&gt;
&lt;br /&gt;
===== Optimized build =====&lt;br /&gt;
&lt;br /&gt;
Whoops, we benchmarked the debug version. Let&#039;s make an optimized build to test instead.&lt;br /&gt;
&lt;br /&gt;
 mkdir build_OPT.OBJ &lt;br /&gt;
 cd build_OPT.OBJ &lt;br /&gt;
 ../configure --disable-debug --enable-optimize&lt;br /&gt;
 make &lt;br /&gt;
 cd ..&lt;br /&gt;
&lt;br /&gt;
Repeat the sunspider steps above, and take note of the line that looks like: &lt;br /&gt;
&lt;br /&gt;
 Results are located at sunspider-0.9.1-results/sunspider-results-2010-08-07-17.56.48.js&lt;br /&gt;
&lt;br /&gt;
You&#039;ll need that later. &lt;br /&gt;
&lt;br /&gt;
===== Baseline version / Mercurial Queues =====&lt;br /&gt;
&lt;br /&gt;
We need to time our optimized version against the baseline version. This calls for a brief introduction to mercurial queues, which used to be the way most people managed their SpiderMonkey workflow (though these days many people use native hg, native hg + evolution, or git):&lt;br /&gt;
&lt;br /&gt;
 hg qinit&lt;br /&gt;
 hg qnew my_first_patch -f&lt;br /&gt;
 hg qrefresh&lt;br /&gt;
&lt;br /&gt;
This puts your current work into a patch, managed by Mercurial, symbolically called my_first_patch. To pop the patch off: &lt;br /&gt;
&lt;br /&gt;
 hg qpop&lt;br /&gt;
&lt;br /&gt;
And we&#039;re back to our pristine version.&lt;br /&gt;
&lt;br /&gt;
===== Compare =====&lt;br /&gt;
&lt;br /&gt;
Build again and rerun SunSpider again. You should now have two files like: &lt;br /&gt;
&lt;br /&gt;
 sunspider-0.9.1-results/sunspider-results-2010-08-07-17.56.48.js&lt;br /&gt;
&lt;br /&gt;
Compare them using the compare script: &lt;br /&gt;
&lt;br /&gt;
 cd SunSpider &lt;br /&gt;
 ./sunspider-compare-results --shell=../build_DBG.OBJ/js --suite=sunspider-0.9.1 FILE1-withoutPatch FILE2-withPatch&lt;br /&gt;
&lt;br /&gt;
=== Get a real bug  ===&lt;br /&gt;
&lt;br /&gt;
At this point, you&#039;ve seen nearly everything you need to do hack on SpiderMonkey. So it&#039;s time to get a real bug to work on. You can get a bug on [http://www.joshmatthews.net/bugsahoy/?jseng=1&amp;amp;unowned=1 Bugs Ahoy].&lt;br /&gt;
&lt;br /&gt;
Fix the bug, updating the bug report with your progress, and asking questions as you go (either in the bug comments, or in [irc://irc.mozilla.org/#jsapi #jsapi]). When it&#039;s done, repeat all the steps above. Then it&#039;s time to get your patch into the tree.&lt;br /&gt;
&lt;br /&gt;
=== Submit a patch  ===&lt;br /&gt;
&lt;br /&gt;
To get the patch from mercurial, use: &lt;br /&gt;
&lt;br /&gt;
 hg qdiff # if you&#039;re using queues or&lt;br /&gt;
 hg diff  # if you&#039;re not&lt;br /&gt;
&lt;br /&gt;
Add it to the bug as an attachment. &lt;br /&gt;
&lt;br /&gt;
=== Get a review ===&lt;br /&gt;
&lt;br /&gt;
Nothing gets into the tree without a review, so you&#039;ll need one. The [[JavaScript:Hackers|SpiderMonkey hackers list]] is a good place to start: if your patch changes something listed as an area of expertise for someone there, that&#039;s a good person to ask for a review.&lt;br /&gt;
&lt;br /&gt;
Alternatively run &amp;lt;code&amp;gt;hg blame&amp;lt;/code&amp;gt; on the files you&#039;ve changed, and check who has been changing related code recently. They&#039;re likely to be good candidates. An irc bot can automate this process for a single file if you enter &amp;quot;/msg mrgiggles who can review something.cpp?&amp;quot; into your irc client.&lt;br /&gt;
&lt;br /&gt;
The review will consist of comments on your changes, suggesting or requesting alternative ways to do something and asking you to make changes where needed. They might also request additional changes, for example tests. Fix what they ask, resubmit the patch to bugzilla, and ask for another review. After you repeat this step a few times, they will mark the patch as &amp;quot;&amp;lt;code&amp;gt;r+&amp;lt;/code&amp;gt;&amp;quot; meaning it&#039;s now good to commit.&lt;br /&gt;
&lt;br /&gt;
=== Commit ===&lt;br /&gt;
&lt;br /&gt;
You can&#039;t commit to mozilla-central / mozilla-inbound until you have &amp;quot;level 3&amp;quot; access, so you&#039;ll need someone to do this for you. Try asking in [irc://irc.mozilla.org/#jsapi #jsapi], or add the &amp;lt;code&amp;gt;checkin-needed&amp;lt;/code&amp;gt; keyword to the bug. After you have been contributing for a while, you can get level 3 access by [https://www.mozilla.org/hacking/commit-access-policy/ applying for it].&lt;br /&gt;
&lt;br /&gt;
After committing, a large series of tests will be run to make sure you didn&#039;t break anything. You&#039;ll need to hang around to make sure you didn&#039;t break something. Check [http://tbpl.mozilla.org/?tree=Firefox the Firefox tree] for failures. Sometimes failures will be spurious: ask [irc://irc.mozilla.org/#jsapi for help] determining when this is the case, to start. (Over time you&#039;ll figure out when this is and isn&#039;t the case yourself.)&lt;br /&gt;
&lt;br /&gt;
== Overview of the JS engine ==&lt;br /&gt;
&lt;br /&gt;
The JS engine is a swiftly moving target. The most detailed information is available at https://developer.mozilla.org/en/SpiderMonkey. Here are some particularly interesting, mostly up-to-date resources:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== High level overviews ===&lt;br /&gt;
&lt;br /&gt;
(Outdated) http://hacks.mozilla.org/2010/03/a-quick-note-on-javascript-engine-components/&lt;br /&gt;
&lt;br /&gt;
https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Internals&lt;br /&gt;
&lt;br /&gt;
=== Medium level documentation ===&lt;br /&gt;
&lt;br /&gt;
jsapi.h: http://hg.mozilla.org/mozilla-central/file/tip/js/src/jsapi.h&lt;br /&gt;
&lt;br /&gt;
Frequently used coding recipes and mappings from JS idioms to SpiderMonkey code: https://developer.mozilla.org/En/SpiderMonkey/JSAPI_Cookbook&lt;br /&gt;
&lt;br /&gt;
=== Detailed documentation ===&lt;br /&gt;
&lt;br /&gt;
Build: https://developer.mozilla.org/en/SpiderMonkey/Build_Documentation&lt;br /&gt;
&lt;br /&gt;
Testing: https://developer.mozilla.org/en/SpiderMonkey/Running_Automated_JavaScript_Tests&lt;br /&gt;
&lt;br /&gt;
Shell: https://developer.mozilla.org/En/SpiderMonkey/Introduction_to_the_JavaScript_shell&lt;br /&gt;
&lt;br /&gt;
Function reference: https://developer.mozilla.org/en/SpiderMonkey/JSAPI_Reference&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Collaboration and teamwork ==&lt;br /&gt;
&lt;br /&gt;
=== Communication (in descending order of information content) ===&lt;br /&gt;
&lt;br /&gt;
Nearly all communication is handled through [https://bugzilla.mozilla.org Bugzilla]. All bugs, feature requests, issues, enhancements, etc, are all referred to as bugs. No code may enter the Mozilla repository without being a patch attached to a bugzilla bug first. To follow all SpiderMonkey related bugs:&lt;br /&gt;
&lt;br /&gt;
 Go to [https://bugzilla.mozilla.org/userprefs.cgi?tab=email email preferences]&lt;br /&gt;
 Watch the user general@spidermonkey.bugs&lt;br /&gt;
&lt;br /&gt;
SpiderMonkey contributors generally hang out in the very active [irc://irc.mozilla.org/jsapi #jsapi IRC channel].&lt;br /&gt;
&lt;br /&gt;
The [https://www.mozilla.org/about/forums/#dev-tech-js-engine-internals js-internals mailing list] is used for communicating with other SpiderMonkey hackers. (&amp;lt;i&amp;gt;Internals&amp;lt;/i&amp;gt; as in discussing the internals of the SpiderMonkey engine. All are welcome on the list.).&lt;br /&gt;
&lt;br /&gt;
Reading Planet Mozilla is the best way to keep up with the Mozilla project, which includes some SpiderMonkey related blogs:&lt;br /&gt;
&lt;br /&gt;
 [https://blog.mozilla.org/javascript General JavaScript blog]&lt;br /&gt;
 [http://blog.mozilla.com/jorendorff Jason Orendorff]&lt;br /&gt;
 [http://blog.mozilla.com/nnethercote/ Nicholas Nethercote]&lt;br /&gt;
 [http://whereswalden.com/ Jeff Walden]&lt;br /&gt;
 [https://itcouldbesomuchbetter.wordpress.com Jim Blandy]&lt;br /&gt;
 [https://jandemooij.nl/ Jan de Mooij]&lt;br /&gt;
 [https://h4writer.com/ Hannes Verschore]&lt;br /&gt;
 [http://rfrn.org/~shu/ Shu-yu Guo]&lt;br /&gt;
 [https://blog.benj.me/tag/mozilla.html Benjamin Bouvier]&lt;br /&gt;
&lt;br /&gt;
The [https://developer.mozilla.org/en/SpiderMonkey#Community js-engine mailing list] is generally used for communicating with people who embed SpiderMonkey, such as asking questions and announcing API changes. No actual development happens on the list.&lt;br /&gt;
&lt;br /&gt;
== Code considerations ==&lt;br /&gt;
&lt;br /&gt;
=== Repository ===&lt;br /&gt;
&lt;br /&gt;
Most active work on SpiderMonkey is done in the [http://hg.mozilla.org/mozilla-central mozilla-central] branch of the mozilla repository.&lt;br /&gt;
&lt;br /&gt;
=== Coding Style ===&lt;br /&gt;
&lt;br /&gt;
For many years, SpiderMonkey was written in C, and is gradually moving to C++. We still avoid many features such as run-time type information and virtual functions, but have come around to the glory of templates and namespaces relatively recently. Read the [[JavaScript:SpiderMonkey:C++ Coding Style|Coding Style]]. Do NOT read the portability guidelines, which I will not link to, since they are very out of date.&lt;br /&gt;
&lt;br /&gt;
=== Workflow ===&lt;br /&gt;
&lt;br /&gt;
Everything goes through bugzilla. We find a bug or have an idea, then submit it to bugzilla, then file patches to solve it. When it is solved, the patch is reviewed by team members, and is then committed to the [http://hg.mozilla.org/mozilla-central mozilla-central repository]. A link to the commit is then added as a comment to the bug.&lt;br /&gt;
&lt;br /&gt;
As well as committing to [http://hg.mozilla.org/mozilla-central mozilla-central], we also have the option of committing to [http://hg.mozilla.org/integration/mozilla-inbound mozilla-inbound], which is automatically merged to mozilla-central by a Sheriff. This exempts us from watching [http://tbpl.mozilla.org tinderbox] to check for errors in our patches, and commits are automatically backed out if errors are found.&lt;br /&gt;
&lt;br /&gt;
==== Sample Workflows ====&lt;br /&gt;
&lt;br /&gt;
(Outdated) [http://blog.mozilla.com/nnethercote/2009/07/27/how-i-work-on-tracemonkey/ Nicholas Nethercote: How I work on Tracemonkey]&lt;br /&gt;
&lt;br /&gt;
=== Policy ===&lt;br /&gt;
&lt;br /&gt;
The following docs are for the Mozilla project, and differ ever so slightly from what you should do for SpiderMonkey. For example, you should find reviewers in #jsapi rather than #developers.&lt;br /&gt;
&lt;br /&gt;
[http://www.mozilla.org/hacking/committer/ How to get commit access]&lt;br /&gt;
&lt;br /&gt;
[https://developer.mozilla.org/en/Creating_a_patch How to make patches]&lt;br /&gt;
&lt;br /&gt;
[https://developer.mozilla.org/En/Developer_Guide/How_to_Submit_a_Patch Submitting a patch]&lt;br /&gt;
&lt;br /&gt;
[https://developer.mozilla.org/en/Supported_build_configurations Supported Platforms]&lt;br /&gt;
&lt;br /&gt;
==== .hgrc file ====&lt;br /&gt;
&lt;br /&gt;
This .hgrc file contains a lot of the wisdom distilled through the wiki:&lt;br /&gt;
&lt;br /&gt;
 [extensions]&lt;br /&gt;
 mq =&lt;br /&gt;
 &lt;br /&gt;
 [ui]&lt;br /&gt;
 username = First Last &amp;lt;email@domain.tld&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
 [alias]&lt;br /&gt;
 qfulldiff = diff --rev qparent:.&lt;br /&gt;
 &lt;br /&gt;
 [defaults]&lt;br /&gt;
 diff = -p -U 8&lt;br /&gt;
 qdiff = -p -U 8&lt;br /&gt;
 qnew = -U&lt;br /&gt;
 commit = -v&lt;br /&gt;
 &lt;br /&gt;
 [diff]&lt;br /&gt;
 git = true&lt;br /&gt;
 showfunc = true&lt;br /&gt;
 unified = 8&lt;br /&gt;
 &lt;br /&gt;
 [paths]&lt;br /&gt;
 try = ssh://email@domain.tld@hg.mozilla.org/try/&lt;br /&gt;
&lt;br /&gt;
=== Try server  ===&lt;br /&gt;
&lt;br /&gt;
Often, you may be a little wary of breaking things. Mozilla has a [[Build:TryServer|Try Server]] where you can send a patch, and it&#039;ll be built and tested on tons of machines, which report to [http://tbpl.mozilla.org/?tree=Try TBPL]. Although you don&#039;t have [https://www.mozilla.org/hacking/commit-access-policy/ access] to TryServer just yet, you can get someone else to push it there for you. Just attach a patch to your bug, and ask in a comment, or on [irc://irc.mozilla.org/#jsapi #jsapi]. To be able to push to try-server yourself, you will need &amp;quot;level 1&amp;quot; access, which you can [https://www.mozilla.org/hacking/commit-access-policy/ request] once you&#039;ve contributed a patch or two.&lt;br /&gt;
&lt;br /&gt;
=== Mercurial Queues ===&lt;br /&gt;
&lt;br /&gt;
Since most of our lives revolve around patches, and we use Mercurial, nearly everybody uses Mercurial queues.&lt;br /&gt;
&lt;br /&gt;
Queues are based on the idea of patch management. Each queue consists of a series of patches, applied sequentially. The aim of the game is to split potential commits into simple, bite-sized chunks which are easy to review. This also makes it simple to experiment without polluting your existing work on a bug, to spin parts off into new bugs, and to rapidly apply and unapply patches (as demonstrated in the tutorial above).&lt;br /&gt;
&lt;br /&gt;
==== Enabling ====&lt;br /&gt;
&lt;br /&gt;
Add the following snippet to your .hgrc file to enable MQ&lt;br /&gt;
&lt;br /&gt;
 [extensions]&lt;br /&gt;
 mq =&lt;br /&gt;
&lt;br /&gt;
==== Example MQ workflow ====&lt;br /&gt;
&lt;br /&gt;
Clone the repository to deal with a bug:&lt;br /&gt;
&lt;br /&gt;
  hg clone http://hg.mozilla.org/mozilla-central&lt;br /&gt;
&lt;br /&gt;
Initialize your queue:&lt;br /&gt;
&lt;br /&gt;
  hg qinit -c&lt;br /&gt;
&lt;br /&gt;
Create a new patch, with some name:&lt;br /&gt;
&lt;br /&gt;
  hg qnew first_attempt&lt;br /&gt;
&lt;br /&gt;
Work on the patch, try to fix the bug, test, compile, etc.&lt;br /&gt;
&lt;br /&gt;
Refresh (save your work into the patch):&lt;br /&gt;
&lt;br /&gt;
 hg qrefresh&lt;br /&gt;
&lt;br /&gt;
Repeat a few times.&lt;br /&gt;
&lt;br /&gt;
Rename the patch (because your first name wasn&#039;t appliable):&lt;br /&gt;
&lt;br /&gt;
 hg qrename refactor_the_whatsit&lt;br /&gt;
&lt;br /&gt;
Create a new patch to try a logically separate part of the same bug:&lt;br /&gt;
&lt;br /&gt;
 hg qnew rip_out_the_old_thing&lt;br /&gt;
&lt;br /&gt;
Repeat the process a few times, until you have solved the problem. During this time, it can often be useful to go back and forth between patches:&lt;br /&gt;
&lt;br /&gt;
 hg qpop # unapply a patch&lt;br /&gt;
 hg qpush # reapply a patch&lt;br /&gt;
 hg qpop -a # unapply all patches&lt;br /&gt;
 hg qpush -a # reapply all patches&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Combine all the patches into a single patch, which you submit to bugzilla:&lt;br /&gt;
&lt;br /&gt;
 hg qpush -a&lt;br /&gt;
 hg qdiff --rev qparent:. &amp;gt; my_wonderful_patch.patch&lt;br /&gt;
&lt;br /&gt;
Commit the patches to your local patch repository, in case you make a mistake (You might do this periodically):&lt;br /&gt;
&lt;br /&gt;
 hg qcommit -m &amp;quot;Some message. Doesn&#039;t have to be good, this won&#039;t be committed to the repository, it&#039;s just for you&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Go back to the old patches and fiddle with them based on feedback:&lt;br /&gt;
&lt;br /&gt;
 hg qpop&lt;br /&gt;
 hg qrefresh&lt;br /&gt;
 etc&lt;br /&gt;
&lt;br /&gt;
There are some more complex techniques that we won&#039;t go into in detail. You can enable only some patches using qguard and qselect, and you can reorder the patches by manually editing the .hg/patches/series file. But be careful!&lt;br /&gt;
&lt;br /&gt;
[[Category:New Contributor Landing Page]]&lt;/div&gt;</summary>
		<author><name>Sfink</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=JavaScript:New_to_SpiderMonkey&amp;diff=1150951</id>
		<title>JavaScript:New to SpiderMonkey</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=JavaScript:New_to_SpiderMonkey&amp;diff=1150951"/>
		<updated>2016-10-11T15:37:36Z</updated>

		<summary type="html">&lt;p&gt;Sfink: /* Baseline version / Mercurial Queues */ the sequencing of the wording was awkward&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Tutorial: your first patch  ==&lt;br /&gt;
&lt;br /&gt;
The first step to getting involved with SpiderMonkey is to make your first patch. This guides you through it, and at the end you should have learnt a lot of the procedures and formalisms involved in getting things done here.&lt;br /&gt;
&lt;br /&gt;
We&#039;ll assume you&#039;re on a Unix-y platform, and that you know what you&#039;re doing. We&#039;ll ignore nearly all details. &lt;br /&gt;
&lt;br /&gt;
=== Get the code ===&lt;br /&gt;
&lt;br /&gt;
Spidermonkey development happens in the &amp;quot;mozilla-central&amp;quot; mercurial repository:&lt;br /&gt;
&lt;br /&gt;
 hg clone http://hg.mozilla.org/mozilla-central spidermonkey&lt;br /&gt;
&lt;br /&gt;
=== Build the js shell ===&lt;br /&gt;
&lt;br /&gt;
Most of the time, you&#039;ll be working with the Javascript shell, instead of the full Firefox browser. So build the shell: &lt;br /&gt;
&lt;br /&gt;
 cd spidermonkey/js/src&lt;br /&gt;
 cp configure.in configure &amp;amp;&amp;amp; chmod +x configure # or autoconf2.13 or autoconf-2.13&lt;br /&gt;
 mkdir build_DBG.OBJ &lt;br /&gt;
 cd build_DBG.OBJ &lt;br /&gt;
 ../configure --enable-debug --disable-optimize&lt;br /&gt;
 make # or make -j8&lt;br /&gt;
 cd ..&lt;br /&gt;
&lt;br /&gt;
If you&#039;re having trouble or are missing dependencies, refer to [https://developer.mozilla.org/en/SpiderMonkey/Build_Documentation#Building_SpiderMonkey_tip Building SpiderMonkey Tip].&lt;br /&gt;
&lt;br /&gt;
=== Fix something ===&lt;br /&gt;
&lt;br /&gt;
At this point, you&#039;re ready to make your first fix. &lt;br /&gt;
&lt;br /&gt;
 TODO: something useless. Maybe adding a datemicrosecond function.&lt;br /&gt;
&lt;br /&gt;
==== Building your changes ====&lt;br /&gt;
&lt;br /&gt;
Having made the change, build the shell again. &lt;br /&gt;
&lt;br /&gt;
 make -C build_DBG.OBJ&lt;br /&gt;
&lt;br /&gt;
==== Testing your changes ====&lt;br /&gt;
&lt;br /&gt;
It builds. Hurray. Time to run the tests to check you haven&#039;t broken anything. &lt;br /&gt;
&lt;br /&gt;
 jit-test/jit_test.py build_DBG.OBJ/dist/bin/js&lt;br /&gt;
(The location of the shell has changed, it used to be build_DBG.OBJ/js)&lt;br /&gt;
&lt;br /&gt;
The jit-tests are pretty quick, and should give you an idea if you&#039;ve gotten something wrong. Assuming nothing goes wrong, try the ref-tests: &lt;br /&gt;
&lt;br /&gt;
 tests/jstests.py build_DBG.OBJ/dist/bin/js&lt;br /&gt;
&lt;br /&gt;
Note that some of these tests fail depending on the timezone and locale they&#039;re run in, so if you get any errors that don&#039;t seem related to your changes, re-run the tests with a shell build without your changes applied and compare the results.&lt;br /&gt;
&lt;br /&gt;
==== Benchmark your changes ====&lt;br /&gt;
&lt;br /&gt;
Tests all pass. Congrats, you didn&#039;t break anything. Now, did you make it faster or slower? We benchmark using the v8 and SunSpider benchmarks. Get the benchmarks: &lt;br /&gt;
&lt;br /&gt;
 svn checkout http://svn.webkit.org/repository/webkit/trunk/PerformanceTests/SunSpider&lt;br /&gt;
&lt;br /&gt;
And now run them: &lt;br /&gt;
&lt;br /&gt;
 cd SunSpider &lt;br /&gt;
 ./sunspider --shell=../build_DBG.OBJ/dist/bin/js --run=30 --suite=sunspider-0.9.1 &lt;br /&gt;
 cd ..&lt;br /&gt;
&lt;br /&gt;
===== Optimized build =====&lt;br /&gt;
&lt;br /&gt;
Whoops, we benchmarked the debug version. Let&#039;s make an optimized build to test instead.&lt;br /&gt;
&lt;br /&gt;
 mkdir build_OPT.OBJ &lt;br /&gt;
 cd build_OPT.OBJ &lt;br /&gt;
 ../configure --disable-debug --enable-optimize&lt;br /&gt;
 make &lt;br /&gt;
 cd ..&lt;br /&gt;
&lt;br /&gt;
Repeat the sunspider steps above, and take note of the line that looks like: &lt;br /&gt;
&lt;br /&gt;
 Results are located at sunspider-0.9.1-results/sunspider-results-2010-08-07-17.56.48.js&lt;br /&gt;
&lt;br /&gt;
You&#039;ll need that later. &lt;br /&gt;
&lt;br /&gt;
===== Baseline version / Mercurial Queues =====&lt;br /&gt;
&lt;br /&gt;
We need to time our optimized version against the baseline version. This calls for a brief introduction to mercurial queues, which used to be the way most people managed their SpiderMonkey workflow (though these days many people use native hg, native hg + evolution, or git):&lt;br /&gt;
&lt;br /&gt;
 hg qinit&lt;br /&gt;
 hg qnew my_first_patch -f&lt;br /&gt;
 hg qrefresh&lt;br /&gt;
&lt;br /&gt;
This puts your current work into a patch, managed by Mercurial, symbolically called my_first_patch. To pop the patch off: &lt;br /&gt;
&lt;br /&gt;
 hg qpop&lt;br /&gt;
&lt;br /&gt;
And we&#039;re back to our pristine version.&lt;br /&gt;
&lt;br /&gt;
===== Compare =====&lt;br /&gt;
&lt;br /&gt;
Build again and rerun SunSpider again. You should now have two files like: &lt;br /&gt;
&lt;br /&gt;
 sunspider-0.9.1-results/sunspider-results-2010-08-07-17.56.48.js&lt;br /&gt;
&lt;br /&gt;
Compare them using the compare script: &lt;br /&gt;
&lt;br /&gt;
 cd SunSpider &lt;br /&gt;
 ./sunspider-compare-results --shell=../build_DBG.OBJ/js --suite=sunspider-0.9.1 FILE1-withoutPatch FILE2-withPatch&lt;br /&gt;
&lt;br /&gt;
=== Get a real bug  ===&lt;br /&gt;
&lt;br /&gt;
At this point, you&#039;ve seen nearly everything you need to do hack on SpiderMonkey. So it&#039;s time to get a real bug to work on. You can get a bug on [http://www.joshmatthews.net/bugsahoy/?jseng=1&amp;amp;unowned=1 Bugs Ahoy].&lt;br /&gt;
&lt;br /&gt;
Fix the bug, updating the bug report with your progress, and asking questions as you go (either in the bug comments, or in [irc://irc.mozilla.org/#jsapi #jsapi]). When it&#039;s done, repeat all the steps above. Then it&#039;s time to get your patch into the tree.&lt;br /&gt;
&lt;br /&gt;
=== Submit a patch  ===&lt;br /&gt;
&lt;br /&gt;
To get the patch from mercurial, use: &lt;br /&gt;
&lt;br /&gt;
 hg qdiff # if you&#039;re using queues or&lt;br /&gt;
 hg diff  # if you&#039;re not&lt;br /&gt;
&lt;br /&gt;
Add it to the bug as an attachment. &lt;br /&gt;
&lt;br /&gt;
=== Get a review ===&lt;br /&gt;
&lt;br /&gt;
Nothing gets into the tree without a review, so you&#039;ll need one. The [[JavaScript:Hackers|SpiderMonkey hackers list]] is a good place to start: if your patch changes something listed as an area of expertise for someone there, that&#039;s a good person to ask for a review.&lt;br /&gt;
&lt;br /&gt;
Alternatively run &amp;lt;code&amp;gt;hg blame&amp;lt;/code&amp;gt; on the files you&#039;ve changed, and check who has been changing related code recently. They&#039;re likely to be good candidates.&lt;br /&gt;
&lt;br /&gt;
The review will consist of comments on your changes, suggesting or requesting alternative ways to do something and asking you to make changes where needed. They might also request additional changes, for example tests. Fix what they ask, resubmit the patch to bugzilla, and ask for another review. After you repeat this step a few times, they&#039;re mark the patch as &amp;quot;&amp;lt;code&amp;gt;r+&amp;lt;/code&amp;gt;&amp;quot; meaning it&#039;s now good to commit.&lt;br /&gt;
&lt;br /&gt;
=== Commit ===&lt;br /&gt;
&lt;br /&gt;
You can&#039;t commit to mozilla-central / mozilla-inbound until you have &amp;quot;level 3&amp;quot; access, so you&#039;ll need someone to do this for you. Try asking in [irc://irc.mozilla.org/#jsapi #jsapi], or add the &amp;lt;code&amp;gt;checkin-needed&amp;lt;/code&amp;gt; keyword to the bug. After you have been contributing for a while, you can get level 3 access by [https://www.mozilla.org/hacking/commit-access-policy/ applying for it].&lt;br /&gt;
&lt;br /&gt;
After committing, a large series of tests will be run to make sure you didn&#039;t break anything. You&#039;ll need to hang around to make sure you didn&#039;t break something. Check [http://tbpl.mozilla.org/?tree=Firefox the Firefox tree] for failures. Sometimes failures will be spurious: ask [irc://irc.mozilla.org/#jsapi for help] determining when this is the case, to start. (Over time you&#039;ll figure out when this is and isn&#039;t the case yourself.)&lt;br /&gt;
&lt;br /&gt;
== Overview of the JS engine ==&lt;br /&gt;
&lt;br /&gt;
The JS engine is a swiftly moving target. The most detailed information is available at https://developer.mozilla.org/en/SpiderMonkey. Here are some particularly interesting, mostly up-to-date resources:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== High level overviews ===&lt;br /&gt;
&lt;br /&gt;
(Outdated) http://hacks.mozilla.org/2010/03/a-quick-note-on-javascript-engine-components/&lt;br /&gt;
&lt;br /&gt;
https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Internals&lt;br /&gt;
&lt;br /&gt;
=== Medium level documentation ===&lt;br /&gt;
&lt;br /&gt;
jsapi.h: http://hg.mozilla.org/mozilla-central/file/tip/js/src/jsapi.h&lt;br /&gt;
&lt;br /&gt;
Frequently used coding recipes and mappings from JS idioms to SpiderMonkey code: https://developer.mozilla.org/En/SpiderMonkey/JSAPI_Cookbook&lt;br /&gt;
&lt;br /&gt;
=== Detailed documentation ===&lt;br /&gt;
&lt;br /&gt;
Build: https://developer.mozilla.org/en/SpiderMonkey/Build_Documentation&lt;br /&gt;
&lt;br /&gt;
Testing: https://developer.mozilla.org/en/SpiderMonkey/Running_Automated_JavaScript_Tests&lt;br /&gt;
&lt;br /&gt;
Shell: https://developer.mozilla.org/En/SpiderMonkey/Introduction_to_the_JavaScript_shell&lt;br /&gt;
&lt;br /&gt;
Function reference: https://developer.mozilla.org/en/SpiderMonkey/JSAPI_Reference&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Collaboration and teamwork ==&lt;br /&gt;
&lt;br /&gt;
=== Communication (in descending order of information content) ===&lt;br /&gt;
&lt;br /&gt;
Nearly all communication is handled through [https://bugzilla.mozilla.org Bugzilla]. All bugs, feature requests, issues, enhancements, etc, are all referred to as bugs. No code may enter the Mozilla repository without being a patch attached to a bugzilla bug first. To follow all SpiderMonkey related bugs:&lt;br /&gt;
&lt;br /&gt;
 Go to [https://bugzilla.mozilla.org/userprefs.cgi?tab=email email preferences]&lt;br /&gt;
 Watch the user general@spidermonkey.bugs&lt;br /&gt;
&lt;br /&gt;
SpiderMonkey contributors generally hang out in the very active [irc://irc.mozilla.org/jsapi #jsapi IRC channel].&lt;br /&gt;
&lt;br /&gt;
The [https://www.mozilla.org/about/forums/#dev-tech-js-engine-internals js-internals mailing list] is used for communicating with other SpiderMonkey hackers. (&amp;lt;i&amp;gt;Internals&amp;lt;/i&amp;gt; as in discussing the internals of the SpiderMonkey engine. All are welcome on the list.).&lt;br /&gt;
&lt;br /&gt;
Reading Planet Mozilla is the best way to keep up with the Mozilla project, which includes some SpiderMonkey related blogs:&lt;br /&gt;
&lt;br /&gt;
 [https://blog.mozilla.org/javascript General JavaScript blog]&lt;br /&gt;
 [http://blog.mozilla.com/jorendorff Jason Orendorff]&lt;br /&gt;
 [http://blog.mozilla.com/nnethercote/ Nicholas Nethercote]&lt;br /&gt;
 [http://whereswalden.com/ Jeff Walden]&lt;br /&gt;
 [https://itcouldbesomuchbetter.wordpress.com Jim Blandy]&lt;br /&gt;
 [https://jandemooij.nl/ Jan de Mooij]&lt;br /&gt;
 [https://h4writer.com/ Hannes Verschore]&lt;br /&gt;
 [http://rfrn.org/~shu/ Shu-yu Guo]&lt;br /&gt;
 [https://blog.benj.me/tag/mozilla.html Benjamin Bouvier]&lt;br /&gt;
&lt;br /&gt;
The [https://developer.mozilla.org/en/SpiderMonkey#Community js-engine mailing list] is generally used for communicating with people who embed SpiderMonkey, such as asking questions and announcing API changes. No actual development happens on the list.&lt;br /&gt;
&lt;br /&gt;
== Code considerations ==&lt;br /&gt;
&lt;br /&gt;
=== Repository ===&lt;br /&gt;
&lt;br /&gt;
Most active work on SpiderMonkey is done in the [http://hg.mozilla.org/mozilla-central mozilla-central] branch of the mozilla repository.&lt;br /&gt;
&lt;br /&gt;
=== Coding Style ===&lt;br /&gt;
&lt;br /&gt;
For many years, SpiderMonkey was written in C, and is gradually moving to C++. We still avoid many features such as run-time type information and virtual functions, but have come around to the glory of templates and namespaces relatively recently. Read the [[JavaScript:SpiderMonkey:C++ Coding Style|Coding Style]]. Do NOT read the portability guidelines, which I will not link to, since they are very out of date.&lt;br /&gt;
&lt;br /&gt;
=== Workflow ===&lt;br /&gt;
&lt;br /&gt;
Everything goes through bugzilla. We find a bug or have an idea, then submit it to bugzilla, then file patches to solve it. When it is solved, the patch is reviewed by team members, and is then committed to the [http://hg.mozilla.org/mozilla-central mozilla-central repository]. A link to the commit is then added as a comment to the bug.&lt;br /&gt;
&lt;br /&gt;
As well as committing to [http://hg.mozilla.org/mozilla-central mozilla-central], we also have the option of committing to [http://hg.mozilla.org/integration/mozilla-inbound mozilla-inbound], which is automatically merged to mozilla-central by a Sheriff. This exempts us from watching [http://tbpl.mozilla.org tinderbox] to check for errors in our patches, and commits are automatically backed out if errors are found.&lt;br /&gt;
&lt;br /&gt;
==== Sample Workflows ====&lt;br /&gt;
&lt;br /&gt;
(Outdated) [http://blog.mozilla.com/nnethercote/2009/07/27/how-i-work-on-tracemonkey/ Nicholas Nethercote: How I work on Tracemonkey]&lt;br /&gt;
&lt;br /&gt;
=== Policy ===&lt;br /&gt;
&lt;br /&gt;
The following docs are for the Mozilla project, and differ ever so slightly from what you should do for SpiderMonkey. For example, you should find reviewers in #jsapi rather than #developers.&lt;br /&gt;
&lt;br /&gt;
[http://www.mozilla.org/hacking/committer/ How to get commit access]&lt;br /&gt;
&lt;br /&gt;
[https://developer.mozilla.org/en/Creating_a_patch How to make patches]&lt;br /&gt;
&lt;br /&gt;
[https://developer.mozilla.org/En/Developer_Guide/How_to_Submit_a_Patch Submitting a patch]&lt;br /&gt;
&lt;br /&gt;
[https://developer.mozilla.org/en/Supported_build_configurations Supported Platforms]&lt;br /&gt;
&lt;br /&gt;
==== .hgrc file ====&lt;br /&gt;
&lt;br /&gt;
This .hgrc file contains a lot of the wisdom distilled through the wiki:&lt;br /&gt;
&lt;br /&gt;
 [extensions]&lt;br /&gt;
 mq =&lt;br /&gt;
 &lt;br /&gt;
 [ui]&lt;br /&gt;
 username = First Last &amp;lt;email@domain.tld&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
 [alias]&lt;br /&gt;
 qfulldiff = diff --rev qparent:.&lt;br /&gt;
 &lt;br /&gt;
 [defaults]&lt;br /&gt;
 diff = -p -U 8&lt;br /&gt;
 qdiff = -p -U 8&lt;br /&gt;
 qnew = -U&lt;br /&gt;
 commit = -v&lt;br /&gt;
 &lt;br /&gt;
 [diff]&lt;br /&gt;
 git = true&lt;br /&gt;
 showfunc = true&lt;br /&gt;
 unified = 8&lt;br /&gt;
 &lt;br /&gt;
 [paths]&lt;br /&gt;
 try = ssh://email@domain.tld@hg.mozilla.org/try/&lt;br /&gt;
&lt;br /&gt;
=== Try server  ===&lt;br /&gt;
&lt;br /&gt;
Often, you may be a little wary of breaking things. Mozilla has a [[Build:TryServer|Try Server]] where you can send a patch, and it&#039;ll be built and tested on tons of machines, which report to [http://tbpl.mozilla.org/?tree=Try TBPL]. Although you don&#039;t have [https://www.mozilla.org/hacking/commit-access-policy/ access] to TryServer just yet, you can get someone else to push it there for you. Just attach a patch to your bug, and ask in a comment, or on [irc://irc.mozilla.org/#jsapi #jsapi]. To be able to push to try-server yourself, you will need &amp;quot;level 1&amp;quot; access, which you can [https://www.mozilla.org/hacking/commit-access-policy/ request] once you&#039;ve contributed a patch or two.&lt;br /&gt;
&lt;br /&gt;
=== Mercurial Queues ===&lt;br /&gt;
&lt;br /&gt;
Since most of our lives revolve around patches, and we use Mercurial, nearly everybody uses Mercurial queues.&lt;br /&gt;
&lt;br /&gt;
Queues are based on the idea of patch management. Each queue consists of a series of patches, applied sequentially. The aim of the game is to split potential commits into simple, bite-sized chunks which are easy to review. This also makes it simple to experiment without polluting your existing work on a bug, to spin parts off into new bugs, and to rapidly apply and unapply patches (as demonstrated in the tutorial above).&lt;br /&gt;
&lt;br /&gt;
==== Enabling ====&lt;br /&gt;
&lt;br /&gt;
Add the following snippet to your .hgrc file to enable MQ&lt;br /&gt;
&lt;br /&gt;
 [extensions]&lt;br /&gt;
 mq =&lt;br /&gt;
&lt;br /&gt;
==== Example MQ workflow ====&lt;br /&gt;
&lt;br /&gt;
Clone the repository to deal with a bug:&lt;br /&gt;
&lt;br /&gt;
  hg clone http://hg.mozilla.org/mozilla-central&lt;br /&gt;
&lt;br /&gt;
Initialize your queue:&lt;br /&gt;
&lt;br /&gt;
  hg qinit -c&lt;br /&gt;
&lt;br /&gt;
Create a new patch, with some name:&lt;br /&gt;
&lt;br /&gt;
  hg qnew first_attempt&lt;br /&gt;
&lt;br /&gt;
Work on the patch, try to fix the bug, test, compile, etc.&lt;br /&gt;
&lt;br /&gt;
Refresh (save your work into the patch):&lt;br /&gt;
&lt;br /&gt;
 hg qrefresh&lt;br /&gt;
&lt;br /&gt;
Repeat a few times.&lt;br /&gt;
&lt;br /&gt;
Rename the patch (because your first name wasn&#039;t appliable):&lt;br /&gt;
&lt;br /&gt;
 hg qrename refactor_the_whatsit&lt;br /&gt;
&lt;br /&gt;
Create a new patch to try a logically separate part of the same bug:&lt;br /&gt;
&lt;br /&gt;
 hg qnew rip_out_the_old_thing&lt;br /&gt;
&lt;br /&gt;
Repeat the process a few times, until you have solved the problem. During this time, it can often be useful to go back and forth between patches:&lt;br /&gt;
&lt;br /&gt;
 hg qpop # unapply a patch&lt;br /&gt;
 hg qpush # reapply a patch&lt;br /&gt;
 hg qpop -a # unapply all patches&lt;br /&gt;
 hg qpush -a # reapply all patches&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Combine all the patches into a single patch, which you submit to bugzilla:&lt;br /&gt;
&lt;br /&gt;
 hg qpush -a&lt;br /&gt;
 hg qdiff --rev qparent:. &amp;gt; my_wonderful_patch.patch&lt;br /&gt;
&lt;br /&gt;
Commit the patches to your local patch repository, in case you make a mistake (You might do this periodically):&lt;br /&gt;
&lt;br /&gt;
 hg qcommit -m &amp;quot;Some message. Doesn&#039;t have to be good, this won&#039;t be committed to the repository, it&#039;s just for you&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Go back to the old patches and fiddle with them based on feedback:&lt;br /&gt;
&lt;br /&gt;
 hg qpop&lt;br /&gt;
 hg qrefresh&lt;br /&gt;
 etc&lt;br /&gt;
&lt;br /&gt;
There are some more complex techniques that we won&#039;t go into in detail. You can enable only some patches using qguard and qselect, and you can reorder the patches by manually editing the .hg/patches/series file. But be careful!&lt;br /&gt;
&lt;br /&gt;
[[Category:New Contributor Landing Page]]&lt;/div&gt;</summary>
		<author><name>Sfink</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=JavaScript:New_to_SpiderMonkey&amp;diff=1150949</id>
		<title>JavaScript:New to SpiderMonkey</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=JavaScript:New_to_SpiderMonkey&amp;diff=1150949"/>
		<updated>2016-10-11T15:36:49Z</updated>

		<summary type="html">&lt;p&gt;Sfink: /* Baseline version / Mercurial Queues */ mq is kinda deprecated&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Tutorial: your first patch  ==&lt;br /&gt;
&lt;br /&gt;
The first step to getting involved with SpiderMonkey is to make your first patch. This guides you through it, and at the end you should have learnt a lot of the procedures and formalisms involved in getting things done here.&lt;br /&gt;
&lt;br /&gt;
We&#039;ll assume you&#039;re on a Unix-y platform, and that you know what you&#039;re doing. We&#039;ll ignore nearly all details. &lt;br /&gt;
&lt;br /&gt;
=== Get the code ===&lt;br /&gt;
&lt;br /&gt;
Spidermonkey development happens in the &amp;quot;mozilla-central&amp;quot; mercurial repository:&lt;br /&gt;
&lt;br /&gt;
 hg clone http://hg.mozilla.org/mozilla-central spidermonkey&lt;br /&gt;
&lt;br /&gt;
=== Build the js shell ===&lt;br /&gt;
&lt;br /&gt;
Most of the time, you&#039;ll be working with the Javascript shell, instead of the full Firefox browser. So build the shell: &lt;br /&gt;
&lt;br /&gt;
 cd spidermonkey/js/src&lt;br /&gt;
 cp configure.in configure &amp;amp;&amp;amp; chmod +x configure # or autoconf2.13 or autoconf-2.13&lt;br /&gt;
 mkdir build_DBG.OBJ &lt;br /&gt;
 cd build_DBG.OBJ &lt;br /&gt;
 ../configure --enable-debug --disable-optimize&lt;br /&gt;
 make # or make -j8&lt;br /&gt;
 cd ..&lt;br /&gt;
&lt;br /&gt;
If you&#039;re having trouble or are missing dependencies, refer to [https://developer.mozilla.org/en/SpiderMonkey/Build_Documentation#Building_SpiderMonkey_tip Building SpiderMonkey Tip].&lt;br /&gt;
&lt;br /&gt;
=== Fix something ===&lt;br /&gt;
&lt;br /&gt;
At this point, you&#039;re ready to make your first fix. &lt;br /&gt;
&lt;br /&gt;
 TODO: something useless. Maybe adding a datemicrosecond function.&lt;br /&gt;
&lt;br /&gt;
==== Building your changes ====&lt;br /&gt;
&lt;br /&gt;
Having made the change, build the shell again. &lt;br /&gt;
&lt;br /&gt;
 make -C build_DBG.OBJ&lt;br /&gt;
&lt;br /&gt;
==== Testing your changes ====&lt;br /&gt;
&lt;br /&gt;
It builds. Hurray. Time to run the tests to check you haven&#039;t broken anything. &lt;br /&gt;
&lt;br /&gt;
 jit-test/jit_test.py build_DBG.OBJ/dist/bin/js&lt;br /&gt;
(The location of the shell has changed, it used to be build_DBG.OBJ/js)&lt;br /&gt;
&lt;br /&gt;
The jit-tests are pretty quick, and should give you an idea if you&#039;ve gotten something wrong. Assuming nothing goes wrong, try the ref-tests: &lt;br /&gt;
&lt;br /&gt;
 tests/jstests.py build_DBG.OBJ/dist/bin/js&lt;br /&gt;
&lt;br /&gt;
Note that some of these tests fail depending on the timezone and locale they&#039;re run in, so if you get any errors that don&#039;t seem related to your changes, re-run the tests with a shell build without your changes applied and compare the results.&lt;br /&gt;
&lt;br /&gt;
==== Benchmark your changes ====&lt;br /&gt;
&lt;br /&gt;
Tests all pass. Congrats, you didn&#039;t break anything. Now, did you make it faster or slower? We benchmark using the v8 and SunSpider benchmarks. Get the benchmarks: &lt;br /&gt;
&lt;br /&gt;
 svn checkout http://svn.webkit.org/repository/webkit/trunk/PerformanceTests/SunSpider&lt;br /&gt;
&lt;br /&gt;
And now run them: &lt;br /&gt;
&lt;br /&gt;
 cd SunSpider &lt;br /&gt;
 ./sunspider --shell=../build_DBG.OBJ/dist/bin/js --run=30 --suite=sunspider-0.9.1 &lt;br /&gt;
 cd ..&lt;br /&gt;
&lt;br /&gt;
===== Optimized build =====&lt;br /&gt;
&lt;br /&gt;
Whoops, we benchmarked the debug version. Let&#039;s make an optimized build to test instead.&lt;br /&gt;
&lt;br /&gt;
 mkdir build_OPT.OBJ &lt;br /&gt;
 cd build_OPT.OBJ &lt;br /&gt;
 ../configure --disable-debug --enable-optimize&lt;br /&gt;
 make &lt;br /&gt;
 cd ..&lt;br /&gt;
&lt;br /&gt;
Repeat the sunspider steps above, and take note of the line that looks like: &lt;br /&gt;
&lt;br /&gt;
 Results are located at sunspider-0.9.1-results/sunspider-results-2010-08-07-17.56.48.js&lt;br /&gt;
&lt;br /&gt;
You&#039;ll need that later. &lt;br /&gt;
&lt;br /&gt;
===== Baseline version / Mercurial Queues =====&lt;br /&gt;
&lt;br /&gt;
We need to time our optimized version against the baseline version. This calls for a brief introduction to mercurial queues, which used to be the way most people managed their SpiderMonkey workflow, though these days people use native hg, native hg + evolution, or git: &lt;br /&gt;
&lt;br /&gt;
 hg qinit&lt;br /&gt;
 hg qnew my_first_patch -f&lt;br /&gt;
 hg qrefresh&lt;br /&gt;
&lt;br /&gt;
This puts your current work into a patch, managed by Mercurial, symbolically called my_first_patch. To pop the patch off: &lt;br /&gt;
&lt;br /&gt;
 hg qpop&lt;br /&gt;
&lt;br /&gt;
And we&#039;re back to our pristine version.&lt;br /&gt;
&lt;br /&gt;
===== Compare =====&lt;br /&gt;
&lt;br /&gt;
Build again and rerun SunSpider again. You should now have two files like: &lt;br /&gt;
&lt;br /&gt;
 sunspider-0.9.1-results/sunspider-results-2010-08-07-17.56.48.js&lt;br /&gt;
&lt;br /&gt;
Compare them using the compare script: &lt;br /&gt;
&lt;br /&gt;
 cd SunSpider &lt;br /&gt;
 ./sunspider-compare-results --shell=../build_DBG.OBJ/js --suite=sunspider-0.9.1 FILE1-withoutPatch FILE2-withPatch&lt;br /&gt;
&lt;br /&gt;
=== Get a real bug  ===&lt;br /&gt;
&lt;br /&gt;
At this point, you&#039;ve seen nearly everything you need to do hack on SpiderMonkey. So it&#039;s time to get a real bug to work on. You can get a bug on [http://www.joshmatthews.net/bugsahoy/?jseng=1&amp;amp;unowned=1 Bugs Ahoy].&lt;br /&gt;
&lt;br /&gt;
Fix the bug, updating the bug report with your progress, and asking questions as you go (either in the bug comments, or in [irc://irc.mozilla.org/#jsapi #jsapi]). When it&#039;s done, repeat all the steps above. Then it&#039;s time to get your patch into the tree.&lt;br /&gt;
&lt;br /&gt;
=== Submit a patch  ===&lt;br /&gt;
&lt;br /&gt;
To get the patch from mercurial, use: &lt;br /&gt;
&lt;br /&gt;
 hg qdiff # if you&#039;re using queues or&lt;br /&gt;
 hg diff  # if you&#039;re not&lt;br /&gt;
&lt;br /&gt;
Add it to the bug as an attachment. &lt;br /&gt;
&lt;br /&gt;
=== Get a review ===&lt;br /&gt;
&lt;br /&gt;
Nothing gets into the tree without a review, so you&#039;ll need one. The [[JavaScript:Hackers|SpiderMonkey hackers list]] is a good place to start: if your patch changes something listed as an area of expertise for someone there, that&#039;s a good person to ask for a review.&lt;br /&gt;
&lt;br /&gt;
Alternatively run &amp;lt;code&amp;gt;hg blame&amp;lt;/code&amp;gt; on the files you&#039;ve changed, and check who has been changing related code recently. They&#039;re likely to be good candidates.&lt;br /&gt;
&lt;br /&gt;
The review will consist of comments on your changes, suggesting or requesting alternative ways to do something and asking you to make changes where needed. They might also request additional changes, for example tests. Fix what they ask, resubmit the patch to bugzilla, and ask for another review. After you repeat this step a few times, they&#039;re mark the patch as &amp;quot;&amp;lt;code&amp;gt;r+&amp;lt;/code&amp;gt;&amp;quot; meaning it&#039;s now good to commit.&lt;br /&gt;
&lt;br /&gt;
=== Commit ===&lt;br /&gt;
&lt;br /&gt;
You can&#039;t commit to mozilla-central / mozilla-inbound until you have &amp;quot;level 3&amp;quot; access, so you&#039;ll need someone to do this for you. Try asking in [irc://irc.mozilla.org/#jsapi #jsapi], or add the &amp;lt;code&amp;gt;checkin-needed&amp;lt;/code&amp;gt; keyword to the bug. After you have been contributing for a while, you can get level 3 access by [https://www.mozilla.org/hacking/commit-access-policy/ applying for it].&lt;br /&gt;
&lt;br /&gt;
After committing, a large series of tests will be run to make sure you didn&#039;t break anything. You&#039;ll need to hang around to make sure you didn&#039;t break something. Check [http://tbpl.mozilla.org/?tree=Firefox the Firefox tree] for failures. Sometimes failures will be spurious: ask [irc://irc.mozilla.org/#jsapi for help] determining when this is the case, to start. (Over time you&#039;ll figure out when this is and isn&#039;t the case yourself.)&lt;br /&gt;
&lt;br /&gt;
== Overview of the JS engine ==&lt;br /&gt;
&lt;br /&gt;
The JS engine is a swiftly moving target. The most detailed information is available at https://developer.mozilla.org/en/SpiderMonkey. Here are some particularly interesting, mostly up-to-date resources:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== High level overviews ===&lt;br /&gt;
&lt;br /&gt;
(Outdated) http://hacks.mozilla.org/2010/03/a-quick-note-on-javascript-engine-components/&lt;br /&gt;
&lt;br /&gt;
https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Internals&lt;br /&gt;
&lt;br /&gt;
=== Medium level documentation ===&lt;br /&gt;
&lt;br /&gt;
jsapi.h: http://hg.mozilla.org/mozilla-central/file/tip/js/src/jsapi.h&lt;br /&gt;
&lt;br /&gt;
Frequently used coding recipes and mappings from JS idioms to SpiderMonkey code: https://developer.mozilla.org/En/SpiderMonkey/JSAPI_Cookbook&lt;br /&gt;
&lt;br /&gt;
=== Detailed documentation ===&lt;br /&gt;
&lt;br /&gt;
Build: https://developer.mozilla.org/en/SpiderMonkey/Build_Documentation&lt;br /&gt;
&lt;br /&gt;
Testing: https://developer.mozilla.org/en/SpiderMonkey/Running_Automated_JavaScript_Tests&lt;br /&gt;
&lt;br /&gt;
Shell: https://developer.mozilla.org/En/SpiderMonkey/Introduction_to_the_JavaScript_shell&lt;br /&gt;
&lt;br /&gt;
Function reference: https://developer.mozilla.org/en/SpiderMonkey/JSAPI_Reference&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Collaboration and teamwork ==&lt;br /&gt;
&lt;br /&gt;
=== Communication (in descending order of information content) ===&lt;br /&gt;
&lt;br /&gt;
Nearly all communication is handled through [https://bugzilla.mozilla.org Bugzilla]. All bugs, feature requests, issues, enhancements, etc, are all referred to as bugs. No code may enter the Mozilla repository without being a patch attached to a bugzilla bug first. To follow all SpiderMonkey related bugs:&lt;br /&gt;
&lt;br /&gt;
 Go to [https://bugzilla.mozilla.org/userprefs.cgi?tab=email email preferences]&lt;br /&gt;
 Watch the user general@spidermonkey.bugs&lt;br /&gt;
&lt;br /&gt;
SpiderMonkey contributors generally hang out in the very active [irc://irc.mozilla.org/jsapi #jsapi IRC channel].&lt;br /&gt;
&lt;br /&gt;
The [https://www.mozilla.org/about/forums/#dev-tech-js-engine-internals js-internals mailing list] is used for communicating with other SpiderMonkey hackers. (&amp;lt;i&amp;gt;Internals&amp;lt;/i&amp;gt; as in discussing the internals of the SpiderMonkey engine. All are welcome on the list.).&lt;br /&gt;
&lt;br /&gt;
Reading Planet Mozilla is the best way to keep up with the Mozilla project, which includes some SpiderMonkey related blogs:&lt;br /&gt;
&lt;br /&gt;
 [https://blog.mozilla.org/javascript General JavaScript blog]&lt;br /&gt;
 [http://blog.mozilla.com/jorendorff Jason Orendorff]&lt;br /&gt;
 [http://blog.mozilla.com/nnethercote/ Nicholas Nethercote]&lt;br /&gt;
 [http://whereswalden.com/ Jeff Walden]&lt;br /&gt;
 [https://itcouldbesomuchbetter.wordpress.com Jim Blandy]&lt;br /&gt;
 [https://jandemooij.nl/ Jan de Mooij]&lt;br /&gt;
 [https://h4writer.com/ Hannes Verschore]&lt;br /&gt;
 [http://rfrn.org/~shu/ Shu-yu Guo]&lt;br /&gt;
 [https://blog.benj.me/tag/mozilla.html Benjamin Bouvier]&lt;br /&gt;
&lt;br /&gt;
The [https://developer.mozilla.org/en/SpiderMonkey#Community js-engine mailing list] is generally used for communicating with people who embed SpiderMonkey, such as asking questions and announcing API changes. No actual development happens on the list.&lt;br /&gt;
&lt;br /&gt;
== Code considerations ==&lt;br /&gt;
&lt;br /&gt;
=== Repository ===&lt;br /&gt;
&lt;br /&gt;
Most active work on SpiderMonkey is done in the [http://hg.mozilla.org/mozilla-central mozilla-central] branch of the mozilla repository.&lt;br /&gt;
&lt;br /&gt;
=== Coding Style ===&lt;br /&gt;
&lt;br /&gt;
For many years, SpiderMonkey was written in C, and is gradually moving to C++. We still avoid many features such as run-time type information and virtual functions, but have come around to the glory of templates and namespaces relatively recently. Read the [[JavaScript:SpiderMonkey:C++ Coding Style|Coding Style]]. Do NOT read the portability guidelines, which I will not link to, since they are very out of date.&lt;br /&gt;
&lt;br /&gt;
=== Workflow ===&lt;br /&gt;
&lt;br /&gt;
Everything goes through bugzilla. We find a bug or have an idea, then submit it to bugzilla, then file patches to solve it. When it is solved, the patch is reviewed by team members, and is then committed to the [http://hg.mozilla.org/mozilla-central mozilla-central repository]. A link to the commit is then added as a comment to the bug.&lt;br /&gt;
&lt;br /&gt;
As well as committing to [http://hg.mozilla.org/mozilla-central mozilla-central], we also have the option of committing to [http://hg.mozilla.org/integration/mozilla-inbound mozilla-inbound], which is automatically merged to mozilla-central by a Sheriff. This exempts us from watching [http://tbpl.mozilla.org tinderbox] to check for errors in our patches, and commits are automatically backed out if errors are found.&lt;br /&gt;
&lt;br /&gt;
==== Sample Workflows ====&lt;br /&gt;
&lt;br /&gt;
(Outdated) [http://blog.mozilla.com/nnethercote/2009/07/27/how-i-work-on-tracemonkey/ Nicholas Nethercote: How I work on Tracemonkey]&lt;br /&gt;
&lt;br /&gt;
=== Policy ===&lt;br /&gt;
&lt;br /&gt;
The following docs are for the Mozilla project, and differ ever so slightly from what you should do for SpiderMonkey. For example, you should find reviewers in #jsapi rather than #developers.&lt;br /&gt;
&lt;br /&gt;
[http://www.mozilla.org/hacking/committer/ How to get commit access]&lt;br /&gt;
&lt;br /&gt;
[https://developer.mozilla.org/en/Creating_a_patch How to make patches]&lt;br /&gt;
&lt;br /&gt;
[https://developer.mozilla.org/En/Developer_Guide/How_to_Submit_a_Patch Submitting a patch]&lt;br /&gt;
&lt;br /&gt;
[https://developer.mozilla.org/en/Supported_build_configurations Supported Platforms]&lt;br /&gt;
&lt;br /&gt;
==== .hgrc file ====&lt;br /&gt;
&lt;br /&gt;
This .hgrc file contains a lot of the wisdom distilled through the wiki:&lt;br /&gt;
&lt;br /&gt;
 [extensions]&lt;br /&gt;
 mq =&lt;br /&gt;
 &lt;br /&gt;
 [ui]&lt;br /&gt;
 username = First Last &amp;lt;email@domain.tld&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
 [alias]&lt;br /&gt;
 qfulldiff = diff --rev qparent:.&lt;br /&gt;
 &lt;br /&gt;
 [defaults]&lt;br /&gt;
 diff = -p -U 8&lt;br /&gt;
 qdiff = -p -U 8&lt;br /&gt;
 qnew = -U&lt;br /&gt;
 commit = -v&lt;br /&gt;
 &lt;br /&gt;
 [diff]&lt;br /&gt;
 git = true&lt;br /&gt;
 showfunc = true&lt;br /&gt;
 unified = 8&lt;br /&gt;
 &lt;br /&gt;
 [paths]&lt;br /&gt;
 try = ssh://email@domain.tld@hg.mozilla.org/try/&lt;br /&gt;
&lt;br /&gt;
=== Try server  ===&lt;br /&gt;
&lt;br /&gt;
Often, you may be a little wary of breaking things. Mozilla has a [[Build:TryServer|Try Server]] where you can send a patch, and it&#039;ll be built and tested on tons of machines, which report to [http://tbpl.mozilla.org/?tree=Try TBPL]. Although you don&#039;t have [https://www.mozilla.org/hacking/commit-access-policy/ access] to TryServer just yet, you can get someone else to push it there for you. Just attach a patch to your bug, and ask in a comment, or on [irc://irc.mozilla.org/#jsapi #jsapi]. To be able to push to try-server yourself, you will need &amp;quot;level 1&amp;quot; access, which you can [https://www.mozilla.org/hacking/commit-access-policy/ request] once you&#039;ve contributed a patch or two.&lt;br /&gt;
&lt;br /&gt;
=== Mercurial Queues ===&lt;br /&gt;
&lt;br /&gt;
Since most of our lives revolve around patches, and we use Mercurial, nearly everybody uses Mercurial queues.&lt;br /&gt;
&lt;br /&gt;
Queues are based on the idea of patch management. Each queue consists of a series of patches, applied sequentially. The aim of the game is to split potential commits into simple, bite-sized chunks which are easy to review. This also makes it simple to experiment without polluting your existing work on a bug, to spin parts off into new bugs, and to rapidly apply and unapply patches (as demonstrated in the tutorial above).&lt;br /&gt;
&lt;br /&gt;
==== Enabling ====&lt;br /&gt;
&lt;br /&gt;
Add the following snippet to your .hgrc file to enable MQ&lt;br /&gt;
&lt;br /&gt;
 [extensions]&lt;br /&gt;
 mq =&lt;br /&gt;
&lt;br /&gt;
==== Example MQ workflow ====&lt;br /&gt;
&lt;br /&gt;
Clone the repository to deal with a bug:&lt;br /&gt;
&lt;br /&gt;
  hg clone http://hg.mozilla.org/mozilla-central&lt;br /&gt;
&lt;br /&gt;
Initialize your queue:&lt;br /&gt;
&lt;br /&gt;
  hg qinit -c&lt;br /&gt;
&lt;br /&gt;
Create a new patch, with some name:&lt;br /&gt;
&lt;br /&gt;
  hg qnew first_attempt&lt;br /&gt;
&lt;br /&gt;
Work on the patch, try to fix the bug, test, compile, etc.&lt;br /&gt;
&lt;br /&gt;
Refresh (save your work into the patch):&lt;br /&gt;
&lt;br /&gt;
 hg qrefresh&lt;br /&gt;
&lt;br /&gt;
Repeat a few times.&lt;br /&gt;
&lt;br /&gt;
Rename the patch (because your first name wasn&#039;t appliable):&lt;br /&gt;
&lt;br /&gt;
 hg qrename refactor_the_whatsit&lt;br /&gt;
&lt;br /&gt;
Create a new patch to try a logically separate part of the same bug:&lt;br /&gt;
&lt;br /&gt;
 hg qnew rip_out_the_old_thing&lt;br /&gt;
&lt;br /&gt;
Repeat the process a few times, until you have solved the problem. During this time, it can often be useful to go back and forth between patches:&lt;br /&gt;
&lt;br /&gt;
 hg qpop # unapply a patch&lt;br /&gt;
 hg qpush # reapply a patch&lt;br /&gt;
 hg qpop -a # unapply all patches&lt;br /&gt;
 hg qpush -a # reapply all patches&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Combine all the patches into a single patch, which you submit to bugzilla:&lt;br /&gt;
&lt;br /&gt;
 hg qpush -a&lt;br /&gt;
 hg qdiff --rev qparent:. &amp;gt; my_wonderful_patch.patch&lt;br /&gt;
&lt;br /&gt;
Commit the patches to your local patch repository, in case you make a mistake (You might do this periodically):&lt;br /&gt;
&lt;br /&gt;
 hg qcommit -m &amp;quot;Some message. Doesn&#039;t have to be good, this won&#039;t be committed to the repository, it&#039;s just for you&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Go back to the old patches and fiddle with them based on feedback:&lt;br /&gt;
&lt;br /&gt;
 hg qpop&lt;br /&gt;
 hg qrefresh&lt;br /&gt;
 etc&lt;br /&gt;
&lt;br /&gt;
There are some more complex techniques that we won&#039;t go into in detail. You can enable only some patches using qguard and qselect, and you can reorder the patches by manually editing the .hg/patches/series file. But be careful!&lt;br /&gt;
&lt;br /&gt;
[[Category:New Contributor Landing Page]]&lt;/div&gt;</summary>
		<author><name>Sfink</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=JavaScript:New_to_SpiderMonkey&amp;diff=1150947</id>
		<title>JavaScript:New to SpiderMonkey</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=JavaScript:New_to_SpiderMonkey&amp;diff=1150947"/>
		<updated>2016-10-11T15:34:44Z</updated>

		<summary type="html">&lt;p&gt;Sfink: /* Build the js shell */ configure.in isn&amp;#039;t really an autoconf input script anymore; it will invoke autoconf on the real stuff for you. Prefer a command that works regardless of local naming.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Tutorial: your first patch  ==&lt;br /&gt;
&lt;br /&gt;
The first step to getting involved with SpiderMonkey is to make your first patch. This guides you through it, and at the end you should have learnt a lot of the procedures and formalisms involved in getting things done here.&lt;br /&gt;
&lt;br /&gt;
We&#039;ll assume you&#039;re on a Unix-y platform, and that you know what you&#039;re doing. We&#039;ll ignore nearly all details. &lt;br /&gt;
&lt;br /&gt;
=== Get the code ===&lt;br /&gt;
&lt;br /&gt;
Spidermonkey development happens in the &amp;quot;mozilla-central&amp;quot; mercurial repository:&lt;br /&gt;
&lt;br /&gt;
 hg clone http://hg.mozilla.org/mozilla-central spidermonkey&lt;br /&gt;
&lt;br /&gt;
=== Build the js shell ===&lt;br /&gt;
&lt;br /&gt;
Most of the time, you&#039;ll be working with the Javascript shell, instead of the full Firefox browser. So build the shell: &lt;br /&gt;
&lt;br /&gt;
 cd spidermonkey/js/src&lt;br /&gt;
 cp configure.in configure &amp;amp;&amp;amp; chmod +x configure # or autoconf2.13 or autoconf-2.13&lt;br /&gt;
 mkdir build_DBG.OBJ &lt;br /&gt;
 cd build_DBG.OBJ &lt;br /&gt;
 ../configure --enable-debug --disable-optimize&lt;br /&gt;
 make # or make -j8&lt;br /&gt;
 cd ..&lt;br /&gt;
&lt;br /&gt;
If you&#039;re having trouble or are missing dependencies, refer to [https://developer.mozilla.org/en/SpiderMonkey/Build_Documentation#Building_SpiderMonkey_tip Building SpiderMonkey Tip].&lt;br /&gt;
&lt;br /&gt;
=== Fix something ===&lt;br /&gt;
&lt;br /&gt;
At this point, you&#039;re ready to make your first fix. &lt;br /&gt;
&lt;br /&gt;
 TODO: something useless. Maybe adding a datemicrosecond function.&lt;br /&gt;
&lt;br /&gt;
==== Building your changes ====&lt;br /&gt;
&lt;br /&gt;
Having made the change, build the shell again. &lt;br /&gt;
&lt;br /&gt;
 make -C build_DBG.OBJ&lt;br /&gt;
&lt;br /&gt;
==== Testing your changes ====&lt;br /&gt;
&lt;br /&gt;
It builds. Hurray. Time to run the tests to check you haven&#039;t broken anything. &lt;br /&gt;
&lt;br /&gt;
 jit-test/jit_test.py build_DBG.OBJ/dist/bin/js&lt;br /&gt;
(The location of the shell has changed, it used to be build_DBG.OBJ/js)&lt;br /&gt;
&lt;br /&gt;
The jit-tests are pretty quick, and should give you an idea if you&#039;ve gotten something wrong. Assuming nothing goes wrong, try the ref-tests: &lt;br /&gt;
&lt;br /&gt;
 tests/jstests.py build_DBG.OBJ/dist/bin/js&lt;br /&gt;
&lt;br /&gt;
Note that some of these tests fail depending on the timezone and locale they&#039;re run in, so if you get any errors that don&#039;t seem related to your changes, re-run the tests with a shell build without your changes applied and compare the results.&lt;br /&gt;
&lt;br /&gt;
==== Benchmark your changes ====&lt;br /&gt;
&lt;br /&gt;
Tests all pass. Congrats, you didn&#039;t break anything. Now, did you make it faster or slower? We benchmark using the v8 and SunSpider benchmarks. Get the benchmarks: &lt;br /&gt;
&lt;br /&gt;
 svn checkout http://svn.webkit.org/repository/webkit/trunk/PerformanceTests/SunSpider&lt;br /&gt;
&lt;br /&gt;
And now run them: &lt;br /&gt;
&lt;br /&gt;
 cd SunSpider &lt;br /&gt;
 ./sunspider --shell=../build_DBG.OBJ/dist/bin/js --run=30 --suite=sunspider-0.9.1 &lt;br /&gt;
 cd ..&lt;br /&gt;
&lt;br /&gt;
===== Optimized build =====&lt;br /&gt;
&lt;br /&gt;
Whoops, we benchmarked the debug version. Let&#039;s make an optimized build to test instead.&lt;br /&gt;
&lt;br /&gt;
 mkdir build_OPT.OBJ &lt;br /&gt;
 cd build_OPT.OBJ &lt;br /&gt;
 ../configure --disable-debug --enable-optimize&lt;br /&gt;
 make &lt;br /&gt;
 cd ..&lt;br /&gt;
&lt;br /&gt;
Repeat the sunspider steps above, and take note of the line that looks like: &lt;br /&gt;
&lt;br /&gt;
 Results are located at sunspider-0.9.1-results/sunspider-results-2010-08-07-17.56.48.js&lt;br /&gt;
&lt;br /&gt;
You&#039;ll need that later. &lt;br /&gt;
&lt;br /&gt;
===== Baseline version / Mercurial Queues =====&lt;br /&gt;
&lt;br /&gt;
We need to time our optimized version against the baseline version. This calls for a brief introduction to mercurial queues, which most people think is a pretty good way of managing their SpiderMonkey workflow: &lt;br /&gt;
&lt;br /&gt;
 hg qinit&lt;br /&gt;
 hg qnew my_first_patch -f&lt;br /&gt;
 hg qrefresh&lt;br /&gt;
&lt;br /&gt;
This puts your current work into a patch, managed by Mercurial, symbolically called my_first_patch. To pop the patch off: &lt;br /&gt;
&lt;br /&gt;
 hg qpop&lt;br /&gt;
&lt;br /&gt;
And we&#039;re back to our pristine version.&lt;br /&gt;
&lt;br /&gt;
===== Compare =====&lt;br /&gt;
&lt;br /&gt;
Build again and rerun SunSpider again. You should now have two files like: &lt;br /&gt;
&lt;br /&gt;
 sunspider-0.9.1-results/sunspider-results-2010-08-07-17.56.48.js&lt;br /&gt;
&lt;br /&gt;
Compare them using the compare script: &lt;br /&gt;
&lt;br /&gt;
 cd SunSpider &lt;br /&gt;
 ./sunspider-compare-results --shell=../build_DBG.OBJ/js --suite=sunspider-0.9.1 FILE1-withoutPatch FILE2-withPatch&lt;br /&gt;
&lt;br /&gt;
=== Get a real bug  ===&lt;br /&gt;
&lt;br /&gt;
At this point, you&#039;ve seen nearly everything you need to do hack on SpiderMonkey. So it&#039;s time to get a real bug to work on. You can get a bug on [http://www.joshmatthews.net/bugsahoy/?jseng=1&amp;amp;unowned=1 Bugs Ahoy].&lt;br /&gt;
&lt;br /&gt;
Fix the bug, updating the bug report with your progress, and asking questions as you go (either in the bug comments, or in [irc://irc.mozilla.org/#jsapi #jsapi]). When it&#039;s done, repeat all the steps above. Then it&#039;s time to get your patch into the tree.&lt;br /&gt;
&lt;br /&gt;
=== Submit a patch  ===&lt;br /&gt;
&lt;br /&gt;
To get the patch from mercurial, use: &lt;br /&gt;
&lt;br /&gt;
 hg qdiff # if you&#039;re using queues or&lt;br /&gt;
 hg diff  # if you&#039;re not&lt;br /&gt;
&lt;br /&gt;
Add it to the bug as an attachment. &lt;br /&gt;
&lt;br /&gt;
=== Get a review ===&lt;br /&gt;
&lt;br /&gt;
Nothing gets into the tree without a review, so you&#039;ll need one. The [[JavaScript:Hackers|SpiderMonkey hackers list]] is a good place to start: if your patch changes something listed as an area of expertise for someone there, that&#039;s a good person to ask for a review.&lt;br /&gt;
&lt;br /&gt;
Alternatively run &amp;lt;code&amp;gt;hg blame&amp;lt;/code&amp;gt; on the files you&#039;ve changed, and check who has been changing related code recently. They&#039;re likely to be good candidates.&lt;br /&gt;
&lt;br /&gt;
The review will consist of comments on your changes, suggesting or requesting alternative ways to do something and asking you to make changes where needed. They might also request additional changes, for example tests. Fix what they ask, resubmit the patch to bugzilla, and ask for another review. After you repeat this step a few times, they&#039;re mark the patch as &amp;quot;&amp;lt;code&amp;gt;r+&amp;lt;/code&amp;gt;&amp;quot; meaning it&#039;s now good to commit.&lt;br /&gt;
&lt;br /&gt;
=== Commit ===&lt;br /&gt;
&lt;br /&gt;
You can&#039;t commit to mozilla-central / mozilla-inbound until you have &amp;quot;level 3&amp;quot; access, so you&#039;ll need someone to do this for you. Try asking in [irc://irc.mozilla.org/#jsapi #jsapi], or add the &amp;lt;code&amp;gt;checkin-needed&amp;lt;/code&amp;gt; keyword to the bug. After you have been contributing for a while, you can get level 3 access by [https://www.mozilla.org/hacking/commit-access-policy/ applying for it].&lt;br /&gt;
&lt;br /&gt;
After committing, a large series of tests will be run to make sure you didn&#039;t break anything. You&#039;ll need to hang around to make sure you didn&#039;t break something. Check [http://tbpl.mozilla.org/?tree=Firefox the Firefox tree] for failures. Sometimes failures will be spurious: ask [irc://irc.mozilla.org/#jsapi for help] determining when this is the case, to start. (Over time you&#039;ll figure out when this is and isn&#039;t the case yourself.)&lt;br /&gt;
&lt;br /&gt;
== Overview of the JS engine ==&lt;br /&gt;
&lt;br /&gt;
The JS engine is a swiftly moving target. The most detailed information is available at https://developer.mozilla.org/en/SpiderMonkey. Here are some particularly interesting, mostly up-to-date resources:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== High level overviews ===&lt;br /&gt;
&lt;br /&gt;
(Outdated) http://hacks.mozilla.org/2010/03/a-quick-note-on-javascript-engine-components/&lt;br /&gt;
&lt;br /&gt;
https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Internals&lt;br /&gt;
&lt;br /&gt;
=== Medium level documentation ===&lt;br /&gt;
&lt;br /&gt;
jsapi.h: http://hg.mozilla.org/mozilla-central/file/tip/js/src/jsapi.h&lt;br /&gt;
&lt;br /&gt;
Frequently used coding recipes and mappings from JS idioms to SpiderMonkey code: https://developer.mozilla.org/En/SpiderMonkey/JSAPI_Cookbook&lt;br /&gt;
&lt;br /&gt;
=== Detailed documentation ===&lt;br /&gt;
&lt;br /&gt;
Build: https://developer.mozilla.org/en/SpiderMonkey/Build_Documentation&lt;br /&gt;
&lt;br /&gt;
Testing: https://developer.mozilla.org/en/SpiderMonkey/Running_Automated_JavaScript_Tests&lt;br /&gt;
&lt;br /&gt;
Shell: https://developer.mozilla.org/En/SpiderMonkey/Introduction_to_the_JavaScript_shell&lt;br /&gt;
&lt;br /&gt;
Function reference: https://developer.mozilla.org/en/SpiderMonkey/JSAPI_Reference&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Collaboration and teamwork ==&lt;br /&gt;
&lt;br /&gt;
=== Communication (in descending order of information content) ===&lt;br /&gt;
&lt;br /&gt;
Nearly all communication is handled through [https://bugzilla.mozilla.org Bugzilla]. All bugs, feature requests, issues, enhancements, etc, are all referred to as bugs. No code may enter the Mozilla repository without being a patch attached to a bugzilla bug first. To follow all SpiderMonkey related bugs:&lt;br /&gt;
&lt;br /&gt;
 Go to [https://bugzilla.mozilla.org/userprefs.cgi?tab=email email preferences]&lt;br /&gt;
 Watch the user general@spidermonkey.bugs&lt;br /&gt;
&lt;br /&gt;
SpiderMonkey contributors generally hang out in the very active [irc://irc.mozilla.org/jsapi #jsapi IRC channel].&lt;br /&gt;
&lt;br /&gt;
The [https://www.mozilla.org/about/forums/#dev-tech-js-engine-internals js-internals mailing list] is used for communicating with other SpiderMonkey hackers. (&amp;lt;i&amp;gt;Internals&amp;lt;/i&amp;gt; as in discussing the internals of the SpiderMonkey engine. All are welcome on the list.).&lt;br /&gt;
&lt;br /&gt;
Reading Planet Mozilla is the best way to keep up with the Mozilla project, which includes some SpiderMonkey related blogs:&lt;br /&gt;
&lt;br /&gt;
 [https://blog.mozilla.org/javascript General JavaScript blog]&lt;br /&gt;
 [http://blog.mozilla.com/jorendorff Jason Orendorff]&lt;br /&gt;
 [http://blog.mozilla.com/nnethercote/ Nicholas Nethercote]&lt;br /&gt;
 [http://whereswalden.com/ Jeff Walden]&lt;br /&gt;
 [https://itcouldbesomuchbetter.wordpress.com Jim Blandy]&lt;br /&gt;
 [https://jandemooij.nl/ Jan de Mooij]&lt;br /&gt;
 [https://h4writer.com/ Hannes Verschore]&lt;br /&gt;
 [http://rfrn.org/~shu/ Shu-yu Guo]&lt;br /&gt;
 [https://blog.benj.me/tag/mozilla.html Benjamin Bouvier]&lt;br /&gt;
&lt;br /&gt;
The [https://developer.mozilla.org/en/SpiderMonkey#Community js-engine mailing list] is generally used for communicating with people who embed SpiderMonkey, such as asking questions and announcing API changes. No actual development happens on the list.&lt;br /&gt;
&lt;br /&gt;
== Code considerations ==&lt;br /&gt;
&lt;br /&gt;
=== Repository ===&lt;br /&gt;
&lt;br /&gt;
Most active work on SpiderMonkey is done in the [http://hg.mozilla.org/mozilla-central mozilla-central] branch of the mozilla repository.&lt;br /&gt;
&lt;br /&gt;
=== Coding Style ===&lt;br /&gt;
&lt;br /&gt;
For many years, SpiderMonkey was written in C, and is gradually moving to C++. We still avoid many features such as run-time type information and virtual functions, but have come around to the glory of templates and namespaces relatively recently. Read the [[JavaScript:SpiderMonkey:C++ Coding Style|Coding Style]]. Do NOT read the portability guidelines, which I will not link to, since they are very out of date.&lt;br /&gt;
&lt;br /&gt;
=== Workflow ===&lt;br /&gt;
&lt;br /&gt;
Everything goes through bugzilla. We find a bug or have an idea, then submit it to bugzilla, then file patches to solve it. When it is solved, the patch is reviewed by team members, and is then committed to the [http://hg.mozilla.org/mozilla-central mozilla-central repository]. A link to the commit is then added as a comment to the bug.&lt;br /&gt;
&lt;br /&gt;
As well as committing to [http://hg.mozilla.org/mozilla-central mozilla-central], we also have the option of committing to [http://hg.mozilla.org/integration/mozilla-inbound mozilla-inbound], which is automatically merged to mozilla-central by a Sheriff. This exempts us from watching [http://tbpl.mozilla.org tinderbox] to check for errors in our patches, and commits are automatically backed out if errors are found.&lt;br /&gt;
&lt;br /&gt;
==== Sample Workflows ====&lt;br /&gt;
&lt;br /&gt;
(Outdated) [http://blog.mozilla.com/nnethercote/2009/07/27/how-i-work-on-tracemonkey/ Nicholas Nethercote: How I work on Tracemonkey]&lt;br /&gt;
&lt;br /&gt;
=== Policy ===&lt;br /&gt;
&lt;br /&gt;
The following docs are for the Mozilla project, and differ ever so slightly from what you should do for SpiderMonkey. For example, you should find reviewers in #jsapi rather than #developers.&lt;br /&gt;
&lt;br /&gt;
[http://www.mozilla.org/hacking/committer/ How to get commit access]&lt;br /&gt;
&lt;br /&gt;
[https://developer.mozilla.org/en/Creating_a_patch How to make patches]&lt;br /&gt;
&lt;br /&gt;
[https://developer.mozilla.org/En/Developer_Guide/How_to_Submit_a_Patch Submitting a patch]&lt;br /&gt;
&lt;br /&gt;
[https://developer.mozilla.org/en/Supported_build_configurations Supported Platforms]&lt;br /&gt;
&lt;br /&gt;
==== .hgrc file ====&lt;br /&gt;
&lt;br /&gt;
This .hgrc file contains a lot of the wisdom distilled through the wiki:&lt;br /&gt;
&lt;br /&gt;
 [extensions]&lt;br /&gt;
 mq =&lt;br /&gt;
 &lt;br /&gt;
 [ui]&lt;br /&gt;
 username = First Last &amp;lt;email@domain.tld&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
 [alias]&lt;br /&gt;
 qfulldiff = diff --rev qparent:.&lt;br /&gt;
 &lt;br /&gt;
 [defaults]&lt;br /&gt;
 diff = -p -U 8&lt;br /&gt;
 qdiff = -p -U 8&lt;br /&gt;
 qnew = -U&lt;br /&gt;
 commit = -v&lt;br /&gt;
 &lt;br /&gt;
 [diff]&lt;br /&gt;
 git = true&lt;br /&gt;
 showfunc = true&lt;br /&gt;
 unified = 8&lt;br /&gt;
 &lt;br /&gt;
 [paths]&lt;br /&gt;
 try = ssh://email@domain.tld@hg.mozilla.org/try/&lt;br /&gt;
&lt;br /&gt;
=== Try server  ===&lt;br /&gt;
&lt;br /&gt;
Often, you may be a little wary of breaking things. Mozilla has a [[Build:TryServer|Try Server]] where you can send a patch, and it&#039;ll be built and tested on tons of machines, which report to [http://tbpl.mozilla.org/?tree=Try TBPL]. Although you don&#039;t have [https://www.mozilla.org/hacking/commit-access-policy/ access] to TryServer just yet, you can get someone else to push it there for you. Just attach a patch to your bug, and ask in a comment, or on [irc://irc.mozilla.org/#jsapi #jsapi]. To be able to push to try-server yourself, you will need &amp;quot;level 1&amp;quot; access, which you can [https://www.mozilla.org/hacking/commit-access-policy/ request] once you&#039;ve contributed a patch or two.&lt;br /&gt;
&lt;br /&gt;
=== Mercurial Queues ===&lt;br /&gt;
&lt;br /&gt;
Since most of our lives revolve around patches, and we use Mercurial, nearly everybody uses Mercurial queues.&lt;br /&gt;
&lt;br /&gt;
Queues are based on the idea of patch management. Each queue consists of a series of patches, applied sequentially. The aim of the game is to split potential commits into simple, bite-sized chunks which are easy to review. This also makes it simple to experiment without polluting your existing work on a bug, to spin parts off into new bugs, and to rapidly apply and unapply patches (as demonstrated in the tutorial above).&lt;br /&gt;
&lt;br /&gt;
==== Enabling ====&lt;br /&gt;
&lt;br /&gt;
Add the following snippet to your .hgrc file to enable MQ&lt;br /&gt;
&lt;br /&gt;
 [extensions]&lt;br /&gt;
 mq =&lt;br /&gt;
&lt;br /&gt;
==== Example MQ workflow ====&lt;br /&gt;
&lt;br /&gt;
Clone the repository to deal with a bug:&lt;br /&gt;
&lt;br /&gt;
  hg clone http://hg.mozilla.org/mozilla-central&lt;br /&gt;
&lt;br /&gt;
Initialize your queue:&lt;br /&gt;
&lt;br /&gt;
  hg qinit -c&lt;br /&gt;
&lt;br /&gt;
Create a new patch, with some name:&lt;br /&gt;
&lt;br /&gt;
  hg qnew first_attempt&lt;br /&gt;
&lt;br /&gt;
Work on the patch, try to fix the bug, test, compile, etc.&lt;br /&gt;
&lt;br /&gt;
Refresh (save your work into the patch):&lt;br /&gt;
&lt;br /&gt;
 hg qrefresh&lt;br /&gt;
&lt;br /&gt;
Repeat a few times.&lt;br /&gt;
&lt;br /&gt;
Rename the patch (because your first name wasn&#039;t appliable):&lt;br /&gt;
&lt;br /&gt;
 hg qrename refactor_the_whatsit&lt;br /&gt;
&lt;br /&gt;
Create a new patch to try a logically separate part of the same bug:&lt;br /&gt;
&lt;br /&gt;
 hg qnew rip_out_the_old_thing&lt;br /&gt;
&lt;br /&gt;
Repeat the process a few times, until you have solved the problem. During this time, it can often be useful to go back and forth between patches:&lt;br /&gt;
&lt;br /&gt;
 hg qpop # unapply a patch&lt;br /&gt;
 hg qpush # reapply a patch&lt;br /&gt;
 hg qpop -a # unapply all patches&lt;br /&gt;
 hg qpush -a # reapply all patches&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Combine all the patches into a single patch, which you submit to bugzilla:&lt;br /&gt;
&lt;br /&gt;
 hg qpush -a&lt;br /&gt;
 hg qdiff --rev qparent:. &amp;gt; my_wonderful_patch.patch&lt;br /&gt;
&lt;br /&gt;
Commit the patches to your local patch repository, in case you make a mistake (You might do this periodically):&lt;br /&gt;
&lt;br /&gt;
 hg qcommit -m &amp;quot;Some message. Doesn&#039;t have to be good, this won&#039;t be committed to the repository, it&#039;s just for you&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Go back to the old patches and fiddle with them based on feedback:&lt;br /&gt;
&lt;br /&gt;
 hg qpop&lt;br /&gt;
 hg qrefresh&lt;br /&gt;
 etc&lt;br /&gt;
&lt;br /&gt;
There are some more complex techniques that we won&#039;t go into in detail. You can enable only some patches using qguard and qselect, and you can reorder the patches by manually editing the .hg/patches/series file. But be careful!&lt;br /&gt;
&lt;br /&gt;
[[Category:New Contributor Landing Page]]&lt;/div&gt;</summary>
		<author><name>Sfink</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=Benchmarking_advice&amp;diff=1144193</id>
		<title>Benchmarking advice</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=Benchmarking_advice&amp;diff=1144193"/>
		<updated>2016-08-16T17:06:47Z</updated>

		<summary type="html">&lt;p&gt;Sfink: maybe an interwiki link?&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[mdn:docs/Mozilla/Benchmarking]]&lt;/div&gt;</summary>
		<author><name>Sfink</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=Benchmarking_advice&amp;diff=1144191</id>
		<title>Benchmarking advice</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=Benchmarking_advice&amp;diff=1144191"/>
		<updated>2016-08-16T17:03:14Z</updated>

		<summary type="html">&lt;p&gt;Sfink: looks like you cannot redirect to an external page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;See https://developer.mozilla.org/en-US/docs/Mozilla/Benchmarking&lt;/div&gt;</summary>
		<author><name>Sfink</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=Benchmarking_advice&amp;diff=1144184</id>
		<title>Benchmarking advice</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=Benchmarking_advice&amp;diff=1144184"/>
		<updated>2016-08-16T16:29:17Z</updated>

		<summary type="html">&lt;p&gt;Sfink: maybe?&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [https://developer.mozilla.org/en-US/docs/Mozilla/Benchmarking]&lt;/div&gt;</summary>
		<author><name>Sfink</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=Benchmarking_advice&amp;diff=1144182</id>
		<title>Benchmarking advice</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=Benchmarking_advice&amp;diff=1144182"/>
		<updated>2016-08-16T16:27:21Z</updated>

		<summary type="html">&lt;p&gt;Sfink: fix redir?&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[https://developer.mozilla.org/en-US/docs/Mozilla/Benchmarking]]&lt;/div&gt;</summary>
		<author><name>Sfink</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=Benchmarking_advice&amp;diff=1144177</id>
		<title>Benchmarking advice</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=Benchmarking_advice&amp;diff=1144177"/>
		<updated>2016-08-16T16:23:57Z</updated>

		<summary type="html">&lt;p&gt;Sfink: redirect to mdn&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT https://developer.mozilla.org/en-US/docs/Mozilla/Benchmarking&lt;/div&gt;</summary>
		<author><name>Sfink</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=Benchmarking_advice&amp;diff=1144068</id>
		<title>Benchmarking advice</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=Benchmarking_advice&amp;diff=1144068"/>
		<updated>2016-08-16T01:06:36Z</updated>

		<summary type="html">&lt;p&gt;Sfink: Created page with &amp;quot;= Debug Builds =  Debug builds (--enable-debug) and non-optimized builds (--disable-optimize) are &amp;#039;&amp;#039;&amp;#039;much&amp;#039;&amp;#039;&amp;#039; slower. Any performance metrics gathered by such builds are largel...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Debug Builds =&lt;br /&gt;
&lt;br /&gt;
Debug builds (--enable-debug) and non-optimized builds (--disable-optimize) are &#039;&#039;&#039;much&#039;&#039;&#039; slower. Any performance metrics gathered by such builds are largely unrelated to the what the performance a release browser would be.&lt;br /&gt;
&lt;br /&gt;
= Poisoning =&lt;br /&gt;
&lt;br /&gt;
Many Firefox builds have a diagnostic tool that causes crashes to happen sooner and produce much more actionable information, but also slow down regular usage substantially. In particular, &amp;quot;GC poisoning&amp;quot; is used in all debug builds, and in optimized nightly builds (but not opt developer edition or beta builds). The poisoning can be disabled by setting the environment variable&lt;br /&gt;
&lt;br /&gt;
    JSGC_DISABLE_POISONING=1&lt;br /&gt;
&lt;br /&gt;
before starting the browser.&lt;/div&gt;</summary>
		<author><name>Sfink</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=User:Sfink&amp;diff=1144067</id>
		<title>User:Sfink</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=User:Sfink&amp;diff=1144067"/>
		<updated>2016-08-16T00:58:35Z</updated>

		<summary type="html">&lt;p&gt;Sfink: /* &amp;quot;My&amp;quot; Pages */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Where I&#039;m putting stuff:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;Things that are generally useful&#039;&#039;: just throw them into their appropriate place on the wiki, of course. Then agonize over whether they should be on MDC instead.&lt;br /&gt;
* &#039;&#039;Rough stuff that nevertheless may contain information useful to others&#039;&#039;: use a &amp;quot;sfink/&amp;quot; prefix, so that they show up in searches but are clearly associated with a user (me) and not taken too seriously.&lt;br /&gt;
* &#039;&#039;Notes for myself that are unlikely to be useful to anyone else&#039;&#039;: use the &amp;quot;User&amp;quot; namespace, specifically the prefix &amp;quot;User:sfink/&amp;quot; to prevent it from showing up in a search unless someone specifically asks to see user pages.&lt;br /&gt;
&lt;br /&gt;
== &amp;quot;My&amp;quot; Pages ==&lt;br /&gt;
&lt;br /&gt;
From newest to oldest, roughly.&lt;br /&gt;
&lt;br /&gt;
Generally useful, maybe:&lt;br /&gt;
&lt;br /&gt;
* [[Benchmarking advice]]&lt;br /&gt;
* [[Measuring GC performance]]&lt;br /&gt;
* [[Managing GC-visible resources]] - best name I came up with, and I don&#039;t like it&lt;br /&gt;
* [[sfink/Moving GC]]&lt;br /&gt;
* [[sfink/Static Rooting Analysis]]&lt;br /&gt;
* [[sfink/Draft - GC Pointer Handling]]&lt;br /&gt;
* [[sfink/JS Stack Walking]]&lt;br /&gt;
* [[sfink/Memory Ideas]]&lt;br /&gt;
* [[Multiple Project Repositories]]&lt;br /&gt;
* [[Using SlowCalls]]&lt;br /&gt;
* [[Using XPerf]]&lt;br /&gt;
* [[sfink/Contexts and Compartments]]&lt;br /&gt;
* [[sfink/Thought Experiment - One Minute Builds]] - shouldn&#039;t really have a sfink/ prefix, but I couldn&#039;t think of a good title&lt;br /&gt;
* [[mrgiggles]] - IRC bot&lt;br /&gt;
&lt;br /&gt;
Generally useless, probably:&lt;br /&gt;
&lt;br /&gt;
* [[AllHands2011/tbplPlanning]]&lt;br /&gt;
* [[sfink/JS Profiling-Related APIs]] - attempting to make some sense of the various probes/hooks/engines&lt;br /&gt;
* [[sfink/Performance Thoughts]] - disorganized notes on performance&lt;br /&gt;
* [[User:sfink/Working On]] - obsolete-on-arrival page listing what I&#039;m working on&lt;br /&gt;
* [[sfink/Laptop Setup]] - notes on configuring my laptop with Fedora Linux&lt;br /&gt;
* [[sfink/Building Mozilla]] - notes on compiling the tree&lt;br /&gt;
* [[sfink/Projects]]&lt;br /&gt;
&lt;br /&gt;
== Useful/Relevant Links ==&lt;br /&gt;
&lt;br /&gt;
* [[JavaScript]]&lt;br /&gt;
* [[Performance:Home Page]]&lt;br /&gt;
* [[sfink/Useful Notes]] - Stuff gathered from email, web, etc. that could be useful to others as well&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{VerifiedUser}}&lt;/div&gt;</summary>
		<author><name>Sfink</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=Javascript:Hazard_Builds&amp;diff=1137962</id>
		<title>Javascript:Hazard Builds</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=Javascript:Hazard_Builds&amp;diff=1137962"/>
		<updated>2016-06-28T20:42:06Z</updated>

		<summary type="html">&lt;p&gt;Sfink: /* Static Analysis for Rooting Hazards */ put useful stuff at top&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Static Analysis for Rooting Hazards ==&lt;br /&gt;
&lt;br /&gt;
Treeherder can run two static analysis builds: the full browser (linux64-haz), just the JS shell (linux64-shell-haz). They show up on treeherder as &#039;&#039;&#039;H&#039;&#039;&#039; and &#039;&#039;&#039;SM(H)&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Diagnosing a hazard failure ===&lt;br /&gt;
&lt;br /&gt;
Click on the &#039;&#039;&#039;H&#039;&#039;&#039; build link, select the &amp;quot;Job details&amp;quot; pane on the bottom right, follow the &amp;quot;Inspect Task&amp;quot; link, and download the &amp;quot;public/build/hazards.txt.gz&amp;quot; file.&lt;br /&gt;
&lt;br /&gt;
Example snippet:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Function &#039;jsopcode.cpp:uint8 DecompileExpressionFromStack(JSContext*, int32, int32, class JS::Handle&amp;lt;JS::Value&amp;gt;, int8**)&#039; has unrooted &#039;ed&#039; of type &#039;ExpressionDecompiler&#039; live across GC call &#039;uint8 ExpressionDecompiler::decompilePC(uint8*)&#039; at js/src/jsopcode.cpp:1866&lt;br /&gt;
    js/src/jsopcode.cpp:1866: Assume(74,75, !__temp_23*, true)&lt;br /&gt;
    js/src/jsopcode.cpp:1867: Assign(75,76, return := 0)&lt;br /&gt;
    js/src/jsopcode.cpp:1867: Call(76,77, ed.~ExpressionDecompiler())&lt;br /&gt;
GC Function: uint8 ExpressionDecompiler::decompilePC(uint8*)&lt;br /&gt;
    JSString* js::ValueToSource(JSContext*, class JS::Handle&amp;lt;JS::Value&amp;gt;)&lt;br /&gt;
    uint8 js::Invoke(JSContext*, JS::Value*, JS::Value*, uint32, JS::Value*, class JS::MutableHandle&amp;lt;JS::Value&amp;gt;)&lt;br /&gt;
    uint8 js::Invoke(JSContext*, JS::CallArgs, uint32)&lt;br /&gt;
    JSScript* JSFunction::getOrCreateScript(JSContext*)&lt;br /&gt;
    uint8 JSFunction::createScriptForLazilyInterpretedFunction(JSContext*, class JS::Handle&amp;lt;JSFunction*&amp;gt;)&lt;br /&gt;
    uint8 JSRuntime::cloneSelfHostedFunctionScript(JSContext*, class JS::Handle&amp;lt;js::PropertyName*&amp;gt;, class JS::Handle&amp;lt;JSFunction*&amp;gt;)&lt;br /&gt;
    JSScript* js::CloneScript(JSContext*, class JS::Handle&amp;lt;JSObject*&amp;gt;, class JS::Handle&amp;lt;JSFunction*&amp;gt;, const class JS::Handle&amp;lt;JSScript*&amp;gt;, uint32)&lt;br /&gt;
    JSObject* js::CloneStaticBlockObject(JSContext*, class JS::Handle&amp;lt;JSObject*&amp;gt;, class JS::Handle&amp;lt;js::StaticBlockObject*&amp;gt;)&lt;br /&gt;
    js::StaticBlockObject* js::StaticBlockObject::create(js::ExclusiveContext*)&lt;br /&gt;
    js::Shape* js::EmptyShape::getInitialShape(js::ExclusiveContext*, js::Class*, js::TaggedProto, JSObject*, JSObject*, uint32, uint32)&lt;br /&gt;
    js::Shape* js::EmptyShape::getInitialShape(js::ExclusiveContext*, js::Class*, js::TaggedProto, JSObject*, JSObject*, uint64, uint32)&lt;br /&gt;
    js::UnownedBaseShape* js::BaseShape::getUnowned(js::ExclusiveContext*, js::StackBaseShape*)&lt;br /&gt;
    js::BaseShape* js_NewGCBaseShape(js::ThreadSafeContext*) [with js::AllowGC allowGC = (js::AllowGC)1u]&lt;br /&gt;
    js::BaseShape* js::gc::NewGCThing(js::ThreadSafeContext*, uint32, uint64, uint32) [with T = js::BaseShape; js::AllowGC allowGC = (js::AllowGC)1u; size_t = long unsigned int]&lt;br /&gt;
    void js::gc::RunDebugGC(JSContext*)&lt;br /&gt;
    void js::MinorGC(JSRuntime*, uint32)&lt;br /&gt;
    GC&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This means that a rooting hazard was discovered at js/src/jsopcode.cpp line 1866, in the function DecompileExpressionFromStack (it is prefixed with the filename because it&#039;s a static function.) The problem is that they&#039;re an unrooted variable &#039;ed&#039; that holds an ExpressionDecompiler live across a call to decompilePC. &amp;quot;Live&amp;quot; means that the variable is used after the call to decompilePC returns. decompilePC may trigger a GC according to the static call stack given starting from the line beginning with &amp;quot;GC Function:&amp;quot;. The hazard itself has some barely comprehensible Assume(...) and Call(...) gibberish that describes the exact path of the variable into the function call. That stuff is rarely useful -- usually, you&#039;ll only need to look at it if it&#039;s complaining about a temporary and you want to know where the temporary came from. The type &#039;ExpressionDecompiler&#039; is believed to hold pointers to GC-controlled objects of some sort. The analysis currently does not describe the exact field it is worried about.&lt;br /&gt;
&lt;br /&gt;
To unpack this a little, the analysis is saying the following can happen:&lt;br /&gt;
&lt;br /&gt;
* ExpressionDecompiler contains some pointer to a GC thing. For example, it might have a field &#039;obj&#039; of type &#039;JSObject*&#039;.&lt;br /&gt;
* DecompileExpressionFromStack is called.&lt;br /&gt;
* A pointer is stored in that field of the &#039;ed&#039; variable.&lt;br /&gt;
* decompilePC is invoked, which calls ValueToSource, which calls Invoke, which eventually calls js::MinorGC&lt;br /&gt;
* during the resulting garbage collection, the object pointed to by ed.obj is moved to a different location. All pointers stored in the JS heap are updated automatically, as are all rooted pointers. ed.obj is not, because the GC doesn&#039;t know about it.&lt;br /&gt;
* after decompilePC returns, something accesses ed.obj. This is now a stale pointer, and may refer to just about anything -- the wrong object, an invalid object, or whatever. Badness 10000, as TeX would say.&lt;br /&gt;
&lt;br /&gt;
=== Analysis implementation ===&lt;br /&gt;
&lt;br /&gt;
These builds are performed as follows:&lt;br /&gt;
&lt;br /&gt;
* run the script testing/taskcluster/scripts/builder/build-haz-linux.sh, which sets up a build environment and runs the analysis within it, then uploads the resulting files&lt;br /&gt;
** compile an optimized JS shell to later run the analysis&lt;br /&gt;
** compile the browser with gcc, using a slightly modified version of the sixgill (http://svn.sixgill.org) gcc plugin, producing a set of .xdb files describing everything encountered during the compilation&lt;br /&gt;
** analyze the .xdb files with scripts in js/src/devtools/rootAnalysis&lt;br /&gt;
&lt;br /&gt;
=== Running the analysis ===&lt;br /&gt;
&lt;br /&gt;
==== Pushing to try ====&lt;br /&gt;
&lt;br /&gt;
The easiest way to run an analysis is to push to try with the trychooser line |try: -b do -p linux64-haz| (or, if the hazards of interest are contained entirely within js/src, use |try: -b do -p linux64-shell-haz| for a much faster result). The expected turnaround time for linux64-haz is just under 2 hours.&lt;br /&gt;
&lt;br /&gt;
The output will be uploaded and a link named &amp;quot;results&amp;quot; will be placed into the &amp;quot;job details&amp;quot; info pane on treeherder. If the analysis fails, you will see the number of failures. Navigate to the hazards.txt.gz file.&lt;br /&gt;
&lt;br /&gt;
==== Running locally ====&lt;br /&gt;
&lt;br /&gt;
To run the browser analysis, you must be on a Fedora/RedHat/CentOS linux64 machine. See js/src/devtools/rootAnalysis/README.md.&lt;br /&gt;
&lt;br /&gt;
If you are running Debian or Ubuntu, then there is currently a problem running the full browser analysis. You can coerce the shell-only build to work by doing something like:&lt;br /&gt;
&lt;br /&gt;
  sudo apt-get install autoconf2.13 libnspr4 libnspr4-dev&lt;br /&gt;
  sudo ln -s autoconf2.13 /usr/bin/autoconf-2.13&lt;br /&gt;
  export CFLAGS=&amp;quot;-B/usr/lib/x86_64-linux-gnu -I/usr/include/x86_64-linux-gnu&amp;quot;&lt;br /&gt;
  export CXXFLAGS=&amp;quot;-B/usr/lib/x86_64-linux-gnu -I/usr/include/x86_64-linux-gnu&amp;quot;&lt;br /&gt;
&lt;br /&gt;
before running the script.&lt;br /&gt;
&lt;br /&gt;
=== So you broke the analysis by adding a hazard. Now what? ===&lt;br /&gt;
&lt;br /&gt;
Backout, fix the hazard, or (final resort) update the expected number of hazards in js/src/devtools/rootAnalysis/expect.browser.json.&lt;br /&gt;
&lt;br /&gt;
The most common way to fix a hazard is to change the variable to be a Rooted type, as described in http://dxr.mozilla.org/mozilla-central/source/js/public/RootingAPI.h#l21&lt;br /&gt;
&lt;br /&gt;
For more complicated cases, ask on #jsapi. If you don&#039;t get a response, ping sfink, terrence, or jonco.&lt;/div&gt;</summary>
		<author><name>Sfink</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=Sheriffing/How_To/Unified_Repos&amp;diff=1137422</id>
		<title>Sheriffing/How To/Unified Repos</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=Sheriffing/How_To/Unified_Repos&amp;diff=1137422"/>
		<updated>2016-06-23T04:22:38Z</updated>

		<summary type="html">&lt;p&gt;Sfink: /* Backouts */ fmting&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Unified Repos ==&lt;br /&gt;
* http://mozilla-version-control-tools.readthedocs.org/en/latest/hgmozilla/unifiedrepo.html&lt;br /&gt;
* https://mozilla-version-control-tools.readthedocs.org/en/latest/hgmozilla/firefoxtree.html&lt;br /&gt;
&lt;br /&gt;
=== Setting up the repo ===&lt;br /&gt;
* Set up your ssh key yourself&lt;br /&gt;
* Install Mercurial 3.2 or higher&lt;br /&gt;
* Make a copy of your .hgrc file for safekeeping and delete the original&lt;br /&gt;
* hg clone https://hg.mozilla.org/mozilla-central&lt;br /&gt;
* cd mozilla-central&lt;br /&gt;
* ./mach mercurial-setup&lt;br /&gt;
Configure mercurial as desired &amp;lt;br /&amp;gt;&lt;br /&gt;
The following will pull all (or at least most) of the branches sheriffs need to have on hand:&lt;br /&gt;
* hg pull inbound &amp;amp;&amp;amp; hg pull fx-team &amp;amp;&amp;amp; hg pull aurora &amp;amp;&amp;amp; hg pull beta &amp;amp;&amp;amp; hg pull esr38&lt;br /&gt;
If you need other branches, you can find their names in the [https://hg.mozilla.org/hgcustom/version-control-tools/file/default/pylib/mozautomation/mozautomation/repository.py firefoxtree extension source].&lt;br /&gt;
&lt;br /&gt;
You should now have everything set up for proper use! &amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Maybe rename the folder from &amp;quot;mozilla-central&amp;quot; to &amp;quot;unifiedrepo&amp;quot; or something to make it clear it&#039;s more than just mozilla-central?&lt;br /&gt;
&lt;br /&gt;
The `hg fxheads` command should list references to each of the relevant branch names, and the current revision and commit message for each.&lt;br /&gt;
&lt;br /&gt;
With [https://bugzilla.mozilla.org/show_bug.cgi?id=1116861 bug 1116861] landed in version-control-tools, you can now use the following commands to pull from groups of repositories with a single command:&lt;br /&gt;
* hg pull fxtrees # this will pull from all branches listed with the fxheads command&lt;br /&gt;
* hg pull integration # this will pull from the mozilla-inbound, b2g-inbound, and fx-team branches&lt;br /&gt;
* hg pull releases # this will pull from pretty much every release branch (FYI: including old, unused branches)&lt;br /&gt;
&lt;br /&gt;
=== Merges ===&lt;br /&gt;
This assumes you have your unified repo all set up so that `hg fxheads` lists each of central, b2ginbound, fx-team, and inbound.&lt;br /&gt;
&lt;br /&gt;
To merge a specific non-tip &amp;lt;revision&amp;gt; from mozilla-inbound to mozilla-central:&lt;br /&gt;
# hg pull central&lt;br /&gt;
# hg pull inbound&lt;br /&gt;
# hg up central&lt;br /&gt;
# hg merge -r &amp;lt;revision&amp;gt;&lt;br /&gt;
# hg commit -m &amp;quot;Merge mozilla-inbound to mozilla-central a=merge&amp;quot;&lt;br /&gt;
# hg push -r . central&lt;br /&gt;
&lt;br /&gt;
To merge mozilla-central into mozilla-inbound:&lt;br /&gt;
# hg pull central&lt;br /&gt;
# hg pull inbound&lt;br /&gt;
# hg up inbound&lt;br /&gt;
# hg merge central&lt;br /&gt;
# hg commit -m &amp;quot;Merge mozilla-central to mozilla-inbound a=merge&amp;quot;&lt;br /&gt;
# hg push -r . inbound&lt;br /&gt;
&lt;br /&gt;
* If the `hg merge central` command results in &amp;quot;abort: nothing to merge&amp;quot;, you should instead use `hg update -r &amp;lt;mozilla-central&#039;s tip revision&amp;gt;` to do a non-merging update, then you can do `hg push -r . inbound` to push it as usual.&lt;br /&gt;
&lt;br /&gt;
=== Checkin-neededs ===&lt;br /&gt;
This assumes we&#039;re checking things in to fx-team. Replace fx-team with another branch name as needed.&lt;br /&gt;
&lt;br /&gt;
===== Single repository and single set of patches =====&lt;br /&gt;
Update fx-team and prepare for the patches:&lt;br /&gt;
* hg pull fx-team&lt;br /&gt;
* hg up fx-team&lt;br /&gt;
* hg bookmark fx-team-checkins&lt;br /&gt;
Import the patches:&lt;br /&gt;
* hg import https://link.to/correct/checkin-needed.patch&lt;br /&gt;
* Repeat ^ as needed for all fx-team checkin-needed patches&lt;br /&gt;
Verify your outgoing changes:&lt;br /&gt;
* hg out -r . fx-team&lt;br /&gt;
If you haven&#039;t lost a push race:&lt;br /&gt;
* hg push -r . fx-team&lt;br /&gt;
If you lost a push race:&lt;br /&gt;
* hg pull fx-team&lt;br /&gt;
* hg rebase -d fx-team&lt;br /&gt;
* hg push -r . fx-team&lt;br /&gt;
Delete your no longer needed bookmark:&lt;br /&gt;
* hg bookmark -d fx-team-checkins&lt;br /&gt;
&lt;br /&gt;
===== Multiple repositories with a single set of patches each =====&lt;br /&gt;
You can set up multiple sets of patches at once against multiple repositories:&lt;br /&gt;
Update fx-team&lt;br /&gt;
* hg pull fx-team &amp;amp;&amp;amp; hg up fx-team&lt;br /&gt;
Create a bookmark to base your fx-team checkin-needed patches&lt;br /&gt;
* hg bookmark fxteam-checkins&lt;br /&gt;
Import a bunch of patches against fx-team&lt;br /&gt;
* hg import &amp;lt;patch1&amp;gt;&lt;br /&gt;
* hg import &amp;lt;patch2&amp;gt;&lt;br /&gt;
Update inbound and make a bookmark for inbound patches&lt;br /&gt;
* hg pull inbound &amp;amp;&amp;amp; hg up inbound &amp;amp;&amp;amp; hg bookmark inbound-checkins&lt;br /&gt;
Import some patches against inbound&lt;br /&gt;
* hg import &amp;lt;patch3&amp;gt;&lt;br /&gt;
* hg import &amp;lt;patch4&amp;gt;&lt;br /&gt;
See what you&#039;d be pushing to inbound and push it&lt;br /&gt;
* hg out -r . inbound # this will only show patch3 and patch4&lt;br /&gt;
* hg push -r . inbound # this only pushes patch3 and patch4&lt;br /&gt;
* hg bookmark -d inbound-checkins # delete inbound&#039;s checkin bookmark as it&#039;s not needed&lt;br /&gt;
Go back to your fx-team checkins and add another patch to the bookmark, then push it&lt;br /&gt;
* hg up fxteam-checkins&lt;br /&gt;
* hg import &amp;lt;patch5&amp;gt;&lt;br /&gt;
* hg out -r . fx-team # this will be patch1, patch2, and patch5&lt;br /&gt;
* hg push -r . fx-team&lt;br /&gt;
* hg bookmark -d fxteam-checkins&lt;br /&gt;
&lt;br /&gt;
===== Single repository with multiple sets of patches =====&lt;br /&gt;
Or have multiple sets of patches against a single repository:&lt;br /&gt;
Update fx-team&lt;br /&gt;
* hg pull fx-team &amp;amp;&amp;amp; hg up fx-team&lt;br /&gt;
Make the first bookmark/set&lt;br /&gt;
* hg bookmark fxteam-checkins-1&lt;br /&gt;
* hg import &amp;lt;patch1&amp;gt;&lt;br /&gt;
* hg import &amp;lt;patch2&amp;gt;&lt;br /&gt;
Make the second set&lt;br /&gt;
* hg up fx-team &amp;amp;&amp;amp; hg bookmark fxteam-checkins-2&lt;br /&gt;
* hg import &amp;lt;patch3&amp;gt;&lt;br /&gt;
* hg import &amp;lt;patch4&amp;gt;&lt;br /&gt;
See what&#039;s going to be pushed in each&lt;br /&gt;
* hg out -r . fx-team # patch3 and patch4&lt;br /&gt;
* hg up fxteam-checkins-1 &amp;amp;&amp;amp; hg out -r . fx-team # patch1 and patch2&lt;br /&gt;
Push the first set&lt;br /&gt;
* hg push -r . fx-team # pushes patch1 and patch2&lt;br /&gt;
Get ready to push the second set&lt;br /&gt;
* hg up fxteam-checkins-2&lt;br /&gt;
* hg rebase -d fx-team # Rebase the second set onto the now-pushed first set&lt;br /&gt;
And push it&lt;br /&gt;
* hg push -r . fx-team # pushes patch3 and patch4&lt;br /&gt;
Delete the now-unneeded bookmarks&lt;br /&gt;
* hg bookmark -d fxteam-checkins-1&lt;br /&gt;
* hg bookmark -d fxteam-checkins-2&lt;br /&gt;
&lt;br /&gt;
=== Uplifts ===&lt;br /&gt;
If branch-specific patches are posted, follow the checkin-needed instructions above, importing the patches onto the release branch.&lt;br /&gt;
&lt;br /&gt;
If you&#039;re uplifting directly from an m-c checkin to aurora:&lt;br /&gt;
&lt;br /&gt;
Pull and update to prepare for the uplifts:&lt;br /&gt;
* hg pull central&lt;br /&gt;
* hg pull aurora&lt;br /&gt;
* hg up aurora&lt;br /&gt;
Graft the mc commit and bring up the editor to edit the commit message, adding &amp;quot;a=foo&amp;quot; as needed:&lt;br /&gt;
* hg graft --edit -r &amp;lt;revision&amp;gt;&lt;br /&gt;
Repeat the previous step as needed for all uplifts as needed.&lt;br /&gt;
Verify the outgoing changes and push:&lt;br /&gt;
* hg out -r . aurora&lt;br /&gt;
* hg push -r . aurora&lt;br /&gt;
&lt;br /&gt;
You can graft a range of commits at once if that&#039;s easier:&lt;br /&gt;
* hg graft -r &amp;lt;toprevision&amp;gt;::&amp;lt;bottomrevision&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Read the documentation for [https://mozilla-version-control-tools.readthedocs.org/en/latest/hgmozilla/unifiedrepo.html#uplifting-backporting-commits graft] for further help.&lt;br /&gt;
&lt;br /&gt;
=== Backouts ===&lt;br /&gt;
Better tools are coming:&lt;br /&gt;
* https://bugzilla.mozilla.org/show_bug.cgi?id=1117632&lt;br /&gt;
* https://bugzilla.mozilla.org/show_bug.cgi?id=1121211&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The standard backout command makes backing out revisions more difficult than it should, as it won&#039;t pre-fill the backout commit message with a bug number:&lt;br /&gt;
* Copy backout &amp;lt;revision&amp;gt; from treeherder, note the bug &amp;lt;number&amp;gt;, and remember the &amp;lt;reason&amp;gt;&lt;br /&gt;
* hg backout -r &amp;lt;revision&amp;gt;&lt;br /&gt;
** This should open up your editor with a completely empty commit message. Type in the backout message like &amp;quot;Backout revision &amp;lt;revision&amp;gt; (bug &amp;lt;number&amp;gt;) for &amp;lt;reason&amp;gt;&amp;quot; (possibly with &amp;quot;CLOSED TREE&amp;quot; in there to get around a closure hook).&lt;br /&gt;
* hg push -r . &amp;lt;tree&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[https://hg.mozilla.org/hgcustom/version-control-tools/file/4e7ab9638cf0/hgext/qbackout qbackout] can still be used, though you will want to use `hg oops` in place of `hg qbackout` (eg if you use `hg share` to get multiple working directories, qbackout and other uses of mq do not play nice with shared repos):&lt;br /&gt;
* Copy the backout &amp;lt;revision&amp;gt; from treeherder&lt;br /&gt;
* hg oops -e -r &amp;lt;revision&amp;gt;&lt;br /&gt;
** This should open up your editor with a prepopulated commit message like &amp;quot;Backed out &amp;lt;revision&amp;gt; (bug &amp;lt;number&amp;gt;)&amp;quot;. Add in the &amp;lt;reason&amp;gt; and possibly &amp;quot;CLOSED TREE&amp;quot; to get around a closure hook.&lt;br /&gt;
* hg out -r . &amp;lt;tree&amp;gt;&lt;br /&gt;
** to double-check what you will be pushing&lt;br /&gt;
* hg push -r . &amp;lt;tree&amp;gt;&lt;br /&gt;
&lt;br /&gt;
qbackout can also back out a range of commits in a single backout commit:&lt;br /&gt;
* hg oops -e -s -r &amp;lt;toprevision&amp;gt;:&amp;lt;bottomrevision&amp;gt;&lt;br /&gt;
** This will open your editor with a prepopulated commit message like &amp;quot;Backed out &amp;lt;toprevision&amp;gt;,&amp;lt;anymiddlerevisions&amp;gt;,&amp;lt;bottomrevision&amp;gt; (bug &amp;lt;number&amp;gt;,any other bug &amp;lt;numbers&amp;gt;)&amp;quot;. Add in the &amp;lt;reason&amp;gt; and possibly &amp;quot;CLOSED TREE&amp;quot; to get around a closure hook.&lt;br /&gt;
* hg push -r . &amp;lt;tree&amp;gt;&lt;br /&gt;
(Omit oops&#039;s -s flag to back out each individual revision in the range as a separate commit.)&lt;br /&gt;
&lt;br /&gt;
==== Revert a backout ====&lt;br /&gt;
* `hg graft`, see https://mozilla-version-control-tools.readthedocs.org/en/latest/hgmozilla/common.html#revive-a-commit-that-was-backed-out&lt;br /&gt;
&lt;br /&gt;
=== Rebasing after losing a push race ===&lt;br /&gt;
This assumes you have commits you&#039;re attempting to push to mozilla-inbound when you lose a push race with someone. Change `inbound` to the correct branch name as needed.&lt;br /&gt;
&lt;br /&gt;
* hg pull inbound &lt;br /&gt;
* hg rebase -d inbound &lt;br /&gt;
* hg push -r . inbound&lt;br /&gt;
&lt;br /&gt;
=== Recovering from mistakes ===&lt;br /&gt;
&amp;lt;big&amp;gt;WARNING:&amp;lt;/big&amp;gt; This will strip out any commits that haven&#039;t been pushed to the remote repositories, regardless of what branch/label/tag those commits are on. (So if you have local changes on inbound and run this command to strip something bad on fx-team, both inbound and fx-team will be stripped.) Only do this if you don&#039;t care about any of those commits!&lt;br /&gt;
* hg strip &#039;not public()&#039;&lt;br /&gt;
&lt;br /&gt;
You may also need to use some combination of the following to get things back to a known-good state:&lt;br /&gt;
* hg purge # http://mercurial.selenic.com/wiki/PurgeExtension&lt;br /&gt;
* hg up -C&lt;br /&gt;
&lt;br /&gt;
=== See what you&#039;re about to push ===&lt;br /&gt;
`hg out` without any flags added will show you a LOT of unrelated commits. To see just what you&#039;ll be pushing to a given branch, use `hg out -r . &amp;lt;branch&amp;gt;`&lt;br /&gt;
* hg out -r . inbound&lt;br /&gt;
** This will only display the things you&#039;re about to push to the inbound branch&lt;br /&gt;
&lt;br /&gt;
=== View incoming changes ===&lt;br /&gt;
Since your unified repo will likely have all changesets from the various branches pulled locally, `hg in &amp;lt;somebranch&amp;gt; -r &amp;lt;somerev&amp;gt;` will likely not help you see what would be pulled into your current branch from &amp;lt;somebranch&amp;gt; up to that &amp;lt;somerev&amp;gt;.&lt;br /&gt;
Instead, you can use the following to print out the equivalent. Say you want to see what would be merged onto mozilla-central from b2g-inbound&#039;s revision ca142ec8ba0f:&lt;br /&gt;
&lt;br /&gt;
Make sure m-c is fully up to date:&lt;br /&gt;
* hg pull central &lt;br /&gt;
* hg up central &lt;br /&gt;
Get all of b2g-inbound&#039;s changesets:&lt;br /&gt;
* hg pull b2ginbound&lt;br /&gt;
Do a preview of the merge without actually performing the merge:&lt;br /&gt;
* hg merge -r ca142ec8ba0f -P&lt;br /&gt;
This will print out everything on b2g-inbound (up to and including revision ca142ec8ba0f) that is not already on mozilla-central.&lt;br /&gt;
&lt;br /&gt;
=== See the log for a particular branch ===&lt;br /&gt;
* hg log -fr [branch]&lt;br /&gt;
&lt;br /&gt;
= Extras =&lt;br /&gt;
== hg aliases ==&lt;br /&gt;
I set up the following aliases in my global .hgrc file to make merging things around trunk a little faster:&lt;br /&gt;
 [alias]&lt;br /&gt;
 # merge tree $1, revision $2 to central, optionally appending $3 (for &amp;quot;CLOSED TREE&amp;quot;, etc)&lt;br /&gt;
 mergetocentral = !$HG pull central ; $HG up central ; $HG pull $1 ; $HG merge $2 ; $HG commit -m &amp;quot;Merge $1 to central, a=merge $3&amp;quot; ; $HG push -r . central&lt;br /&gt;
 # merge central tip to tree $1, optionally appending $2 (for &amp;quot;CLOSED TREE&amp;quot;, etc)&lt;br /&gt;
 mergetointegration = !$HG pull central ; $HG pull $1 ; $HG up $1 ; $HG merge central ; $HG commit -m &amp;quot;Merge m-c to $1, a=merge $2&amp;quot; ; $HG push -r . $1&lt;br /&gt;
&lt;br /&gt;
With these set up, I can merge fx-team&#039;s revision 04a3d9130aa0 over to mozilla-central with the following command:&lt;br /&gt;
 hg mergetocentral fx-team 04a3d9130aa0&lt;br /&gt;
and then I can merge mozilla-central&#039;s tip back to fx-team with the following command:&lt;br /&gt;
 hg mergetointegration fx-team&lt;br /&gt;
This cuts down on a lot of repetitive typing, saving a bit of time.&lt;br /&gt;
&lt;br /&gt;
For merging from reviewboard patches, there&#039;s this alias&lt;br /&gt;
  rbimport = !hg transplant -e -s https://reviewboard-hg.mozilla.org/gecko -b $1&lt;br /&gt;
&lt;br /&gt;
Then, it&#039;s matter of importing the right hash like the following command:&lt;br /&gt;
  hg rbimport dd1462ba321db983061b94e30cee92b6bd81e908&lt;/div&gt;</summary>
		<author><name>Sfink</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=Sheriffing/How_To/Unified_Repos&amp;diff=1137421</id>
		<title>Sheriffing/How To/Unified Repos</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=Sheriffing/How_To/Unified_Repos&amp;diff=1137421"/>
		<updated>2016-06-23T04:21:39Z</updated>

		<summary type="html">&lt;p&gt;Sfink: /* Backouts */ backticks do not format code&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Unified Repos ==&lt;br /&gt;
* http://mozilla-version-control-tools.readthedocs.org/en/latest/hgmozilla/unifiedrepo.html&lt;br /&gt;
* https://mozilla-version-control-tools.readthedocs.org/en/latest/hgmozilla/firefoxtree.html&lt;br /&gt;
&lt;br /&gt;
=== Setting up the repo ===&lt;br /&gt;
* Set up your ssh key yourself&lt;br /&gt;
* Install Mercurial 3.2 or higher&lt;br /&gt;
* Make a copy of your .hgrc file for safekeeping and delete the original&lt;br /&gt;
* hg clone https://hg.mozilla.org/mozilla-central&lt;br /&gt;
* cd mozilla-central&lt;br /&gt;
* ./mach mercurial-setup&lt;br /&gt;
Configure mercurial as desired &amp;lt;br /&amp;gt;&lt;br /&gt;
The following will pull all (or at least most) of the branches sheriffs need to have on hand:&lt;br /&gt;
* hg pull inbound &amp;amp;&amp;amp; hg pull fx-team &amp;amp;&amp;amp; hg pull aurora &amp;amp;&amp;amp; hg pull beta &amp;amp;&amp;amp; hg pull esr38&lt;br /&gt;
If you need other branches, you can find their names in the [https://hg.mozilla.org/hgcustom/version-control-tools/file/default/pylib/mozautomation/mozautomation/repository.py firefoxtree extension source].&lt;br /&gt;
&lt;br /&gt;
You should now have everything set up for proper use! &amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Maybe rename the folder from &amp;quot;mozilla-central&amp;quot; to &amp;quot;unifiedrepo&amp;quot; or something to make it clear it&#039;s more than just mozilla-central?&lt;br /&gt;
&lt;br /&gt;
The `hg fxheads` command should list references to each of the relevant branch names, and the current revision and commit message for each.&lt;br /&gt;
&lt;br /&gt;
With [https://bugzilla.mozilla.org/show_bug.cgi?id=1116861 bug 1116861] landed in version-control-tools, you can now use the following commands to pull from groups of repositories with a single command:&lt;br /&gt;
* hg pull fxtrees # this will pull from all branches listed with the fxheads command&lt;br /&gt;
* hg pull integration # this will pull from the mozilla-inbound, b2g-inbound, and fx-team branches&lt;br /&gt;
* hg pull releases # this will pull from pretty much every release branch (FYI: including old, unused branches)&lt;br /&gt;
&lt;br /&gt;
=== Merges ===&lt;br /&gt;
This assumes you have your unified repo all set up so that `hg fxheads` lists each of central, b2ginbound, fx-team, and inbound.&lt;br /&gt;
&lt;br /&gt;
To merge a specific non-tip &amp;lt;revision&amp;gt; from mozilla-inbound to mozilla-central:&lt;br /&gt;
# hg pull central&lt;br /&gt;
# hg pull inbound&lt;br /&gt;
# hg up central&lt;br /&gt;
# hg merge -r &amp;lt;revision&amp;gt;&lt;br /&gt;
# hg commit -m &amp;quot;Merge mozilla-inbound to mozilla-central a=merge&amp;quot;&lt;br /&gt;
# hg push -r . central&lt;br /&gt;
&lt;br /&gt;
To merge mozilla-central into mozilla-inbound:&lt;br /&gt;
# hg pull central&lt;br /&gt;
# hg pull inbound&lt;br /&gt;
# hg up inbound&lt;br /&gt;
# hg merge central&lt;br /&gt;
# hg commit -m &amp;quot;Merge mozilla-central to mozilla-inbound a=merge&amp;quot;&lt;br /&gt;
# hg push -r . inbound&lt;br /&gt;
&lt;br /&gt;
* If the `hg merge central` command results in &amp;quot;abort: nothing to merge&amp;quot;, you should instead use `hg update -r &amp;lt;mozilla-central&#039;s tip revision&amp;gt;` to do a non-merging update, then you can do `hg push -r . inbound` to push it as usual.&lt;br /&gt;
&lt;br /&gt;
=== Checkin-neededs ===&lt;br /&gt;
This assumes we&#039;re checking things in to fx-team. Replace fx-team with another branch name as needed.&lt;br /&gt;
&lt;br /&gt;
===== Single repository and single set of patches =====&lt;br /&gt;
Update fx-team and prepare for the patches:&lt;br /&gt;
* hg pull fx-team&lt;br /&gt;
* hg up fx-team&lt;br /&gt;
* hg bookmark fx-team-checkins&lt;br /&gt;
Import the patches:&lt;br /&gt;
* hg import https://link.to/correct/checkin-needed.patch&lt;br /&gt;
* Repeat ^ as needed for all fx-team checkin-needed patches&lt;br /&gt;
Verify your outgoing changes:&lt;br /&gt;
* hg out -r . fx-team&lt;br /&gt;
If you haven&#039;t lost a push race:&lt;br /&gt;
* hg push -r . fx-team&lt;br /&gt;
If you lost a push race:&lt;br /&gt;
* hg pull fx-team&lt;br /&gt;
* hg rebase -d fx-team&lt;br /&gt;
* hg push -r . fx-team&lt;br /&gt;
Delete your no longer needed bookmark:&lt;br /&gt;
* hg bookmark -d fx-team-checkins&lt;br /&gt;
&lt;br /&gt;
===== Multiple repositories with a single set of patches each =====&lt;br /&gt;
You can set up multiple sets of patches at once against multiple repositories:&lt;br /&gt;
Update fx-team&lt;br /&gt;
* hg pull fx-team &amp;amp;&amp;amp; hg up fx-team&lt;br /&gt;
Create a bookmark to base your fx-team checkin-needed patches&lt;br /&gt;
* hg bookmark fxteam-checkins&lt;br /&gt;
Import a bunch of patches against fx-team&lt;br /&gt;
* hg import &amp;lt;patch1&amp;gt;&lt;br /&gt;
* hg import &amp;lt;patch2&amp;gt;&lt;br /&gt;
Update inbound and make a bookmark for inbound patches&lt;br /&gt;
* hg pull inbound &amp;amp;&amp;amp; hg up inbound &amp;amp;&amp;amp; hg bookmark inbound-checkins&lt;br /&gt;
Import some patches against inbound&lt;br /&gt;
* hg import &amp;lt;patch3&amp;gt;&lt;br /&gt;
* hg import &amp;lt;patch4&amp;gt;&lt;br /&gt;
See what you&#039;d be pushing to inbound and push it&lt;br /&gt;
* hg out -r . inbound # this will only show patch3 and patch4&lt;br /&gt;
* hg push -r . inbound # this only pushes patch3 and patch4&lt;br /&gt;
* hg bookmark -d inbound-checkins # delete inbound&#039;s checkin bookmark as it&#039;s not needed&lt;br /&gt;
Go back to your fx-team checkins and add another patch to the bookmark, then push it&lt;br /&gt;
* hg up fxteam-checkins&lt;br /&gt;
* hg import &amp;lt;patch5&amp;gt;&lt;br /&gt;
* hg out -r . fx-team # this will be patch1, patch2, and patch5&lt;br /&gt;
* hg push -r . fx-team&lt;br /&gt;
* hg bookmark -d fxteam-checkins&lt;br /&gt;
&lt;br /&gt;
===== Single repository with multiple sets of patches =====&lt;br /&gt;
Or have multiple sets of patches against a single repository:&lt;br /&gt;
Update fx-team&lt;br /&gt;
* hg pull fx-team &amp;amp;&amp;amp; hg up fx-team&lt;br /&gt;
Make the first bookmark/set&lt;br /&gt;
* hg bookmark fxteam-checkins-1&lt;br /&gt;
* hg import &amp;lt;patch1&amp;gt;&lt;br /&gt;
* hg import &amp;lt;patch2&amp;gt;&lt;br /&gt;
Make the second set&lt;br /&gt;
* hg up fx-team &amp;amp;&amp;amp; hg bookmark fxteam-checkins-2&lt;br /&gt;
* hg import &amp;lt;patch3&amp;gt;&lt;br /&gt;
* hg import &amp;lt;patch4&amp;gt;&lt;br /&gt;
See what&#039;s going to be pushed in each&lt;br /&gt;
* hg out -r . fx-team # patch3 and patch4&lt;br /&gt;
* hg up fxteam-checkins-1 &amp;amp;&amp;amp; hg out -r . fx-team # patch1 and patch2&lt;br /&gt;
Push the first set&lt;br /&gt;
* hg push -r . fx-team # pushes patch1 and patch2&lt;br /&gt;
Get ready to push the second set&lt;br /&gt;
* hg up fxteam-checkins-2&lt;br /&gt;
* hg rebase -d fx-team # Rebase the second set onto the now-pushed first set&lt;br /&gt;
And push it&lt;br /&gt;
* hg push -r . fx-team # pushes patch3 and patch4&lt;br /&gt;
Delete the now-unneeded bookmarks&lt;br /&gt;
* hg bookmark -d fxteam-checkins-1&lt;br /&gt;
* hg bookmark -d fxteam-checkins-2&lt;br /&gt;
&lt;br /&gt;
=== Uplifts ===&lt;br /&gt;
If branch-specific patches are posted, follow the checkin-needed instructions above, importing the patches onto the release branch.&lt;br /&gt;
&lt;br /&gt;
If you&#039;re uplifting directly from an m-c checkin to aurora:&lt;br /&gt;
&lt;br /&gt;
Pull and update to prepare for the uplifts:&lt;br /&gt;
* hg pull central&lt;br /&gt;
* hg pull aurora&lt;br /&gt;
* hg up aurora&lt;br /&gt;
Graft the mc commit and bring up the editor to edit the commit message, adding &amp;quot;a=foo&amp;quot; as needed:&lt;br /&gt;
* hg graft --edit -r &amp;lt;revision&amp;gt;&lt;br /&gt;
Repeat the previous step as needed for all uplifts as needed.&lt;br /&gt;
Verify the outgoing changes and push:&lt;br /&gt;
* hg out -r . aurora&lt;br /&gt;
* hg push -r . aurora&lt;br /&gt;
&lt;br /&gt;
You can graft a range of commits at once if that&#039;s easier:&lt;br /&gt;
* hg graft -r &amp;lt;toprevision&amp;gt;::&amp;lt;bottomrevision&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Read the documentation for [https://mozilla-version-control-tools.readthedocs.org/en/latest/hgmozilla/unifiedrepo.html#uplifting-backporting-commits graft] for further help.&lt;br /&gt;
&lt;br /&gt;
=== Backouts ===&lt;br /&gt;
Better tools are coming:&lt;br /&gt;
* https://bugzilla.mozilla.org/show_bug.cgi?id=1117632&lt;br /&gt;
* https://bugzilla.mozilla.org/show_bug.cgi?id=1121211&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The standard backout command makes backing out revisions more difficult than it should, as it won&#039;t pre-fill the backout commit message with a bug number:&lt;br /&gt;
* Copy backout &amp;lt;revision&amp;gt; from treeherder, note the bug &amp;lt;number&amp;gt;, and remember the &amp;lt;reason&amp;gt;&lt;br /&gt;
* hg backout -r &amp;lt;revision&amp;gt;&lt;br /&gt;
** This should open up your editor with a completely empty commit message. Type in the backout message like &amp;quot;Backout revision &amp;lt;revision&amp;gt; (bug &amp;lt;number&amp;gt;) for &amp;lt;reason&amp;gt;&amp;quot; (possibly with &amp;quot;CLOSED TREE&amp;quot; in there to get around a closure hook).&lt;br /&gt;
* hg push -r . &amp;lt;tree&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[https://hg.mozilla.org/hgcustom/version-control-tools/file/4e7ab9638cf0/hgext/qbackout qbackout] can still be used, though you will want to use `hg oops` in place of `hg qbackout` (eg if you use `hg share` to get multiple working directories, qbackout and other uses of mq do not play nice with shared repos):&lt;br /&gt;
* Copy the backout &amp;lt;revision&amp;gt; from treeherder&lt;br /&gt;
* hg oops -e -r &amp;lt;revision&amp;gt;&lt;br /&gt;
** This should open up your editor with a prepopulated commit message like &amp;quot;Backed out &amp;lt;revision&amp;gt; (bug &amp;lt;number&amp;gt;)&amp;quot;. Add in the &amp;lt;reason&amp;gt; and possibly &amp;quot;CLOSED TREE&amp;quot; to get around a closure hook.&lt;br /&gt;
* hg out -r . &amp;lt;tree&amp;gt; &#039;&#039;(to double-check what you will be pushing)&#039;&#039;&lt;br /&gt;
* hg push -r . &amp;lt;tree&amp;gt;&lt;br /&gt;
&lt;br /&gt;
qbackout can also back out a range of commits in a single backout commit:&lt;br /&gt;
* hg oops -e -s -r &amp;lt;toprevision&amp;gt;:&amp;lt;bottomrevision&amp;gt;&lt;br /&gt;
** This will open your editor with a prepopulated commit message like &amp;quot;Backed out &amp;lt;toprevision&amp;gt;,&amp;lt;anymiddlerevisions&amp;gt;,&amp;lt;bottomrevision&amp;gt; (bug &amp;lt;number&amp;gt;,any other bug &amp;lt;numbers&amp;gt;)&amp;quot;. Add in the &amp;lt;reason&amp;gt; and possibly &amp;quot;CLOSED TREE&amp;quot; to get around a closure hook.&lt;br /&gt;
* hg push -r . &amp;lt;tree&amp;gt;&lt;br /&gt;
(Omit oops&#039;s -s flag to back out each individual revision in the range as a separate commit.)&lt;br /&gt;
&lt;br /&gt;
==== Revert a backout ====&lt;br /&gt;
* `hg graft`, see https://mozilla-version-control-tools.readthedocs.org/en/latest/hgmozilla/common.html#revive-a-commit-that-was-backed-out&lt;br /&gt;
&lt;br /&gt;
=== Rebasing after losing a push race ===&lt;br /&gt;
This assumes you have commits you&#039;re attempting to push to mozilla-inbound when you lose a push race with someone. Change `inbound` to the correct branch name as needed.&lt;br /&gt;
&lt;br /&gt;
* hg pull inbound &lt;br /&gt;
* hg rebase -d inbound &lt;br /&gt;
* hg push -r . inbound&lt;br /&gt;
&lt;br /&gt;
=== Recovering from mistakes ===&lt;br /&gt;
&amp;lt;big&amp;gt;WARNING:&amp;lt;/big&amp;gt; This will strip out any commits that haven&#039;t been pushed to the remote repositories, regardless of what branch/label/tag those commits are on. (So if you have local changes on inbound and run this command to strip something bad on fx-team, both inbound and fx-team will be stripped.) Only do this if you don&#039;t care about any of those commits!&lt;br /&gt;
* hg strip &#039;not public()&#039;&lt;br /&gt;
&lt;br /&gt;
You may also need to use some combination of the following to get things back to a known-good state:&lt;br /&gt;
* hg purge # http://mercurial.selenic.com/wiki/PurgeExtension&lt;br /&gt;
* hg up -C&lt;br /&gt;
&lt;br /&gt;
=== See what you&#039;re about to push ===&lt;br /&gt;
`hg out` without any flags added will show you a LOT of unrelated commits. To see just what you&#039;ll be pushing to a given branch, use `hg out -r . &amp;lt;branch&amp;gt;`&lt;br /&gt;
* hg out -r . inbound&lt;br /&gt;
** This will only display the things you&#039;re about to push to the inbound branch&lt;br /&gt;
&lt;br /&gt;
=== View incoming changes ===&lt;br /&gt;
Since your unified repo will likely have all changesets from the various branches pulled locally, `hg in &amp;lt;somebranch&amp;gt; -r &amp;lt;somerev&amp;gt;` will likely not help you see what would be pulled into your current branch from &amp;lt;somebranch&amp;gt; up to that &amp;lt;somerev&amp;gt;.&lt;br /&gt;
Instead, you can use the following to print out the equivalent. Say you want to see what would be merged onto mozilla-central from b2g-inbound&#039;s revision ca142ec8ba0f:&lt;br /&gt;
&lt;br /&gt;
Make sure m-c is fully up to date:&lt;br /&gt;
* hg pull central &lt;br /&gt;
* hg up central &lt;br /&gt;
Get all of b2g-inbound&#039;s changesets:&lt;br /&gt;
* hg pull b2ginbound&lt;br /&gt;
Do a preview of the merge without actually performing the merge:&lt;br /&gt;
* hg merge -r ca142ec8ba0f -P&lt;br /&gt;
This will print out everything on b2g-inbound (up to and including revision ca142ec8ba0f) that is not already on mozilla-central.&lt;br /&gt;
&lt;br /&gt;
=== See the log for a particular branch ===&lt;br /&gt;
* hg log -fr [branch]&lt;br /&gt;
&lt;br /&gt;
= Extras =&lt;br /&gt;
== hg aliases ==&lt;br /&gt;
I set up the following aliases in my global .hgrc file to make merging things around trunk a little faster:&lt;br /&gt;
 [alias]&lt;br /&gt;
 # merge tree $1, revision $2 to central, optionally appending $3 (for &amp;quot;CLOSED TREE&amp;quot;, etc)&lt;br /&gt;
 mergetocentral = !$HG pull central ; $HG up central ; $HG pull $1 ; $HG merge $2 ; $HG commit -m &amp;quot;Merge $1 to central, a=merge $3&amp;quot; ; $HG push -r . central&lt;br /&gt;
 # merge central tip to tree $1, optionally appending $2 (for &amp;quot;CLOSED TREE&amp;quot;, etc)&lt;br /&gt;
 mergetointegration = !$HG pull central ; $HG pull $1 ; $HG up $1 ; $HG merge central ; $HG commit -m &amp;quot;Merge m-c to $1, a=merge $2&amp;quot; ; $HG push -r . $1&lt;br /&gt;
&lt;br /&gt;
With these set up, I can merge fx-team&#039;s revision 04a3d9130aa0 over to mozilla-central with the following command:&lt;br /&gt;
 hg mergetocentral fx-team 04a3d9130aa0&lt;br /&gt;
and then I can merge mozilla-central&#039;s tip back to fx-team with the following command:&lt;br /&gt;
 hg mergetointegration fx-team&lt;br /&gt;
This cuts down on a lot of repetitive typing, saving a bit of time.&lt;br /&gt;
&lt;br /&gt;
For merging from reviewboard patches, there&#039;s this alias&lt;br /&gt;
  rbimport = !hg transplant -e -s https://reviewboard-hg.mozilla.org/gecko -b $1&lt;br /&gt;
&lt;br /&gt;
Then, it&#039;s matter of importing the right hash like the following command:&lt;br /&gt;
  hg rbimport dd1462ba321db983061b94e30cee92b6bd81e908&lt;/div&gt;</summary>
		<author><name>Sfink</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=Sheriffing/How_To/Unified_Repos&amp;diff=1137420</id>
		<title>Sheriffing/How To/Unified Repos</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=Sheriffing/How_To/Unified_Repos&amp;diff=1137420"/>
		<updated>2016-06-23T04:16:44Z</updated>

		<summary type="html">&lt;p&gt;Sfink: /* Backouts */ switch to hg oops&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Unified Repos ==&lt;br /&gt;
* http://mozilla-version-control-tools.readthedocs.org/en/latest/hgmozilla/unifiedrepo.html&lt;br /&gt;
* https://mozilla-version-control-tools.readthedocs.org/en/latest/hgmozilla/firefoxtree.html&lt;br /&gt;
&lt;br /&gt;
=== Setting up the repo ===&lt;br /&gt;
* Set up your ssh key yourself&lt;br /&gt;
* Install Mercurial 3.2 or higher&lt;br /&gt;
* Make a copy of your .hgrc file for safekeeping and delete the original&lt;br /&gt;
* hg clone https://hg.mozilla.org/mozilla-central&lt;br /&gt;
* cd mozilla-central&lt;br /&gt;
* ./mach mercurial-setup&lt;br /&gt;
Configure mercurial as desired &amp;lt;br /&amp;gt;&lt;br /&gt;
The following will pull all (or at least most) of the branches sheriffs need to have on hand:&lt;br /&gt;
* hg pull inbound &amp;amp;&amp;amp; hg pull fx-team &amp;amp;&amp;amp; hg pull aurora &amp;amp;&amp;amp; hg pull beta &amp;amp;&amp;amp; hg pull esr38&lt;br /&gt;
If you need other branches, you can find their names in the [https://hg.mozilla.org/hgcustom/version-control-tools/file/default/pylib/mozautomation/mozautomation/repository.py firefoxtree extension source].&lt;br /&gt;
&lt;br /&gt;
You should now have everything set up for proper use! &amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Maybe rename the folder from &amp;quot;mozilla-central&amp;quot; to &amp;quot;unifiedrepo&amp;quot; or something to make it clear it&#039;s more than just mozilla-central?&lt;br /&gt;
&lt;br /&gt;
The `hg fxheads` command should list references to each of the relevant branch names, and the current revision and commit message for each.&lt;br /&gt;
&lt;br /&gt;
With [https://bugzilla.mozilla.org/show_bug.cgi?id=1116861 bug 1116861] landed in version-control-tools, you can now use the following commands to pull from groups of repositories with a single command:&lt;br /&gt;
* hg pull fxtrees # this will pull from all branches listed with the fxheads command&lt;br /&gt;
* hg pull integration # this will pull from the mozilla-inbound, b2g-inbound, and fx-team branches&lt;br /&gt;
* hg pull releases # this will pull from pretty much every release branch (FYI: including old, unused branches)&lt;br /&gt;
&lt;br /&gt;
=== Merges ===&lt;br /&gt;
This assumes you have your unified repo all set up so that `hg fxheads` lists each of central, b2ginbound, fx-team, and inbound.&lt;br /&gt;
&lt;br /&gt;
To merge a specific non-tip &amp;lt;revision&amp;gt; from mozilla-inbound to mozilla-central:&lt;br /&gt;
# hg pull central&lt;br /&gt;
# hg pull inbound&lt;br /&gt;
# hg up central&lt;br /&gt;
# hg merge -r &amp;lt;revision&amp;gt;&lt;br /&gt;
# hg commit -m &amp;quot;Merge mozilla-inbound to mozilla-central a=merge&amp;quot;&lt;br /&gt;
# hg push -r . central&lt;br /&gt;
&lt;br /&gt;
To merge mozilla-central into mozilla-inbound:&lt;br /&gt;
# hg pull central&lt;br /&gt;
# hg pull inbound&lt;br /&gt;
# hg up inbound&lt;br /&gt;
# hg merge central&lt;br /&gt;
# hg commit -m &amp;quot;Merge mozilla-central to mozilla-inbound a=merge&amp;quot;&lt;br /&gt;
# hg push -r . inbound&lt;br /&gt;
&lt;br /&gt;
* If the `hg merge central` command results in &amp;quot;abort: nothing to merge&amp;quot;, you should instead use `hg update -r &amp;lt;mozilla-central&#039;s tip revision&amp;gt;` to do a non-merging update, then you can do `hg push -r . inbound` to push it as usual.&lt;br /&gt;
&lt;br /&gt;
=== Checkin-neededs ===&lt;br /&gt;
This assumes we&#039;re checking things in to fx-team. Replace fx-team with another branch name as needed.&lt;br /&gt;
&lt;br /&gt;
===== Single repository and single set of patches =====&lt;br /&gt;
Update fx-team and prepare for the patches:&lt;br /&gt;
* hg pull fx-team&lt;br /&gt;
* hg up fx-team&lt;br /&gt;
* hg bookmark fx-team-checkins&lt;br /&gt;
Import the patches:&lt;br /&gt;
* hg import https://link.to/correct/checkin-needed.patch&lt;br /&gt;
* Repeat ^ as needed for all fx-team checkin-needed patches&lt;br /&gt;
Verify your outgoing changes:&lt;br /&gt;
* hg out -r . fx-team&lt;br /&gt;
If you haven&#039;t lost a push race:&lt;br /&gt;
* hg push -r . fx-team&lt;br /&gt;
If you lost a push race:&lt;br /&gt;
* hg pull fx-team&lt;br /&gt;
* hg rebase -d fx-team&lt;br /&gt;
* hg push -r . fx-team&lt;br /&gt;
Delete your no longer needed bookmark:&lt;br /&gt;
* hg bookmark -d fx-team-checkins&lt;br /&gt;
&lt;br /&gt;
===== Multiple repositories with a single set of patches each =====&lt;br /&gt;
You can set up multiple sets of patches at once against multiple repositories:&lt;br /&gt;
Update fx-team&lt;br /&gt;
* hg pull fx-team &amp;amp;&amp;amp; hg up fx-team&lt;br /&gt;
Create a bookmark to base your fx-team checkin-needed patches&lt;br /&gt;
* hg bookmark fxteam-checkins&lt;br /&gt;
Import a bunch of patches against fx-team&lt;br /&gt;
* hg import &amp;lt;patch1&amp;gt;&lt;br /&gt;
* hg import &amp;lt;patch2&amp;gt;&lt;br /&gt;
Update inbound and make a bookmark for inbound patches&lt;br /&gt;
* hg pull inbound &amp;amp;&amp;amp; hg up inbound &amp;amp;&amp;amp; hg bookmark inbound-checkins&lt;br /&gt;
Import some patches against inbound&lt;br /&gt;
* hg import &amp;lt;patch3&amp;gt;&lt;br /&gt;
* hg import &amp;lt;patch4&amp;gt;&lt;br /&gt;
See what you&#039;d be pushing to inbound and push it&lt;br /&gt;
* hg out -r . inbound # this will only show patch3 and patch4&lt;br /&gt;
* hg push -r . inbound # this only pushes patch3 and patch4&lt;br /&gt;
* hg bookmark -d inbound-checkins # delete inbound&#039;s checkin bookmark as it&#039;s not needed&lt;br /&gt;
Go back to your fx-team checkins and add another patch to the bookmark, then push it&lt;br /&gt;
* hg up fxteam-checkins&lt;br /&gt;
* hg import &amp;lt;patch5&amp;gt;&lt;br /&gt;
* hg out -r . fx-team # this will be patch1, patch2, and patch5&lt;br /&gt;
* hg push -r . fx-team&lt;br /&gt;
* hg bookmark -d fxteam-checkins&lt;br /&gt;
&lt;br /&gt;
===== Single repository with multiple sets of patches =====&lt;br /&gt;
Or have multiple sets of patches against a single repository:&lt;br /&gt;
Update fx-team&lt;br /&gt;
* hg pull fx-team &amp;amp;&amp;amp; hg up fx-team&lt;br /&gt;
Make the first bookmark/set&lt;br /&gt;
* hg bookmark fxteam-checkins-1&lt;br /&gt;
* hg import &amp;lt;patch1&amp;gt;&lt;br /&gt;
* hg import &amp;lt;patch2&amp;gt;&lt;br /&gt;
Make the second set&lt;br /&gt;
* hg up fx-team &amp;amp;&amp;amp; hg bookmark fxteam-checkins-2&lt;br /&gt;
* hg import &amp;lt;patch3&amp;gt;&lt;br /&gt;
* hg import &amp;lt;patch4&amp;gt;&lt;br /&gt;
See what&#039;s going to be pushed in each&lt;br /&gt;
* hg out -r . fx-team # patch3 and patch4&lt;br /&gt;
* hg up fxteam-checkins-1 &amp;amp;&amp;amp; hg out -r . fx-team # patch1 and patch2&lt;br /&gt;
Push the first set&lt;br /&gt;
* hg push -r . fx-team # pushes patch1 and patch2&lt;br /&gt;
Get ready to push the second set&lt;br /&gt;
* hg up fxteam-checkins-2&lt;br /&gt;
* hg rebase -d fx-team # Rebase the second set onto the now-pushed first set&lt;br /&gt;
And push it&lt;br /&gt;
* hg push -r . fx-team # pushes patch3 and patch4&lt;br /&gt;
Delete the now-unneeded bookmarks&lt;br /&gt;
* hg bookmark -d fxteam-checkins-1&lt;br /&gt;
* hg bookmark -d fxteam-checkins-2&lt;br /&gt;
&lt;br /&gt;
=== Uplifts ===&lt;br /&gt;
If branch-specific patches are posted, follow the checkin-needed instructions above, importing the patches onto the release branch.&lt;br /&gt;
&lt;br /&gt;
If you&#039;re uplifting directly from an m-c checkin to aurora:&lt;br /&gt;
&lt;br /&gt;
Pull and update to prepare for the uplifts:&lt;br /&gt;
* hg pull central&lt;br /&gt;
* hg pull aurora&lt;br /&gt;
* hg up aurora&lt;br /&gt;
Graft the mc commit and bring up the editor to edit the commit message, adding &amp;quot;a=foo&amp;quot; as needed:&lt;br /&gt;
* hg graft --edit -r &amp;lt;revision&amp;gt;&lt;br /&gt;
Repeat the previous step as needed for all uplifts as needed.&lt;br /&gt;
Verify the outgoing changes and push:&lt;br /&gt;
* hg out -r . aurora&lt;br /&gt;
* hg push -r . aurora&lt;br /&gt;
&lt;br /&gt;
You can graft a range of commits at once if that&#039;s easier:&lt;br /&gt;
* hg graft -r &amp;lt;toprevision&amp;gt;::&amp;lt;bottomrevision&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Read the documentation for [https://mozilla-version-control-tools.readthedocs.org/en/latest/hgmozilla/unifiedrepo.html#uplifting-backporting-commits graft] for further help.&lt;br /&gt;
&lt;br /&gt;
=== Backouts ===&lt;br /&gt;
Better tools are coming:&lt;br /&gt;
* https://bugzilla.mozilla.org/show_bug.cgi?id=1117632&lt;br /&gt;
* https://bugzilla.mozilla.org/show_bug.cgi?id=1121211&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The standard backout command makes backing out revisions more difficult than it should, as it won&#039;t pre-fill the backout commit message with a bug number:&lt;br /&gt;
* Copy backout &amp;lt;revision&amp;gt; from treeherder, note the bug &amp;lt;number&amp;gt;, and remember the &amp;lt;reason&amp;gt;&lt;br /&gt;
* `hg backout -r &amp;lt;revision&amp;gt;`&lt;br /&gt;
** This should open up your editor with a completely empty commit message. Type in the backout message like &amp;quot;Backout revision &amp;lt;revision&amp;gt; (bug &amp;lt;number&amp;gt;) for &amp;lt;reason&amp;gt;&amp;quot; (possibly with &amp;quot;CLOSED TREE&amp;quot; in there to get around a closure hook).&lt;br /&gt;
* `hg push -r . &amp;lt;tree&amp;gt;`&lt;br /&gt;
&lt;br /&gt;
[https://hg.mozilla.org/hgcustom/version-control-tools/file/4e7ab9638cf0/hgext/qbackout qbackout] can still be used, though you will want to use `hg oops` in place of `hg qbackout` (eg if you use `hg share` to get multiple working directories, qbackout and other uses of mq do not play nice with shared repos):&lt;br /&gt;
* Copy the backout &amp;lt;revision&amp;gt; from treeherder&lt;br /&gt;
* `hg oops -e -r &amp;lt;revision&amp;gt;`&lt;br /&gt;
** This should open up your editor with a prepopulated commit message like &amp;quot;Backed out &amp;lt;revision&amp;gt; (bug &amp;lt;number&amp;gt;)&amp;quot;. Add in the &amp;lt;reason&amp;gt; and possibly &amp;quot;CLOSED TREE&amp;quot; to get around a closure hook.&lt;br /&gt;
* `hg out -r . &amp;lt;tree&amp;gt;` to double-check what you will be pushing&lt;br /&gt;
* `hg push -r . &amp;lt;tree&amp;gt;`&lt;br /&gt;
&lt;br /&gt;
qbackout can also back out a range of commits in a single backout commit:&lt;br /&gt;
* `hg oops -e -s -r &amp;lt;toprevision&amp;gt;:&amp;lt;bottomrevision&amp;gt;`&lt;br /&gt;
** This will open your editor with a prepopulated commit message like &amp;quot;Backed out &amp;lt;toprevision&amp;gt;,&amp;lt;anymiddlerevisions&amp;gt;,&amp;lt;bottomrevision&amp;gt; (bug &amp;lt;number&amp;gt;,any other bug &amp;lt;numbers&amp;gt;)&amp;quot;. Add in the &amp;lt;reason&amp;gt; and possibly &amp;quot;CLOSED TREE&amp;quot; to get around a closure hook.&lt;br /&gt;
* `hg push -r . &amp;lt;tree&amp;gt;`&lt;br /&gt;
(Omit oops&#039;s -s flag to back out each individual revision in the range as a separate commit.)&lt;br /&gt;
&lt;br /&gt;
==== Revert a backout ====&lt;br /&gt;
* https://mozilla-version-control-tools.readthedocs.org/en/latest/hgmozilla/common.html#revive-a-commit-that-was-backed-out&lt;br /&gt;
&lt;br /&gt;
=== Rebasing after losing a push race ===&lt;br /&gt;
This assumes you have commits you&#039;re attempting to push to mozilla-inbound when you lose a push race with someone. Change `inbound` to the correct branch name as needed.&lt;br /&gt;
&lt;br /&gt;
* hg pull inbound &lt;br /&gt;
* hg rebase -d inbound &lt;br /&gt;
* hg push -r . inbound&lt;br /&gt;
&lt;br /&gt;
=== Recovering from mistakes ===&lt;br /&gt;
&amp;lt;big&amp;gt;WARNING:&amp;lt;/big&amp;gt; This will strip out any commits that haven&#039;t been pushed to the remote repositories, regardless of what branch/label/tag those commits are on. (So if you have local changes on inbound and run this command to strip something bad on fx-team, both inbound and fx-team will be stripped.) Only do this if you don&#039;t care about any of those commits!&lt;br /&gt;
* hg strip &#039;not public()&#039;&lt;br /&gt;
&lt;br /&gt;
You may also need to use some combination of the following to get things back to a known-good state:&lt;br /&gt;
* hg purge # http://mercurial.selenic.com/wiki/PurgeExtension&lt;br /&gt;
* hg up -C&lt;br /&gt;
&lt;br /&gt;
=== See what you&#039;re about to push ===&lt;br /&gt;
`hg out` without any flags added will show you a LOT of unrelated commits. To see just what you&#039;ll be pushing to a given branch, use `hg out -r . &amp;lt;branch&amp;gt;`&lt;br /&gt;
* hg out -r . inbound&lt;br /&gt;
** This will only display the things you&#039;re about to push to the inbound branch&lt;br /&gt;
&lt;br /&gt;
=== View incoming changes ===&lt;br /&gt;
Since your unified repo will likely have all changesets from the various branches pulled locally, `hg in &amp;lt;somebranch&amp;gt; -r &amp;lt;somerev&amp;gt;` will likely not help you see what would be pulled into your current branch from &amp;lt;somebranch&amp;gt; up to that &amp;lt;somerev&amp;gt;.&lt;br /&gt;
Instead, you can use the following to print out the equivalent. Say you want to see what would be merged onto mozilla-central from b2g-inbound&#039;s revision ca142ec8ba0f:&lt;br /&gt;
&lt;br /&gt;
Make sure m-c is fully up to date:&lt;br /&gt;
* hg pull central &lt;br /&gt;
* hg up central &lt;br /&gt;
Get all of b2g-inbound&#039;s changesets:&lt;br /&gt;
* hg pull b2ginbound&lt;br /&gt;
Do a preview of the merge without actually performing the merge:&lt;br /&gt;
* hg merge -r ca142ec8ba0f -P&lt;br /&gt;
This will print out everything on b2g-inbound (up to and including revision ca142ec8ba0f) that is not already on mozilla-central.&lt;br /&gt;
&lt;br /&gt;
=== See the log for a particular branch ===&lt;br /&gt;
* hg log -fr [branch]&lt;br /&gt;
&lt;br /&gt;
= Extras =&lt;br /&gt;
== hg aliases ==&lt;br /&gt;
I set up the following aliases in my global .hgrc file to make merging things around trunk a little faster:&lt;br /&gt;
 [alias]&lt;br /&gt;
 # merge tree $1, revision $2 to central, optionally appending $3 (for &amp;quot;CLOSED TREE&amp;quot;, etc)&lt;br /&gt;
 mergetocentral = !$HG pull central ; $HG up central ; $HG pull $1 ; $HG merge $2 ; $HG commit -m &amp;quot;Merge $1 to central, a=merge $3&amp;quot; ; $HG push -r . central&lt;br /&gt;
 # merge central tip to tree $1, optionally appending $2 (for &amp;quot;CLOSED TREE&amp;quot;, etc)&lt;br /&gt;
 mergetointegration = !$HG pull central ; $HG pull $1 ; $HG up $1 ; $HG merge central ; $HG commit -m &amp;quot;Merge m-c to $1, a=merge $2&amp;quot; ; $HG push -r . $1&lt;br /&gt;
&lt;br /&gt;
With these set up, I can merge fx-team&#039;s revision 04a3d9130aa0 over to mozilla-central with the following command:&lt;br /&gt;
 hg mergetocentral fx-team 04a3d9130aa0&lt;br /&gt;
and then I can merge mozilla-central&#039;s tip back to fx-team with the following command:&lt;br /&gt;
 hg mergetointegration fx-team&lt;br /&gt;
This cuts down on a lot of repetitive typing, saving a bit of time.&lt;br /&gt;
&lt;br /&gt;
For merging from reviewboard patches, there&#039;s this alias&lt;br /&gt;
  rbimport = !hg transplant -e -s https://reviewboard-hg.mozilla.org/gecko -b $1&lt;br /&gt;
&lt;br /&gt;
Then, it&#039;s matter of importing the right hash like the following command:&lt;br /&gt;
  hg rbimport dd1462ba321db983061b94e30cee92b6bd81e908&lt;/div&gt;</summary>
		<author><name>Sfink</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=Sfink/Memory_Ideas&amp;diff=1135856</id>
		<title>Sfink/Memory Ideas</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=Sfink/Memory_Ideas&amp;diff=1135856"/>
		<updated>2016-06-04T23:46:42Z</updated>

		<summary type="html">&lt;p&gt;Sfink: /* Problem F: Hard to track down problems */ Remove hard breaks to fix formatting&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Problem A: System too unusable to diagnose ==&lt;br /&gt;
&lt;br /&gt;
When a bad memory leak kicks in, the system can be too unusable to get useful data out.&lt;br /&gt;
&lt;br /&gt;
=== Solutions: Make it easier to get information out when the system is suffering ===&lt;br /&gt;
&lt;br /&gt;
[[#A1]] Periodically log memory-related information (existing bug, I think? also&lt;br /&gt;
telemetry)&lt;br /&gt;
&lt;br /&gt;
[[#A2]] Maintain a rotating database of detailed memory-related information (cf&lt;br /&gt;
atop)&lt;br /&gt;
&lt;br /&gt;
[[#A3]] Make about:memory capable of outputting to a file, for use with a&lt;br /&gt;
command-line invocation &#039;firefox about:memory?verbose=1&amp;amp;outfile=...&#039;&lt;br /&gt;
&lt;br /&gt;
=== Solution: Prevent the system from getting into such a bad state ===&lt;br /&gt;
&lt;br /&gt;
[[#A4]] Make a per-compartment (or per-?) cap on memory usage&lt;br /&gt;
&lt;br /&gt;
[[#A5]] When sufferingMode==true, disable GC/CC on big tabs. Probably need to&lt;br /&gt;
deactivate them too.&lt;br /&gt;
&lt;br /&gt;
[[#A6]] Early warning when memory usage is getting too high&lt;br /&gt;
&lt;br /&gt;
[[#A7]] Crash reporter-like UI for reporting memory problems (do not require an&lt;br /&gt;
actual crash to trigger)&lt;br /&gt;
&lt;br /&gt;
== Problem B: Regular users can&#039;t generate useful reports  ==&lt;br /&gt;
&lt;br /&gt;
Hard for regular users to generate a useful memory problem report&lt;br /&gt;
&lt;br /&gt;
(all solutions from problem A are relevant here)&lt;br /&gt;
&lt;br /&gt;
[[#B1]] Provide a way to dump and submit a reachability graph&lt;br /&gt;
&lt;br /&gt;
[[#B2]] Documentation for how to best help with a memory problem, with various&lt;br /&gt;
steps to follow.&lt;br /&gt;
&lt;br /&gt;
[[#B3]] Track memory to individual page/tab/compartment/principals.&lt;br /&gt;
&lt;br /&gt;
[[#B4]] Tools for generating profiles with subsets of addons installed (or for&lt;br /&gt;
running with different subsets of addons within one profile)&lt;br /&gt;
&lt;br /&gt;
[[#B5]] Tools for blaming memory usage on addons (eg detecting &amp;quot;safe&amp;quot; addons to&lt;br /&gt;
remove from consideration. Cross-referencing other users&#039; addons and memory&lt;br /&gt;
usage similar to the crash correlation reports -- requires telemetry.)&lt;br /&gt;
&lt;br /&gt;
== Problem C: Knowledgeable users can&#039;t generate useful reports ==&lt;br /&gt;
&lt;br /&gt;
Hard for developers or knowledgeable and motivated users to generate&lt;br /&gt;
a useful memory problem report&lt;br /&gt;
&lt;br /&gt;
The above problem B crossed into this, so everything there is relevant.&lt;br /&gt;
&lt;br /&gt;
[[#C1]] Rationalize and document all of our various leak-detection tools.&lt;br /&gt;
&lt;br /&gt;
[[#C2]] Automation and Windows equivalents of my /proc/&amp;lt;pid&amp;gt;/maps hacks&lt;br /&gt;
&lt;br /&gt;
[[#C3]] Dumpers that give full heap, full graph, pruned graph. Visualizers,&lt;br /&gt;
analyzers, etc. of the dumps.&lt;br /&gt;
&lt;br /&gt;
[[#C4]] Collect age of various memory objects (how many CCs or GCs it has been&lt;br /&gt;
alive.)&lt;br /&gt;
&lt;br /&gt;
== Problem D: Uncollected garbage ==&lt;br /&gt;
&lt;br /&gt;
Garbage is not collected&lt;br /&gt;
&lt;br /&gt;
=== Solution: Report cycles that CC misses ===&lt;br /&gt;
&lt;br /&gt;
[[#D1]] Conservative scanner to find cycles involving things not marked as&lt;br /&gt;
CC-participants and report them as suspicious.&lt;br /&gt;
&lt;br /&gt;
=== Solution: Report resources that leak over time but are still referenced (so they are cleaned up before shutdown) ===&lt;br /&gt;
&lt;br /&gt;
[[#D2]] Register &amp;quot;expected lifetime&amp;quot; at acquisition time. Report things that live&lt;br /&gt;
longer than expected, filtered by diagnostics. (&amp;quot;lifetime assertions&amp;quot;? Not&lt;br /&gt;
quite.)&lt;br /&gt;
&lt;br /&gt;
[[#D3]] Detect subgraphs that grow (at a constant rate?) while a page is open.&lt;br /&gt;
&lt;br /&gt;
[[#D4]] Detect subgraphs that are never accessed&lt;br /&gt;
&lt;br /&gt;
== Problem E: Unleaked but excessive memory usage ==&lt;br /&gt;
&lt;br /&gt;
High memory usage, not leaked&lt;br /&gt;
&lt;br /&gt;
(aside from current work like generational gc)&lt;br /&gt;
&lt;br /&gt;
[[#E1]] &amp;quot;Simulator&amp;quot; that runs over logs and estimates peak memory usage if CC/GC&lt;br /&gt;
ran at optimal times.&lt;br /&gt;
&lt;br /&gt;
[[#E2]] Use reproducible test runs to evaluate what the performance/memory&lt;br /&gt;
tradeoff is for various things (eg jit code, structure sizes)&lt;br /&gt;
&lt;br /&gt;
== Problem F: Hard to track down problems ==&lt;br /&gt;
&lt;br /&gt;
Hard to navigate through a memory dump or the current state to track&lt;br /&gt;
down a specific problem&lt;br /&gt;
&lt;br /&gt;
[[#F1]] Dump all roots of a compartment, and trace roots back to the XPCOM/DOM/whatever thing that is holding onto that root (when available)&lt;br /&gt;
&lt;br /&gt;
[[#F2]] Go from JS object to things keeping it alive (dump out GC edges) -- see jimb&#039;s findReferences (currently JS shell only)&lt;br /&gt;
&lt;br /&gt;
[[#F3]] Record addr,size,stack at every allocation (kgadd&#039;s heap visualizer)&lt;br /&gt;
&lt;br /&gt;
[[#F4]] &lt;br /&gt;
&lt;br /&gt;
----------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
Details:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&#039;A2&#039;&amp;gt;A2. atop records a ton of statistics about memory, disk, network, CPU, and other things at a 10 minute sampling interval. Stats are collected both on a global and per-process granularity. It monitors every process that starts and stops, even if the process appeared and disappeared entirely between two samples. It dumps all this in a somewhat-compressed binary log.&lt;br /&gt;
&lt;br /&gt;
The visual UI has a good set of heuristics for detecting &amp;quot;large&amp;quot; values, and coloring the output accordingly. If your disk is busy for &amp;gt;90% of the sampling interval, it&#039;ll turn red. If your network traffic is a high percentage of the expected maximum bandwidth, it&#039;ll turn red. etc.&lt;br /&gt;
&lt;br /&gt;
It lets you use it in &#039;top-like&#039; mode, where it displays the current state of things, as well as in a historical mode where it reads from a log file. (It is decidedly *not* seamless between the two, but it should be.)&lt;br /&gt;
&lt;br /&gt;
It also allows dumping historical data to text files. I&#039;ve used that for generating graphs of various values.&lt;br /&gt;
&lt;br /&gt;
For the browser, many of the same metrics are applicable, but I&#039;d also like an equivalent of the processes&#039; info. The idea is to know &amp;quot;what was going on at&lt;br /&gt;
XXX?&amp;quot; So it should be user and browser actions, which tab was active, network requests, significant events firing, etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&#039;A3&#039;&amp;gt;A3. The idea is that rather than waiting for the screen to redraw for every action in getting to about:memory, you just do firefox &#039;about:memory...&#039; and go have a cup of tea while it thinks about it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&#039;A5&#039;&amp;gt;A5. This is based on pure speculation, but I don&#039;t understand why the browser is so incredibly unusable when memory usage is going nuts. Why is all that memory being touched? Why isn&#039;t it just swapped out and forgotten? Under the assumption that it&#039;s the GC scanning it over and over again, it seems like it would be nice to suppress GC in this situation. Generational GC could eliminate this problem in a nicer and much more principled way.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&#039;B2&#039;&amp;gt;B2. I have the impression that we have many, many memory-related problem reports that end up being useless. I think that&#039;s really our fault; it&#039;s too hard for users to file useful bug reports. Experienced Mozilla devs don&#039;t even know what to do.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&#039;B5&#039;&amp;gt;B5. eg: collect up all API calls that an addon makes (or record them, or whatever.) Maintain a whitelist of APIs. (If you pass in a string, assume it may be duplicated a thousand times and stored in a sqlite DB forever, but if you&#039;re just setting existing booleans or reading state, you&#039;re blameless.)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&#039;C2&#039;&amp;gt;C2. When looking at a memory leak, I took several snapshots of /proc/&amp;lt;pid&amp;gt;/maps, diffed them to find a memory region that appeared and did not disappear, and then dumped out the raw memory to a file. Then I ran strings on it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&#039;D2&#039;&amp;gt;D2. I don&#039;t really know enough about the system to flesh this out properly, but it seems like when you have a bunch of memory lingering around when it really ought to be dead, that many of the objects comprising that memory should be able to &amp;quot;know&amp;quot; that they *probably* shouldn&#039;t live past... the current page, or for more than a few seconds, or whatever. Assuming this is possible, it should be possible to walk up a dominator graph and give a fairly directed answer to &amp;quot;why has this outlived what it thought its lifespan would be?&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Not every memory allocation needs to be marked for this to work. You just need one object within the &amp;quot;leaked&amp;quot; memory to be marked.&lt;br /&gt;
&lt;br /&gt;
It could also walk the graph &amp;quot;en masse&amp;quot; to ignore individual objects that are reachable longer than expected and focus on the clusters of objects that are kept alive by the same thing. (I&#039;m thinking that the expected lifetime is a guess, and may be inaccurate.)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&#039;D4&#039;&amp;gt;D4. eg use mprotect on a random subset of the heap to find pages (or smaller regions, but that&#039;s harder) that are never accessed after some point. Remove the GC/CC from consideration.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>Sfink</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=Javascript:Automation_Builds&amp;diff=1133924</id>
		<title>Javascript:Automation Builds</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=Javascript:Automation_Builds&amp;diff=1133924"/>
		<updated>2016-05-23T20:54:50Z</updated>

		<summary type="html">&lt;p&gt;Sfink: /* Reproducing a build */ warnaserr is obsolete&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= The Builds =&lt;br /&gt;
&lt;br /&gt;
All of the &#039;&#039;&#039;SM(...)&#039;&#039;&#039; builds appearing on Treeherder are JS shell-only builds. Currently, they all&lt;br /&gt;
* Checkout the source&lt;br /&gt;
* Configure using a set of options appropriate to the specific build&lt;br /&gt;
* Build (by simply invoking make)&lt;br /&gt;
* Run tests, possibly differently depending on the specific build&lt;br /&gt;
&lt;br /&gt;
All of this is done by running the shell script js/src/devtools/automation/autospider.sh &amp;lt;variant&amp;gt;, where &amp;lt;variant&amp;gt; is one of the filenames in js/src/devtools/automation/variants/.&lt;br /&gt;
&lt;br /&gt;
= Reproducing a build =&lt;br /&gt;
&lt;br /&gt;
You should be able to closely replicate a TH build by running autospider.sh yourself. For example, to replicate &#039;&#039;&#039;SM(cgc)&#039;&#039;&#039;, you could be anywhere within your checkout, and run&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;gecko-root&amp;gt;/js/src/devtools/automation/autospider.sh --clobber compacting&lt;br /&gt;
&lt;br /&gt;
The default objdir is &amp;lt;gecko-root&amp;gt;/obj-spider. You can change it by setting the $OBJDIR environment variable.&lt;br /&gt;
&lt;br /&gt;
To narrow the test down, delete some of the lines at the end of autospider.sh that run the various tests.&lt;br /&gt;
&lt;br /&gt;
== Mapping variants to SM(...) names ==&lt;br /&gt;
&lt;br /&gt;
There is no good way. They&#039;re hardcoded in the Treeherder code. Many of them even show up in multiple repos. Here&#039;s a snapshot:&lt;br /&gt;
&lt;br /&gt;
* SM(cgc) - compacting&lt;br /&gt;
* SM(p) - plain or plaindebug&lt;br /&gt;
* SM(arm) - arm-sim or arm-sim-osx&lt;br /&gt;
* SM(arm64) - arm64-sim&lt;br /&gt;
* SM(exr) - exactrooting&lt;br /&gt;
* SM(r) - rootanalysis&lt;br /&gt;
* SM(pkg) - Standalone SpiderMonkey package.&lt;br /&gt;
&lt;br /&gt;
== Aside on SM(pkg) ==&lt;br /&gt;
&lt;br /&gt;
The SM(pkg) builds create a tarball of all the sources used to make a standalone SpiderMonkey library and shell, untar it somewhere else, and then runs the autospider command listed above. To reproduce this packaging and unpackaging behavior, you can run this command:&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;gecko-root&amp;gt;/testing/taskcluster/scripts/builder/build-sm-package.sh&lt;/div&gt;</summary>
		<author><name>Sfink</name></author>
	</entry>
</feed>