<?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"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Zor&#039;s Blog &#187; Mono</title>
	<atom:link href="http://xtzgzorex.wordpress.com/category/mono/feed/" rel="self" type="application/rss+xml" />
	<link>http://xtzgzorex.wordpress.com</link>
	<description>Seeing Sharp</description>
	<lastBuildDate>Tue, 07 May 2013 22:44:37 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='xtzgzorex.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Zor&#039;s Blog &#187; Mono</title>
		<link>http://xtzgzorex.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://xtzgzorex.wordpress.com/osd.xml" title="Zor&#039;s Blog" />
	<atom:link rel='hub' href='http://xtzgzorex.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Demystifying Garbage Collectors</title>
		<link>http://xtzgzorex.wordpress.com/2012/10/11/demystifying-garbage-collectors/</link>
		<comments>http://xtzgzorex.wordpress.com/2012/10/11/demystifying-garbage-collectors/#comments</comments>
		<pubDate>Thu, 11 Oct 2012 22:24:40 +0000</pubDate>
		<dc:creator>XTZGZoReX</dc:creator>
				<category><![CDATA[C]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[D]]></category>
		<category><![CDATA[Erlang]]></category>
		<category><![CDATA[MCI]]></category>
		<category><![CDATA[Mono]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Rust]]></category>

		<guid isPermaLink="false">http://xtzgzorex.wordpress.com/?p=865</guid>
		<description><![CDATA[There seems to be a lot of confusion among developers on how garbage collectors actually work. They really aren&#8217;t as magical as some people think; in many ways, some garbage collectors are actually quite crude and &#8212; by modern developer standards &#8212; evil, unmaintainable, and full of subtle gotchas (the latter is certainly true no &#8230; <a href="http://xtzgzorex.wordpress.com/2012/10/11/demystifying-garbage-collectors/" class="more-link">Continue reading <span class="meta-nav">&#187;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=xtzgzorex.wordpress.com&#038;blog=13381977&#038;post=865&#038;subd=xtzgzorex&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>There seems to be a lot of confusion among developers on how garbage collectors actually work. They really aren&#8217;t as magical as some people think; in many ways, some garbage collectors are actually quite crude and &#8212; by modern developer standards &#8212; evil, unmaintainable, and full of subtle gotchas (the latter is certainly true no matter one&#8217;s perspective). In this post, I&#8217;ll try to shed some light on how GCs work in a way that (hopefully) any developer can understand. I do assume that the reader is at least familiar with basic computer memory concepts (C knowledge is preferred).</p>
<p>Note: This is a very long blog post. Grab some coffee.</p>
<h1>Reachability Analysis</h1>
<p>All garbage collectors are essentially based on one fundamental concept, regardless of whether they support reference counting or similar mechanisms: Reachability analysis (also known as liveness analysis, though this is less common and usually more associated with compiler lingo). The idea is that, given a set of roots, the collector will scan the entire heap (the set AllObjects) recursively, constantly adding to a set LiveObjects those objects that it finds to be live. When the scan is complete, the relative complement of LiveObjects with respect to AllObjects (that is, all objects that are in AllObjects but <em>not</em> in LiveObjects) are considered unreachable, and are thus deallocated (garbage collected). This process is typically referred to as a mark-sweep algorithm.</p>
<p>(The set theoretic terminology is quite intentional, by the way; there can be no duplicate elements.)</p>
<p>We can express the above algorithm as:</p>
<pre>collect()
    // First find all live objects.
    mark()

    // Then reclaim dead objects.
    sweep()

mark()
    // The root set contains pointers to
    // static fields that in turn *can*
    // contain pointers to objects. They
    // can also simply contain a null
    // value.
    for Field in Roots do
        Object = *Field

        // If not a null pointer, push
        // it into the work list for
        // scanning below. Also mark it
        // as live immediately.
        if Object != null do
            push(LiveObjects, Object)
            push(WorkList, Object)

    // Now start processing the work
    // list. It'll eventually become
    // empty once the entire heap has
    // been scanned.
    while !empty(WorkList) do
        Object = pop(WorkList)

        // Now recursively scan all
        // objects for references and
        // mark them live, push them
        // into the work list, rinse;
        // repeat.
        for Field in Object do
            ReferencedObject = *Field

            if ReferencedObject != null and
                !contains(LiveObjects, ReferencedObject) do
                push(LiveObjects, ReferencedObject)
                push(WorkList, ReferencedObject)

sweep()
    // The relative complement of
    // LiveObjects with respect to
    // AllObjects = dead objects.
    DeadObjects = complement(LiveObjects, AllObjects)

    // Free all dead objects.
    while !empty(DeadObjects) do
        Object = pop(DeadObjects)
        free(Object)

    // Since LiveObjects contains
    // all the relevant objects
    // that are left, we can simply
    // assign it to AllObjects.
    AllObjects = LiveObjects</pre>
<p>(This algorithm is a variation of the one Jones uses in his <a href="http://gchandbook.org/">Garbage Collection Handbook</a> &#8211; which, by the way, is a fantastic book that I fully recommend if you&#8217;re interested in garbage collectors.)</p>
<p>So, to reiterate, what this algorithm does is:</p>
<ol>
<li>Marks all roots as live.</li>
<li>Populates the initial work list with root objects.</li>
<li>Walks the heap recursively marking reachable objects live.</li>
<li>Frees all dead objects.</li>
<li>Repopulates the AllObjects set with the LiveObjects set.</li>
</ol>
<p>That&#8217;s really all there is to reachability analysis and mark-sweep. Of course, a real GC is more complicated for a number of reasons:</p>
<ul>
<li>Simply maintaining sets of objects is not very efficient at all.</li>
<li>Marking is often implemented via bitmaps or flipping bits directly on objects instead of maintaining an expensive set.</li>
<li>Scanning thread stacks, thread-local storage (TLS) locations, and registers is much more complex than the above.</li>
<li>I omitted allocation code entirely &#8211; allocation algorithms make up a lot of the complexity in a GC, particularly because lock-free allocation is desirable.</li>
<li>Most collector types will want to pause all threads when starting a collection, and resume them when done.</li>
<li>Some GC algorithms will even want to mutate the heap layout (moving and copying collectors).</li>
<li>Some concurrent (and sometimes even generational) GC algorithms require read and write barriers to be inserted in generated code by the compiler.</li>
<li>In some cases, a GC has to consider that an object reference can not only be null, but also completely <em>invalid</em> even if non-null.</li>
</ul>
<p>&#8230; And many others. But one thing at a time.</p>
<h1>Memory Layout</h1>
<p>We&#8217;ll need to discuss the memory layout of garbage collected objects a bit before getting further into the details of garbage collectors.</p>
<p>The memory layout of collector-managed objects varies a lot depending on the language or virtual machine involved. To give some examples:</p>
<ul>
<li>C: An object consists purely of what has been declared/explicitly allocated.</li>
<li>D: An object contains a virtual table, a monitor pointer, and its fields.</li>
<li>Mono: An object consists of a virtual table, a synchronization block pointer, and then its fields.</li>
<li>MCI: An object consists of a type info pointer, a word of GC-specific bits, a user-modifiable reference field, and its regular fields.</li>
</ul>
<p>The reason C doesn&#8217;t throw any hidden fields into objects is, of course, because of its very close-to-the-metal memory model. This means that the collector cannot (trivially, at least) store data before an object&#8217;s contents.</p>
<p>In D, things are quite different: Since the language is built with GC as the default memory allocation mechanism, the compiler reserves two words of memory in the header of all objects. The first is a simple pointer to a virtual table (i.e. your run-of-the-mill virtual function dispatch table). This virtual table also happens to point to a type information structure that the GC can make use of. The second is a pointer to a so-called monitor. This is just fancy terminology for a mutex. This monitor structure, though, happens to also be used by the GC for registering object finalizers (more on that further into the post). So, all in all, the D compiler helps the GC a lot by providing type information and places to store information.</p>
<p>In the Mono virtual machine, things are quite similar to D. The first word of an object is a pointer to a virtual table, which contains a type information structure and function addresses like in D. The second word points to the synchronization block. This one is a bit of a beast: It&#8217;s used to store a monitor (the entire thing, not just a mutex pointer), cache hash values (necessary for moving/copying collectors), and a few other things. For objects that don&#8217;t implement GetHashCode, their hash is calculated from their address. This poses a problem when objects are moved around in memory (and thus change addresses). The purpose of the cached hash field is thus to remember the hash value even when the object is moved. This is a reasonable approach (really, the only not-incredibly-complicated one) because, at worst, some objects will have equal hash codes occasionally.</p>
<p>In MCI, the design of object headers is quite different from other virtual machines. Since the VM has no particular support for virtual function dispatch (but certainly lets you implement it in the code you pass to it), the first word simply points to a type information structure (which also contains a bitmap of the physical type layout &#8211; used for faster scanning). The second word is completely opaque and the use is specific to the garbage collector that the VM is started with. The third word is a user-modifiable field that can contain any reference type (managed objects, arrays, and vectors all allow this). This field is always scanned by the GC. The motivation for that was to make implementation of some higher-level language features like virtual dispatch easier.</p>
<p>In general, in an environment where objects contain information usable by the GC, the GC is going to be more efficient and/or more precise. The GC will have an even better time if the compiler emits load/store GC barriers (not to be confused with memory barriers). More on those and type precision further into the post.</p>
<h1>Threading</h1>
<p>For now, we&#8217;ll assume concurrent garbage collectors don&#8217;t exist (which is not the case, but ignorance is bliss). Let&#8217;s look at how so-called stop-the-world (STW) collectors work.</p>
<p>For non-concurrent, STW collectors, it is absolutely essential that all non-collector threads are stopped before a collection starts. This is so because if other threads were running while the collector is scanning the heap, it might miss objects that were recently made live and end up freeing them, which is clearly a Bad Thing (TM). For moving and copying collectors, things could get even worse &#8211; some parts of the heap (or roots) might end up with lingering references!</p>
<p>So, a non-concurrent GC generally performs a collection like this:</p>
<ol>
<li>A thread attempts to allocate memory, but none is available.</li>
<li>The collector hijacks the allocating thread.</li>
<li>All other threads are suspended (typically via POSIX signals; Windows has a SuspendThread function).</li>
<li>A collection is performed.</li>
<li>Memory is allocated, either via newly freed memory or by asking the OS for more memory.</li>
<li>All other threads are resumed (again, POSIX signals; ResumeThread on Windows).</li>
<li>Any pending finalizers are executed (either on the hijacked thread or on a dedicated asynchronous thread).</li>
<li>The GC returns the hijacked thread to the allocation site, with the newly allocated memory.</li>
<li>The program continues on&#8230;</li>
</ol>
<p>There are some things worth noting here: First, step 7 may not actually return any memory; if the GC failed to allocate memory one way or another, it would likely throw an exception or return a null pointer. Second, in step 3, the GC may actually skip some threads that it uses internally. This is the case for collectors that do parallel marking of the heap. Third, never mind finalization for now. We&#8217;ll get to it.</p>
<p>Probably the most prominent criticism of STW collectors is exactly that: They&#8217;re STW. There are several problems with this property:</p>
<ul>
<li>Programs can stop at (practically) arbitrary locations/times.</li>
<li>Pause times are unbounded (for most collectors &#8211; real time collectors do exist, but are rare).</li>
<li>The programmer must take care that low-level threading code cannot be disrupted by pauses.</li>
</ul>
<p>All of these make concurrent collectors generally more preferable than STW collectors, but concurrent collectors are significantly harder to implement &#8211; we&#8217;ll also get to that.</p>
<p>Finally, regardless of what collector type is in use, whenever a thread is started, the collector must be notified in such a way that it can add the thread&#8217;s TLS areas to its roots (and remove them when the thread goes down). Some languages and virtual machines take this to a whole other level; for example, the Erlang VM exclusively does per-process garbage collection, which significantly speeds up collection overall (keep in mind that <a href="http://www.erlang.org/doc/reference_manual/processes.html">Erlang processes are extremely small</a>). Erlang can get away with this because there is no global state that needs to be garbage collected. It is very likely that the Rust language will go with a similar model.</p>
<h1>Finalization</h1>
<p>There is often a need to perform some kind of user-defined cleanup when an object is collected. Most garbage collected languages have features that allow this in some form or another.</p>
<p>C#:</p>
<pre>class Foo
{
    ~Foo()
    {
        PerformCleanup();
    }
}</pre>
<p>D:</p>
<pre>class Foo
{
    ~this()
    {
        performCleanup();
    }
}</pre>
<p>Rust:</p>
<pre>struct Foo
{
    drop
    {
        perform_cleanup();
    }
}</pre>
<p>Some languages call them destructors, but the universal term used in GC lingo is finalizer; it finalizes the object&#8217;s lifetime.</p>
<p>Exactly when a finalizer runs is very specific to the language or virtual machine. To name a few approaches that exist:</p>
<ul>
<li>An object is finalized whenever nothing has references to it. This means that two objects pointing to each other can create a cycle in which no finalizers are invoked on the two objects, ever. Worse yet, even an object holding a pointer to itself can prevent finalization.</li>
<li>An object is finalized whenever nothing has references to it, except itself. This is a variation of the above aforementioned approach which is slightly safer. Cycles between multiple objects are still problematic.</li>
<li>An object is finalized whenever nothing has references to it, except itself or other dead objects. This permits both cycles and self pointers.</li>
</ul>
<p>The last approach is arguably the safest, but it does also mean that a finalizer cannot assume anything about the state of other objects that the finalizer&#8217;s object refers to. This is by far the most common kind of finalization used in programming languages, due to its safety traits.</p>
<p>As I mentioned earlier, finalizers are executed just before the GC transfers control of the calling thread back to the application. Again, depending on the language and virtual machine, finalizers are executed either on the calling thread or on an asynchronous finalization thread (or multiple, in some cases). For implementations where finalizers are executed on the calling thread, the finalized objects can be trivially deallocated right after finalization. For those that enqueue finalizers on a separate thread, things go like this:</p>
<ol>
<li>The object is enqueued on a separate thread.</li>
<li>The GC resumes program execution.</li>
<li>The finalization thread finalizes the object.</li>
<li>The object is deallocated.</li>
</ol>
<p>If the garbage collector implements the third (and safest) finalization technique mentioned before, it can choose to do some extra work to make finalizers less prone to looking at objects with an invalid state (because they have been finalized before). This is fairly trivial: Given a finalizable object, go over all of its reference fields and set them to a null value. This will in all likelihood result in some kind of null reference exception, should the finalizer attempt to access these fields, thereby making it clear to the programmer what went wrong. This is not commonly done, however; for instance, the Java and C# GCs do not do this.</p>
<p>Finally, consider this piece of C# code:</p>
<pre>static Foo F;

class Foo
{
    ~Foo()
    {
        F = this;
    }
}</pre>
<p>When Foo&#8217;s finalizer is executed, it assigns itself to a global variable, effectively making itself reachable again &#8211; this is called resurrection. In most implementations, this makes the object perfectly reachable and live, but when the object again becomes unreachable, its finalizer will <em>not</em> run again. Typically, an implementation will provide a function to register an object for finalization again for these cases.</p>
<p>That&#8217;s it. Finalization is actually rather simple at its core; the only confusing aspect of it is that everyone does it differently in some way. I&#8217;m of the opinion that the third finalization approach is always the right one, but changing implementations to use that once they&#8217;ve already settled on another technique would of course be a very breaking change&#8230;</p>
<h1>Weak References</h1>
<p>When memory is scarce, a common technique in garbage collected languages is to use weak references to refer to non-essential resources. A weak reference is much like a regular reference except that the collector is free to collect the pointed-to object. That may seem insane, but it&#8217;s important to note that when the collector deallocates a weakly referenced object, it sets weak references to a null value such that no lingering references will stick around. Objects that are strongly referenced <em>and</em> weakly referenced will not be collected.</p>
<p>When an allocation attempt happens and the GC is out of memory, it can either do a collection cycle, then check if some memory has become free and return that, or it can choose to allocate from the OS immediately. Either way, if no memory is available, it&#8217;ll have to consult the OS. Now, the point of weak references is that after having scanned the heap, the collector can choose to deallocate a few weakly referenced objects in order to make space, instead of consulting the OS for more memory.</p>
<p>A common use of weak references is to maintain in-memory caches that are allowed to lose data.</p>
<h1>Moving and Copying</h1>
<p>One problem that typical mark-sweep collectors face is heap fragmentation. GCs typically allocate and deallocate memory from the OS in pages (which usually translates to 4096 bytes). So, imagine that you allocate a bunch of objects which all get put into a page. All but one of these objects eventually become unreachable and are deallocated. Now you have one object, possibly not bigger than a couple of bytes, keeping an entire page (4096 bytes) alive! This is clearly bad when thousands (or even millions) of objects are allocated over time in a program: Not only is redundant memory reserved, the OS will eventually run out of memory and resort to swapping because it can&#8217;t allocate more pages &#8211; meanwhile the GC is holding onto lots of pages with plenty of space, but a couple of objects happen to keep them committed.</p>
<p>Most garbage collectors deal with this problem by using heap compaction. Heap compaction algorithms can largely be separated into two categories: Moving algorithms, which move objects around to maximize use of page space, and copying algorithms, which copy between two separate heaps on every collection cycle, automatically gaining compaction. The latter is the one typically used in production garbage collectors today (especially in the young generation of generational collectors).</p>
<p>Describing all of the various compaction algorithms is out of scope for this blog post, but I&#8217;ll describe the fundamental ideas behind each category.</p>
<p>Moving compaction is based on simply pushing objects back into the beginning of the heap on every collection cycle. The goal is to make as efficient use of page space as possible to (try to) eliminate gaps. Once done, the collector can choose to either return excess empty pages to the OS or keep them around to serve allocation requests.</p>
<p>The purpose of copying compaction is to be faster than moving compaction at the expense of space. The heap is split up into two so-called semispaces called from-space and to-space. All allocation requests happen into to-space. When no more memory is available and the collector has to do a collection cycle, it flips the roles of the two semispaces; that is, the to-space is now from-space and vice versa. Then, the collector starts scanning the from-space. All objects that are found to be live are copied over to to-space in a simple bump pointer style. All remaining objects in from-space are effectively dead and can be deallocated in bulk. The advantage of this algorithm lies in the copying being very fast due to simply incrementing a pointer in to-space, while the obvious disadvantage is that two equally-sized heaps must be maintained even though one is largely unused until a collection cycle occurs.</p>
<p>It&#8217;s clear that both moving and copying algorithms have overhead compared to simple mark-sweep algorithms, but they are essential in long-running applications that must not go down due to a fragmented heap.</p>
<p>The above seems simple enough, but consider that when we copy and move objects, we effectively invalidate all pointers that point to them! This is not an unsolvable problem: The collector must simply update all pointers accordingly. This, as it turns out, is very simple in a type precise environment, while in an uncooperative environment (e.g. in C), it is practically impossible. More on that when we get to type precision.</p>
<h1>Pinning</h1>
<p>When interoperating with external, non-garbage collected code, it is essential to be able to tell the garbage collector that an object must not be collected even if it appears to be dead. This process is called pinning; that is, the object is pinned in place. The term actually originates from moving and copying collectors, because there it also means that the collector is not allowed to move or copy the object.</p>
<p>Let&#8217;s go with an example in pseudocode:</p>
<pre>work()
    managed_func_1()
    managed_func_2()

managed_func_1()
    Object = new()

    // Pin the object since it will
    // be hidden in a global variable
    // not scanned by the GC.
    pin(Object)

    unmanaged_func_1(Object)

unmanaged_func_1(Object)
    // The object is logically live
    // because a reference exists,
    // but the GC can't see it, hence
    // the pinning above.
    GlobalVariable = Object

managed_func_2()
    Object = unmanaged_func_2()

    // Unpin the object so the GC
    // knows the object is eligible
    // for collection again.
    unpin(Object)

unmanaged_func_2()
    Object = GlobalVariable

    // Null out the global variable
    // so we don't have a lingering
    // reference hanging around.
    GlobalVariable = null

    return Object</pre>
<p>This is a little pathological, but it illustrates the point of pinning: Keeping an object alive when the GC can&#8217;t see it.</p>
<h1>Type Precision</h1>
<p>Type precision is probably one of the most important aspects of modern garbage collectors. Without precise type information, it is impossible to tell whether something in memory is a plain integer or a pointer. Conservative garbage collectors (such as the Boehm-Demers-Weiser collector for C and C++) have no type information to work with, so they must <em>conservatively</em> assume that any integer that could be a pointer to a managed object is a pointer to a managed object. This can result in so-called false pointers that keep dead objects alive. This isn&#8217;t a huge problem on 64-bit systems due to the significantly larger address space, but on 32-bit systems, it can be a showstopper for some types of applications.</p>
<p>But that&#8217;s not the only use for type information. Moving and copying collectors are, in practice, impossible to implement without type information because they don&#8217;t know where to update pointers in the program. If no type information is available, the collector could easily end up overwriting a plain integer, actively altering program semantics. This would obviously (also) be a Bad Thing (TM).</p>
<p>Type information does not have to be completely precise about exactly what kind of data type is in every possible memory location &#8211; it suffices to know what memory locations hold managed references (and should thus be scanned and possibly rewritten by the collector). A collector isn&#8217;t concerned with any other data types (such as integers and floats), so those can be left out in the information provided by the compiler or virtual machine.</p>
<p>Now, type information makes precise heap scanning trivial, but what about the stack and machine registers? In practice, keeping track of when a reference is in a register is very hard and often not worth the effort, so scanning registers conservatively is a universally acceptable approach. The same goes for all roots (global variables, TLS data, and so on), though providing type information for those would be trivial too.</p>
<p>The stack is where things get interesting: The compiler can work out what slots in a stack frame can contain references when it generates code. It (or a virtual machine, for that matter) can then emit a so-called stack map that the garbage collector can use. The garbage collector will walk the call stack of stopped threads, working out exactly what&#8217;s present in the various slots. This makes stack scanning much more precise than usual &#8211; consider that, given a 2 MB stack, there are 524288 unique storage slots (on a 32-bit machine). That&#8217;s quite a few false pointers if the garbage collector is not precise.</p>
<p>On the other hand, the likelihood of these slots holding values that would actually keep objects alive is relatively low. It&#8217;s also worth considering that stack maps consume a lot of space by themselves, so using them may not always be desirable. This is particularly true in a JIT-compiling virtual machine where a lot of data structures already have to be maintained, eating quite some memory.</p>
<h1>Concurrency and Barriers</h1>
<p>In applications that run on workstations, it is desirable for the program not to have long pause times. This is not a problem for server applications and the like, but a user doesn&#8217;t want to sit and wait for an application to react to their input. Concurrent garbage collectors solve this problem by performing garbage collection while the program is running and never actually pausing any threads. This does mean that some processing time is lost due to synchronization between program threads and GC threads, but on the other hand, the application will be much smoother to work with.</p>
<p>Since concurrent GCs run on one or several separate threads from the main program, it is clear that there would not be much to gain if the machine the program is running on doesn&#8217;t have SMP. While that wouldn&#8217;t prevent a concurrent GC from working with the same semantics as on an SMP machine, it would be significantly slower than just using a plain STW collector. Thankfully, lack of SMP isn&#8217;t much of a problem in this day and age.</p>
<p>Probably the biggest problem with concurrent garbage collectors is maintaining collector invariants (that is, conditions that must hold throughout garbage collector logic). Since the program runs concurrently with the collector, it could easily race against the collector, resulting in lingering references and other nasty things. The solution to this problem is GC barriers: These are very small code stubs that are inserted into the program at locations where various memory operations are performed. They perform small, usually atomic, operations that help maintain invariants in the face of concurrent mutation and scanning of the heap.</p>
<p>Barriers require compiler or virtual machine support. One problem with barriers and static compilers is that they essentially form a very strict ABI between the program and the garbage collector, giving little flexibility to run the same program with different collectors without recompiling. JIT-compiling virtual machines are more flexible in this regard because they can simply mutate the intermediate representation of the program to insert barriers just before emitting native code.</p>
<p>What barriers do varies a lot depending on the GC implementation, and where they are inserted varies even more. Most commonly, they can be inserted for memory loads/stores, array loads/stores, field loads/stores, and so on.</p>
<p>To see an example of a real world barrier implementation, <a href="http://www.cs.ucsb.edu/~urs/oocsb/self/papers/write-barrier.html">take a look at this paper</a>.</p>
<h1>Optimization</h1>
<p>A lot of people are skeptical of the performance of garbage collectors &#8211; and rightfully so. Given all of the above, it&#8217;s not hard to imagine how much work an actual GC implementation has to do when performing collections. But, as with any other technology, you must optimize for the technology you&#8217;re using, not the technology you <em>wish</em> you were using.</p>
<p>A few guidelines to go by:</p>
<ul>
<li>If your data structure is smaller than 16 (or so) bytes, it probably shouldn&#8217;t be an object.</li>
<li>Recycle objects that you create many instances of (object pooling).</li>
<li>Never allocate during intensive work where throughput is important.</li>
<li>Avoid <a href="http://en.wikipedia.org/wiki/Object_type_(object-oriented_programming)#Boxing">boxing</a> like the plague if you can.</li>
<li>Prefer mutable data structures over immutable ones when performance is essential.</li>
<li>Prefer a concurrent GC for workstation programs; an STW GC for server programs.</li>
<li>Use weak references for non-essential data.</li>
<li>Avoid pinning too many objects as it can severely inhibit the garbage collector&#8217;s work.</li>
<li>Don&#8217;t use finalizers if you don&#8217;t have to.</li>
</ul>
<h1>Conclusion</h1>
<p>While this post is fairly abstract in comparison to actual GC implementations, I hope it has shed some light on how garbage collectors work. If you understand the things in this post, that&#8217;s enough to understand how to work with a garbage collector and optimize for it, in practice &#8211; you don&#8217;t have to know every little implementation detail.</p>
<p>If there&#8217;s anything you find unclear in this post or perhaps completely unanswered, please leave a comment! It&#8217;s entirely possible that I forgot something due to the lengthy nature of this post.</p>
<h1>But, But, Internals?!</h1>
<p>Sorry, but actual garbage collector implementations are complex beasts full of clever and subtle optimizations and algorithms. Even describing the algorithms behind a single implementation would have made this blog post &#8212; quite literally &#8212; 10 times as long as it is now.</p>
<p>If you&#8217;re interested in garbage collector implementations, I recommend taking a look at some open source code:</p>
<ul>
<li><a href="https://github.com/D-Programming-Language/druntime/tree/master/src/gc">The D runtime&#8217;s GC</a></li>
<li><a href="https://github.com/parrot/parrot/tree/master/src/gc">The Parrot VM&#8217;s GC</a></li>
<li><a href="https://github.com/mono/mono/tree/master/mono/metadata">The Mono SGen GC</a></li>
<li><a href="https://github.com/ivmai/bdwgc">The Boehm-Demers-Weiser GC</a></li>
</ul>
<p>Many others exist out there. These are just the ones I happen to be familiar with.</p>
<p>Also, again, I really recommend the <a href="http://gchandbook.org/">Garbage Collection Handbook</a>.</p>
<br />Filed under: <a href='http://xtzgzorex.wordpress.com/category/c-2/'>C</a>, <a href='http://xtzgzorex.wordpress.com/category/c/'>C#</a>, <a href='http://xtzgzorex.wordpress.com/category/d/'>D</a>, <a href='http://xtzgzorex.wordpress.com/category/erlang/'>Erlang</a>, <a href='http://xtzgzorex.wordpress.com/category/mci/'>MCI</a>, <a href='http://xtzgzorex.wordpress.com/category/mono/'>Mono</a>, <a href='http://xtzgzorex.wordpress.com/category/programming/'>Programming</a>, <a href='http://xtzgzorex.wordpress.com/category/rust/'>Rust</a>  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/xtzgzorex.wordpress.com/865/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/xtzgzorex.wordpress.com/865/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=xtzgzorex.wordpress.com&#038;blog=13381977&#038;post=865&#038;subd=xtzgzorex&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://xtzgzorex.wordpress.com/2012/10/11/demystifying-garbage-collectors/feed/</wfw:commentRss>
		<slash:comments>23</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/42c54d81a5ed511408e947ccd526d858?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">XTZGZoReX</media:title>
		</media:content>
	</item>
		<item>
		<title>C#/Mono: Playing with Pointers</title>
		<link>http://xtzgzorex.wordpress.com/2012/05/05/cmono-playing-with-pointers/</link>
		<comments>http://xtzgzorex.wordpress.com/2012/05/05/cmono-playing-with-pointers/#comments</comments>
		<pubDate>Sat, 05 May 2012 14:33:22 +0000</pubDate>
		<dc:creator>XTZGZoReX</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[ILAsm]]></category>
		<category><![CDATA[Mono]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://xtzgzorex.wordpress.com/?p=835</guid>
		<description><![CDATA[I haven&#8217;t blogged in a while. Let&#8217;s fix that! So, I&#8217;ve been programming a lot in D lately, which means systems programming, which means pointers! Pointers are amazing. You can do all sorts of crazy and awesome hacks with them. C# and the .NET Framework try to abstract pointers away from us. But fear not, &#8230; <a href="http://xtzgzorex.wordpress.com/2012/05/05/cmono-playing-with-pointers/" class="more-link">Continue reading <span class="meta-nav">&#187;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=xtzgzorex.wordpress.com&#038;blog=13381977&#038;post=835&#038;subd=xtzgzorex&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>I haven&#8217;t blogged in a while. Let&#8217;s fix that!</p>
<p>So, I&#8217;ve been programming a lot in D lately, which means systems programming, which means pointers! Pointers are amazing. You can do all sorts of crazy and awesome hacks with them. C# and the .NET Framework try to abstract pointers away from us. But fear not, for there are ways around this safety nonsense!</p>
<p>It turns out that on Mono, you can pin an object even if it contains managed data. This makes it safe to modify an object&#8217;s internal layout even in the presence of a moving GC (well, kinda, sorta). You can&#8217;t take the address of the object, however, which means we must resort to some IL hackery.</p>
<p>Thus, the code:</p>
<pre>using System;
using System.Reflection.Emit;
using System.Runtime.InteropServices;

public unsafe delegate void PointerAction(byte* pointer);

public static class ObjectExtensions
{
    private static object _lock = new object();
    private static Func _addrOf;

    private static IntPtr AddressOf(object obj)
    {
        lock (_lock)
        {
            if (_addrOf == null)
            {
                var dm = new DynamicMethod(string.Empty, typeof(IntPtr), new[] { typeof(object) },
                                           typeof(ObjectExtensions), true);

                var il = dm.GetILGenerator();

                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Conv_I);
                il.Emit(OpCodes.Ret);

                _addrOf = (Func)dm.CreateDelegate(typeof(Func));
            }
        }

        return _addrOf(obj);
    }

    public static unsafe byte* ToPointer(this object obj)
    {
        if (obj == null)
            throw new ArgumentNullException("obj");

        GCHandle handle;

        try
        {
            handle = GCHandle.Alloc(obj, GCHandleType.Pinned);

            return (byte*)AddressOf(obj).ToPointer();
        }
        finally
        {
            if (handle.IsAllocated)
                handle.Free();
        }
    }

    public static unsafe void WithPointer(this object obj, PointerAction action)
    {
        if (obj == null)
            throw new ArgumentNullException("obj");

        if (action == null)
            throw new ArgumentNullException("action");

        GCHandle handle;

        try
        {
            handle = GCHandle.Alloc(obj, GCHandleType.Pinned);

            action((byte*)AddressOf(obj).ToPointer());
        }
        finally
        {
            if (handle.IsAllocated)
                handle.Free();
        }
    }
}</pre>
<p>(Kudos to ki9a on #mono for coming up with the dynamic method IL!)</p>
<p>Now, don&#8217;t try to run that on Microsoft .NET. It will blow up.</p>
<p>Now that we can get at the internals of objects, let&#8217;s try it out:</p>
<pre>static class Program
{
    static unsafe void Main()
    {
        var str = "foo!";
        object obj = new { foo = 0, bar = (object)null }; // create an object with an int32 field and a reference field

        void* vtable = null;
        void* sync = null;
        int length = 0;
        void* chars = null;

        str.WithPointer(ptr =&gt;
        {
            vtable = *(void**)ptr;
            sync = *(void**)(ptr + sizeof(void*));
            length = *(int*)(ptr + sizeof(void*) * 2);
            chars = *(void**)(ptr + sizeof(void*) * 2 + sizeof(int));
        });

        obj.WithPointer(ptr =&gt;
        {
            *(void**)ptr = vtable;
            *(void**)(ptr + sizeof(void*)) = sync;
            *(int*)(ptr + sizeof(void*) * 2) = length;
            *(void**)(ptr + sizeof(void*) * 2 + sizeof(int)) = chars;
        });

        Console.WriteLine((string)obj); // prints "foo!"
    }
}</pre>
<p>Oh boy. Some explanation is probably in order.</p>
<p>First of all, let me explain the layout of objects in Mono. Every object has a header consisting of two machine words. The first word points to the object&#8217;s VTable, which describes its type, methods, etc. The second word holds the so-called synchronization block, which is used to implement <a href="http://msdn.microsoft.com/en-us/library/system.threading.monitor.aspx">monitors</a> (<a href="http://msdn.microsoft.com/en-us/library/c5kehkcz(v=vs.100).aspx">C# lock</a>). Now, strings have two extra fields: One 32-bit field which holds the string&#8217;s length, and one machine word field which points to the raw characters backing the string.</p>
<p>Now look at this line:</p>
<pre>object obj = new { foo = 0, bar = (object)null }; // create an object with an int32 field and a reference field</pre>
<p>What we&#8217;re doing here is creating an anonymous object with a physical structure similar to that of a string. Needless to say, whether it actually <em>is</em> similar is completely implementation-defined. The runtime may decide to reorder fields as it sees fit, and may even make the foo field a 64-bit integer on a 64-bit system. But, what&#8217;s important here is that the resulting object has enough space to hold the contents of a string object.</p>
<p>Now we get to the fun stuff:</p>
<pre>str.WithPointer(ptr =&gt;
{
    vtable = *(void**)ptr;
    sync = *(void**)(ptr + sizeof(void*));
    length = *(int*)(ptr + sizeof(void*) * 2);
    chars = *(void**)(ptr + sizeof(void*) * 2 + sizeof(int));
});</pre>
<p>Here, we read out the VTable, synchronization block, length, and character array fields of the &#8220;foo!&#8221; string object. It is (more or less) safe, since the WithPointer method ensures that the object is pinned while we do our stuff.</p>
<p>Next:</p>
<pre>obj.WithPointer(ptr =&gt;
{
    *(void**)ptr = vtable;
    *(void**)(ptr + sizeof(void*)) = sync;
    *(int*)(ptr + sizeof(void*) * 2) = length;
    *(void**)(ptr + sizeof(void*) * 2 + sizeof(int)) = chars;
});</pre>
<p>Here we assign the values we read out from the string object earlier to the object we created with a similar physical layout to that of string objects. Our anonymously-typed object is now effectively a string.</p>
<p>Let&#8217;s prove that:</p>
<pre>Console.WriteLine((string)obj); // prints "foo!"</pre>
<p>Note two things here: First, the cast succeeded. It would normally have resulted in an InvalidCastException. So far so good. Second, the call actually prints what we expect. This means that we got the physical layout of the string object right.</p>
<p>Note that all of this was done on an x86 machine running 64-bit Linux with Mono 2.10.8. I have no idea whether it will work with any other Mono version, architecture, bitness, or operating system.</p>
<p>Will this break the runtime? Possibly! Will the GC explode? Likely! Will it leak memory? Definitely!</p>
<p>Don&#8217;t do this in production code. Like, seriously, don&#8217;t.</p>
<p><strong>Update:</strong> As lupus points out, I actually got the string layout wrong! The characters of a string are embedded directly in the object. This code just turned out to work because of word size on 64-bit x86. I&#8217;ll leave it as an exercise to the reader to adapt the code to arbitrary amounts of embedded characters. ;)</p>
<br />Filed under: <a href='http://xtzgzorex.wordpress.com/category/c/'>C#</a>, <a href='http://xtzgzorex.wordpress.com/category/ilasm/'>ILAsm</a>, <a href='http://xtzgzorex.wordpress.com/category/mono/'>Mono</a>, <a href='http://xtzgzorex.wordpress.com/category/programming/'>Programming</a>  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/xtzgzorex.wordpress.com/835/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/xtzgzorex.wordpress.com/835/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=xtzgzorex.wordpress.com&#038;blog=13381977&#038;post=835&#038;subd=xtzgzorex&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://xtzgzorex.wordpress.com/2012/05/05/cmono-playing-with-pointers/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/42c54d81a5ed511408e947ccd526d858?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">XTZGZoReX</media:title>
		</media:content>
	</item>
		<item>
		<title>GithubSharp with ServiceStack.Text</title>
		<link>http://xtzgzorex.wordpress.com/2012/01/30/githubsharp-with-servicestack-text/</link>
		<comments>http://xtzgzorex.wordpress.com/2012/01/30/githubsharp-with-servicestack-text/#comments</comments>
		<pubDate>Mon, 30 Jan 2012 11:05:05 +0000</pubDate>
		<dc:creator>XTZGZoReX</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Mono]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://xtzgzorex.wordpress.com/?p=815</guid>
		<description><![CDATA[At Xamarin, we&#8217;ve been using GithubSharp to access the GitHub API for some time. We ran into some issues with it, however, because the JSON serializers in .NET are buggy as hell (one had trouble deserializing a simple dictionary; another couldn&#8217;t handle large payloads). Therefore, we forked and branched the project and made it use &#8230; <a href="http://xtzgzorex.wordpress.com/2012/01/30/githubsharp-with-servicestack-text/" class="more-link">Continue reading <span class="meta-nav">&#187;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=xtzgzorex.wordpress.com&#038;blog=13381977&#038;post=815&#038;subd=xtzgzorex&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>At Xamarin, we&#8217;ve been using GithubSharp to access the GitHub API for some time. We ran into some issues with it, however, because the JSON serializers in .NET are buggy as hell (one had trouble deserializing a simple dictionary; another couldn&#8217;t handle large payloads). Therefore, we <a href="https://github.com/xamarin/GithubSharp/tree/servicestack">forked and branched</a> the project and made it use ServiceStack.Text, which works nicely (and has the added effect of working on Mono).</p>
<p>Note that our branch is for version 2.0 of the GitHub API; the author of GithubSharp, Erik Zaadi, is now working on GithubSharp for GitHub&#8217;s 3.0 API, using ServiceStack.Text.</p>
<br />Filed under: <a href='http://xtzgzorex.wordpress.com/category/c/'>C#</a>, <a href='http://xtzgzorex.wordpress.com/category/mono/'>Mono</a>, <a href='http://xtzgzorex.wordpress.com/category/programming/'>Programming</a>  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/xtzgzorex.wordpress.com/815/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/xtzgzorex.wordpress.com/815/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=xtzgzorex.wordpress.com&#038;blog=13381977&#038;post=815&#038;subd=xtzgzorex&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://xtzgzorex.wordpress.com/2012/01/30/githubsharp-with-servicestack-text/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/42c54d81a5ed511408e947ccd526d858?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">XTZGZoReX</media:title>
		</media:content>
	</item>
		<item>
		<title>Life: Status Update</title>
		<link>http://xtzgzorex.wordpress.com/2011/09/12/life-status-update/</link>
		<comments>http://xtzgzorex.wordpress.com/2011/09/12/life-status-update/#comments</comments>
		<pubDate>Mon, 12 Sep 2011 16:59:12 +0000</pubDate>
		<dc:creator>XTZGZoReX</dc:creator>
				<category><![CDATA[Life]]></category>
		<category><![CDATA[MCI]]></category>
		<category><![CDATA[Mono]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://xtzgzorex.wordpress.com/?p=759</guid>
		<description><![CDATA[I really don&#8217;t blog about my life often, but a lot of interesting stuff has been happening lately that I&#8217;d like to share. First, I&#8217;ve just become an intern at Xamarin. I&#8217;ll be working on the documentation build system and integration into the website and the MonoDevelop IDE. I was hired after GSoC was over, &#8230; <a href="http://xtzgzorex.wordpress.com/2011/09/12/life-status-update/" class="more-link">Continue reading <span class="meta-nav">&#187;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=xtzgzorex.wordpress.com&#038;blog=13381977&#038;post=759&#038;subd=xtzgzorex&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>I really don&#8217;t blog about my life often, but a lot of interesting stuff has been happening lately that I&#8217;d like to share.</p>
<p>First, I&#8217;ve just become an intern at <a href="http://xamarin.com/">Xamarin</a>. I&#8217;ll be working on the documentation build system and integration into the website and the MonoDevelop IDE. I was hired after GSoC was over, following a recommendation from Miguel. I&#8217;m really looking forward to working with Xamarin; it&#8217;s an awesome team of skilled hackers.</p>
<p>Second, I&#8217;ve been accepted into university, starting February 1 (at <a href="http://www.ucnorth.dk/">the UCN</a>). The Danish name for the course I&#8217;m taking is &#8220;datamatiker&#8221;. They call it computer science in English, but it&#8217;s actually much more practically oriented than that (i.e. actual software development rather than theory). I was accepted based on my ability in the software development field, as I don&#8217;t fulfill the formal requirements (yet). This means I&#8217;ll probably quit high school, as I&#8217;d rather pursue something software-related than natural sciences.</p>
<p>In other (less life-related) news, I&#8217;ve also been putting some time into writing a compiler infrastructure library. I&#8217;ll be posting more about the goals and directions of that later.</p>
<br />Filed under: <a href='http://xtzgzorex.wordpress.com/category/life/'>Life</a>, <a href='http://xtzgzorex.wordpress.com/category/mci/'>MCI</a>, <a href='http://xtzgzorex.wordpress.com/category/mono/'>Mono</a>, <a href='http://xtzgzorex.wordpress.com/category/programming/'>Programming</a>  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/xtzgzorex.wordpress.com/759/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/xtzgzorex.wordpress.com/759/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=xtzgzorex.wordpress.com&#038;blog=13381977&#038;post=759&#038;subd=xtzgzorex&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://xtzgzorex.wordpress.com/2011/09/12/life-status-update/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/42c54d81a5ed511408e947ccd526d858?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">XTZGZoReX</media:title>
		</media:content>
	</item>
		<item>
		<title>GSoC and the State of ILAsm</title>
		<link>http://xtzgzorex.wordpress.com/2011/08/23/gsoc-and-the-state-of-ilasm/</link>
		<comments>http://xtzgzorex.wordpress.com/2011/08/23/gsoc-and-the-state-of-ilasm/#comments</comments>
		<pubDate>Tue, 23 Aug 2011 17:59:53 +0000</pubDate>
		<dc:creator>XTZGZoReX</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[GSoC]]></category>
		<category><![CDATA[ILAsm]]></category>
		<category><![CDATA[Mono]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://xtzgzorex.wordpress.com/?p=735</guid>
		<description><![CDATA[GSoC 2011 is now officially over, and I figure I should write some sort of status post. First of all, the project is not completely done. I had anticipated this early on, and discussed with JB which parts I should focus on for the deadline. I did get a fair bit done for the deadline, &#8230; <a href="http://xtzgzorex.wordpress.com/2011/08/23/gsoc-and-the-state-of-ilasm/" class="more-link">Continue reading <span class="meta-nav">&#187;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=xtzgzorex.wordpress.com&#038;blog=13381977&#038;post=735&#038;subd=xtzgzorex&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>GSoC 2011 is now officially over, and I figure I should write some sort of status post.</p>
<p>First of all, the project is not completely done. I had anticipated this early on, and discussed with JB which parts I should focus on for the deadline. I did get a fair bit done for the deadline, but I wouldn&#8217;t quite say it&#8217;s ready for production use yet. I did, however, pass the final evaluation, as JB agreed to let me finish the project outside of GSoC (which I fully intend to do).</p>
<p>The project actually ended up being more involved than originally planned. The idea was to simply swap the PEAPI back end with Cecil, but I quickly realized that this was not quite as trivial as it seemed back then. I ended up ripping out the old code generation completely, emptying the code of every last parser production, updating the parser to .NET 4.0, and finally, adding the Cecil code generation back end in. You might think that all of this would have taken most of the entire GSoC period, but a lot of time was spent on spec reading too, not to mention figuring out weird quirks and corner cases in the Microsoft implementation of ILAsm. It&#8217;s scary just how much of the ILAsm language is poorly documented or not documented at all.</p>
<p>I&#8217;d like to extend my thanks to everyone in #cecil @ irc.gnome.org for helping me understand ILAsm, CIL, and the CLI in general.</p>
<p>I&#8217;ve also made some progress on the ILDasm front. It&#8217;s still missing a lot of features, but it does disassemble types and methods decently at this point. I&#8217;ll work more on it later; ILAsm comes first.</p>
<p>I recently switched ILAsm to a deferred type resolution model. This was JB&#8217;s idea, as a way to solve <a href="http://xtzgzorex.wordpress.com/2011/07/19/ilasm-the-mono-implementation/">the generic parameter issue I blogged about earlier</a>, and it&#8217;s worked nicely so far. This was probably the last major issue in the new ILAsm, so I expect to be doing more ILDasm work soon (there are only a couple of known ILAsm issues left).</p>
<p>During GSoC I also wrote a command line interface to the Mono soft debugger (SDB). It&#8217;s available <a href="https://github.com/alexrp/sdb-cli">here</a>. I wrote it primarily because using MonoDevelop (which was the only existing interface to SDB at the time) as a debugger for a command line application was not very convenient. This debugger also has a few cool features such as decompilation of code with no source code (through ICSharpCode.Decompiler).</p>
<p>Overall, it&#8217;s been a very fun and educational program for me. I now know a lot of things about the CLI that I didn&#8217;t have the slightest clue about before, and I finally managed to contribute something really significant to Mono. Working with JB and the Mono community has been an awesome experience, as everyone&#8217;s very helpful and easily approachable. I would definitely do this again if I get the chance.</p>
<p>I&#8217;ll probably make a final blog post whenever I get this entire project merged into mainline Mono.</p>
<br />Filed under: <a href='http://xtzgzorex.wordpress.com/category/c/'>C#</a>, <a href='http://xtzgzorex.wordpress.com/category/gsoc/'>GSoC</a>, <a href='http://xtzgzorex.wordpress.com/category/ilasm/'>ILAsm</a>, <a href='http://xtzgzorex.wordpress.com/category/mono/'>Mono</a>, <a href='http://xtzgzorex.wordpress.com/category/programming/'>Programming</a>  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/xtzgzorex.wordpress.com/735/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/xtzgzorex.wordpress.com/735/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=xtzgzorex.wordpress.com&#038;blog=13381977&#038;post=735&#038;subd=xtzgzorex&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://xtzgzorex.wordpress.com/2011/08/23/gsoc-and-the-state-of-ilasm/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/42c54d81a5ed511408e947ccd526d858?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">XTZGZoReX</media:title>
		</media:content>
	</item>
		<item>
		<title>ILAsm: The Mono Implementation</title>
		<link>http://xtzgzorex.wordpress.com/2011/07/19/ilasm-the-mono-implementation/</link>
		<comments>http://xtzgzorex.wordpress.com/2011/07/19/ilasm-the-mono-implementation/#comments</comments>
		<pubDate>Tue, 19 Jul 2011 11:06:37 +0000</pubDate>
		<dc:creator>XTZGZoReX</dc:creator>
				<category><![CDATA[GSoC]]></category>
		<category><![CDATA[ILAsm]]></category>
		<category><![CDATA[Mono]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://xtzgzorex.wordpress.com/?p=704</guid>
		<description><![CDATA[This time, I&#8217;ll write about some issues I faced during development of Mono&#8217;s ILAsm and how I got around them. I&#8217;ve had to make several changes that make Mono&#8217;s ILAsm stricter than MS.NET&#8217;s or outright incompatible. First of all, we have generic parameters. In MS.NET&#8217;s ILAsm, !0 and !!0 are simply emitted as VAR 0 &#8230; <a href="http://xtzgzorex.wordpress.com/2011/07/19/ilasm-the-mono-implementation/" class="more-link">Continue reading <span class="meta-nav">&#187;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=xtzgzorex.wordpress.com&#038;blog=13381977&#038;post=704&#038;subd=xtzgzorex&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>This time, I&#8217;ll write about some issues I faced during development of Mono&#8217;s ILAsm and how I got around them. I&#8217;ve had to make several changes that make Mono&#8217;s ILAsm stricter than MS.NET&#8217;s or outright incompatible.</p>
<p>First of all, we have generic parameters. In MS.NET&#8217;s ILAsm, !0 and !!0 are simply emitted as VAR 0 and MVAR 0 in the metadata, meaning that you could do something like:</p>
<pre>.method public static !!0 Foo(!!1 bar)
{
    ldarg bar
    ret
}</pre>
<p>Even though !!1 refers to a generic parameter that does not exist, MS.NET&#8217;s ILAsm will gladly emit it, and not even warn you. Due to an API &#8220;limitation&#8221; in Cecil, Mono&#8217;s ILAsm cannot do this. All GenericParameter objects must have an owner (i.e. the type or method definition/reference) and must be contained in that owner&#8217;s GenericParameters collection at the correct index. Therefore, Mono&#8217;s ILAsm would throw an error for the above code, since !!0 is out of bounds. This is a slightly annoying incompatibility, but there&#8217;s not much I can do about it other than patching Cecil. That&#8217;s only going to happen, though, if it won&#8217;t cause API breaks for version 1.0.</p>
<p>Second, properties like .file alignment, .imagebase, and .stackreserve aren&#8217;t fully supported. Cecil currently has no way of setting these on a module. ILAsm will check the values and error if they&#8217;re invalid, though.</p>
<p>Third, several native and variant types are not supported in marshal signatures. These include variant, void, syschar, decimal, date, objectref, nested struct and null, void, int64, uint64, unsigned int64, lpstr, lpwstr, safearray, hresult, carray, userdefined, record, filetime, blob, stream, storage streamed_object, stored_object, blob_object, cf, clsid, as well as pointers/references/vectors of these. The reason is that Cecil doesn&#8217;t expose any way to set these types. Either way, most of these are deprecated nowadays. All other native/variant types are supported.</p>
<p>Fourth, support for .data declarations is very limited (we actually only do a weak attempt at emulating them). Cecil has no way of emitting data constants, and they&#8217;re implementation-defined anyway. Currently, the only thing we do with them is copy them to the InitialValue property of field definitions where appropriate. This is far from correct, but it&#8217;s the best we can do. Either way, you should avoid using these declarations. They don&#8217;t make a whole lot of sense in managed land.</p>
<p>Fifth, we have no support for parsing System.Reflection-notation strings (yet). This means that things like custom marshalers aren&#8217;t supported (the syntax will simply be ignored). A type parsing API will supposedly be exposed in Cecil 1.0.</p>
<p>Sixth, support for declarative security syntax is limited. While we support the full syntax specified by the standard, we don&#8217;t support all of the syntax MS.NET&#8217;s ILAsm does (specifically, the syntax resembling verbal custom attribute initialization).</p>
<p>Seventh, exported types are unfinished because Cecil lacks a way to manipulate the File table directly, and because of the lack of a type parser.</p>
<p>Eighth, we can&#8217;t emit custom attributes on manifest resources and assembly references. This is a Cecil limitation which should be relatively easy to fix.</p>
<p>Lastly, the .vtable/.vtfixup/.vtentry directives are unsupported. Again, these will be implemented once Cecil has support for them.</p>
<p>There are some other incompatibilities, but they&#8217;re very subtle and you&#8217;re unlikely to ever encounter them. And even if you do, ILAsm will warn you.</p>
<p>Generally, the differences between the two implementations will only be encountered in obscure features that most users are highly unlikely to be using, or when attempting to use nonstandard syntax. Rule of thumb: Stay away from these things and you&#8217;re safe.</p>
<br />Filed under: <a href='http://xtzgzorex.wordpress.com/category/gsoc/'>GSoC</a>, <a href='http://xtzgzorex.wordpress.com/category/ilasm/'>ILAsm</a>, <a href='http://xtzgzorex.wordpress.com/category/mono/'>Mono</a>, <a href='http://xtzgzorex.wordpress.com/category/programming/'>Programming</a>  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/xtzgzorex.wordpress.com/704/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/xtzgzorex.wordpress.com/704/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=xtzgzorex.wordpress.com&#038;blog=13381977&#038;post=704&#038;subd=xtzgzorex&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://xtzgzorex.wordpress.com/2011/07/19/ilasm-the-mono-implementation/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/42c54d81a5ed511408e947ccd526d858?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">XTZGZoReX</media:title>
		</media:content>
	</item>
		<item>
		<title>ILAsm: The Microsoft Implementation</title>
		<link>http://xtzgzorex.wordpress.com/2011/06/09/ilasm-the-microsoft-implementation/</link>
		<comments>http://xtzgzorex.wordpress.com/2011/06/09/ilasm-the-microsoft-implementation/#comments</comments>
		<pubDate>Thu, 09 Jun 2011 10:09:54 +0000</pubDate>
		<dc:creator>XTZGZoReX</dc:creator>
				<category><![CDATA[GSoC]]></category>
		<category><![CDATA[ILAsm]]></category>
		<category><![CDATA[Mono]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://xtzgzorex.wordpress.com/?p=660</guid>
		<description><![CDATA[So, we&#8217;re now 3 weeks into GSoC, and I figure I should start blogging about my work. This post will be about the ILAsm standard (specified in ECMA 335) and the Microsoft implementation. There are several annoying differences and incompatibilities between the two. As part of figuring them out, I&#8217;ve been reading Expert .NET 2.0 &#8230; <a href="http://xtzgzorex.wordpress.com/2011/06/09/ilasm-the-microsoft-implementation/" class="more-link">Continue reading <span class="meta-nav">&#187;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=xtzgzorex.wordpress.com&#038;blog=13381977&#038;post=660&#038;subd=xtzgzorex&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>So, we&#8217;re now 3 weeks into GSoC, and I figure I should start blogging about my work.</p>
<p>This post will be about the ILAsm standard (specified in ECMA 335) and the Microsoft implementation. There are several annoying differences and incompatibilities between the two. As part of figuring them out, I&#8217;ve been reading <a href="http://www.amazon.com/Expert-NET-Assembler-Serge-Lidin/dp/1590596463">Expert .NET 2.0 IL Assembler</a> and <a href="http://msdn.microsoft.com/en-us/netframework/aa569283">the Microsoft-annotated ECMA 335 standard</a>.</p>
<p>The first difference is that MS.NET&#8217;s ILAsm does not respect the unsigned modifier on integer types. This means that an unsigned int32 will in effect be treated as an int32 (signed). I&#8217;ve chosen to break compatibility with Microsoft and correctly emit an unsigned integer, primarily because I think this is an outright stupid bug. Note that you can still get an unsigned integer by using uint32 with MS.NET. The latter form is preferred, anyway.</p>
<p>Second, MS.NET does not have the platformapi keyword. Instead, you have to use the winapi keyword, which makes your ILAsm source code unportable. In Mono&#8217;s ILAsm, we support both, in order to aid portability.</p>
<p>Third, MS.NET allows #line instead of .line for specifying source line information. This seems to be for compatibility reasons. Mono&#8217;s ILAsm supports both notations.</p>
<p>Fourth, MS.NET has a bunch of directives that just don&#8217;t exist in the standard. Specifically .file alignment, .imagebase, .language, and .namespace. We support all of them, though the first two currently have no actual effect. Note that use of .namespace is considered bad practice.</p>
<p>Fifth, MS.NET&#8217;s ILAsm doesn&#8217;t use .culture for specifying culture information, but rather .locale. This is directly against the standard, and the assembler won&#8217;t even recognize .culture. Mono&#8217;s ILAsm supports both notations.</p>
<p>Sixth, the MS.NET ILAsm doesn&#8217;t require the .hash directive; if it&#8217;s not specified, the hash will automatically be computed.</p>
<p>Seventh, the MS.NET ILAsm allows using &#8220;value class&#8221; in place of &#8220;valuetype&#8221; for indicating value types. This is relatively easy to handle, and Mono&#8217;s ILAsm does so. It is, however, considered bad notation.</p>
<p>Lastly, the MS.NET ILAsm allows specifying things like calling convention, type attributes, method attributes, field attributes, parameter attributes, and so on using flags(int32) notation. I&#8217;m sure this was done for a reason, but it seems like a great way to give developers the opportunity to make their programs unportable or impossible to run at all.</p>
<p>There are a lot of other incompatibilities, but they&#8217;re less annoying and easier to work around/implement.</p>
<p>That&#8217;s it for the this post. Next time: Implementation details of Mono&#8217;s ILAsm.</p>
<br />Filed under: <a href='http://xtzgzorex.wordpress.com/category/gsoc/'>GSoC</a>, <a href='http://xtzgzorex.wordpress.com/category/ilasm/'>ILAsm</a>, <a href='http://xtzgzorex.wordpress.com/category/mono/'>Mono</a>, <a href='http://xtzgzorex.wordpress.com/category/programming/'>Programming</a>  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/xtzgzorex.wordpress.com/660/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/xtzgzorex.wordpress.com/660/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=xtzgzorex.wordpress.com&#038;blog=13381977&#038;post=660&#038;subd=xtzgzorex&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://xtzgzorex.wordpress.com/2011/06/09/ilasm-the-microsoft-implementation/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/42c54d81a5ed511408e947ccd526d858?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">XTZGZoReX</media:title>
		</media:content>
	</item>
		<item>
		<title>Mono Summer of Code</title>
		<link>http://xtzgzorex.wordpress.com/2011/04/26/mono-summer-of-code/</link>
		<comments>http://xtzgzorex.wordpress.com/2011/04/26/mono-summer-of-code/#comments</comments>
		<pubDate>Tue, 26 Apr 2011 15:36:45 +0000</pubDate>
		<dc:creator>XTZGZoReX</dc:creator>
				<category><![CDATA[GSoC]]></category>
		<category><![CDATA[Mono]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://xtzgzorex.wordpress.com/?p=641</guid>
		<description><![CDATA[Around a month ago, I turned in a GSoC 2011 proposal to rewrite Mono&#8217;s ILAsm (IL assembler) to use Cecil as its code generation back end, as well as write a managed ILDasm (IL disassembler), as Mono&#8217;s current monodis is written in C and relies greatly on the runtime itself. Yesterday, I received word that &#8230; <a href="http://xtzgzorex.wordpress.com/2011/04/26/mono-summer-of-code/" class="more-link">Continue reading <span class="meta-nav">&#187;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=xtzgzorex.wordpress.com&#038;blog=13381977&#038;post=641&#038;subd=xtzgzorex&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Around a month ago, I turned in a <a href="http://code.google.com/soc/">GSoC</a> 2011 <a href="http://www.google-melange.com/gsoc/proposal/review/google/gsoc2011/xtzgzorex/1">proposal</a> to rewrite Mono&#8217;s ILAsm (IL assembler) to use Cecil as its code generation back end, as well as write a managed ILDasm (IL disassembler), as Mono&#8217;s current monodis is written in C and relies greatly on the runtime itself. Yesterday, I received word that the proposal has been accepted, and that I&#8217;m going to participate in GSoC!</p>
<p>My friend, <a href="https://github.com/WolfgangSt">Wolfgang Steffens</a>, who&#8217;s the primary developer on SL#, also had <a href="http://www.google-melange.com/gsoc/project/google/gsoc2011/wolfgangst/20001">a GSoC project</a> accepted, which seeks to incorporate SL# in the Axiom game engine. This would be a great way for us to draw more attention to the library, and also makes shader development for Axiom users much easier.</p>
<p>There are a lot of other interesting projects going on with Mono this year &#8211; check them out <a href="http://www.google-melange.com/gsoc/org/google/gsoc2011/mono">here</a>.</p>
<br />Filed under: <a href='http://xtzgzorex.wordpress.com/category/gsoc/'>GSoC</a>, <a href='http://xtzgzorex.wordpress.com/category/mono/'>Mono</a>, <a href='http://xtzgzorex.wordpress.com/category/programming/'>Programming</a>  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/xtzgzorex.wordpress.com/641/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/xtzgzorex.wordpress.com/641/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=xtzgzorex.wordpress.com&#038;blog=13381977&#038;post=641&#038;subd=xtzgzorex&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://xtzgzorex.wordpress.com/2011/04/26/mono-summer-of-code/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/42c54d81a5ed511408e947ccd526d858?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">XTZGZoReX</media:title>
		</media:content>
	</item>
		<item>
		<title>SL# and Mono</title>
		<link>http://xtzgzorex.wordpress.com/2011/04/24/sl-and-mono/</link>
		<comments>http://xtzgzorex.wordpress.com/2011/04/24/sl-and-mono/#comments</comments>
		<pubDate>Sun, 24 Apr 2011 14:26:33 +0000</pubDate>
		<dc:creator>XTZGZoReX</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Mono]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[SL#]]></category>

		<guid isPermaLink="false">http://xtzgzorex.wordpress.com/?p=634</guid>
		<description><![CDATA[It turned out that SL# 1.4 did not run on Mono as we had expected. Due to a bug in Mono&#8217;s CancellationToken that caused a new instance to be canceled by default, ICSharpCode.Decompiler didn&#8217;t actually decompile methods. This issue was seen in both Mono 2.8 and 2.10.1. A bug has been filed, and we worked &#8230; <a href="http://xtzgzorex.wordpress.com/2011/04/24/sl-and-mono/" class="more-link">Continue reading <span class="meta-nav">&#187;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=xtzgzorex.wordpress.com&#038;blog=13381977&#038;post=634&#038;subd=xtzgzorex&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>It turned out that SL# 1.4 did not run on Mono as we had expected. Due to a bug in Mono&#8217;s CancellationToken that caused a new instance to be canceled by default, ICSharpCode.Decompiler didn&#8217;t actually decompile methods. This issue was seen in both Mono 2.8 and 2.10.1. <a href="https://bugzilla.novell.com/show_bug.cgi?id=689459">A bug has been filed</a>, and we <a href="https://github.com/IgniteInteractiveStudio/SLSharp/commit/9fe368c895d4c162a94663ec141b3974c4b09cbe#diff-1">worked around the issue</a> for now.</p>
<p>Another bug we encountered (which is only relevant for SL# master) was invalid IL generation, <a href="https://github.com/IgniteInteractiveStudio/SLSharp/commit/9fe368c895d4c162a94663ec141b3974c4b09cbe#diff-0">which has also been fixed</a>. Curiously, Microsoft&#8217;s CLR actually executed the IL correctly, even though the local variable had an incompatible type&#8230; Mono was much more helpful here, in that it threw an InvalidProgramException. As said, the latter issue is only relevant for master, not 1.4.</p>
<p>We might release a 1.4.1 package of SL# in a few days that addresses the first issue. If you don&#8217;t want to wait, grab <a href="https://github.com/IgniteInteractiveStudio/SLSharp/commit/1a9eefaeade8fd80c36ae52bb927e71ad74ffe43">this commit</a> and apply the CancellationToken workaround.</p>
<p><strong>Edit:</strong> Oh, and this seems to be my 100th blog post! Yay!</p>
<br />Filed under: <a href='http://xtzgzorex.wordpress.com/category/c/'>C#</a>, <a href='http://xtzgzorex.wordpress.com/category/mono/'>Mono</a>, <a href='http://xtzgzorex.wordpress.com/category/programming/'>Programming</a>, <a href='http://xtzgzorex.wordpress.com/category/sl/'>SL#</a>  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/xtzgzorex.wordpress.com/634/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/xtzgzorex.wordpress.com/634/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=xtzgzorex.wordpress.com&#038;blog=13381977&#038;post=634&#038;subd=xtzgzorex&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://xtzgzorex.wordpress.com/2011/04/24/sl-and-mono/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/42c54d81a5ed511408e947ccd526d858?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">XTZGZoReX</media:title>
		</media:content>
	</item>
		<item>
		<title>SL# 1.4 Released</title>
		<link>http://xtzgzorex.wordpress.com/2011/04/22/sl-1-4-released/</link>
		<comments>http://xtzgzorex.wordpress.com/2011/04/22/sl-1-4-released/#comments</comments>
		<pubDate>Fri, 22 Apr 2011 16:04:45 +0000</pubDate>
		<dc:creator>XTZGZoReX</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Mono]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[SL#]]></category>

		<guid isPermaLink="false">http://xtzgzorex.wordpress.com/?p=627</guid>
		<description><![CDATA[After less than a month with SL# 1.3, we&#8217;ve decided to release version 1.4. This is probably the release with the most changes that we&#8217;ve done so far: Full support for all GLSL data types (including matrices) Support for in and inout through C#&#8217;s ref and out keywords Switched to ICSharpCode.Decompiler instead of our homegrown &#8230; <a href="http://xtzgzorex.wordpress.com/2011/04/22/sl-1-4-released/" class="more-link">Continue reading <span class="meta-nav">&#187;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=xtzgzorex.wordpress.com&#038;blog=13381977&#038;post=627&#038;subd=xtzgzorex&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>After <a href="http://xtzgzorex.wordpress.com/2011/03/30/sl-1-3-released-as-open-source/">less than a month with SL# 1.3</a>, we&#8217;ve decided to release version 1.4.</p>
<p>This is probably the release with the most changes that we&#8217;ve done so far:</p>
<ul>
<li>Full support for all GLSL data types (including matrices)</li>
<li>Support for in and inout through C#&#8217;s ref and out keywords</li>
<li>Switched to ICSharpCode.Decompiler instead of our homegrown one</li>
<li>Support for many more language constructs due to switching decompiler engine</li>
<li>Support for hundreds of GLSL functions that we didn&#8217;t have before</li>
<li>Shader.DebugMode now actually works as expected</li>
<li>Better type checking/verification when translating</li>
<li>We now expose a sane standalone API (GlslTransform) for GLSL translation, should you want to use it</li>
<li>We now only ship one assembly, IIS.SLSharp.dll</li>
<li>Lots of cleanups to the public API; we no longer expose any internals</li>
<li>Lots and lots of bug fixes</li>
</ul>
<p>That&#8217;s a fairly impressive list of changes if you compare to our previous ones! We&#8217;ve been incredibly productive with SL# lately, and GitHub certainly has been a booster, with its new intuitive Issues 2.0.</p>
<p>As usual, the Git repository sits <a href="https://github.com/IgniteInteractiveStudio/SLSharp">here</a> (note that master is quite ahead of this release). Downloads can be found <a href="https://github.com/IgniteInteractiveStudio/SLSharp/downloads">here</a>, and <a href="http://www.nuget.org/List/Packages/SLSharp">the updated NuGet package has been published</a>.</p>
<p>If you run into any issues, please report them on <a href="https://github.com/IgniteInteractiveStudio/SLSharp/issues?milestone=&amp;labels=&amp;state=open">the issue tracker</a> as always.</p>
<p>Lastly, the reason we chose to release 1.4 so quickly is because we&#8217;re doing heavy work on making SL# engine-agnostic. This means that 1.4 will be the last release that depends on OpenTK. Future versions (2.0 and on) will support various engines (OpenTK, Axiom, XNA, SlimDX) as well as several languages (GLSL, HLSL, Cg) through bindings. This new architecture should also make it easier to add more native-feeling support for F# (through function quotations). This of course means that we&#8217;ll be doing massive (breaking) changes and refactoring to our API and possibly even our syntax, hence the major version bump.</p>
<p>With that said, enjoy!</p>
<br />Filed under: <a href='http://xtzgzorex.wordpress.com/category/c/'>C#</a>, <a href='http://xtzgzorex.wordpress.com/category/mono/'>Mono</a>, <a href='http://xtzgzorex.wordpress.com/category/programming/'>Programming</a>, <a href='http://xtzgzorex.wordpress.com/category/sl/'>SL#</a>  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/xtzgzorex.wordpress.com/627/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/xtzgzorex.wordpress.com/627/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=xtzgzorex.wordpress.com&#038;blog=13381977&#038;post=627&#038;subd=xtzgzorex&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://xtzgzorex.wordpress.com/2011/04/22/sl-1-4-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/42c54d81a5ed511408e947ccd526d858?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">XTZGZoReX</media:title>
		</media:content>
	</item>
	</channel>
</rss>