<?xml version="1.0" encoding="UTF-8"?>
<!--Generated by Squarespace Site Server v5.9.2 (http://www.squarespace.com/) on Wed, 10 Mar 2010 08:12:50 GMT--><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><title>Blog</title><link>http://www.masonchang.com/blog/</link><description></description><lastBuildDate>Thu, 04 Feb 2010 22:11:51 +0000</lastBuildDate><copyright></copyright><language>en-US</language><generator>Squarespace Site Server v5.9.2 (http://www.squarespace.com/)</generator><item><title>Where is Flash going?</title><dc:creator>Mason Chang</dc:creator><pubDate>Thu, 04 Feb 2010 18:09:45 +0000</pubDate><link>http://www.masonchang.com/blog/2010/2/4/where-is-flash-going.html</link><guid isPermaLink="false">429636:4779963:6561214</guid><description><![CDATA[<p>When you roam the online forums and look at the reaction of the iPad not having Flash, you can see two distinct camps. People are either angry because they can't use Flash or happy to see Flash not installed. Now with the iPad and the iPhone dominating the mobile market, more than ever, people are predicting that Flash will die.<br /><br />In some cases, the concerns are absolutely correct. The example everyone is using is video - and I personally agree that Flash should not be the dominant video player. Video should be an open standard because it's so integral to the web. It is in the HTML5 spec so that any browser implementor can play video. You're going to want to use HTML5 for video, for if not ALL video, at least most. Same with a few animations. Flash should die as the de facto video player. But the death of one application does not mean the death of a whole platform.<br /><br />If you look at Flash as a ubiquitous video player only, it really is all downhill. The real problem is that the platform almost hit 100% ubiquity. What's so sad is that once you hit 100%, you can only go down and that's what's overlooked. So yes, Flash will probably decline, but death? If Flash remains on 80% of all browsers, that's still a very impressive and quite alive platform. What Flash really needs to do then, is move away from playing video and displaying annoying ads, to becoming a platform to build applications.<br /><br />This brings up the question of whether or not there is room for Rich Internet Applications and extra plugins in general (Flash, SilverLight, Java FX, and Google Native Client). I don't pretend to be able to accurately predict the future, but history tells us developers are going to want to do something that HTML/AJAX/CSS can't do. That's why plugins were invented in the first place. All Adobe can do is make something awesome and try to court developers. So who will want to use Flash to build applications?<br /><br />Most web developers don't seem to care. One argument for Flash is that it streamlines the whole web application development workflow from start to finish. You don't need to mess with HTML, JavaScript, CSS, PHP, SQL, etc. However, this has been the case for a while and you still don't see that many developers jumping onto Flash, SilverLight, or Java FX. The pain of so many web technologies, of dealing with all the browser incompatabilities, isn't painful enough for people to jump aboard any of these plugin systems. The quality of developer tools don't seem compelling enough either. SilverLight's whole ecosystem is lightyears ahead of Flash's, yet few people jump to SilverLight. As a whole, web developers just don't want to deal with plugins unless they absolutely have to and only then they use Flash because it's installed everywhere. While the use of plugins in general will decline, the first choice will still be Flash.<br /><br />What about the big mobile web growth? There are mobile versions of web applications and there are native apps. There is a clear want for native applications on phones. The big elephant is the iPhone and it's descendants (iPod touch, iPad). While it doesn't support Flash, there is a hack around in Creative Suite 5 to have Flash applications on the iPhone. Every other phone will have native Flash. Near ubiquity on mobile platforms is a compelling case. Unlike the web where you have three main rendering engines (IE, Gecko, WebKit) that are all trying to implement some standard (IE 6 doesn't count), all the cell phones are completely different. Writing an application for a BlackBerry is completely different from an Android device. The "write once, run anywhere" may be worthwhile on mobile and that's also where growth is. I can see many developers saying it's nice that I only have to write three types of applications instead of a billion: A normal web app with PHP, HTML, etc, an iPhone app, and an <a href="http://arstechnica.com/gadgets/news/2009/10/flash-101-coming-to-just-about-every-platform-but-iphone.ars">everyone else application</a> in Flash. At least it stops at three.<br /><br />Lastly, the market Adobe targets are the designers and content creators. Adobe's products let content creators focus on making content, not coding. Designers should not have to know anything at all about code period. Only the more advanced users, who want to do something that can't be done in the regular toolset should have to look at code. Then they should have the ability to tinker with it. As long as Adobe focuses on letting content creators create, Adobe wins. Adobe makes money off tools with no clear competitors. There is nothing out there that says Adobe can't have two buttons on all the designer tools: publish to HTML5 if thats all they need. If they want to do something HTML doesn't support, have a "Publish to Flash" button. I actually see this being an amazing selling point.<br /><br />When you look at Flash as a pure video player and if the world revolves around the iPhone, it does look like Flash is starting the slow spiral to irrelevance. Realistically Flash is probably not going to remain the dominant video player, but it is going to be on everything but the iPhone - quite a big difference than death. The real question then, is what new areas will Flash be used in, and will it be awesome enough to attract anyone? As a partial Flash VM developer, I find it quite interesting. It frees me to start looking at markets that Flash may never have been used in before. Server Flash? Can it compete with PHP or ASP.NET? Can I install it on my TV and play some games? If Flash isn't constrained to annoying ads and a video player, where could it go? How does Flash give content creators awesome ways to display their great work in a fluid manner? That's a much more interesting question than asking "how can we save Flash?".</p>
<p>Other Opinions:</p>
<ul>
<li>Daring Fireball <a href="http://daringfireball.net/2010/01/apple_adobe_flash">here</a>, <a href="http://daringfireball.net/2010/01/blue_boxes">here</a>, and <a href="http://daringfireball.net/2009/12/html5_video_unusable">here</a></li>
<li><a href="http://www.cinchcast.com/scobleizer/20299">Rober Scoblet and Luke Kilpatrick</a></li>
<li><a href="http://blogs.adobe.com/conversations/2010/02/open_access_to_content_and_app.html">Adobe CTO Kevin Lynch</a> and <a href="http://www.techcrunch.com/2010/02/02/adobe-cto-kevin-lynch-defends-flash/">TechCrunch's response</a></li>
<li><a href="http://blogs.adobe.com/jnack/2010/01/sympathy_for_the_devil.html">John Nack on Adobe</a></li>
</ul>
<p>Random Notes:</p>
<ul>
<li>Tamarin is the virtual machine inside Flash. <a href="https://developer.mozilla.org/en/Tamarin">The VM is all open source</a>.</li>
<li>Most of the Tamarin team develops on the mac. I'm the weird one who uses Windows.</li>
</ul>
<p>Disclaimer: I am a part time intern in Adobe's research lab (not product! I have no idea what product is doing.) working on the Tamarin VM. I'm also a student which lets me do things that may not be practical from a business perspective. All thoughts expressed are mine and mine alone (I'm sure there is some bias here). They do not represent Adobe or Adobe's position on anything. I don't have any insider knowledge nor influence as to what Flash is going to be doing. And no I was not asked nor paid to write this post by anyone at Adobe.</p>]]></description><wfw:commentRss>http://www.masonchang.com/blog/rss-comments-entry-6561214.xml</wfw:commentRss></item><item><title>The Real Value of an Internship</title><dc:creator>Mason Chang</dc:creator><pubDate>Tue, 02 Feb 2010 06:25:22 +0000</pubDate><link>http://www.masonchang.com/blog/2010/2/1/the-real-value-of-an-internship.html</link><guid isPermaLink="false">429636:4779963:6526916</guid><description><![CDATA[<p>New Essay up on what an internship is really for.</p>
<blockquote>
<p>Most people assume that the most valuable thing you get out of an internship is a full time job once you graduate. While I'd be silly not to assume that a full time job is extremely valuable, especially with 10% unemployment, there is a second more valuable aspect: The ability to explore.</p>
</blockquote>
<p>Check it out <a href="http://www.masonchang.com/essays/2010/2/1/the-real-value-of-an-internship.html">here</a>.</p>]]></description><wfw:commentRss>http://www.masonchang.com/blog/rss-comments-entry-6526916.xml</wfw:commentRss></item><item><title>Coders at Work</title><category>Books</category><dc:creator>Mason Chang</dc:creator><pubDate>Mon, 21 Dec 2009 19:34:20 +0000</pubDate><link>http://www.masonchang.com/blog/2009/12/21/coders-at-work.html</link><guid isPermaLink="false">429636:4779963:6031823</guid><description><![CDATA[<p>Coders At Work, by Peter Seibel, interviews 15 famous computer scientists about both the technical and non-technical issues in computer science.<br /><br />Seibel starts off by asking every person how they learned to program. The person answers, and Siebel keeps digging for more wherever it goes, creating a conversational tone that makes the book an easy read with immense depth. Whenever a pause in the conversation is hit, Siebel asks another standard question. Rinse and repeat for 4 or 5 main questions. Siebel is quite a skilled interviewer. He goes in depth when he needs to and gives each question enough time to cover the major issues. The result is that you get to see how 15 respected people have totally different views on the same subject.<br /><br />For example, how is computer science as a field, going to solve parallelism? We have so many cores and no idea what to do with them. Many say functional languages are the way to go as they give you this nice ability to go do some piece of work given an independent set of data. Others say transactional memory is just one of many ways to solve the concurrent problem.<br /><br />The book also gives insight as to how differently people approach programming. Some like the "bottom-up" approach: you just start writing code, hashing things out as they go. Some, notably Donald Knuth, like to think about the program for months on end before even touching a computer. Some programmers need nothing more than a text editor and print statements to debug any program. Amazingly, one of the interviewees who is known for his debugging abilities, simply rewrites everything and magically bugs go away.<br /><br />Since the programmers were good, many eventually moved into management. Siebel asked about managing computer scientists starting with one of the biggest problems: "how do you find great talent?". Some of the interviewees went with a very unsatisfying answer - it's a gut feeling. They have to talk with the person for an hour. They have to bounce ideas off someone's head, see how their head works. Or they just ask them about their old projects and see what problems they encountered and how they solved them. Thankfully, many of the interviewees didn't like the logic puzzle approach to finding people. (I bomb magnificently at such puzzles!)<br /><br />Others such as the director of Yahoo pointed out that he looks at their writing skills. If they have great English, they probably have great code. A few other people said the same thing. Then it hit me that it could entirely be true. Both writing and coding are fundamentally about translating an idea into something understandable. English for humans; code for computers. Both use the same thought processes. An essay needs structure, needs to be edited, and rewritten numerous times, which sounds a lot like refactoring.<br /><br />The great thing is that coders at work is filled with many more "ah ha!" moments. These 15 genius' just keep throwing insight after insight in such explicit glory that I found myself feeling like a better programmer just by reading the book. If you're a programmer that cares about the craft at all, you need this book.</p>]]></description><wfw:commentRss>http://www.masonchang.com/blog/rss-comments-entry-6031823.xml</wfw:commentRss></item><item><title>A C++ Name Demangler</title><dc:creator>Mason Chang</dc:creator><pubDate>Thu, 10 Dec 2009 20:07:56 +0000</pubDate><link>http://www.masonchang.com/blog/2009/12/10/a-c-name-demangler.html</link><guid isPermaLink="false">429636:4779963:6034685</guid><description><![CDATA[<p>C++ compilers <a href="http://en.wikipedia.org/wiki/Name_mangling#Simple_example">mangle function names</a>, or rewrite them into something that is unique across the whole program. However, the new names are usually unreadable. You need to demangle them back into a human readable format.</p>
<p>I needed to demangle some C++ method names for debugging purposes and couldn't find an easy to use/build/embed demangler library. Instead, I stripped out parts of the C++ name demangler from GNU binutils and embeded that.</p>
<p>If you need such functionality, you can <a href="http://www.masonchang.com/storage/software/demangler.rar">download the bare minimum stripped C++ name demangler here</a>.</p>
<p><em>* Provided without warranty, under the GPL license.</em></p>]]></description><wfw:commentRss>http://www.masonchang.com/blog/rss-comments-entry-6034685.xml</wfw:commentRss></item><item><title>Constructing SSA the Easy Way</title><category>Better Know a Virtual Machine</category><dc:creator>Mason Chang</dc:creator><pubDate>Wed, 09 Dec 2009 03:21:17 +0000</pubDate><link>http://www.masonchang.com/blog/2009/12/8/constructing-ssa-the-easy-way.html</link><guid isPermaLink="false">429636:4779963:6023509</guid><description><![CDATA[<p>My good colleague of mine, <a href="http://michael.bebenita.com/">Michael Bebenita</a>, has written a short paper on how to construct <a href="http://en.wikipedia.org/wiki/Static_single_assignment_form">Static Single Assignment</a>, a common way to represent programs in optimizing compilers. <a href="http://www.masonchang.com/storage/pdfs/ssa.pdf">Check it out here</a>.</p>
<p>Abstract:</p>
<blockquote>
<p>Static Single Assignment (SSA) form has become ubiquitous in compilers as an intermediate program representation. The use of SSA simplifies many compiler optimizations and makes the life of compiler writers easier. Many techniques exist to convert programs into SSA form, many of which I find unnecessarily difficult. In this paper I will present a simple technique to convert programs in and out of SSA form.</p>
</blockquote>]]></description><wfw:commentRss>http://www.masonchang.com/blog/rss-comments-entry-6023509.xml</wfw:commentRss></item><item><title>Calling C++ in LIR</title><category>Better Know a Tamarin</category><category>Better Know a Virtual Machine</category><category>Tamarin</category><dc:creator>Mason Chang</dc:creator><pubDate>Tue, 01 Dec 2009 17:33:04 +0000</pubDate><link>http://www.masonchang.com/blog/2009/12/1/calling-c-in-lir.html</link><guid isPermaLink="false">429636:4779963:5942996</guid><description><![CDATA[<p>JIT compiled code needs to call C++ methods to do the heavy lifting. Metadata about C++ methods such as the parameters, the return type, etc is needed to create LIR that can call into those methods. Tamarin does this through the use of the <em>CallInfo </em>data structure:</p>
<p><!-- code formatted by http://manoli.net/csharpformat/ --></p>
<div class="csharpcode">
<pre class="alt"><span class="kwrd">struct</span> CallInfo</pre>
<pre>{</pre>
<pre class="alt">    uintptr_t   _address;        <span class="rem">// Address of the method</span></pre>
<pre>    uint32_t    _argtypes:27;    <span class="rem">// 9 3-bit fields indicating arg type</span></pre>
<pre class="alt">    AbiKind     _abi:3;</pre>
<pre>&nbsp;</pre>
<pre class="alt">    verbose_only ( <span class="kwrd">const</span> <span class="kwrd">char</span>* _name; )</pre>
<pre>};</pre>
</div>
<p>The _address field is the address of the C++ method.<br /><br />The _argtypes field is a bit encoding of the number of parameters, the types of each parameter, and the return type. For example, consider a C++ method that has the declaration:</p>
<p><!-- code formatted by http://manoli.net/csharpformat/ --></p>
<div class="csharpcode">
<pre class="alt"><span class="kwrd">void</span> someFunction(<span class="kwrd">int</span> someParameter, <span class="kwrd">double</span> otherParameter);</pre>
</div>
<p>&nbsp;</p>
<p>Void types are represented by the decimal number 0 (binary 000). Integer types are represented by the decimal number 2 (binary 010). Double types are represented by the decimal number 1 (binary 001). The _argtypes, in binary would look like:<br /><br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;010 | 001 | 000<br /><br />The parameters are laid out in reverse order, with the return type being the right most 3 bits. Since there are only 27 bits, LIR can only make calls to a C++ method that have at most 8 parameters. <br /><br />The AbiKind represents <a href="http://en.wikipedia.org/wiki/X86_calling_conventions">how the C++ method is called</a>.</p>
<p><!-- code formatted by http://manoli.net/csharpformat/ --></p>
<div class="csharpcode">
<pre class="alt"><span class="kwrd">enum</span> AbiKind {</pre>
<pre>    ABI_FASTCALL,</pre>
<pre class="alt">    ABI_THISCALL,</pre>
<pre>    ABI_STDCALL,</pre>
<pre class="alt">    ABI_CDECL</pre>
<pre>};</pre>
</div>
<p>&nbsp;</p>
<p>FastCall stores a few parameters into registers instead of pushing them onto the stack. A THISCALL means that the C++ method is part of a class, and requires that the instance of an object be passed in. I haven't seen STDCALL be used at all. A CDECL call stands for C declaration, where all parameters are pushed onto the stack prior to calling the method.<br /><br />All these CallInfo structures are manually created and maintained in Tamarin in the file core/jit-calls.h. Consider the C++ method declaration:</p>
<p><!-- code formatted by http://manoli.net/csharpformat/ --></p>
<div class="csharpcode">
<pre class="alt"><span class="kwrd">static</span> <span class="kwrd">void</span> AvmCore::atomWriteBarrier(MMgc::GC *gc, <span class="kwrd">const</span> <span class="kwrd">void</span> *container, <br />                                                       Atom *address, Atom atomNew);</pre>
</div>
<p>&nbsp;</p>
<p>The macro declaration to create the CallInfo structure for atomWriteBarrier is:<br /><!-- code formatted by http://manoli.net/csharpformat/ --></p>
<div class="csharpcode">
<pre class="alt">FUNCTION(FUNCADDR(AvmCore::atomWriteBarrier), SIG4(V,P,P,P,A), atomWriteBarrier)</pre>
</div>
<p>&nbsp;</p>
<p>Each of these funky words is another macro:</p>
<ul>
<li><strong>FUNCTION </strong>- AvmCore::atomWriteBarrier uses the ABI_CDECL calling convention.</li>
<li><strong>FUNCADDR </strong>- This is a static method.</li>
<li><strong>SIG4(V,P,P,P,A)</strong> - Represents the CallInfo::_argtypes field. V is a void method. The next 3 parameters are (P)ointer types. The last parameter is an (A)tom type.</li>
<li><strong>atomWriteBarrier</strong> - The name of the method, which is used for debugging purposes.</li>
</ul>
<p>The current list of C++ methods all manually created and maintained, which is a really annoying hassle. With the LLVM bitcode to LIR translator, the number of CallInfos grows dramatically because C++ methods usually call lots of other C++ methods. Consider the atomWriteBarrier code:</p>
<p><!-- code formatted by http://manoli.net/csharpformat/ --></p>
<div class="csharpcode">
<pre class="alt"><span class="kwrd">void</span> AvmCore::atomWriteBarrier(MMgc::GC *gc, <span class="kwrd">const</span> <span class="kwrd">void</span> *container, Atom *address, Atom atomNew)</pre>
<pre>{ </pre>
<pre class="alt">    decr_atom(*address);</pre>
<pre>    incr_atom(gc, container, atomNew);</pre>
<pre class="alt">    *address = atomNew;</pre>
<pre>}</pre>
</div>
<p>&nbsp;</p>
<p>There are no CallInfo structures for decr_atom() and incr_atom(), but they have to be created. If a targeted inline C++ method calls a C++ method that doesn't already have a CallInfo structure, a new CallInfo for the newly called C++ method must be created.<br /><br />While the list can manually be created, it would be horrendously annoying. Instead, we automatically create a new file called jit-calls-generated.h that contains all the new generated CallInfo structures.</p>
<h3><span style="font-size: 110%;">Automatically creating a CallInfo structure:</span></h3>
<p>Consider the C++ method declaration for decr_atom:<br /><!-- code formatted by http://manoli.net/csharpformat/ --></p>
<div class="csharpcode">
<pre class="alt"><span class="kwrd">static</span> <span class="kwrd">void</span> decr_atom(Atom <span class="kwrd">const</span> a);</pre>
</div>
<p>&nbsp;</p>
<p>The declaration in LLVMbitcode:</p>
<!-- code formatted by http://manoli.net/csharpformat/ -->
<div class="csharpcode">
<pre class="alt">define <span class="kwrd">void</span> @AvmCore::decr_atomEi(i32 %a); </pre>
</div>
<p>&nbsp;</p>
<p>When translating bitcode to LIR, the bitcode contains the parameter and return types. It also provides the name of the method. The last missing piece of the AbiKind.<br /><br />LLVM bitcode has an explicit <em>FASTCALL </em>modifier for methods that use the <em>FASTCALL </em>calling convention. However, bitcode contains no explicit distinction between a <em>CDECL </em>and <em>THISCALL </em>calling convention. The call site in bitcode only says that a pointer is being passed into a method. The distinction between a <em>CDECL/THISCAL</em>L is found at the function definition, NOT declaration.<br /><br />The LLVM function definition for a <em>THISCALL </em>looks like:</p>
<!-- code formatted by http://manoli.net/csharpformat/ -->
<div class="csharpcode">
<pre class="alt">define i32 @Toplevel::add2(%<span class="str">"struct.avmplus::Toplevel"</span>* %<span class="kwrd">this</span>, i32 %leftOperand, i32 %rightOperand); </pre>
</div>
<p>&nbsp;</p>
<p>The first parameter is explicitly named "this". If the first parameter of a function definition is named "<span style="text-decoration: underline;">this</span>", then the C++ method uses the <em>THISCALL </em>AbiKind. This detection scheme is safe because "<span style="text-decoration: underline;">this</span>" is a keyword in C++, and you can't name a value "<span style="text-decoration: underline;">this</span>". The function declaration would show the name of the instance being passed in, rather than the name "<span style="text-decoration: underline;">this</span>", therefore being incorrect.</p>
<h2>What can't be called:</h2>
<p>While the majority of C++ methods can be called from LIR, there are some limitations. A C++ object's constructor cannot be called as it is against the C++ specification to get the address of a constructor (<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1905.pdf">C++ Standard, section 12.1.12</a>). At the moment, we create a C++ wrapper that calls the constructor. LIR then calls the wrapper. A polymorphic call cannot be called as it's a runtime lookup based on a virtual method table.</p>]]></description><wfw:commentRss>http://www.masonchang.com/blog/rss-comments-entry-5942996.xml</wfw:commentRss></item><item><title>Defining a Good Academic Paper</title><dc:creator>Mason Chang</dc:creator><pubDate>Wed, 18 Nov 2009 18:56:09 +0000</pubDate><link>http://www.masonchang.com/blog/2009/11/18/defining-a-good-academic-paper.html</link><guid isPermaLink="false">429636:4779963:5843579</guid><description><![CDATA[<p>New essay up on defining a good academic paper:</p>
<p><a href="http://www.masonchang.com/essays/2009/11/18/defining-a-good-academic-paper.html">http://www.masonchang.com/essays/2009/11/18/defining-a-good-academic-paper.html</a></p>]]></description><wfw:commentRss>http://www.masonchang.com/blog/rss-comments-entry-5843579.xml</wfw:commentRss></item><item><title>Example C++ to LIR Translation</title><category>Better Know a Tamarin</category><category>Better Know a Virtual Machine</category><category>Tamarin</category><dc:creator>Mason Chang</dc:creator><pubDate>Wed, 11 Nov 2009 23:43:24 +0000</pubDate><link>http://www.masonchang.com/blog/2009/11/11/example-c-to-lir-translation.html</link><guid isPermaLink="false">429636:4779963:5768637</guid><description><![CDATA[<p>There are a lot of translation steps to go from C++ to bitcode to LIR. This post hopefully solidifies everything with a concrete example. Consider ActionScript source that adds two variables and assigns the sum to another variable.</p>
<p><!-- code formatted by http://manoli.net/csharpformat/ --></p>
<div class="csharpcode">
<pre class="alt">var a;</pre>
<pre>var b;</pre>
<pre class="alt">var sum = a + b; <br /></pre>
</div>
<p>&nbsp;</p>
<p>The LIR that is normally generated is:</p>
<p><!-- code formatted by http://manoli.net/csharpformat/ --></p>
<div class="csharpcode">
<pre class="alt">left = load left[0]</pre>
<pre>right = load right[0]</pre>
<pre class="alt">add = icall #add ( left, right )</pre>
<pre>&nbsp;</pre>
<pre class="alt">store vars[32] = add</pre>
</div>
<div class="csharpcode"></div>
<div class="csharpcode"></div>
<p>&nbsp;</p>
<p>First, the two variables <em>left</em> and <em>right</em>, which are <strong>a</strong> and <strong>b</strong> in the AS3 source code, are loaded. Next, a call to the VM C++ method <em>add</em> is generated. The result of <em>add</em> is stored into LIR <em>vars[32]</em>, which is a location in memory and represents the AS3 variable sum.</p>
<p>Instead of calling Add, the JIT should inline the method. To do that, C++ has to be converted to LIR. The VM C++ method that does the actual add has the source:</p>
<p><!-- code formatted by http://manoli.net/csharpformat/ --></p>
<div class="csharpcode">
<pre class="alt">Atom Toplevel::add(Atom left, Atom right)</pre>
<pre>{</pre>
<pre class="alt">    BITCODE_INLINEABLE  <span class="rem">// Indicate that we want to translate this method to LIR</span></pre>
<pre>    <span class="kwrd">if</span> (areNumbers(left, right)) {        <span class="kwrd"><br />        return</span> addNumbers(left, right);</pre>
<pre class="alt">    }</pre>
<pre>    <span class="kwrd">else</span> {</pre>
<pre>        <span class="kwrd">return</span> addUnknown(left,right);</pre>
<pre class="alt">    }</pre>
<pre>}</pre>
</div>
<p>&nbsp;</p>
<p>The add method is part of a C++ object named Toplevel. ActionScript values are modeled as Atoms in C++. An Atom is a 32 bit integer with the bottom 3 bits used for type information. The C++ source checks to see what the "+" operator does depending on the types of the two values. Once Tamarin is compiled with llvm, it produces bitcode that looks like:</p>
<p><!-- code formatted by http://manoli.net/csharpformat/ --></p>
<div class="csharpcode">
<pre class="alt">define i32 @add2(%<span class="str">"struct.avmplus::Toplevel"</span>* %<span class="kwrd">this</span>, i32 %left, i32 %right) {</pre>
<pre>entry:</pre>
<pre class="alt">    call <span class="kwrd">void</span> @enableBitcodeInlining() <span class="rem">// The macro expansion of BITCODE_INLINEABLE</span></pre>
<pre>&nbsp;</pre>
<pre class="alt">    %0 = call i8 @areNumbers(%<span class="str">"struct.avmplus::Toplevel"</span>* %<span class="kwrd">this</span>, i32 %left, i32 %right) </pre>
<pre>    %toBool = icmp eq i8 %0, 0      </pre>
<pre class="alt">&nbsp;</pre>
<pre>    <span class="rem">// if true go to addNumbers, otherwise addUnknown</span></pre>
<pre class="alt">    br %toBool, label %addNumbers, label %addUnknown    </pre>
<pre>&nbsp;</pre>
<pre class="alt">addNumbers:     </pre>
<pre>    %1 = call i32 @addNumbers(%<span class="str">"struct.avmplus::Toplevel"</span>* %<span class="kwrd">this</span>, i32 %left, i32 %right) </pre>
<pre class="alt">    ret i32 %1</pre>
<pre>&nbsp;</pre>
<pre class="alt">addUnknown:       </pre>
<pre>    %2 = call i32 @addUnknown(%<span class="str">"struct.avmplus::Toplevel"</span>* %<span class="kwrd">this</span>, i32 %left, i32 %right) </pre>
<pre class="alt">    ret i32 %2</pre>
<pre>}</pre>
</div>
<p>&nbsp;</p>
<p>The LLVM bitcode is in <a href="http://en.wikipedia.org/wiki/Static_single_assignment_form">SSA form</a> and retains all of the type information and control flow. The call to <em>enableBitcodeInlining</em> is the C++ source macro BITCODE_INLINEABLE. The static translator looks for a call to <em>enableBitcodeInlining</em> as an indicator to translate the method to LIR. The llvm type i32 represents an integer, which is what a C++ Atom really is. Finally, the resulting LIR once the C++ add method is inlined into the LIR instead of being called is:</p>
<p><!-- code formatted by http://manoli.net/csharpformat/ --></p>
<div class="csharpcode">
<pre class="alt">left = load leftp[0]</pre>
<pre>right = load rightp[0]</pre>
<pre class="alt">&nbsp;</pre>
<pre>inline( left, right )</pre>
<pre class="alt">    retVal = stackAlloc 4</pre>
<pre>    isNumberAdd = icall #areNumbers (left, right)</pre>
<pre class="alt">&nbsp;</pre>
<pre>    eq1 = eq isNumberAdd, 0</pre>
<pre class="alt">    jump <span class="kwrd">true</span> eq1 -&gt; addNumbersLabel</pre>
<pre>    jump <span class="kwrd">false</span> eq1 -&gt; addUnknownLabel</pre>
<pre class="alt">&nbsp;</pre>
<pre>addNumbersLabel:</pre>
<pre class="alt">    addNumbers = icall #addNumbers (left, right)</pre>
<pre>    store retVal[0] = addNumbers</pre>
<pre class="alt">    jump -&gt; endInline </pre>
<pre>&nbsp;</pre>
<pre class="alt">addUnknownLabel:</pre>
<pre>    addUnknown = icall #addUnknown (left,right)</pre>
<pre class="alt">    store retVal[0] = addUnknown</pre>
<pre>    jump -&gt; endInline </pre>
<pre class="alt">&nbsp;</pre>
<pre>endInline:</pre>
<pre class="alt">&nbsp;</pre>
<pre>ld5 = load retVal[0]</pre>
<pre class="alt">sti vars[32] = ld5</pre>
</div>
<p>&nbsp;</p>
<p>The LIR still needs to load the left and right operands prior to inlining the method. Space is then allocated on the stack for the return value of the method. The C++ return statements become LIR store values at the allocated stack location. The C++ call statements remain LIR call statements, unless they too are explicitly inlined. In the original LIR, the value returned from call add was stored into the location vars[32]. Now, the return value is loaded from retVal and stored again into vars[32], completing the inlining of C++ add.</p>
<p>Although not in this example, the translator takes the same approach used by return statements for Phi functions. LIR doesn't have a Phi opcode. Instead, stores are pushed up to the basic block where the value is flowing into the Phi function. The actual Phi turns into a load from the store location.</p>
<p>Also, the translator always follows LLVM semantics and creates both the true and false branches in LIR. Future work is to optimize away one of the branches and add a LIR_phi instruction.</p>]]></description><wfw:commentRss>http://www.masonchang.com/blog/rss-comments-entry-5768637.xml</wfw:commentRss></item><item><title>The Developer Productivity Case for C++ Translation</title><category>Better Know a Tamarin</category><category>Better Know a Virtual Machine</category><category>Tamarin</category><dc:creator>Mason Chang</dc:creator><pubDate>Tue, 03 Nov 2009 19:17:10 +0000</pubDate><link>http://www.masonchang.com/blog/2009/11/3/the-developer-productivity-case-for-c-translation.html</link><guid isPermaLink="false">429636:4779963:5683503</guid><description><![CDATA[<p><!-- code formatted by http://manoli.net/csharpformat/ --></p>
<p>Why go through all this trouble to translate C++ into LIR? The "easiest" or most direct route is to manually create and inline LIR that represents the functionality we want. Consider adding two values:</p>
<p><!-- code formatted by http://manoli.net/csharpformat/ --></p>
<div class="csharpcode">
<pre class="alt"><span class="kwrd">if</span> (areNumbers(left, right)) {</pre>
<pre>    <span class="rem">// do integer add</span></pre>
<pre class="alt">    <span class="kwrd">return</span> sum</pre>
<pre>}</pre>
<pre class="alt"><span class="kwrd">else</span> {</pre>
<pre>    <span class="rem">// do lots of look ups and checks</span></pre>
<pre class="alt">    <span class="kwrd">return</span> sum</pre>
<pre>} </pre>
</div>
<p>&nbsp;</p>
<p>We could create the LIR that represents areNumbers and the x86 integer add, and have it up and running tomorrow. The problem is that it becomes a maintanence hassle. Tamarin would have a bunch of manually inlined LIR snippets that is difficult to understand and debug. The following is the simplified equivalent LIR for the code snippet above:</p>
<div class="csharpcode">
<pre class="alt">ld1 = load vars[4]</pre>
<pre>ld2 = load vars[8]</pre>
<pre class="alt">&nbsp;</pre>
<pre>areNumbers1 = call areNumbers(ld1, ld2)</pre>
<pre class="alt">eq1 = eq areNumbers, 0</pre>
<pre>jump <span class="kwrd">false</span> slowPath</pre>
<pre class="alt">&nbsp;</pre>
<pre>   <span class="rem">// fall through to fast path</span></pre>
<pre class="alt">   <span class="rem">// do integer add</span></pre>
<pre>   store returnValue[0], sum</pre>
<pre class="alt">&nbsp;</pre>
<pre>slowPath:</pre>
<pre class="alt">   <span class="rem">// more checks</span></pre>
<pre>   store returnValue[0], sum</pre>
<pre class="alt">&nbsp;</pre>
<pre>ld3 = returnValue[0]</pre>
<pre class="alt">ret ld3<br /></pre>
</div>
<p>&nbsp;</p>
<p>It's a lot nicer to just code the functionality in C++, where its a lot more maintainable, malleable, and easier to debug. The counter-argument is that you have to develop the translation program and maintain another piece of code. While that's true, overall, there is less work, and a lot less pain. (Debugging LIR is a painful process). Developer productivity is actually the main reason Adobe's investing in what I consider an "infrastructure" software update.</p>]]></description><wfw:commentRss>http://www.masonchang.com/blog/rss-comments-entry-5683503.xml</wfw:commentRss></item><item><title>Adding More Cowbell to Tamarin</title><category>Better Know a Tamarin</category><category>Better Know a Virtual Machine</category><category>NanoJIT</category><category>Tamarin</category><dc:creator>Mason Chang</dc:creator><pubDate>Fri, 30 Oct 2009 08:10:06 +0000</pubDate><link>http://www.masonchang.com/blog/2009/10/30/adding-more-cowbell-to-tamarin.html</link><guid isPermaLink="false">429636:4779963:5654390</guid><description><![CDATA[<img src="http://www.masonchang.com/storage/post-images/systemStructure.jpg?__SQUARESPACE_CACHEVERSION=1256888734358" alt="" />]]></description><wfw:commentRss>http://www.masonchang.com/blog/rss-comments-entry-5654390.xml</wfw:commentRss></item></channel></rss>