<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	>

<channel>
	<title>Rooftop lab</title>
	<atom:link href="http://blog.mozilla.com/jorendorff/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.mozilla.com/jorendorff</link>
	<description>where we're building a better ActionMonkey from parts</description>
	<pubDate>Thu, 21 Aug 2008 21:47:13 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6</generator>
	<language>en</language>
			<item>
		<title>Underscores</title>
		<link>http://blog.mozilla.com/jorendorff/2008/08/21/underscores/</link>
		<comments>http://blog.mozilla.com/jorendorff/2008/08/21/underscores/#comments</comments>
		<pubDate>Thu, 21 Aug 2008 21:47:13 +0000</pubDate>
		<dc:creator>jorendorff</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.mozilla.com/jorendorff/?p=16</guid>
		<description><![CDATA[One of the funny little benefits of switching the Mozilla Developer Center from MediaWiki to Deki is that page names can contain actual underscores.  The big headline on the JS_EvaluateScript page always used to say “JS EvaluateScript”.
Well, not anymore!  Since Deki has an HTTP API, I was able to write a Python script [...]]]></description>
			<content:encoded><![CDATA[<p>One of the funny little benefits of switching the Mozilla Developer Center from MediaWiki to Deki is that page names can contain actual underscores.  The big headline on the <a href="http://developer.mozilla.org/en/JS_EvaluateScript"><code>JS_EvaluateScript</code></a> page always used to say “JS EvaluateScript”.</p>
<p>Well, not anymore!  Since Deki has an HTTP API, I was able to write a Python script to fix the titles of all the JSAPI pages at once.  The <a href="http://hg.mozilla.org/users/jorendorff_mozilla.com/deki-client/">source code</a> includes a Python module for loading and saving Deki wiki pages.  Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mozilla.com/jorendorff/2008/08/21/underscores/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Push to try</title>
		<link>http://blog.mozilla.com/jorendorff/2008/08/18/push-to-try/</link>
		<comments>http://blog.mozilla.com/jorendorff/2008/08/18/push-to-try/#comments</comments>
		<pubDate>Mon, 18 Aug 2008 17:29:33 +0000</pubDate>
		<dc:creator>jorendorff</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[mercurial]]></category>

		<category><![CDATA[share and enjoy]]></category>

		<guid isPermaLink="false">http://blog.mozilla.com/jorendorff/?p=15</guid>
		<description><![CDATA[Thanks to Ben Hearsum and Ted Mielczarek, the Try server has a cool new feature: you can now try out some changes without manually creating and uploading a patch.  Just hg commit or hg qrefresh your work, and then
    hg push -f ssh://hg.mozilla.org/try/
The Try server will kick off Linux, Windows, and [...]]]></description>
			<content:encoded><![CDATA[<p>Thanks to Ben Hearsum and Ted Mielczarek, the Try server has a cool new feature: you can now try out some changes without manually creating and uploading a patch.  Just <code>hg commit</code> or <code>hg qrefresh</code> your work, and then</p>
<pre>    <b>hg push -f ssh://hg.mozilla.org/try/</b></pre>
<p>The Try server will kick off Linux, Windows, and Mac builds with all your latest changes.  Specifically, it&#8217;ll build your <code>hg tip</code> revision.</p>
<p>Details:</p>
<ul>
<li>
<p>If you&#8217;re using <a href="http://developer.mozilla.org/en/docs/Mercurial_Queues">Mercurial Queues</a>, this <code>push</code> command pushes any patches that are currently applied, and the Try server will build the result.  (This is an awesome feature, not a bug!)</p>
</li>
<li>
<p>If you&#8217;ve ever pushed anything to <tt>mozilla-central</tt>, you already have the right permissions to do this.  If not, see <a href="http://developer.mozilla.org/en/docs/Mercurial_FAQ#How_do_I_check_stuff_in.3F">the Mercurial FAQ</a> for more information about pushing.</p>
</li>
<li>
<p>The <a href="https://wiki.mozilla.org/Build:TryServer">Try server wiki page</a> has more information about the Try server, including where to find the finished builds.</p>
</li>
<li>
<p>You don&#8217;t need to clone or pull from the <tt>try</tt> repo, and you probably don&#8217;t want to.  You&#8217;d get every half-baked changeset anybody ever tested.</p>
</li>
<li>
<p>You can abbreviate the push command even further.  If you add these lines to your <tt>$HOME/.hgrc</tt> file:</p>
<pre>[paths]
try = ssh://hg.mozilla.org/try/</pre>
<p>then the command becomes <code>hg push -f try</code>.  Or you could use a script or an alias.</p>
</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.mozilla.com/jorendorff/2008/08/18/push-to-try/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Mercurial, and other monsters</title>
		<link>http://blog.mozilla.com/jorendorff/2008/02/06/mercurial-and-other-monsters/</link>
		<comments>http://blog.mozilla.com/jorendorff/2008/02/06/mercurial-and-other-monsters/#comments</comments>
		<pubDate>Wed, 06 Feb 2008 21:42:32 +0000</pubDate>
		<dc:creator>jorendorff</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.mozilla.com/jorendorff/2008/02/06/mercurial-and-other-monsters/</guid>
		<description><![CDATA[Brad Lassey recently vented some understandable frustration with Mercurial, the new distributed version control system we&#8217;re using for Mozilla 2 development.
I sympathize with Brad, especially because almost all of the comments seem to be along the lines of “No no, you&#8217;re mistaken, Mercurial makes things easier, not harder” or “Well, you should have done X,” [...]]]></description>
			<content:encoded><![CDATA[<p>Brad Lassey recently vented some <a href="http://blog.mozilla.com/blassey" title="Brad's blog - Hg as a collaboration tool">understandable frustration</a> with <a href="http://developer.mozilla.org/en/docs/Mercurial" title="developer.mozilla.org - Mercurial">Mercurial</a>, the new distributed version control system we&#8217;re using for Mozilla 2 development.</p>
<p>I sympathize with Brad, especially because almost all of the comments seem to be along the lines of “No no, you&#8217;re mistaken, Mercurial makes things <em>easier</em>, not harder” or “Well, you should have done X,” without understanding Brad&#8217;s problem.</p>
<p>Still, I think Brad&#8217;s frustration is somewhat misplaced.  The other side of the story involves Windows Vista.  Brad did some work in a Mercurial repo on Vista, then zipped up the whole repo and moved it to a Windows XP VM.  This is supposed to work just fine.  But (and this part, we think, this is due to a brilliant top-secret feature of Windows Vista called <a href="http://doughennig.blogspot.com/2007/05/has-file-been-virtualized.html" title="Has a file been virtulized?">virtualization</a>, a feature so awful the mobile developers have resorted to logging in as Administrator all the time) Brad ended up with a zip file that had multiple copies of some files.  Whatever Vista put into that zip, extracting it on XP produced a corrupt repository.  (Specifically, Mercurial&#8217;s working directory was at revision X, but it thought it was at revision Y.)</p>
<p>Mercurial is different in a lot of ways.  Compared to CVS, it&#8217;s more flexible and more complex.  Mercurial vs. CVS reminds me of C++ vs. C:</p>
<ul>
<li>There are a lot of quite different ways to use it.</li>
<li>There are some ease-of-use issues.</li>
<li>It&#8217;s easy to think you understand it, and how to use it, and which features to ignore, and exactly how everyone else should use it, when you really really don&#8217;t.</li>
<li>Conversations about how to use it are not going to be trivial.</li>
<li>Getting started by using Mercurial as “a better CVS” doesn&#8217;t deliver a huge win and is a little frustrating, because some things don&#8217;t quite translate.</li>
<li>Perhaps most importantly, <a href="http://www.fullduplex.org/humor/2006/10/how-to-shoot-yourself-in-the-foot-in-any-programming-language/" title="fullduplex.org: How to shoot yourself in the foot in any programming language">shooting yourself in the foot</a> feels a lot like C++.  I&#8217;ve done it a few times now—boring stories.</li>
</ul>
<p>After ten years of ups and downs with C++, I&#8217;ve made my peace with it and wouldn&#8217;t want to go back to pure C.</p>
<p><strong>Update:</strong> It turns out Brad&#8217;s problem was at least partly caused by the Mercurial binary distribution he was using.  The default hgmerge script was broken in an exciting way.  I believe it&#8217;s fixed in the latest binary distribution.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mozilla.com/jorendorff/2008/02/06/mercurial-and-other-monsters/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Improving malloc() locality</title>
		<link>http://blog.mozilla.com/jorendorff/2007/10/30/improving-malloc-locality/</link>
		<comments>http://blog.mozilla.com/jorendorff/2007/10/30/improving-malloc-locality/#comments</comments>
		<pubDate>Tue, 30 Oct 2007 19:08:56 +0000</pubDate>
		<dc:creator>jorendorff</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.mozilla.com/jorendorff/2007/10/30/improving-malloc-locality/</guid>
		<description><![CDATA[This is cool (if you care how malloc() works, always a big if), but it requires a lot of background.
Background
One very common way to implement malloc() is to use size classes and freelists.  If you already know all about this, skip this section.
Here&#8217;s a sample malloc() that uses size classes and freelists.  (Note [...]]]></description>
			<content:encoded><![CDATA[<p>This is cool (if you care how <code>malloc()</code> works, always a big if), but it requires a lot of background.</p>
<h4>Background</h4>
<p>One very common way to implement <code>malloc()</code> is to use size classes and freelists.  If you already know all about this, skip this section.</p>
<p>Here&#8217;s a sample <code>malloc()</code> that uses size classes and freelists.  (Note that size classes have nothing to do with the object-oriented notion of a class.)</p>
<pre>void * malloc(size_t nbytes)
{
    /* Say you want 24 bytes.  Well, there's an allocator that
     * specifically serves up 24-byte chunks of memory.  (Actually
     * if you ask for 21, 22, or 23 bytes, you'll probably get the
     * same allocator.) This is what I mean by <em>size classes</em>.
     */
    FixedSizeAllocator *allocator = getAllocatorForSize(nbytes);

    /* Each allocator maintains a linked list of free buffers.
     * This is what I mean by <em>freelists</em>.  Usually there's
     * something in the freelist, so allocation
     * is super-fast.  But occasionally it's empty.
     */
    if (allocator-&gt;freelist == NULL)
        return allocateNewBuf(allocator);  /* (the slow path) */

    /* The super-fast path.  Just pop the first item off the freelist. */
    void *item = allocator-&gt;freelist;
    allocator-&gt;freelist = LINKED_LIST_NEXT(item);
    return item;  /* man, that was fast! */
}

/* free() is super-fast, too. */
void free(void *buf)
{
    /* First get the allocator... */
    size_t bufsize = GET_SIZE_OF_BUF(buf);  /* (usually stashed nearby) */
    FixedSizeAllocator *allocator = getAllocatorForSize(bufsize);

    /* Then just push this buffer back onto the freelist.  Zoom zoom! */
    LINKED_LIST_NEXT(item) = allocator-&gt;freelist;
    allocator-&gt;freelist = item;
}</pre>
<p>See how simple and fast that is?  Even if all the freelists are initially empty, each time you <code>free()</code> memory, it goes on a freelist.  So pretty soon, almost every call to <code>malloc()</code> is just popping a ready buffer off a linked list.</p>
<p>I&#8217;m glossing over <code>allocateNewBuf()</code> here, but it doesn&#8217;t have to be complicated.  Basically it just asks the OS for pages of memory in chunks of, say, 4KB; and treats it as an array of smaller chunks, returning the next chunk in the array each time it&#8217;s called.</p>
<h4>The locality problem</h4>
<p>It all seems pretty awesome, right?  It did to me.  Then one day Brendan Eich mentioned to me that this approach can lead to fragmentation.</p>
<p>That surprised me.  After all, the point of size classes is to avoid the fragmentation you get if you try to allocate buffers of all sizes from the same heap. Google for “best-fit” or “first-fit”—the results are all about heap fragmentation.</p>
<p>Now, in case you haven&#8217;t met Brendan, I should explain a bit.  He talks fast and he says amazing things.  His speech is full of metaphors you might need to think about for a while in a quiet room and examples you&#8217;ve never heard of.  The average word Brendan uses is rarer than the average word you or I use.  So Brendan&#8217;s output is ludicrously high-bandwidth, often impossible to keep up with; but at least you can Google what you don&#8217;t understand.  Spending a few days puzzling over what Brendan meant by some five-word off-the-cuff remark, and ultimately decompressing it into a rewarding insight, is merely typical.  At least, for me.  No exaggeration.</p>
<p>In this case, I eventually found out Brendan was referring to a different, and potentially much <em>worse</em> kind of heap fragmentation than the kind I was familiar with.  At program startup, ten calls to <code>malloc(24)</code> will typically return ten buffers that are close together in memory.  Maybe even right next to each other, like an array.  This is by design.  It provides great cache locality and page locality.  But as time goes by, the application <code>free()</code>s buffers in no particular order, so the freelists tend to get shuffled.  Eventually, ten calls to <code>malloc(24)</code> might return pointers into ten different pages of otherwise unused memory: the worst possible locality.</p>
<p>This weekend I suddenly realized that MMgc&#8217;s fast <code>malloc</code>-like allocator, <code>MMgc::FixedMalloc</code>—a piece of code I read <em>months</em> ago—contains a clever workaround for this problem!</p>
<p><code>FixedMalloc</code> uses per-page freelists.  Each fixed-size allocator has a linked list of pages.  Each page has a freelist for the buffers in that page.  <code>malloc()</code> always consumes one page&#8217;s freelist completely before going to another page.</p>
<p>I&#8217;m sure this trick is well-known in the field, but what&#8217;s a blog for, if not advertising your own ignorance?</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mozilla.com/jorendorff/2007/10/30/improving-malloc-locality/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Mozilla 2 status post</title>
		<link>http://blog.mozilla.com/jorendorff/2007/10/23/mozilla-2-status-post/</link>
		<comments>http://blog.mozilla.com/jorendorff/2007/10/23/mozilla-2-status-post/#comments</comments>
		<pubDate>Tue, 23 Oct 2007 15:35:20 +0000</pubDate>
		<dc:creator>jorendorff</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.mozilla.com/jorendorff/2007/10/23/mozilla-2-status-post/</guid>
		<description><![CDATA[I just posted to mozilla.dev.platform about Mozilla 2 platform changes.  In short:  Mercurial is coming, Tamarin is coming, and we&#8217;re going to give garbage collection a chance to prove itself.
]]></description>
			<content:encoded><![CDATA[<p>I just posted to mozilla.dev.platform about <a href="http://groups.google.com/group/mozilla.dev.platform/browse_thread/thread/7dad3da651386eb3/acbeeab5ef444b08">Mozilla 2 platform changes</a>.  In short:  Mercurial is coming, Tamarin is coming, and we&#8217;re going to give garbage collection a chance to prove itself.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mozilla.com/jorendorff/2007/10/23/mozilla-2-status-post/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Help us free the technical docs from www.mozilla.org</title>
		<link>http://blog.mozilla.com/jorendorff/2007/09/04/help-us-free-the-technical-docs-from-www.mozilla.org/</link>
		<comments>http://blog.mozilla.com/jorendorff/2007/09/04/help-us-free-the-technical-docs-from-www.mozilla.org/#comments</comments>
		<pubDate>Tue, 04 Sep 2007 12:21:52 +0000</pubDate>
		<dc:creator>jorendorff</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.mozilla.com/jorendorff/2007/09/04/help-us-free-the-technical-docs-from-www.mozilla.org/</guid>
		<description><![CDATA[Want to help the Mozilla project?  Here&#8217;s something anyone with a web browser can help with.
A lot of technical documents still live on www.mozilla.org.  This is bad for a lot of reasons, but fundamentally it&#8217;s just the wrong place for them.  developer.mozilla.org is their proper home.  The pages will be much [...]]]></description>
			<content:encoded><![CDATA[<p>Want to help the Mozilla project?  Here&#8217;s something anyone with a web browser can help with.</p>
<p>A lot of technical documents still live on www.mozilla.org.  This is bad for a lot of reasons, but fundamentally it&#8217;s just the wrong place for them.  <a href="http://developer.mozilla.org/">developer.mozilla.org</a> is their proper home.  The pages will be much easier for us all to find, improve, and maintain there.</p>
<p>You can help migrate this content.</p>
<ul>
<li>Find a page to migrate.  <a href="http://developer.mozilla.org/en/docs/MDC:Existing_Content">MDC:Existing Content</a> is the nerve center of this operation and contains <a href="http://developer.mozilla.org/en/docs/MDC:Existing_Content#Working_List">a huge list</a>.  (Seasoned hackers might prefer to <a href="http://www.mozilla.org/contribute/writing/cvs">grab the source code</a> for the entire www.mozilla.org web site from CVS and use their best judgment about what to migrate.  Some things are clearly technical docs; some aren&#8217;t.)</li>
<li>View → Page Source.  Copy the HTML code for the page.</li>
<li>Paste it into an <a href="http://labs.seapine.com/htmltowiki.cgi">HTML to Wiki</a> converter.  (Unfortunately, this one has a few bugs.  Watch for glitches with non-ASCII characters like <code>&amp;</code><code>nbsp;</code>.  It also converts <code>+</code> signs to spaces.  Quaint bug, very 1995.  If you know of a better converter that requires no download, let me know.)</li>
<li>Make a new page on developer.mozilla.org.  The easiest way is to edit <a href="http://developer.mozilla.org/en/docs/MDC:Existing_Content">MDC:Existing Content</a>, find the link that you&#8217;re about to migrate, and add: <code>- now migrating to [[Title of the new page you want to make]]</code>.  Click Save Page.  Now MDC:Existing Content should have a red link (you just added it).  Click the link to go to the new, empty page, then click &#8220;edit this page&#8221;.</li>
<li>Paste in the Wiki code.  In the Summary field, write &#8220;migrated from &#8221; and paste in the URL of the old www.mozilla.org page.  Click &#8220;Save Page&#8221;.</li>
<li>Look at the new page.  If it looks awful in any way, click the &#8220;Edit&#8221; link on the right-hand side and clean it up.  (the &#8220;Editing help&#8221; link might help you figure out what&#8217;s wrong).</li>
<li>Follow the 5 <a href="http://developer.mozilla.org/en/docs/MDC:Existing_Content#After_Document_Migration">After Document Migration</a> steps to make sure (a) people can find your new page; and (b) nobody else does the same work all over again.</li>
</ul>
<p>See?  Easy and fun.  This is what I do now when something&#8217;s building.  So far I&#8217;ve migrated 23 pages.</p>
<p>If you really want a new best friend, write an extension to make this process less ridiculous.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mozilla.com/jorendorff/2007/09/04/help-us-free-the-technical-docs-from-www.mozilla.org/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Conservative stack scanning 101</title>
		<link>http://blog.mozilla.com/jorendorff/2007/08/09/conservative-stack-scanning-101/</link>
		<comments>http://blog.mozilla.com/jorendorff/2007/08/09/conservative-stack-scanning-101/#comments</comments>
		<pubDate>Thu, 09 Aug 2007 17:41:23 +0000</pubDate>
		<dc:creator>jorendorff</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.mozilla.com/jorendorff/2007/08/09/conservative-stack-scanning-101/</guid>
		<description><![CDATA[Maybe you&#8217;re curious about how the MMgc garbage collector works.  Here&#8217;s my rambling attempt to explain it on IRC this morning (edited for clarity and layout).
(Note: The MMgc documentation is another good place to start, if you already know all about the C++ stack and heap.)
peter: this "scanning the C stack" is a mystery [...]]]></description>
			<content:encoded><![CDATA[<p>Maybe you&#8217;re curious about how the MMgc garbage collector works.  Here&#8217;s my rambling attempt to explain it on IRC this morning (edited for clarity and layout).</p>
<p>(Note: The <a href="http://wiki.mozilla.org/Tamarin::MMgc">MMgc documentation</a> is another good place to start, if you already know all about the C++ stack and heap.)</p>
<pre>peter: this "scanning the C stack" is a mystery to me
peter: I had no idea C was reflective like this
jorendorff: Oh, it's not <img src='http://blog.mozilla.com/jorendorff/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />
peter: ok good because I never heard of such things!
jorendorff: Happy to explain.  <img src='http://blog.mozilla.com/jorendorff/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />
jorendorff: Or try. <img src='http://blog.mozilla.com/jorendorff/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />
jorendorff: But you need to understand a little about how C works in practice.
jorendorff: What do you know about "the stack"?
peter: not much I guess
peter: I know about regular C dynamic memory use
jorendorff: Well, when your program runs, and main() gets called,
jorendorff: say you've got some local variables in there.
jorendorff: C has to store them somewhere.  What happens is
jorendorff: ...C has some memory, maybe 64K bytes, set aside
jorendorff: ...for local variables.
peter: yep
peter: set aside by the OS, correct?
jorendorff: eh, not exactly
jorendorff: C asks the OS for 64K bytes, the OS says sure, here you go,
peter: right
peter: ok
jorendorff: ...and C uses those for the stack.
jorendorff: But the OS doesn't know what C is doing with them.
peter: ok</pre>
<p>Here when I talk about &#8220;C&#8221; doing things, I really mean &#8220;the C language runtime&#8221;.  This is code that the C linker automatically links into every C/C++ program.  It&#8217;s called <tt>libc</tt> on Unix.  On Windows, they call it the CRT.</p>
<pre>jorendorff: So.  C remembers how much of the stack is in use.
jorendorff: (It has a machine register pointing to "the top of the stack")
jorendorff: (...on intel x86, this is ESP)
peter: C's malloc asks for memory from this 64kb and manages it
peter: making sure things that need to be in even alignment, are
peter: and so on
jorendorff: Well, the stack is separate from all malloc'd memory.
peter: ahh ok
jorendorff: Local variables don't go in malloc'd memory.
peter: gotcha
jorendorff: C actually sets up both the stack and the malloc() heap
jorendorff: before main even runs.
peter: ok
peter: and the stack is the automanaged part for locals
jorendorff: exactly
peter: thats the part everyone likes <img src='http://blog.mozilla.com/jorendorff/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />
jorendorff: right.
jorendorff: OK.  So when main() calls another function,
jorendorff: ...say it calls printf()
jorendorff: C does all this automatically
jorendorff: ...*before* any code in printf() actually executes:
jorendorff: (1) stores a "return address"
jorendorff: so it knows where to pick up again when printf() eventually returns
jorendorff: (2) sets aside some stack space for printf's local variables.
jorendorff: I guess (2) actually happens in some code within printf
jorendorff: ...that is generated automatically by the compiler.
jorendorff: Then printf() runs.
peter: ok
jorendorff: When printf() returns, all those local variables go away.
jorendorff: My point is--
jorendorff: can you see what the data structure for this is like?
jorendorff: "The stack" is just a contiguous chunk of memory.
jorendorff: main()'s locals are at the bottom.
peter: sure
jorendorff: If main() calls another function, those locals are adjacent
jorendorff: and so on
peter: makes sense
jorendorff: it's actually a "stack" in the data structures sense.
jorendorff: ok, what this means is
jorendorff: all local variables, both for the current function
jorendorff: and all its callers,
jorendorff: are in this contiguous chunk of memory.
jorendorff: For each platform (meaning, OS + CPU + compiler)
jorendorff: ...there's a way to find out where that chunk of memory is.
jorendorff: Tamarin does that,
jorendorff: then it scans all that memory during GC
jorendorff: to see where the locals point to.
peter: there is some C header can be included that allows access to all this?
jorendorff: peter: not standard C, no
peter: no but some header
jorendorff: yeah, look in the tamarin source <img src='http://blog.mozilla.com/jorendorff/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </pre>
<p>This magic lives in a macro, <code>MMGC_GET_STACK_EXTENTS</code>, defined in the header <a href="http://hg.mozilla.org/tamarin-central/?file/36623e385dd8/MMgc/GC.h"><tt>MMgc/GC.h</tt></a>.  As you can see, there&#8217;s a separate implementation for each platform.</p>
<p>At any given moment, some locals might be in CPU registers and not on the stack.  To cope with this, the macro uses a few lines of assembly code to dump the contents of all the registers onto the stack.  That way MMgc can just scan the stack and it&#8217;ll see all local variables.</p>
<pre>peter: I have been thinking there would be ways to fool this stack scan
jorendorff: peter: Yes, there would be.  <img src='http://blog.mozilla.com/jorendorff/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />
jorendorff: Can you give me an example, though?
peter: if a local pointer points to  dynamically allocated bit of memory
peter: that points to other dynamically allocated bits
peter: that should not be garbage collected
peter: and there have been a bunch of type casts along the way
jorendorff: Oh, type casts don't affect MMgc at all.
jorendorff: MMgc doesn't look at C/C++ code.
jorendorff: It's looking at raw memory.
peter: ahh right
peter: just inference by bit patterns?
jorendorff: yep
peter: and it follows from local pointers to malloc()ed memory,
peter: and follows the pointers in that memory to other memory, and so on?
jorendorff: yes, in principle -- but
jorendorff: MMgc has its own allocator
jorendorff: that you must use instead of malloc().
peter: ahh
peter: ok
jorendorff: Since it knows all the internal data structures
jorendorff: used by that allocator,
jorendorff: when it follows pointers
jorendorff: it knows the size of every region
jorendorff: and can scan each reachable region for further pointers.</pre>
<p>In addition, MMgc does enough bookkeeping that it knows exactly which parts of memory are GC-managed.  So it can&#8217;t be fooled into following a pointer into bad memory (such as <code>NULL</code> or a pointer to a page of memory that has been returned to the operating system, either of which would immediately crash the process).  The same bookkeeping information helps MMgc avoid mistakenly writing to non-GC-managed memory.  (This matters because it <em>does</em> write to GC-managed memory, just like any other mark-and-sweep garbage collector.)</p>
<p>There are other ways to fool MMgc.  Simply using <code>malloc()</code> is enough —MMgc never scans memory allocated using <code>malloc()</code>.  It&#8217;s up to the programmer to avoid fooling MMgc.  This is not such a heavy burden in practice.</p>
<pre>peter: fascinating stuff
peter: who's the genius that thought up all this stuff?
jorendorff: Some Lisp hacker in prehistory <img src='http://blog.mozilla.com/jorendorff/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />
jorendorff: <img src='http://blog.mozilla.com/jorendorff/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />
jorendorff: Lisp was the first language with GC
jorendorff: you can look up <a href="http://en.wikipedia.org/wiki/Garbage_collection_%28computer_science%29">garbage collection</a> online
jorendorff: It's a whole field of computer science.
jorendorff: It *is* fascinating.
peter: do you know the proper comp sci terminology
peter: for this stack-scan style of GC?
peter: or is it just part of the collective knowledge?
jorendorff: Um,
jorendorff: What MMgc does is called "conservative GC"
jorendorff: which means (a) it doesn't really know the types of variables,
jorendorff: so it scans everything whether it's really a pointer variable or not
peter: ok I've seen that written in a few places recently
jorendorff: and usually (b) it treats all the likely places as "roots"
jorendorff: including the stack
peter: The root of the issue is I had no idea C could analyze it's own stack
jorendorff: heh
jorendorff: C can do anything <img src='http://blog.mozilla.com/jorendorff/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </pre>
<p>Indeed it can—which is why, despite their many deep, fundamental problems, C and C++ remain the weapons of choice for operating system and VM designers.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mozilla.com/jorendorff/2007/08/09/conservative-stack-scanning-101/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Stage 0 home stretch</title>
		<link>http://blog.mozilla.com/jorendorff/2007/08/08/stage-0-home-stretch/</link>
		<comments>http://blog.mozilla.com/jorendorff/2007/08/08/stage-0-home-stretch/#comments</comments>
		<pubDate>Wed, 08 Aug 2007 15:28:26 +0000</pubDate>
		<dc:creator>jorendorff</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.mozilla.com/jorendorff/2007/08/08/stage-0-home-stretch/</guid>
		<description><![CDATA[For the past 4 weeks or so, Ed Lee and I have been incrementally nudging the actionmonkey repository toward a state where we can switch over from SpiderMonkey&#8217;s existing memory management routines to Tamarin&#8217;s memory management library, MMgc.
Today some key patches for ActionMonkey Stage 0 were posted on bug 391211.  These patches delete the [...]]]></description>
			<content:encoded><![CDATA[<p>For the past 4 weeks or so, Ed Lee and I have been incrementally nudging the <code>actionmonkey</code> repository toward a state where we can switch over from SpiderMonkey&#8217;s existing memory management routines to Tamarin&#8217;s memory management library, <a href="http://wiki.mozilla.org/Tamarin::MMgc">MMgc</a>.</p>
<p>Today some key patches for <a href="http://wiki.mozilla.org/JavaScript:ActionMonkey:Stage_0_Whiteboard">ActionMonkey Stage 0</a> were posted on <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=391211">bug 391211</a>.  These patches delete the old JSGCArena scheme and start allocating everything—JavaScript strings, functions, objects, and more—from MMgc.</p>
<p>This change will lead to several simplifications.  For example, SpiderMonkey currently saves a reference to every new object as it&#8217;s created.  This reference keeps the object alive in case GC happens while it&#8217;s new, before it&#8217;s reachable from other data.  The reference lasts until the next object is created.  So as long as you know SpiderMonkey internals reeeally well, and you&#8217;re dead certain no new objects are being created, you can sometimes avoid explicitly rooting an object.  Hmmm, maybe this sounds a little crazy and brittle&#8230; anyway, these &#8220;newborn roots&#8221; will be unnecessary with MMgc, because MMgc scans the C stack.  Even if your new object isn&#8217;t reachable from anywhere else yet, there will be a pointer to it from the stack or registers, so it won&#8217;t be unexpectedly collected.  Similarly, throughout SpiderMonkey, <code>JSTempValueRooter</code>s are used to pin objects referenced by local variables in C code.  These temporary roots are generally short-lived, whereas GC happens rarely; so adding and removing the temporary root is just useless bookkeeping most of the time.  Thanks to MMgc&#8217;s stack scanning, these <code>TempValueRooter</code>s can be deleted altogether.  And third, we&#8217;re planning to delete some bits called <code>GCThingFlags</code> that currently cost us 4 to 8 bytes per allocation.  I&#8217;m curious to see how these simplifications will affect performance.</p>
<p>These cleanup tasks are an easy way to get involved in ActionMonkey, by the way.  Leave a comment if you&#8217;d like to lend a hand.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mozilla.com/jorendorff/2007/08/08/stage-0-home-stretch/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Building ActionMonkey</title>
		<link>http://blog.mozilla.com/jorendorff/2007/07/24/building-actionmonkey/</link>
		<comments>http://blog.mozilla.com/jorendorff/2007/07/24/building-actionmonkey/#comments</comments>
		<pubDate>Tue, 24 Jul 2007 17:20:42 +0000</pubDate>
		<dc:creator>jorendorff</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.mozilla.com/jorendorff/2007/07/24/building-actionmonkey/</guid>
		<description><![CDATA[ActionMonkey dwells on the frontier of Mozilla.  Its source code lives in a Mercurial repository, not CVS.  There is no Tinderbox and no Bonsai.  Worse, the usual build instructions don&#8217;t quite work in ActionMonkey-land, and until now, just building it has involved a lot of guesswork.
Today, some kind-hearted genius updated the ActionMonkey [...]]]></description>
			<content:encoded><![CDATA[<p>ActionMonkey dwells on the frontier of Mozilla.  Its source code lives in a Mercurial repository, not CVS.  There is no Tinderbox and no Bonsai.  Worse, the usual build instructions don&#8217;t quite work in ActionMonkey-land, and until now, just building it has involved a lot of guesswork.</p>
<p>Today, some kind-hearted genius updated the ActionMonkey wiki page with <a href="http://wiki.mozilla.org/JavaScript:ActionMonkey#Building_ActionMonkey">build instructions</a>.  The current status of these instructions is &#8220;it probably works on Mac OS&#8221;.  And I want to make it clear exactly what you&#8217;re getting if you build ActionMonkey today.  It&#8217;s just SpiderMonkey with a few Tamarin genes grafted in, but still inactive.  It&#8217;s very, very early in the game yet.</p>
<p>If life on the frontier is your thing, please take ActionMonkey for a spin.  You can really help us by reporting build system bugs—especially on Windows and Linux.  If you do report a bug, please assign it to <code>jorendorff</code>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mozilla.com/jorendorff/2007/07/24/building-actionmonkey/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Stage 0</title>
		<link>http://blog.mozilla.com/jorendorff/2007/07/19/stage-0/</link>
		<comments>http://blog.mozilla.com/jorendorff/2007/07/19/stage-0/#comments</comments>
		<pubDate>Thu, 19 Jul 2007 14:19:35 +0000</pubDate>
		<dc:creator>jorendorff</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.mozilla.com/jorendorff/2007/07/19/stage-0/</guid>
		<description><![CDATA[Stage 0 of the ActionMonkey project is underway.  Read all about it.  Mardak and I are replacing SpiderMonkey&#8217;s garbage collector with the new Tamarin garbage collector, which is called MMgc (for MacroMedia garbage collector—nobody ever renames anything :).
We&#8217;ve spent the past month almost entirely in preparation for this day.  I&#8217;ve read a [...]]]></description>
			<content:encoded><![CDATA[<p>Stage 0 of the ActionMonkey project is underway.  <a href="http://wiki.mozilla.org/JavaScript:ActionMonkey:Stage_0_Whiteboard" title="ActionMonkey Stage 0 Whiteboard">Read all about it.</a>  Mardak and I are replacing SpiderMonkey&#8217;s garbage collector with the new Tamarin garbage collector, which is called MMgc (for <em>MacroMedia garbage collector</em>—nobody ever renames anything :).</p>
<p>We&#8217;ve spent the past month almost entirely in preparation for this day.  I&#8217;ve read a lot of source code, drawn strange little diagrams, blown away lots and lots of Mercurial repositories, hacked Makefiles, and made a fool of myself on IRC.  Mardak and I have even filed and fixed a few <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=387012" title="ActionMonkey Stage 0 tracking bug">Stage 0 bugs</a>.  But we haven&#8217;t changed anything that would break SpiderMonkey.  We were making sure all the pieces are in place first.</p>
<p><s>Today&#8217;s the day.</s>  (see update)</p>
<p><strong>You can help!</strong>  Review our changes.  Check our thinking.  Or just take the opportunity to learn how a real-world garbage collector works.  Getting involved is super easy.  Log onto Mozilla&#8217;s IRC server, <a href="irc://irc.mozilla.org/mmgc">irc://irc.mozilla.org/mmgc</a> and say my name (jorendorff).  (If the link doesn&#8217;t work for you, try <a href="https://addons.mozilla.org/en-US/firefox/addon/16">the ChatZilla add-on</a>.)</p>
<p><strong>Update:</strong>  Yikes!  Today is not the day.  At Brendan&#8217;s prodding, we have hit upon a safer plan that may avoid breaking SpiderMonkey altogether.  More to come.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mozilla.com/jorendorff/2007/07/19/stage-0/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
