<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" media="screen" href="/styles/xslt/rss.xslt"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:media="http://search.yahoo.com/mrss/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:c9="http://channel9.msdn.com">
<channel>
	<title>Channel 9 Forums - Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
	<atom:link rel="self" type="application/rss+xml" href="http://channel9.msdn.com/Forums/rss"></atom:link>
	<image>
		<url>http://mschnlnine.vo.llnwd.net/d1/Dev/App_Themes/C9/images/feedimage.png</url>
		<title>Channel 9 Forums - Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<link>http://channel9.msdn.com/Forums</link>
	</image>
	<description>Channel 9 keeps you up to date with the latest news and behind the scenes info from Microsoft that developers love to keep up with. From LINQ to SilverLight – Watch videos and hear about all the cool technologies coming and the people behind them.</description>
	<link>http://channel9.msdn.com/Forums</link>
	<language>en</language>
	<pubDate>Tue, 21 May 2013 10:44:01 GMT</pubDate>
	<lastBuildDate>Tue, 21 May 2013 10:44:01 GMT</lastBuildDate>
	<generator>Rev9</generator>
	<c9:totalResults>77</c9:totalResults>
	<c9:pageCount>-77</c9:pageCount>
	<c9:pageSize>-1</c9:pageSize>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p>After playing around with writing an IL interpreter in C# (for fun, not profit -&nbsp;<a href="http://channel9.msdn.com/Forums/Coffeehouse/Has-anyone-considered-writing-an-MSIL-interpreter-in-C">see here</a>), I got the idea to write an IL to C&#43;&#43; compiler that will take a .Net *.exe and do the following:</p><ul><li>Do a static analysis of the code to determine which methods and types are actually in the code path, and ignore everything else. Done </li><li>Create substitute types for all the commonly used types like Int8, Int16, Int32 etc, object, string, DateTime, TimeSpan, etc. Since a lot of the &quot;native&quot; types make internal calls, they need to be replaced with &quot;pure&quot; types. Unfortunately I would also need to create equivalents to other commonly used classes, since any methods that call into internal calls would be flagged as an error. Mostly done (although not all of the base type methods and properties have been implemented yet, just some to test the feasibility of the approach). </li><li>Ensure the type system is fully managed. This means that&nbsp;the actual type of an &quot;object&quot; (or void*)&nbsp;can be determined at runtime. I can take this all the way to what reflection&nbsp;can do&nbsp;right now in .Net, it just depends on how much metadata I care to store in the exe. For instance, right now I don't store&nbsp;a type's namespace, its name or its member layouts etc, but it would be trivial to add it if I find I need it. Done. </li><li>Implement generics. Done. </li><li>Implement boxing/unboxing. Not done yet but should not be too difficult. </li><li>Implement PInvoke. Not implemented yet but this should be relatively trivial since we are already in C&#43;&#43; land. </li><li>Compile a C&#43;&#43; header file, declaring each used type and method. Done </li><li>Compile a C&#43;&#43; source file with method implementations. Of course this involves the actual compiling from IL instructions to C&#43;&#43; code but from my previous experience with the IL interpreter I think this would be relatively easy although time consuming. Not done yet. </li></ul><p>Advantages of this approach:</p><ul><li>You can take the C&#43;&#43; files and compile them for a microcontroller using any supported C&#43;&#43; compiler. </li><li>This should run at almost &quot;native&quot; speed. Currently the .Net framework runs about 100 to 1000 <em>times</em> slower on a microcontroller than the equivalent native code. </li><li>You can use the &quot;full&quot; .Net as opposed to just the .Net Micro Framework, although most of the&nbsp;framework&nbsp;classes' methods would not be available due to them making internal calls (this is a per-method limitation, so some methods might work just fine). </li><li>The exe&nbsp;generated by this should be&nbsp;very small, since only the methods and types that are actually used in the call graph are compiled. For instance, if you never use the method DateTime.Now, that code will never make it into the final exe. This has a big advantage to even the Micro Framework, which still requires all of the .Net runtime to be present on the microcontroller. </li></ul><p>I don't have a problem writing the part of the GC that walks the object graph marking all referenced objects and then deleting unreferenced ones. Since I have full control over the C&#43;&#43; class generation, I intend to implement something like this:</p><p><pre class="brush: cpp">class VirtualObject
{
public:
    Bool m_mark;

    virtual void Mark()
    {
        m_mark = True;
    }
};

class VirtualMyClass : VirtualObject
{
public:
    VirtualObject m_variableA;
    SomeOtherObject m_variableB;

    virtual void Mark()
    {
        if (m_mark)
            return;   // prevent infinite loops if two objects reference each other directly or indirectly

        VirtualObject::Mark();

        if (m_variableA)
            m_variableA-&gt;Mark();

        if (m_variableB)
            m_variableB-&gt;Mark();
    }
};</pre></p><p>The above code would be trivial to create. There would be a &quot;virtual stack&quot; where all &quot;ref types&quot; will be created and referenced to. Now all the GC has to do is&nbsp;to look at all the&nbsp;static variables and the &quot;virtual stack&quot;, and call Mark() on all variables derived from VirtualObject that are not null. Then walk all of the currently allocated VirtualObject types and delete the ones that do not have the mark flag set, and clear the mark flag on the ones that do have it set (for the next pass).</p><p>OK, that was way more than I intended to write, but it helps to get the full picture of what I'm doing. Now to the questions I have...</p><p>So marking and deleting objects are taken care of. But what about compacting the remaining objects? I'm wondering how one would go about implementing VirtualObjects that are &quot;movable&quot;. I have some ideas by they seem way too complex, and it involves having multiple levels of indirection. This doesn't seem ideal either because even if you have an array of objects and use an index as a &quot;handle&quot; for each, if you then allocate 1,000,000 objects, but only end up keeping a reference to the last one, you are stuck with a lookup array that has&nbsp;999,999 items that are null but just the last one is not null. You can't compact the array since something is referencing to the item at index 999,999.</p><p>So what is the correct way to implement a system where object are fully &quot;movable&quot;? Even&nbsp;JITted code&nbsp;would still need to implement this. How do the smart guys do it?</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/d8ca8d616ff148b7977b9f2800fed743#d8ca8d616ff148b7977b9f2800fed743</link>
		<pubDate>Fri, 22 Jul 2011 15:27:50 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/d8ca8d616ff148b7977b9f2800fed743#d8ca8d616ff148b7977b9f2800fed743</guid>
		<dc:creator>BitFlipper</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/BitFlipper/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p></p><blockquote><div class="quoteText">Now all the GC has to do is to look at all the static variables and the &quot;virtual stack&quot;, and call Mark() on all variables derived from VirtualObject that are not null.</div></blockquote><p></p><p>This means that you know where the references to the objects are. If you know this then you can simply update the references when the objects move. An additional level of indirection is not required and it's not efficient anyway.</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/1620b4994a51473c95479f28011683ef#1620b4994a51473c95479f28011683ef</link>
		<pubDate>Fri, 22 Jul 2011 16:54:02 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/1620b4994a51473c95479f28011683ef#1620b4994a51473c95479f28011683ef</guid>
		<dc:creator>Dexter</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/Dexter/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p></p><blockquote><div class="quoteText"><p></p><p><a class="permalink" title="Post Permalink" href="/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/1620b4994a51473c95479f28011683ef">11 minutes&nbsp;ago</a>,<a href="/Niners/Dexter">Dexter</a> wrote</p><p>*snip*</p><p>This means that you know where the references to the objects are. If you know this then you can simply update the references when the objects move. An additional level of indirection is not required and it's not efficient anyway.</p><p></p></div></blockquote><p></p><p>I think you are right. I was thinking that a currently executing function might have a local reference that could not be updated in such cases but if done correctly then this might not be a problem. So all &quot;local&quot; references to objects should really be&nbsp;references to objects&nbsp;on the &quot;virtual object stack&quot; as either a pointer to the <em>location</em> on the virtual stack, or an index to the virtual stack.</p><p>I'll need to give this some more thought but as I said I believe you are correct.</p><p>Somewhat related: Since microcontrollers don't support preemptive multithreading (or at least not the&nbsp;ARM microcontroller&nbsp;I'm playing with) I need to emulate that. The way&nbsp;I'm thinking of doing that is something like this:</p><p>void SomeClass::SomeFunction(VirtualThread* thread)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;// ...code...<br>&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;if (VirtualMachine.PendingContextSwitch)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;VirtualMachine.SwitchContext(thread);<br>&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;// ...code...<br>}</p><p>Usually the static VirtualMachine.PendingContextSwitch value would only be checked at the end of a function, or inside a loop (since there is no way to know how long the loop might take to complete). Also if the function is really long then I might add some additional checks.</p><p>The VirtualMachine.SwitchContext() call will do a context switch on the CPU. This is obviously very CPU dependent, and on the ARM processor you call the SWI instruction. Not sure how to do it on an x86 processor but it would not be too difficult to figure out (I'll stay away from x64 for now).</p><p>The VirtualMachine.PendingContextSwitch value itself would be set to true either periodically by a timer in VirtualMachine&nbsp;on x86, or by a hardware timer interrupt on the ARM processor.</p><p>The above mechanism has the advantage that I can control exactly where the code can be preempted, and maybe update all local references (if it is even needed) if VirtualMachine.SwitchContext returns true. Something like:</p><p>void SomeClass::SomeFunction(VirtualThread* thread)<br>{<br>&nbsp;&nbsp;&nbsp; // ...code...<br><br>&nbsp;&nbsp;&nbsp; if (VirtualMachine.PendingContextSwitch) &amp;&amp; VirtualMachine.SwitchContext(thread)<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // update all local references<br>&nbsp;&nbsp;&nbsp; }<br><br>&nbsp;&nbsp;&nbsp; // ...code...<br>}</p><p>Since most of the time PendingContextSwitch will be false, the check should not add much overhead, even inside tight loops. Once again, would this be the way the smart guys do it, or am I completely missing something here?</p><p>EDIT: Does anyone know what is up with the code formatting? Sometimes it insists putting everything on the same line, no matter whether you put newlines or Shift&#43;newlines. I removed the code from the code blocks to make them readable.</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/5a09d84872dc47f49c359f2801225dc8#5a09d84872dc47f49c359f2801225dc8</link>
		<pubDate>Fri, 22 Jul 2011 17:37:11 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/5a09d84872dc47f49c359f2801225dc8#5a09d84872dc47f49c359f2801225dc8</guid>
		<dc:creator>BitFlipper</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/BitFlipper/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p>Hmm, there's one problem&nbsp;I forgot to mention. In addition to stack and static variables there's one more place where you need to look for references: CPU registers.</p><p>This seems to be rather complicated to solve even in the absence of multithreading due to the fact that you generate C&#43;&#43; code, not assembly. Imagine this:</p><p><pre class="brush: text">void SomeMethod() {
...
foo bar = new foo();
...
}</pre></p><p>Let's say that new runs out of memory and triggers a GC. Let's also say that there's no threading and that the GC happens on the same thread. Even in this simple case you have no idea what the CPU registers contain when the GC code is entered, it's up to the compiler.</p><p>As for threading: I'm not familiar with these microcontrollers but I'm not sure why you would need all that machinery. As long as the CPU supports interrupts you should be able to implement preemptive multithreading without the need for this Pending/Switch stuff. And if the CPU doesn't have interrupts then who is going to set Pending anyway? You may need some form of cooperative multithreading in that case.</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/e5b360a666d74584bdf09f28012cc72b#e5b360a666d74584bdf09f28012cc72b</link>
		<pubDate>Fri, 22 Jul 2011 18:15:05 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/e5b360a666d74584bdf09f28012cc72b#e5b360a666d74584bdf09f28012cc72b</guid>
		<dc:creator>Dexter</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/Dexter/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p>Well, in this case it might be something along these lines:</p><p>[Edit: I changed the code since there were some errors with the stack pointers]</p><p>class VirtualThread<br>{<br>&nbsp;&nbsp;&nbsp; VirtualObject** StackBase;<br>&nbsp;&nbsp;&nbsp; VirtualObject** StackPointer;<br>}<br>&nbsp;&nbsp;&nbsp;</p><p>int SomeMethod(VirtualThread* thread)<br>{<br>&nbsp;&nbsp;&nbsp; int retVal;<br>&nbsp;&nbsp;&nbsp; VirtualObject** stackStart = thread-&gt;StackPointer;<br>&nbsp;&nbsp;&nbsp; *thread-&gt;StackPointer = new foo();<br>&nbsp;&nbsp;&nbsp; VirtualObject** bar = thread-&gt;StackPointer&#43;&#43;;<br>&nbsp;&nbsp;&nbsp;&nbsp;((foo*)*bar)-&gt;DoSomething();<br>&nbsp;&nbsp;&nbsp; // ...code...<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; //&nbsp;The following lines of code would be changed to the code below it<br>&nbsp;&nbsp;&nbsp; // if (someValue)<br>&nbsp;&nbsp;&nbsp; //&nbsp;&nbsp;&nbsp;&nbsp; return 123;<br><br>&nbsp;&nbsp;&nbsp; if (someValue)<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retVal = 123;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; goto Exit:<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; // ...code...<br><br>Exit:<br>&nbsp;&nbsp;&nbsp; thread-&gt;StackPointer = stackStart;<br>&nbsp;&nbsp;&nbsp; return retVal;<br>}</p><p>Or something along those lines. I do think there would need to be at least one level of indirection for local and static ref types.</p><p>Edit: I don't think with the above code there should be an issue with CPU registers since I am explicitly casting what is on the &quot;virtual stack&quot; to an instance of the actual object each time. The object can move between those calls. This is especially true if I use&nbsp;the context switching mechanism I proposed above.</p><p>Edit Edit: About the preemptive multitheading: If you think about it, even if you use a timer or interrupt, you still need to know which virtual thread to switch to. I'm not exactly sure about the details of context switching and register saving etc, but it will&nbsp;basically need to come down to saving all of the registers into some storage (preferably in the VirtualThread class), and then restoring the state from another VirtualThread and continuing execution where it left off.</p><p>So as far as the GC is concerned, now it just needs to enumerate through all VirtualThreads' stacks starting at StackBase up to StackPointer, and if it finds any non-null values there, it just calls VirtualObject::Mark() on it. Now you know exactly which objects are still being used as &quot;locals&quot; withing the executing functions (in addition to also calling VirtualObject::Mark() for each non-null static object).</p><p>Edit Edit Edit: I just realized that the &quot;this&quot; can also move while the class is executing code so it means that a &quot;this&quot; pointer will need to be passed on the stack as well, and all &quot;this&quot; references will need to go through this pointer as well.</p><p>Obviously this is getting more complex but I still think it would be way faster than the current performance we see with the Micro Framework.</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/99b5cbc0ea6c466e97be9f28013fc544#99b5cbc0ea6c466e97be9f28013fc544</link>
		<pubDate>Fri, 22 Jul 2011 19:24:14 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/99b5cbc0ea6c466e97be9f28013fc544#99b5cbc0ea6c466e97be9f28013fc544</guid>
		<dc:creator>BitFlipper</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/BitFlipper/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p></p><blockquote><div class="quoteText">I don't think with the above code there should be an issue with CPU registers since I am explicitly casting what is on the &quot;virtual stack&quot; to an instance of the actual object each time.</div></blockquote><p></p><p>That doesn't matter too much. If you have code like the following:</p><p></p><pre class="brush: cpp">((foo*)*bar)-&gt;DoSomething();((foo*)*bar)-&gt;DoSomething();</pre><p></p><p>the compiler can (and usually will) perform the cast once and store the result into a register. However, this should work fine if you're allocating GC memory between those 2 lines. The compiler can't reuse the value from the previous cast because it has no way to prove that *bar wasn't changed by the memory allocation function.</p><p>Unfortunately this compiler optimization means that you have no way of doing normal preemptive multithreading, you have to use SwitchContext. I'm not what that will do to performance but I see no other way of doing this given the constraints.</p><p></p><blockquote><div class="quoteText">I'm not exactly sure about the details of context switching and register saving etc, but it will basically need to come down to saving all of the registers into some storage (preferably in the VirtualThread class),</div></blockquote><p></p><p>Pretty much yes. One possibility is to save the registers on the current thread's stack and then switch the stack. It's also possible that you won't need to save the registers if you use the SwitchContext approach because the compiler will probably save the &quot;used&quot; registers when it calls the function.</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/fc598c9077de44d5be819f28015450ac#fc598c9077de44d5be819f28015450ac</link>
		<pubDate>Fri, 22 Jul 2011 20:39:02 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/fc598c9077de44d5be819f28015450ac#fc598c9077de44d5be819f28015450ac</guid>
		<dc:creator>Dexter</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/Dexter/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p>My question is what does the &quot;real&quot; framework do with this when it JITs the code? Surely the same issues apply? We know that ref types can move around memory. How does it handle it?</p><p>BTW I now make all functions static, even the instance functions, since I now also pass my own custom &quot;this&quot; pointer and there is no need for the real this pointer.</p><p>So, the following C# method...</p><p>class Foo<br>{<br>&nbsp;&nbsp;&nbsp; int Multiply(int x, int y)<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return x * y;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>}</p><p>...now becomes (at tleast the declaration)...</p><p>class Foo : public VirtualObject<br>{<br>&nbsp;&nbsp;&nbsp; static&nbsp;int Multiply(VirtualThread* pThread, VirtualObject** pThis,&nbsp;int x,&nbsp;int y);<br>}</p><p>Edit: I can't make virtual functions static. I don't believe this will be a problem since AFAIC the virtual tables themselves are static, so it doesn't matter if the class instance moves around memory.</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/c2552947697647728a0b9f2801610c98#c2552947697647728a0b9f2801610c98</link>
		<pubDate>Fri, 22 Jul 2011 21:25:24 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/c2552947697647728a0b9f2801610c98#c2552947697647728a0b9f2801610c98</guid>
		<dc:creator>BitFlipper</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/BitFlipper/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p></p><blockquote><div class="quoteText">Surely the same issues apply?</div></blockquote><p></p><p>Not really. Since CLR's JIT outputs assembly code it has knowledge about what's in the registers or about points where it is safe to stop the code for GC because there's no pointer in any register. Since you're generating C&#43;&#43; code you don't have this luxury, you're at the mercy of the compiler.</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/db37cf9b569245db9fbc9f29006634b6#db37cf9b569245db9fbc9f29006634b6</link>
		<pubDate>Sat, 23 Jul 2011 06:12:07 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/db37cf9b569245db9fbc9f29006634b6#db37cf9b569245db9fbc9f29006634b6</guid>
		<dc:creator>Dexter</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/Dexter/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p></p><blockquote><div class="quoteText"><p></p><p><a class="permalink" title="Post Permalink" href="/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/db37cf9b569245db9fbc9f29006634b6">2 days&nbsp;ago</a>,<a href="/Niners/Dexter">Dexter</a> wrote</p><p>*snip*</p><p>Not really. Since CLR's JIT outputs assembly code it has knowledge about what's in the registers or about points where it is safe to stop the code for GC because there's no pointer in any register. Since you're generating C&#43;&#43; code you don't have this luxury, you're at the mercy of the compiler.</p><p></p></div></blockquote><p></p><p>Actually the CLR doesn't make any assumptions like that. During a garbage collect on a particular thread, it suspends the thread (either by suspending it from another thread or during a call into the runtime, e.g. during a new object allocation). The registers are stored onto the stack and the stack is then inspected for any value that lies within the bounds of the current heap. Any value that falls within an object is marked as live for this round. The root-set computed is therefore a super-set of the &quot;true&quot; root-set, since an integer which happens to hold a value that would also be a valid pointer into the heap might cause a value to live longer than it strictly should, but this doesn't matter since this is much faster than using type information to derive the true root set.</p><p>At this point the thread can be resumed.</p><p>Added to the root set (which is rounded to the nearest object and now has type information which is stored with the object) is all of the objects from the other thread's root sets, all of the static variables (using type information) and thread local variables.</p><p>1) Mark all objects as &quot;black&quot;</p><p>2) Mark all objects from the current live set (computed above) as &quot;gray&quot;</p><p>3) While there are still objects in the gray set:</p><p>&nbsp; 4) Add all objects reachable from that object which are in the black set to the gray set.</p><p>&nbsp; 5) Add the object to the white set.</p><p>6) Goto 3 until the gray set is empty.</p><p>7) Now all objects reachable from the live set are colored white, and all objects colored black are not reachable from the live set.</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/705de888c7aa48abb11c9f2b0156669f#705de888c7aa48abb11c9f2b0156669f</link>
		<pubDate>Mon, 25 Jul 2011 20:46:38 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/705de888c7aa48abb11c9f2b0156669f#705de888c7aa48abb11c9f2b0156669f</guid>
		<dc:creator>evildictaitor</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/evildictaitor/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p></p><blockquote><div class="quoteText"><p></p><p><a class="permalink" title="Post Permalink" href="/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/c2552947697647728a0b9f2801610c98">2 days&nbsp;ago</a>,<a href="/Niners/BitFlipper">BitFlipper</a> wrote</p><p>Edit: I can't make virtual functions static. I don't believe this will be a problem since AFAIC the virtual tables themselves are static, so it doesn't matter if the class instance moves around memory.</p><p></p></div></blockquote><p></p><p>Virtual tables aren't static:</p><p>class myClass {<br>&nbsp; int a;<br>&nbsp; static int b;<br>&nbsp; virtual void myFunc();<br>&nbsp; myClass() {}<br>}</p><p>looks like this in C:</p><p><br>static int _myClass_b;<br>typedef struct <br>{<br>&nbsp; int m_a;<br>&nbsp; void* myFunc<br>} MyClass;&nbsp;<br><br>void _myClass(MyClass* cls)<br>{<br>&nbsp; cls-&gt;myFunc = &amp;MyClass_myFunc;<br>}&nbsp;</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/8f6617879b624f45a7ac9f2b015828f5#8f6617879b624f45a7ac9f2b015828f5</link>
		<pubDate>Mon, 25 Jul 2011 20:53:02 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/8f6617879b624f45a7ac9f2b015828f5#8f6617879b624f45a7ac9f2b015828f5</guid>
		<dc:creator>evildictaitor</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/evildictaitor/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p>@<a href="/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC#c8f6617879b624f45a7ac9f2b015828f5">evildictaitor</a>:</p><p>Thanks for the info about the GC. I'm using a &quot;virtual&quot; stack that only contains ref types so I don't have the problem with objects being incorrectly flagged due to matching int values, etc.</p><p>As far as the vtables are concerned, I believe the vtables themselves are &quot;static&quot; in the sense that there is just one vtable for each type. So even if you create 100 instances of the same type, they all have a hidden pointer that point to the exact same vtable. Hence if you move the class around in memory, it won't matter since it will still point to the same vtable.</p><p>From Wikipedia: &quot;<em>Typically, the compiler creates a separate vtable for each class. When an object is created, a pointer to this vtable, called the virtual table pointer, vpointer or VPTR, is added as a hidden member of this object</em>&quot; <a href="http://en.wikipedia.org/wiki/Vtable">http://en.wikipedia.org/wiki/Vtable</a></p><p>&nbsp;</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/6347c0e5145a48ed89a09f2c0008d706#6347c0e5145a48ed89a09f2c0008d706</link>
		<pubDate>Tue, 26 Jul 2011 00:32:11 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/6347c0e5145a48ed89a09f2c0008d706#6347c0e5145a48ed89a09f2c0008d706</guid>
		<dc:creator>BitFlipper</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/BitFlipper/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p></p><blockquote><div class="quoteText">Actually the CLR doesn't make any assumptions like that.</div></blockquote><p></p><p>Actually it does.</p><p></p><blockquote><div class="quoteText">The registers are stored onto the stack</div></blockquote><p></p><p>Actually no. While the kernel may indeed store the registers on the stack when the thread is suspended the only way for an application to get those registers is to call GetThreadContext. Sure, the CONTEXT that you pass to that function can be stored on stack but that's irrelevant here.</p><p></p><blockquote><div class="quoteText">the stack is then inspected for any value that lies within the bounds of the current heap. Any value that falls within an object is marked as live for this round. The root-set computed is therefore a super-set of the &quot;true&quot; root-set, since an integer which happens to hold a value that would also be a valid pointer into the heap might cause a value to live longer than it strictly should</div></blockquote><p></p><p>Nope, this is not what MS's CLR does. What you're describing here sounds like coservative GC, not compacting GC.</p><p></p><blockquote><div class="quoteText">but this doesn't matter since this is much faster than using type information to derive the true root set.</div></blockquote><p></p><p>Actually it matters a lot because it&nbsp;prevents objects from being moved which was one the main questions in this thread. You can't move objects unless you know exactly where pointers are. Or are you suggesting to modify random values in memory that happen to look like pointers?</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/60c34223e830403084f79f2c0051c565#60c34223e830403084f79f2c0051c565</link>
		<pubDate>Tue, 26 Jul 2011 04:57:43 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/60c34223e830403084f79f2c0051c565#60c34223e830403084f79f2c0051c565</guid>
		<dc:creator>Dexter</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/Dexter/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p>@<a href="/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC#c60c34223e830403084f79f2c0051c565">Dexter</a>:</p><p>Yes I'm finding a lot of complexities while trying to implement a compacting GC. The way I'm planning on doing it is with the &quot;virtual stack&quot; I mentioned previously. Each thread will have such a stack, and each of a function's ref type variables and parameters are&nbsp;really a pointer to a <em>location</em> on&nbsp;this stack&nbsp;like this:</p><p>MyRefType**&nbsp;foo =&nbsp;(MyRefType**)&amp;(&#43;&#43;pThread-&gt;StackPointer);</p><p>So while the value that is stored in the virtual stack can change as the class is moved around, <strong>foo</strong> itself never needs to change. When moving classes around, what&nbsp;I will need to do is check each value on each thread's virtual stack and update any pointers that have changed. Still trying to think what will be the most efficient way of doing this, but I believe in concept it will work.</p><p>For static ref type variables, I will just create one C function that is hardwired to check each class's static ref variables and call the <strong>Mark</strong> mentioned in the original post. Also there will be one C function that is hardwired to update any static ref pointers that have changed.</p><p>For class ref type variables, each class will have a hardwired function that can be used to update any of it's ref type pointers that could have changed. Something like:</p><p>void MyRefType::UpdatePointer(VirtualObject* oldPointer, VirtualObject* newPointer)<br>{<br>&nbsp;&nbsp;&nbsp; if (m_foo == oldPointer)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_foo = newPointer;<br><br>&nbsp;&nbsp;&nbsp; if (m_foo != NULL)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_foo-&gt;UpdatePointer(oldPointer, newPointer);<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; // Do the same for all other class ref types...<br>}</p><p>[<em>Sorry, I'm not doing the code blocks again, sometimes&nbsp;C9 loses it's mind and insists that&nbsp;all code&nbsp;should be on one line only. I'll just indent the text for now (which apparently doesn't seem to work either)</em>]</p><p>Hmm, now that I think about it, that might not work because classes that are not reachable will never be called. If those classes are not rooted but they are still performing some sort of&nbsp;operations (maybe in some long running loop or a timer callback), their class variables will not be updated. So probably I will need to call UpdatePointer on each class while walking the object heap. In that case the UpdatePointer&nbsp;function will only update its own ref type variables,&nbsp;not call into UpdatePointer for each of its non-null ref&nbsp;objects. So it simplifies to:</p><p>void MyRefType::UpdatePointer(VirtualObject* oldPointer, VirtualObject* newPointer)<br>{<br>&nbsp;&nbsp;&nbsp; if (m_foo == oldPointer)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_foo = newPointer;<br>&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp; // Do the same for all other class ref types...<br>}</p><p>On a different topic, I ran into an interesting problem. So I have this concept that I will need to create &quot;pure&quot; classes due to the fact that many of the standard classes make internal calls, which I cannot decompile and create C&#43;&#43; code for. So just as an experiment, I added these lines of code to my C# test app:</p><p>var list = new List&lt;int&gt;();<br>list.Add(1);<br>list.Add(2);</p><p>And&nbsp;my C&#43;&#43;&nbsp;code suddenly got hugely bloated with all sorts of seemingly unrelated classes like&nbsp;the&nbsp;CultureInfo, etc with all of their huge amounts of static string resources etc. It seems that List is referencing those classes somewhere directly or indirectly, possibly through its static constructor. So I'm pulling in all of those types and doing a&nbsp;call graph analysis&nbsp;on&nbsp;their static constructors (which I need to call for all types I include), which is probably why it is detecting that all of those need to be included. Also in most cases it eventually hits an internal call and all bets are off.</p><p>Not sure how to work around that problem. Maybe I can do a better&nbsp;call graph&nbsp;analysis and only&nbsp;include static variables if&nbsp;the call graph actually references&nbsp;them (I might even do this for <em>all</em> variables - if they are never referenced in the call graph, I think they&nbsp;can be completely ignored, no?).</p><p>It&nbsp;won't be fun&nbsp;if I have to create &quot;pure&quot; versions of all the generic types, etc. But remember that the bar in this case is extremenly low: The .Net Micro Framework <a href="http://forums.netduino.com/index.php?/topic/1328-generics-in-netmf">doesn't even support generics at all</a>, so the fact that I do is already a big advantage given the ultimate goal of creating C&#43;&#43; code that can be compiled for a microcontroller.</p><p>Yet another different topic: Right now you can debug your .Net MF code running on a microcontroller using VS, just like any other .Net app (no edit and continue though). Since the .Net MF code is open source, I plan to figure out how it is done and ultimately (far down the line), I'd like to support debugging from VS. I can store as much or as little metadata for each type as I want, so I could make it&nbsp;such that using some VS plugin, I can map a current instance of any type back to the original type in the original .Net code (and pass it's member values to the debugger as well), so I think it should be possible to make a VS debugging plugin. Has anyone had experience with this, and how difficult would such a project be?</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/efbed4f403c74142901f9f2c00ef668c#efbed4f403c74142901f9f2c00ef668c</link>
		<pubDate>Tue, 26 Jul 2011 14:31:37 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/efbed4f403c74142901f9f2c00ef668c#efbed4f403c74142901f9f2c00ef668c</guid>
		<dc:creator>BitFlipper</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/BitFlipper/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p></p><blockquote><div class="quoteText">and each of a function's ref type variables and parameters are really a pointer to a<em>location</em> on this stack like this:</div></blockquote><p></p><p>One thing&nbsp;I don't understand is what are you going to do about value types that contain pointers and are stored on the stack. Did I miss something?</p><p></p><blockquote><div class="quoteText">that might not work because classes that are not reachable will never be called. If those classes are not rooted but they are still performing some sort of operations (maybe in some long running loop or a timer callback), their class variables will not be updated.</div></blockquote><p></p><p>That should never happen, if an object is not reachable then it's garbage and it will be collected. If you pass a GC pointer to native code then you know what you need to do: use &quot;fixed&quot; or GCHandle to prevent the GC from&nbsp;moving/collecting the object.</p><p></p><blockquote><div class="quoteText">So probably I will need to call UpdatePointer on each class while walking the object heap.</div></blockquote><p></p><p>Watch out that moving objects and updating pointers can be extremly tricky. I'm not talking about finding the roots which can be itself a problem, I'm talking about how can you update pointers in an efficient way. One thing is clear: you can't move one object and then call UpdatePointers on all the other objects in the heap, that has quadratic complexity.</p><p>Since evildictait​or mentioned it: have you considered using Boehm GC instead?<a href="http://en.wikipedia.org/wiki/Boehm_garbage_collector">http://en.wikipedia.org/wiki/Boehm_garbage_collector</a></p><p></p><blockquote><div class="quoteText">And my C&#43;&#43; code suddenly got hugely bloated with all sorts of seemingly unrelated classes like the CultureInfo</div></blockquote><p></p><p>Hmm, not sure what CultureInfo has to do with List&lt;&gt;. Maybe the Sort method uses it somehow. Since you wrote that code you should be able to modify it to log some information about why a particular type has been included, right? <img src='http://ecn.channel9.msdn.com/o9/content/images/emoticons/emotion-2.gif?v=c9' alt='Big Smile' /> If I understand correctly now you're including all the methods of an used type, you may consider excluding methods that are never called.</p><p></p><blockquote><div class="quoteText">so I think it should be possible to make a VS debugging plugin. Has anyone had experience with this, and how difficult would such a project be?</div></blockquote><p></p><p>Absolutely no idea but if you can make all the rest work (compiler, GC etc.) then you should be able to write such a plugin too <img src='http://ecn.channel9.msdn.com/o9/content/images/emoticons/emotion-1.gif?v=c9' alt='Smiley' /></p><p>&nbsp;</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/ad6475ae11294d19a2ea9f2c011532f2#ad6475ae11294d19a2ea9f2c011532f2</link>
		<pubDate>Tue, 26 Jul 2011 16:49:15 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/ad6475ae11294d19a2ea9f2c011532f2#ad6475ae11294d19a2ea9f2c011532f2</guid>
		<dc:creator>Dexter</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/Dexter/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p></p><blockquote><div class="quoteText"><p></p><p><a class="permalink" title="Post Permalink" href="/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/ad6475ae11294d19a2ea9f2c011532f2">1 hour&nbsp;ago</a>,<a href="/Niners/Dexter">Dexter</a> wrote</p><p>One thing&nbsp;I don't understand is what are you going to do about value types that contain pointers and are stored on the stack. Did I miss something?</p><p></p></div></blockquote><p></p><p>Yes, a very good point. I've thought of two ways to solve that problem:</p><ol><li>The &quot;easy way out&quot; would be to check whether a struct has any ref type fields and then treat it as a ref type (convert it to a class, which should be trivial). Not ideal since the point of using structs might be to put them in an array. But this could be the initial &quot;solution&quot;. </li><li>A better but more difficult solution: Any structs that have ref type fields also get the same hard-coded functions to manage their pointers just like classes get (Mark and UpdatePointer). Then when the structs get initialized as locals in a function, a pointer to them is pushed onto the virtual stack. Now when the GC walks the stack, those structs will also have their pointer management functions called. For arrays, they can be treated as structs (not boxed), but the array class that holds structs (or ref types), will know how to call each of its array items' pointer management functions.</li></ol><p></p><blockquote><div class="quoteText"><p></p><p>That should never happen, if an object is not reachable then it's garbage and it will be collected. If you pass a GC pointer to native code then you know what you need to do: use &quot;fixed&quot; or GCHandle to prevent the GC from&nbsp;moving/collecting the object.</p><p></p></div></blockquote><p></p><p>Are you sure? Let's say the class has a method like this:</p><p>void MyClass.DoSomething()<br>{<br>&nbsp;&nbsp;&nbsp; while (!someBoolThatWillAlwaysBeTrue)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; someRefObjField.DoSomethingElse();<br>}</p><p>That is certainly not &quot;illegal&quot; code and the compiler can't guard against it. Now if the original ref to MyClass goes out of scope, then it is no longer reachable&nbsp;and it&nbsp;will be GC'd (and hence someRefObjField won't be reachable either and will be GC'd).</p><p></p><blockquote><div class="quoteText"><p></p><p>Watch out that moving objects and updating pointers can be extremly tricky. I'm not talking about finding the roots which can be itself a problem, I'm talking about how can you update pointers in an efficient way. One thing is clear: you can't move one object and then call UpdatePointers on all the other objects in the heap, that has quadratic complexity.</p><p></p></div></blockquote><p></p><p>Yes, and I was wondering about that too. Not sure if it would be faster to send a&nbsp;Dictionary&lt;,&gt; of changed pointers or not. I was thinking that I might just move one class at a time, hence making the GC &quot;incremental&quot;. On a microcontroller it might be more important for the GC to not lock everything up for long periods of times instead of absolute performance. There is often somewhat of a &quot;realtime&quot; nature to microcontrollers with its hardware interrupts etc.</p><p></p><blockquote><div class="quoteText"><p></p><p>Since evildictait​or mentioned it: have you considered using Boehm GC instead?<a href="http://en.wikipedia.org/wiki/Boehm_garbage_collector">http://en.wikipedia.org/wiki/Boehm_garbage_collector</a></p><p></p></div></blockquote><p></p><p>I'll take a look, thanks.</p><p></p><blockquote><div class="quoteText"><p></p><p>Hmm, not sure what CultureInfo has to do with List&lt;&gt;. Maybe the Sort method uses it somehow. Since you wrote that code you should be able to modify it to log some information about why a particular type has been included, right?<img src="http://ecn.channel9.msdn.com/o9/content/images/emoticons/emotion-2.gif?v=c9" alt="Big Smile"></p><p></p></div></blockquote><p></p><p>It&nbsp;possibly came&nbsp;in via one of the exception classes. I'll need to create substitutes for all of those too, so once I do, it might end up filtering out a lot of the unneeded stuff.</p><p></p><blockquote><div class="quoteText"><p></p><p>If I understand correctly now you're including all the methods of an used type, you may consider excluding methods that are never called.</p><p></p></div></blockquote><p></p><p>That is what I'm already doing with my &quot;call graph&quot;. I start at the Assembly.EntryPoint and look at all the IL instructions for any method calls. Any types that get referenced&nbsp;along the way gets added too. This process is repeated recursively for all methods found within the IL.</p><p>What I'm suggesting is improving on this process by stripping the fields out of types that were never referenced during all of the code paths. So if a class has a member field called SomeHugeClass, but the code path never references it,&nbsp;it can be safely removed it altogether. How else is it going to be referenced (other than via the static constructors which I'l treat in the same way)? Of course this makes reflection impossible but that is fine, I think reflection can be left out for now - it is a microcontroller after all.</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/a7ed831b083c4077a02d9f2c0139e26a#a7ed831b083c4077a02d9f2c0139e26a</link>
		<pubDate>Tue, 26 Jul 2011 19:02:49 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/a7ed831b083c4077a02d9f2c0139e26a#a7ed831b083c4077a02d9f2c0139e26a</guid>
		<dc:creator>BitFlipper</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/BitFlipper/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p></p><blockquote><div class="quoteText">A better but more difficult solution: Any structs that have ref type fields also get the same hard-coded functions to manage their pointers just like classes get</div></blockquote><p></p><p>That sounds good. And I might have a slightly different idea, treat the stack frame as objects:</p><ul><li>for each method create a struct that contains all the method parameters and locals</li><li>when you call a method allocate such a struct on the stack (by using alloca or other means)</li><li>fill the parameters </li><li>call the method with a pointer to the allocated struct </li><li>you'll also need to store pointers to these stack frames on that virtual stack of yours or simply chain the stack frames into a linked list (pointed to by the thread)</li></ul><p>Pros:</p><ul><li>&quot;everything&quot; is an object, you don't need separate cases for &quot;real&quot; objects and stack frames</li><li>this works transparently with value types that contain references </li><li>this might avoid the register problem completly. if a method makes a &quot;alloc&quot; call the compiler won't be able to prove that the stack frame object hasn't been modified and it will have to reload any registers that have been previously read from stack frame</li></ul><p>Cons:</p><ul><li>This will very likely disable some compiler optimizations. Usually some of the parameters are passed through registers, this can't happen anymore since the only real parameter will be the pointer to stack frame. Similarly for local variables.</li></ul><p></p><blockquote><div class="quoteText">That is certainly not &quot;illegal&quot; code and the compiler can't guard against it. Now if the original ref to MyClass goes out of scope, then it is no longer reachable and it will be GC'd</div></blockquote><p></p><p>MyClass can't go out of scope, if one of its methods is running then there must be a stack frame for it and that stack frame must contain the &quot;this&quot; pointer for MyClass.</p><p></p><blockquote><div class="quoteText">On a microcontroller it might be more important for the GC to not lock everything up for long periods of times instead of absolute performance.</div></blockquote><p></p><p>Sounds like you want generational GC too. Even more complicated <img src='http://ecn.channel9.msdn.com/o9/content/images/emoticons/emotion-2.gif?v=c9' alt='Big Smile' />.</p><p></p><blockquote><div class="quoteText">What I'm suggesting is improving on this process by stripping the fields out of types that were never referenced during all of the code paths.</div></blockquote><p></p><p>Sure, you could do that. Not sure if it helps with the List&lt;T&gt; case. I looked at the code and it's indeed possible that CultureInfo gets dragged in by an exception (see the Capacity prop). But it's unlikely that you can eliminate that by doing some static code analysis.</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/5f140ca456de41f79d6b9f2c015db285#5f140ca456de41f79d6b9f2c015db285</link>
		<pubDate>Tue, 26 Jul 2011 21:13:12 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/5f140ca456de41f79d6b9f2c015db285#5f140ca456de41f79d6b9f2c015db285</guid>
		<dc:creator>Dexter</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/Dexter/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p>@<a href="/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC#c5f140ca456de41f79d6b9f2c015db285">Dexter</a>:</p><p>Your idea about the structure per function call is interesting but it is going to bloat the code a lot (or at least the source files) since I'll need to create a unique structure for each call.</p><p>My IL to C&#43;&#43; converter is coming along nicely. I have implemented roughly 70% of all IL instructions, enough to get a very good idea about performance. I tested it with a method that calls into another method with various parameters that then loads a string and does some basic math. It ran at about 80% - 90%&nbsp;of the C# version. It was able to complete ~71M calls/sec. Not too bad, considering I have not tried to optimize the code yet.</p><p>The following have been implemented:</p><ul><li>Generics </li><li>Arrays </li><li>Function calls (static, instance, virtual). P/Invoke should be easy to add. </li><li>&quot;Proxy&quot; functions, used to handle static and instance calls on native types, like Int32, bool, etc. I chose not to create structs for these because I think it would be faster to just treat them as native types and use proxy functions (like Int32 Int32_Parse(&quot;123&quot;)). </li><li>Strings. This includes the static (internal) strings, which are really fast to load (IL ldstr). I just pre-create an array of all of the static strings and specify the index to the array in the C&#43;&#43; code. </li><li>The first part of the GC which includes making all ref types accessible in order to mark them before the sweep operations, and allowing updating of any pointers that have changed due to compacting. Classes are movable in theory, but I have not tested this yet. </li><li>About 70% of all IL instructions. </li><li>Some other stuff I forgot about. </li></ul><p>I did run into a bizarre problem though, maybe someone can help me out.</p><p>I have the following C# method:</p><p><pre class="brush: csharp">public class VirtualString : VirtualObject
{
    private UInt16 m_length;
    private unsafe char* m_buffer;

    public unsafe VirtualString(char* pStr)
        : base()
    {
        m_buffer = pStr;
        m_length = 0;

        if (m_buffer == null)
            return;

        while (*pStr&#43;&#43; != 0)
            m_length&#43;&#43;;
    }
}
</pre></p><p>The IL looks&nbsp;like this (I modified ILSpy to show the instruction operand as well):&nbsp;</p><p><pre class="brush: text">    IL_0000: 0x02                    ldarg.0
    IL_0001: 0x28 0x060000a2         call instance void PostCompiler.VirtualTypes.VirtualObject::.ctor()
    IL_0006: 0x00                    nop
    IL_0007: 0x00                    nop
    IL_0008: 0x02                    ldarg.0
    IL_0009: 0x03                    ldarg.1
    IL_000a: 0x7d 0x040001c8         stfld char* PostCompiler.VirtualTypes.VirtualString::m_buffer
    IL_000f: 0x02                    ldarg.0
    IL_0010: 0x16                    ldc.i4.0
    IL_0011: 0x7d 0x040001c7         stfld uint16 PostCompiler.VirtualTypes.VirtualString::m_length
    IL_0016: 0x02                    ldarg.0
    IL_0017: 0x7b 0x040001c8         ldfld char* PostCompiler.VirtualTypes.VirtualString::m_buffer
    IL_001c: 0x16                    ldc.i4.0
    IL_001d: 0xe0                    conv.u
    IL_001e: 0xfe01                    ceq
    IL_0020: 0x16                    ldc.i4.0
    IL_0021: 0xfe01                    ceq
    IL_0023: 0x0a                    stloc.0
    IL_0024: 0x06                    ldloc.0
    IL_0025: 0x2d 0x02               brtrue.s IL_0029

    IL_0027: 0x2b 0x24               br.s IL_004d

    IL_0029: 0x2b 0x0f               br.s IL_003a
    // loop start (head: IL_003a)
        IL_002b: 0x02                    ldarg.0
        IL_002c: 0x25                    dup
        IL_002d: 0x7b 0x040001c7         ldfld uint16 PostCompiler.VirtualTypes.VirtualString::m_length
        IL_0032: 0x17                    ldc.i4.1
        IL_0033: 0x58                    add
        IL_0034: 0xd1                    conv.u2
        IL_0035: 0x7d 0x040001c7         stfld uint16 PostCompiler.VirtualTypes.VirtualString::m_length

        IL_003a: 0x03                    ldarg.1
        IL_003b: 0x25                    dup
        IL_003c: 0x18                    ldc.i4.2
        IL_003d: 0xd3                    conv.i
        IL_003e: 0x58                    add
        IL_003f: 0x10 0x01               starg.s pStr
        IL_0041: 0x49                    ldind.u2
        IL_0042: 0x16                    ldc.i4.0
        IL_0043: 0xfe01                    ceq
        IL_0045: 0x16                    ldc.i4.0
        IL_0046: 0xfe01                    ceq
        IL_0048: 0x0a                    stloc.0
        IL_0049: 0x06                    ldloc.0
        IL_004a: 0x2d 0xdf               brtrue.s IL_002b
    // end loop

    IL_004c: 0x00                    nop

    IL_004d: 0x2a                    ret
}</pre></p><p>My IL&nbsp;-&gt; C&#43;&#43; compiler creates the following&nbsp;C&#43;&#43; code:&nbsp;</p><p><pre class="brush: cpp">/////////////////////
// T8012_VirtualString.T8012_Ctor_VirtualString()
/////////////////////
Void T8012_VirtualString::T8012_Ctor_VirtualString(VirtualThread* pThread, T8012_VirtualString** pThis, Char* pStr)
{

    // Value type locals
    Bool local0 = false;

IL_0000: // ldarg.0
IL_0001: // call: Void .ctor()
    (*pThis)-&gt;T8003_VirtualObject::T8003_Ctor_VirtualObject(pThread, (T8003_VirtualObject**)pThis);

IL_0006: // nop
IL_0007: // nop
IL_0008: // ldarg.0
IL_0009: // ldarg.1
IL_000a: // stfld: Char* m_buffer
    (*pThis)-&gt;m_buffer = pStr;

IL_000f: // ldarg.0
IL_0010: // ldc.i4.0
IL_0011: // stfld: UInt16 m_length
    (*pThis)-&gt;m_length = 0;

IL_0016: // ldarg.0
IL_0017: // ldfld: Char* m_buffer
IL_001c: // ldc.i4.0
IL_001d: // conv.u
IL_001e: // ceq
IL_0020: // ldc.i4.0
IL_0021: // ceq
IL_0023: // stloc.0
    local0 = (((*pThis)-&gt;m_buffer == (Int32)(UInt32)(0)) == 0);

IL_0024: // ldloc.0
IL_0025: // brtrue.s: 2
    if (local0 != 0)
        goto IL_0029;

IL_0027: // br.s: 36
    goto IL_004d;

IL_0029: // br.s: 15
    goto IL_003a;

IL_002b: // ldarg.0
IL_002c: // dup
IL_002d: // ldfld: UInt16 m_length
IL_0032: // ldc.i4.1
IL_0033: // add
IL_0034: // conv.u2
IL_0035: // stfld: UInt16 m_length
    (*pThis)-&gt;m_length = (Int32)(UInt16)(((Int32)(*pThis)-&gt;m_length &#43; 1));

IL_003a: // ldarg.1
IL_003b: // dup
IL_003c: // ldc.i4.2
IL_003d: // conv.i
IL_003e: // add
IL_003f: // starg.s: Char* pStr
    pStr = (Char*)(((Int32)pStr &#43; (Int32)2));

IL_0041: // ldind.u2
IL_0042: // ldc.i4.0
IL_0043: // ceq
IL_0045: // ldc.i4.0
IL_0046: // ceq
IL_0048: // stloc.0
    local0 = ((((UInt16)*(UInt16*)pStr) == 0) == 0);

IL_0049: // ldloc.0
IL_004a: // brtrue.s: -33
    if (local0 != 0)
        goto IL_002b;

IL_004c: // nop
IL_004d: // ret
    return;
}</pre></p><p>EDIT: Here is the C&#43;&#43; class declaration. Note that &quot;Char&quot; is defined as &quot;wchar_t&quot;.</p><p><pre class="brush: cpp">/////////////////////
// Original Name:  System.String
// Native Name:    T8012_VirtualString
// Native TypeRef: 0x8012
/////////////////////
class T8012_VirtualString : public T8003_VirtualObject
{
public:
    UInt16 m_length;
    Char* m_buffer;

    // Constructors
    T8012_VirtualString();
    Void T8012_Ctor_VirtualString(VirtualThread* pThread, T8012_VirtualString** pThis);
    Void T8012_Ctor_VirtualString(VirtualThread* pThread, T8012_VirtualString** pThis, Char* pStr);
    Void T8012_Ctor_VirtualString(VirtualThread* pThread, T8012_VirtualString** pThis, UInt16 length);

    // Special Functions
    virtual UInt16 GetTypeId() { return 0x8012; }
    virtual Bool IsInstanceOf(UInt16 otherId) { return otherId == 0x8012 || otherId == 0x8003; }

    static Int32 get_Length(VirtualThread* pThread, T8012_VirtualString** pThis);
};</pre></p><p>&nbsp;</p><p>The problem is that the code does something different from what the original one does. It always sets m_length to one less than what it should be. The C# version works correctly (pass in &quot;123&quot;, and m_length is set to 3), but the C&#43;&#43; version leaves m_length one too small. I'm confused as to how that can happen (pass in &quot;123&quot; and m_length is set to 2). As far as I can see, my C&#43;&#43; code does exactly what the IL tells it to do. Any ideas?</p><p>Note I can turn the IL labels and instruction comments on/off but turned both on to see the relationship to the original IL better.</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/41ee11c42e4e4029b0709f300143786d#41ee11c42e4e4029b0709f300143786d</link>
		<pubDate>Sat, 30 Jul 2011 19:37:43 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/41ee11c42e4e4029b0709f300143786d#41ee11c42e4e4029b0709f300143786d</guid>
		<dc:creator>BitFlipper</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/BitFlipper/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p>It seems to me it would work right if the instruction at IL_0029 was removed. Of course I can't change the generated code manually to fix the bug since the real bug is obviously in my compiler, but I can't figure out what it is supposedly doing wrong.</p><p>EDIT: OK I found that if I change the C# code to this:</p><p><pre class="brush: csharp">        public unsafe VirtualString(char* pStr)
            : base()
        {
            m_buffer = pStr;
            m_length = 0;

            if (m_buffer == null)
                return;

            while (*pStr != 0)
            {
                m_length&#43;&#43;;
                pStr&#43;&#43;;
            }
        }
</pre></p><p>I get the right results in the C&#43;&#43; version. This indicates that the problem is in how I handle &quot;*pStr&#43;&#43;&quot;.</p><p>EDIT EDIT:I wonder if it has something to do the the &quot;dup&quot; instructions. The way I handle dup is to clone the value of the item on the top of the &quot;virtual&quot; stack and push it so that there are two. Also, the way this virtual stack works is that it contains text that represents the local variable, parameter name&nbsp;or a previous operation. So in the case of the dup at IL_003b, the text on the stack will be &quot;pStr&quot;. So when I perform the dup operation, the two top items on the stack now contain &quot;pStr&quot;. I wonder&nbsp;whether I need to create a completely new local variable when I come across a dup operation.</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/53a5ffba69b944069b769f300147741e#53a5ffba69b944069b769f300147741e</link>
		<pubDate>Sat, 30 Jul 2011 19:52:13 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/53a5ffba69b944069b769f300147741e#53a5ffba69b944069b769f300147741e</guid>
		<dc:creator>BitFlipper</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/BitFlipper/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p></p><blockquote><div class="quoteText">I wonder if it has something to do the the &quot;dup&quot; instructions.</div></blockquote><p></p><p>Yep. If you look at the generated code for IL3A-3F you can easily note that dup has no effect. If you remove the dup then your compiler would generate identical code. That's a good indication that something isn't right.</p><p></p><blockquote><div class="quoteText">So when I perform the dup operation, the two top items on the stack now contain &quot;pStr&quot;.</div></blockquote><p></p><p>dup make a copy of the value, it seems to me that your implementation makes a copy of some sort of reference to the value.</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/1435251b1e83470e95359f3001671831#1435251b1e83470e95359f3001671831</link>
		<pubDate>Sat, 30 Jul 2011 21:47:25 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/1435251b1e83470e95359f3001671831#1435251b1e83470e95359f3001671831</guid>
		<dc:creator>Dexter</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/Dexter/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p></p><blockquote><div class="quoteText">but it is going to bloat the code a lot (or at least the source files) since I'll need to create a unique structure for each call.</div></blockquote><p></p><p>Yes the sources will be a bit bigger but I'd say not by much. Note that you need one struct per method, not per call.</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/79c7f095c01444c083819f300167e33d#79c7f095c01444c083819f300167e33d</link>
		<pubDate>Sat, 30 Jul 2011 21:50:18 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/79c7f095c01444c083819f300167e33d#79c7f095c01444c083819f300167e33d</guid>
		<dc:creator>Dexter</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/Dexter/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p></p><blockquote><div class="quoteText"><p></p><p><a class="permalink" title="Post Permalink" href="/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/1435251b1e83470e95359f3001671831">12 minutes&nbsp;ago</a>,<a href="/Niners/Dexter">Dexter</a> wrote</p><p>*snip*</p><p>Yep. If you look at the generated code for IL3A-3F you can easily note that dup has no effect. If you remove the dup then your compiler would generate identical code. That's a good indication that something isn't right.</p><p>*snip*</p><p>dup make a copy of the value, it seems to me that your implementation makes a copy of some sort of reference to the value.</p><p></p></div></blockquote><p></p><p>I'm trying to understand how it is failing but I can't. To me, those instructions want to add 2 to the value of pStr, which it clearly does via this line of C&#43;&#43; code:</p><p></p><pre class="brush: cpp">pStr = (Char*)(((Int32)pStr &#43; (Int32)2));</pre><p></p><p>Also, stepping through the code, the problem is not that pStr is incremented wrong, it is that&nbsp;m_length is incremented too late.&nbsp;You might be right but I can't figure it out.</p><p>Note&nbsp;the way&nbsp;the IL instructions are notated in the C&#43;&#43; code is that all IL instructions leading up to actual code&nbsp;are grouped together. So all instructions from IL3A-3F results in the line of code shown above. From what I can tell it is performing the correct operation on pStr. pStr showing up twice in the line of code is a direct result of the dup operation.</p><p>I think the bug must be somewhere else.</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/2357006ed0104943bec69f30016da3f7#2357006ed0104943bec69f30016da3f7</link>
		<pubDate>Sat, 30 Jul 2011 22:11:15 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/2357006ed0104943bec69f30016da3f7#2357006ed0104943bec69f30016da3f7</guid>
		<dc:creator>BitFlipper</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/BitFlipper/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p>OK, let me detail this a bit:</p><p><pre class="brush: cpp">IL_003a: // ldarg.1 - load pStr
IL_003b: // dup - duplicate pStr, now the stack contains the value of pStr twice
...
IL_003e: // add - add one of the pStrs and 2
IL_003f: // starg.s: Char* pStr - store the value on top of the stack to pStr
// !!!the original value of pStr remains on top of the stack!!!
    pStr = (Char*)(((Int32)pStr &#43; (Int32)2));IL_0041: // ldind.u2 - load from the address on top of the stack
// that is, from the original pStr
...
    local0 = ((((UInt16)*(UInt16*)pStr) == 0) == 0); // load from pStr - not the original pStr but the incremented one</pre></p><p>The net result is that since you're using the incremented pStr you're one character ahead, this is where the -1 differences comes from.</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/0cad1e07036d418084a29f300171c7ef#0cad1e07036d418084a29f300171c7ef</link>
		<pubDate>Sat, 30 Jul 2011 22:26:19 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/0cad1e07036d418084a29f300171c7ef#0cad1e07036d418084a29f300171c7ef</guid>
		<dc:creator>Dexter</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/Dexter/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p>@<a href="/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC#c0cad1e07036d418084a29f300171c7ef">Dexter</a>:</p><p>Yes, I think you are correct. I'll need to figure out how to create temporary variables in the case of dup. Not as straightforward since ref types need to be stored on the virtual stack to make sure they are not GCd, and those are prepared when the function enters.</p><p>We have company coming over so I won't be able to&nbsp;look at this again until tomorrow or so.</p><p>EDIT: Actually, this might not be so difficult. I already&nbsp;do a pre-pass and attach local variables to certain instructions (newObj, newArr, call, etc), so I can do the same for dup. Then when the function code is written, I check all instructions for local variables (either ref of value types), and create that part of the code. So all I need to do is also create a local variable for dup to store its duplicated value in.</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/0e6da105ee3d4efaaa139f300175f82d#0e6da105ee3d4efaaa139f300175f82d</link>
		<pubDate>Sat, 30 Jul 2011 22:41:34 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/0e6da105ee3d4efaaa139f300175f82d#0e6da105ee3d4efaaa139f300175f82d</guid>
		<dc:creator>BitFlipper</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/BitFlipper/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p>This dup instruction seems like it might be a problem. This is because as far as I can see, there is no way to statically determine what type of object will be on the top of the stack when&nbsp;the dup&nbsp;is encountered.&nbsp;Any part of the code could load a value on the stack, and then jump to the dup instruction.</p><p>So what kind of local variable needs to be created ahead of time to store the duplicate value? An object type? Then if&nbsp;the object on the stack is a value type, the value needs to be boxed.</p><p>Another option could be to determine all possible locations that could jump to the dup and determine what would be on the stack at that time. At runtime, choose the reserved local variable of the right type. Seems complicated but then again it probably would not be too common to find a dup where multiple areas of the code jumps to it.</p><p>Is there a better solution?</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/51f5fbbfe1904050bf3e9f31004eae32#51f5fbbfe1904050bf3e9f31004eae32</link>
		<pubDate>Sun, 31 Jul 2011 04:46:28 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/51f5fbbfe1904050bf3e9f31004eae32#51f5fbbfe1904050bf3e9f31004eae32</guid>
		<dc:creator>BitFlipper</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/BitFlipper/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p>So using ILSpy and looking at it's C# version of the method, it looks like this:</p><p><pre class="brush: csharp">public unsafe VirtualString(char* pStr)
{
    this.m_buffer = pStr;
    this.m_length = 0;
    if (this.m_buffer != null)
    {
        while (true)
        {
            char* expr_3B = pStr;
            pStr = expr_3B &#43; (IntPtr)2 / 2;
            if (*(ushort*)expr_3B == 0)
            {
                break;
            }
            this.m_length &#43;= 1;
        }
    }
}</pre></p><p>So that tells me that it clearly sees the temporary variable as the same type as pStr, and hardcoded as such. I assume that in this case it would be &quot;illegal&quot; IL if you did have a situation where you can reach the dup instruction with different types on the top of the stack. The IL documentation doesn't mention this detail at all. Neither does the book &quot;The Common Language Infrastructure Annotated Standard&quot;. It literally just says &quot;<em>The dup instruction duplicates the top element of the stack</em>&quot;. Nothing else.</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/08b2af894a454d9792199f310058a5d9#08b2af894a454d9792199f310058a5d9</link>
		<pubDate>Sun, 31 Jul 2011 05:22:45 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/08b2af894a454d9792199f310058a5d9#08b2af894a454d9792199f310058a5d9</guid>
		<dc:creator>BitFlipper</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/BitFlipper/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p>Hmm, AFAIK &quot;reach the dup instructions with different types&quot; is not allowed. See 1.8.1.3 Merging Stack States in ECMA 335.</p><p>Even if this is allowed I think it's still possible to deal with. If a basic block containing dup is reached with 2 different stack states then this can be treated as if there actually were 2&nbsp;distinct basic blocks in the first place.</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/1a17a12ff10b41328b029f3100898ad9#1a17a12ff10b41328b029f3100898ad9</link>
		<pubDate>Sun, 31 Jul 2011 08:20:46 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/1a17a12ff10b41328b029f3100898ad9#1a17a12ff10b41328b029f3100898ad9</guid>
		<dc:creator>Dexter</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/Dexter/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p></p><blockquote><div class="quoteText"><p></p><p><a class="permalink" title="Post Permalink" href="/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/1a17a12ff10b41328b029f3100898ad9">6 hours&nbsp;ago</a>,<a href="/Niners/Dexter">Dexter</a> wrote</p><p>Hmm, AFAIK &quot;reach the dup instructions with different types&quot; is not allowed. See 1.8.1.3 Merging Stack States in ECMA 335.</p><p>Even if this is allowed I think it's still possible to deal with. If a basic block containing dup is reached with 2 different stack states then this can be treated as if there actually were 2&nbsp;distinct basic blocks in the first place.</p><p></p></div></blockquote><p></p><p>I looked at section 1.8.1.3 and it mentions how types can be converted. This does help me completely because during my code analysis lets say I find an Int16 on the stack. Now I create a local variable of type Int16. But the at runtime something jumps to the dup instruction from another part of the code, and there happens to be an Int32 on the stack. While I can cast to an Int16, I'm going to lose precision. For now I'm going to go with the assumption that there will always be the same type on the stack when reaching a dup instruction.</p><p>Anyway,&nbsp;I went ahead and changed the code to create an actual local variable for each dup instruction (with the assumption that it can always only be of the type that was on the stack during the initial code analysis pass). Unfortunately I am still seeing the bug where m_length is 1 less than it should be. Below is the new generated C&#43;&#43; code. To me it seems that instruction IL_0029 should jump to instruction IL_002d instead of IL_003a. It is basically skipping the first increment on m_length.&nbsp;Can you spot the bug in my C&#43;&#43; code?</p><p>[EDIT: OK, I'm currently struggling with C9's code formatter in order to not have it put&nbsp;all of the code&nbsp;on one line. I'm selecting the code in VS, copying it, opening the &quot;&lt;/&gt;&quot; code editor dialog in C9, pasting it, selecting the language type, pressing Insert and then Submit. What am I doing wrong? For now, I'm pasting the unformatted code&nbsp;in addition to&nbsp;the single formatted line until I can figure the formatting out]</p><p>&nbsp;&nbsp;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Void T8012_VirtualString::T8012_Ctor_VirtualString(VirtualThread* pThread, T8012_VirtualString** pThis, Char* pStr)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Ref type locals<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; T8012_VirtualString** dupRef0 = (T8012_VirtualString**)&amp;pThread-&gt;StackPointer[1];</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memset(&amp;pThread-&gt;StackPointer[1], 0, sizeof(void*) * 1);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pThread-&gt;StackPointer &#43;= 1;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Value type locals<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Bool local0 = false;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Char* dupValue0 = 0;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IL_0000: // ldarg.0<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IL_0001: // call: Void .ctor()<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (*pThis)-&gt;T8003_VirtualObject::T8003_Ctor_VirtualObject(pThread, (T8003_VirtualObject**)pThis);</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IL_0006: // nop<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IL_0007: // nop<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IL_0008: // ldarg.0<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IL_0009: // ldarg.1<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IL_000a: // stfld: Char* m_buffer<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (*pThis)-&gt;m_buffer = pStr;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IL_000f: // ldarg.0<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IL_0010: // ldc.i4.0<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IL_0011: // stfld: UInt16 m_length<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (*pThis)-&gt;m_length = 0;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IL_0016: // ldarg.0<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IL_0017: // ldfld: Char* m_buffer<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IL_001c: // ldc.i4.0<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IL_001d: // conv.u<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IL_001e: // ceq<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IL_0020: // ldc.i4.0<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IL_0021: // ceq<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IL_0023: // stloc.0<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; local0 = (((*pThis)-&gt;m_buffer == (Int32)(UInt32)(0)) == 0);</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IL_0024: // ldloc.0<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IL_0025: // brtrue.s: 2<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (local0 != 0)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; goto IL_0029;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IL_0027: // br.s: 36<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; goto IL_004d;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IL_0029: // br.s: 15<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; goto IL_003a;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IL_002b: // ldarg.0<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IL_002c: // dup<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (*dupRef0) = *(pThis);</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IL_002d: // ldfld: UInt16 m_length<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IL_0032: // ldc.i4.1<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IL_0033: // add<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IL_0034: // conv.u2<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IL_0035: // stfld: UInt16 m_length<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (*pThis)-&gt;m_length = (Int32)(UInt16)(((Int32)(*dupRef0)-&gt;m_length &#43; 1));</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IL_003a: // ldarg.1<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IL_003b: // dup<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dupValue0 = pStr;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IL_003c: // ldc.i4.2<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IL_003d: // conv.i<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IL_003e: // add<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IL_003f: // starg.s: Char* pStr<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pStr = (Char*)(((Int32)dupValue0 &#43; (Int32)2));</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IL_0041: // ldind.u2<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IL_0042: // ldc.i4.0<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IL_0043: // ceq<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IL_0045: // ldc.i4.0<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IL_0046: // ceq<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IL_0048: // stloc.0<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; local0 = ((((UInt16)*(UInt16*)pStr) == 0) == 0);</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IL_0049: // ldloc.0<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IL_004a: // brtrue.s: -33<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (local0 != 0)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; goto IL_002b;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IL_004c: // nop<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IL_004d: // ret<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; goto Exit;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Exit:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pThread-&gt;StackPointer -= 1;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p><p>[<em>Does the following block of code display properly for anyone? It is all on one line for me. I filed a C9 bug report about this and referred back to this post. I'll leave this extra block of code here until the bug in the forum has been fixed.</em>]</p><p></p><pre class="brush: cpp">void T8012_VirtualString::T8012_Ctor_VirtualString(VirtualThread* pThread, T8012_VirtualString** pThis, Char* pStr){    // Ref type locals    T8012_VirtualString** dupRef0 = (T8012_VirtualString**)&amp;pThread-&gt;StackPointer[1];    memset(&amp;pThread-&gt;StackPointer[1], 0, sizeof(void*) * 1);    pThread-&gt;StackPointer &#43;= 1;    // Value type locals    Bool local0 = false;    Char* dupValue0 = 0;IL_0000: // ldarg.0IL_0001: // call: Void .ctor()    (*pThis)-&gt;T8003_VirtualObject::T8003_Ctor_VirtualObject(pThread, (T8003_VirtualObject**)pThis);IL_0006: // nopIL_0007: // nopIL_0008: // ldarg.0IL_0009: // ldarg.1IL_000a: // stfld: Char* m_buffer    (*pThis)-&gt;m_buffer = pStr;IL_000f: // ldarg.0IL_0010: // ldc.i4.0IL_0011: // stfld: UInt16 m_length    (*pThis)-&gt;m_length = 0;IL_0016: // ldarg.0IL_0017: // ldfld: Char* m_bufferIL_001c: // ldc.i4.0IL_001d: // conv.uIL_001e: // ceqIL_0020: // ldc.i4.0IL_0021: // ceqIL_0023: // stloc.0    local0 = (((*pThis)-&gt;m_buffer == (Int32)(UInt32)(0)) == 0);IL_0024: // ldloc.0IL_0025: // brtrue.s: 2    if (local0 != 0)        goto IL_0029;IL_0027: // br.s: 36    goto IL_004d;IL_0029: // br.s: 15    goto IL_003a;IL_002b: // ldarg.0IL_002c: // dup    (*dupRef0) = *(pThis);IL_002d: // ldfld: UInt16 m_lengthIL_0032: // ldc.i4.1IL_0033: // addIL_0034: // conv.u2IL_0035: // stfld: UInt16 m_length    (*pThis)-&gt;m_length = (Int32)(UInt16)(((Int32)(*dupRef0)-&gt;m_length &#43; 1));IL_003a: // ldarg.1IL_003b: // dup    dupValue0 = pStr;IL_003c: // ldc.i4.2IL_003d: // conv.iIL_003e: // addIL_003f: // starg.s: Char* pStr    pStr = (Char*)(((Int32)dupValue0 &#43; (Int32)2));IL_0041: // ldind.u2IL_0042: // ldc.i4.0IL_0043: // ceqIL_0045: // ldc.i4.0IL_0046: // ceqIL_0048: // stloc.0    local0 = ((((UInt16)*(UInt16*)pStr) == 0) == 0);IL_0049: // ldloc.0IL_004a: // brtrue.s: -33    if (local0 != 0)        goto IL_002b;IL_004c: // nopIL_004d: // ret    goto Exit;Exit:    pThread-&gt;StackPointer -= 1;}</pre><p></p><p>&nbsp;</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/270a3f8516c2480092a19f31011177aa#270a3f8516c2480092a19f31011177aa</link>
		<pubDate>Sun, 31 Jul 2011 16:35:39 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/270a3f8516c2480092a19f31011177aa#270a3f8516c2480092a19f31011177aa</guid>
		<dc:creator>BitFlipper</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/BitFlipper/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p>Hmm, you fixed the dup but the generated code is still not correct. In fact it behaves identically to the old code. It occurred to&nbsp;me now that the problem is more complicated than the buggy dup.</p><p>The IL execution stack contains values. When you do a ldarg (or any other ld) <strong>the value stored in the variable is loaded on the stack</strong>. After a ld you can modify the variable in any way you like, the stack will still contain the original value of the variable.</p><p>Your compiler treats the stack differently, it seems to store references to variables instead of values. This means that whenever you use a stack location that &quot;references&quot; a variable, you get the current value of the variable, not the original one that existed at the time ld was executed.</p><p>Let's see this in the code:</p><p><pre class="brush: cpp">dupValue0 = pStr;
pStr = (Char*)(((Int32)dupValue0 &#43; (Int32)2));
local0 = ((((UInt16)*(UInt16*)pStr) == 0) == 0);
</pre></p><p>Despite it being different, its behavior is exactly the same. The last statement still uses the modified value of pStr instead of using the original one. The correct code should look like this:</p><p><pre class="brush: cpp">oldpStr = pStr;
pStr = (Char*)(((Int32)pStr &#43; (Int32)2));
local0 = ((((UInt16)*(UInt16*)oldpStr) == 0) == 0);
</pre></p><p>PS: editor problems: don't paste from VS, it seems that it generates html that confuses the post editor. Paste the code to notepad and then copy paste from notepad. This ensures that you paste plain text and not some weird html.</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/177ac8276bef429ca5d39f31015343dd#177ac8276bef429ca5d39f31015343dd</link>
		<pubDate>Sun, 31 Jul 2011 20:35:13 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/177ac8276bef429ca5d39f31015343dd#177ac8276bef429ca5d39f31015343dd</guid>
		<dc:creator>Dexter</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/Dexter/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p>Yes I believe you are correct about my compiler really storing references to the values instead of the actual values themselves. This means I will need to create more temporary local variables to hold the actual values on the stack. This might add a lot of local variables since it might be difficult to know when it is safe to re-use a temporary variable.</p><p>So basically for any instruction that pushes either a local or parameter value, I need to create a temporary local variable.</p><p>Hopefully the compiler can optimize most of those away, although it won't be able to do it for ref types which I store on the virtual stack.</p><p>An optimization in this case could be to keep track of the temp locals during the analysis pass and mark them as &quot;free&quot; when they get popped. Then they can be re-used the next time a local or parameter needs to be pushed on the stack (if they are of the same type of course). Basically a pool of temp locals.</p><p>About the code formatting: I tried everything, including pasting into Notepad first. It simply refuses to format the code correctly. I have had success with&nbsp;both pasting directly from VS (but into the popup &quot;&lt;/&gt;&quot; code dialog), or via pasting dirently into the text editor after pasting into Notepad. I think the problem in this case is that a previous formatting tag somewhere on the page is confusing the formatter.</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/ad264dbba884461781329f31016fcd4c#ad264dbba884461781329f31016fcd4c</link>
		<pubDate>Sun, 31 Jul 2011 22:19:07 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/ad264dbba884461781329f31016fcd4c#ad264dbba884461781329f31016fcd4c</guid>
		<dc:creator>BitFlipper</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/BitFlipper/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p>OK so I changed it such that every instruction that pushes a value onto the stack uses a temporary variable. The number of locals exploded as you can see below. It is not too important, since what I'm trying to determine is whether that will solve the problem. Well, the current code <strong>still</strong> has the bug where m_length has a value of 1 less than it should be. Now I'm completely at a loss as to what could be the cause of this issue.</p><p><pre class="brush: cpp">Void T8013_VirtualString::T8013_Ctor_VirtualString(VirtualThread* pThread, T8013_VirtualString** pThis, Char* pStr)
{

    // Ref type locals
    T8013_VirtualString** temp0 = (T8013_VirtualString**)&amp;pThread-&gt;StackPointer[1];
    T8013_VirtualString** temp1 = (T8013_VirtualString**)&amp;pThread-&gt;StackPointer[2];
    T8013_VirtualString** temp3 = (T8013_VirtualString**)&amp;pThread-&gt;StackPointer[3];
    T8013_VirtualString** temp4 = (T8013_VirtualString**)&amp;pThread-&gt;StackPointer[4];
    T8013_VirtualString** temp10 = (T8013_VirtualString**)&amp;pThread-&gt;StackPointer[5];
    T8013_VirtualString** temp11 = (T8013_VirtualString**)&amp;pThread-&gt;StackPointer[6];
    T8013_VirtualString** temp23 = (T8013_VirtualString**)&amp;pThread-&gt;StackPointer[7];
    T8013_VirtualString** temp24 = (T8013_VirtualString**)&amp;pThread-&gt;StackPointer[8];
    T8013_VirtualString** temp26 = (T8013_VirtualString**)&amp;pThread-&gt;StackPointer[9];
    T8013_VirtualString** temp27 = (T8013_VirtualString**)&amp;pThread-&gt;StackPointer[10];
    T8013_VirtualString** temp33 = (T8013_VirtualString**)&amp;pThread-&gt;StackPointer[11];
    T8013_VirtualString** temp34 = (T8013_VirtualString**)&amp;pThread-&gt;StackPointer[12];

    memset(&amp;pThread-&gt;StackPointer[1], 0, sizeof(void*) * 12);
    pThread-&gt;StackPointer &#43;= 12;

    // Value type locals
    Bool local0 = false;
    Char* temp2 = null;
    Char* temp5 = null;
    UInt32 temp6 = 0;
    Int32 temp7 = 0;
    Int32 temp8 = 0;
    Bool temp9 = false;
    UInt16 temp12 = 0;
    Int32 temp13 = 0;
    UInt16 temp14 = 0;
    Char* temp15 = null;
    Char* temp16 = null;
    Int32 temp17 = 0;
    Int32 temp18 = 0;
    UInt16 temp19 = 0;
    Int32 temp20 = 0;
    Int32 temp21 = 0;
    Bool temp22 = false;
    Char* temp25 = null;
    Char* temp28 = null;
    UInt32 temp29 = 0;
    Int32 temp30 = 0;
    Int32 temp31 = 0;
    Bool temp32 = false;
    UInt16 temp35 = 0;
    Int32 temp36 = 0;
    UInt16 temp37 = 0;
    Char* temp38 = null;
    Char* temp39 = null;
    Int32 temp40 = 0;
    Int32 temp41 = 0;
    UInt16 temp42 = 0;
    Int32 temp43 = 0;
    Int32 temp44 = 0;
    Bool temp45 = false;

IL_0000: // ldarg.0
    temp23 = pThis;

IL_0001: // call: Void .ctor()
    (*pThis)-&gt;T8003_VirtualObject::T8003_Ctor_VirtualObject(pThread, (T8003_VirtualObject**)pThis);

IL_0006: // nop
IL_0007: // nop
IL_0008: // ldarg.0
    temp24 = pThis;

IL_0009: // ldarg.1
    temp25 = pStr;

IL_000a: // stfld: Char* m_buffer
    (*pThis)-&gt;m_buffer = pStr;

IL_000f: // ldarg.0
    temp26 = pThis;

IL_0010: // ldc.i4.0
IL_0011: // stfld: UInt16 m_length
    (*pThis)-&gt;m_length = 0;

IL_0016: // ldarg.0
    temp27 = pThis;

IL_0017: // ldfld: Char* m_buffer
    temp28 = (*pThis)-&gt;m_buffer;

IL_001c: // ldc.i4.0
IL_001d: // conv.u
    temp29 = (Int32)(UInt32)(0);

IL_001e: // ceq
    temp30 = (temp28 == (Char*)temp29);

IL_0020: // ldc.i4.0
IL_0021: // ceq
    temp31 = (temp30 == 0);

IL_0023: // stloc.0
    local0 = temp31;

IL_0024: // ldloc.0
    temp32 = local0;

IL_0025: // brtrue.s: 2
    if (temp32 != 0)
        goto IL_0029;

IL_0027: // br.s: 36
    goto IL_004d;

IL_0029: // br.s: 15
    goto IL_003a;

IL_002b: // ldarg.0
    temp33 = pThis;

IL_002c: // dup
    (*temp34) = *(pThis);

IL_002d: // ldfld: UInt16 m_length
    temp35 = (*temp34)-&gt;m_length;

IL_0032: // ldc.i4.1
IL_0033: // add
    temp36 = ((Int32)temp35 &#43; 1);

IL_0034: // conv.u2
    temp37 = (Int32)(UInt16)(temp36);

IL_0035: // stfld: UInt16 m_length
    (*pThis)-&gt;m_length = temp37;

IL_003a: // ldarg.1
    temp38 = pStr;

IL_003b: // dup
    temp39 = pStr;

IL_003c: // ldc.i4.2
IL_003d: // conv.i
    temp40 = (Int32)2;

IL_003e: // add
    temp41 = ((Int32)temp39 &#43; temp40);

IL_003f: // starg.s: Char* pStr
    pStr = (Char*)(temp41);

IL_0041: // ldind.u2
    temp42 = ((UInt16)*(UInt16*)pStr);

IL_0042: // ldc.i4.0
IL_0043: // ceq
    temp43 = (temp42 == (UInt16)0);

IL_0045: // ldc.i4.0
IL_0046: // ceq
    temp44 = (temp43 == 0);

IL_0048: // stloc.0
    local0 = temp44;

IL_0049: // ldloc.0
    temp45 = local0;

IL_004a: // brtrue.s: -33
    if (temp45 != 0)
        goto IL_002b;

IL_004c: // nop
IL_004d: // ret
    goto Exit;

Exit:
    pThread-&gt;StackPointer -= 12;
}</pre></p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/a26fb3a8e59247209e009f310185d3dc#a26fb3a8e59247209e009f310185d3dc</link>
		<pubDate>Sun, 31 Jul 2011 23:39:19 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/a26fb3a8e59247209e009f310185d3dc#a26fb3a8e59247209e009f310185d3dc</guid>
		<dc:creator>BitFlipper</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/BitFlipper/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p>I'm baffled. How did your compiler generate this line?</p><p><pre class="brush: cpp">IL_0041: // ldind.u2
temp42 = ((UInt16)*(UInt16*)pStr);</pre></p><p>Since we talk that the stack contains values and not variables, how did pStr got in this statement? It should be temp38 instead.</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/ff2104391a03439a97a89f320081bf0a#ff2104391a03439a97a89f320081bf0a</link>
		<pubDate>Mon, 01 Aug 2011 07:52:23 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/ff2104391a03439a97a89f320081bf0a#ff2104391a03439a97a89f320081bf0a</guid>
		<dc:creator>Dexter</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/Dexter/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p></p><blockquote><div class="quoteText"><p></p><p><a class="permalink" title="Post Permalink" href="/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/ff2104391a03439a97a89f320081bf0a">7 hours&nbsp;ago</a>,<a href="/Niners/Dexter">Dexter</a> wrote</p><p>I'm baffled. How did your compiler generate this line?</p><div class="syntaxhighlighterHolder"><div id="highlighter_642415" class="syntaxhighlighter cpp ie"><table border="0" cellspacing="0" cellpadding="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div><div class="line number2 index1 alt1">2</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="cpp plain">IL_0041: </code><code class="cpp comments">// ldind.u2</code></div><div class="line number2 index1 alt1"><code class="cpp plain">temp42 = ((UInt16)*(UInt16*)pStr);</code></div></div></td></tr></tbody></table></div></div><p>Since we talk that the stack contains values and not variables, how did pStr got in this statement? It should be temp38 instead.</p><p></p></div></blockquote><p></p><p>Yea good question. I reverted the changes I made to generate the temp variables because that was obviously not the ultimate solution.</p><p>My current idea is to load the variable names onto the stack just like I did before, but then when the variable gets popped, to step back through all of the previous instructions (up until the point it got pushed) and see if anything modified the variable since it was pushed. If so, it will go back and swap it out for a temp variable.&nbsp;It will also swap it out for a temp variable if&nbsp;any instructions inbetween are targets for any branch instruction (in case other code modified the variable).</p><p>The above solution should cut down dramatically on the number of temp locals. But now until I implement that, I might not be able to get back to this problem.</p><p>I plan to copy the above code into a simple function and play around with the code to see if using temp variables in the right places solves the problem. I'm sure it it related to not using temp variables in the right places, just like you mention. Once I understand exactly what the code is supposed to look like, I will make sure my compiler does the right thing.</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/281da5ed426042e79f239f3200fee07e#281da5ed426042e79f239f3200fee07e</link>
		<pubDate>Mon, 01 Aug 2011 15:27:58 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/281da5ed426042e79f239f3200fee07e#281da5ed426042e79f239f3200fee07e</guid>
		<dc:creator>BitFlipper</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/BitFlipper/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p></p><blockquote><div class="quoteText">&nbsp;to step back through all of the previous instructions (up until the point it got pushed)</div></blockquote><p></p><p>Hmm, this is very easy to do when the push and pop are in the same basic block. If they're in different blocks then things can get complicate. One thing that you should note about these temporaries is that they have limited lifetime. Once a temporary is popped it can be reused to store another value.</p><p>IMO, you're trying to get things working and optimize the code at the same time. I think it's better to just get things working first.</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/0569e7eaca344f1081949f320106eabe#0569e7eaca344f1081949f320106eabe</link>
		<pubDate>Mon, 01 Aug 2011 15:57:15 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/0569e7eaca344f1081949f320106eabe#0569e7eaca344f1081949f320106eabe</guid>
		<dc:creator>Dexter</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/Dexter/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p></p><blockquote><div class="quoteText"><p></p><p><a class="permalink" title="Post Permalink" href="/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/0569e7eaca344f1081949f320106eabe">10 minutes&nbsp;ago</a>,<a href="/Niners/Dexter">Dexter</a> wrote</p><p>*snip*</p><p>Hmm, this is very easy to do when the push and pop are in the same basic block. If they're in different blocks then things can get complicate.</p><p></p></div></blockquote><p></p><p>Yes that is why I think I should take into account when branch instructions come inbetween the push and pop instructions. Better to err on the safe side and create temp variables. However I don't think this will add a lot of temp variables because what I find with IL code is that the instructions are grouped pretty tightly. It pushes a few variables, then immediately pops them to perform some operation. I have not seen many cases where it pushes something then goes off to do something else first.</p><p></p><blockquote><div class="quoteText">One thing that you should note about these temporaries is that they have limited lifetime. Once a temporary is popped it can be reused to store another value.</div></blockquote><p></p><p>Yes I plan to have a temp variable pool, and when a temp is popped, it is freed back to the pool. If a following instruction needs a temp of the same type, it will get that freed variable.</p><p></p><blockquote><div class="quoteText">IMO, you're trying to get things working and optimize the code at the same time. I think it's better to just get things working first.</div></blockquote><p></p><p>True, but I always feel that if you know an area of the code needs to execute fast, at least try to keep that in mind so that you don't have to come back later and completely rewrite everything because it was the wrong approach. Also note that one of the goals of this project is to see how much I can outperform the .Net Micro Framework, so some dabbling in various performance tests&nbsp;along the way to see&nbsp;how viable all of this is, is fine I think.</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/6468cf3ddf0449ffa8239f32010c11c8#6468cf3ddf0449ffa8239f32010c11c8</link>
		<pubDate>Mon, 01 Aug 2011 16:16:00 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/6468cf3ddf0449ffa8239f32010c11c8#6468cf3ddf0449ffa8239f32010c11c8</guid>
		<dc:creator>BitFlipper</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/BitFlipper/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p></p><blockquote><div class="quoteText"><p></p><p>Yes I plan to have a temp variable pool, and when a temp is popped, it is free back to the pool. If a following instruction needs a temp of the same size, it will get that freed variable.</p><p></p></div></blockquote><p></p><p>Why? The compiler will find it much easier to optimise your temporaries to use less registers and stack space (on release builds) than you will, but doing it manually will force to compiler to take worse optimisations.</p><p>Make sure you don't ever do performance testing on a debug build, or you'll get a really strange impression of what code is fast and what code is slow.</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/bc0b217ff6aa4f149e659f320113fa1d#bc0b217ff6aa4f149e659f320113fa1d</link>
		<pubDate>Mon, 01 Aug 2011 16:44:48 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/bc0b217ff6aa4f149e659f320113fa1d#bc0b217ff6aa4f149e659f320113fa1d</guid>
		<dc:creator>evildictaitor</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/evildictaitor/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p>@<a href="/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC#cbc0b217ff6aa4f149e659f320113fa1d">evildictaitor</a>:</p><p>The C&#43;&#43; compiler will not be able to optimize my ref types away (and it shouldn't), because I store them on the virtual stack. Creating large numbers of temp ref types is not ideal because that will give more work to the GC, in addition to requiring a larger virtual stack (memory is quite limited on a microcontroller).</p><p>It should not be too difficult to implement a mechanism like I described to reduce the number of temp variables used. In addition, it makes debugging the C&#43;&#43; code easier if there aren't a huge amount of temp variables. Also remember that the C# method we are looking at is only about&nbsp; 6&nbsp;lines of code, and it created&nbsp;45 temp variables. This is going to get insane with complex code.</p><p>BTW, I had a typo in my previous post, which I fixed:</p><p><em>If a following instruction needs a temp of the same <strong>type</strong> [size -&gt; type], it will get that freed variable.</em></p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/56426f7c4ae5421fa20e9f320141837b#56426f7c4ae5421fa20e9f320141837b</link>
		<pubDate>Mon, 01 Aug 2011 19:30:35 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/56426f7c4ae5421fa20e9f320141837b#56426f7c4ae5421fa20e9f320141837b</guid>
		<dc:creator>BitFlipper</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/BitFlipper/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p>OK I was able to fix the problem with the temp variables, although I'd need some thorough testing to verify that it works in all cases. Basically, what I needed to do is whenever an argument, local or static variable gets assigned, I need to check whether that same variable is currently on the stack. If so, I need to get a new temp variable and assigne it the value of the variable, and also replace the previous variable with the temp variable&nbsp;everywhere it shows up on the stack. Below is&nbsp;what the fixed function looks like:</p><p><pre class="brush: cpp">Void VirtualString::Ctor_VirtualString(VirtualThread* pThread, VirtualString** pThis, Char* pStr)
{
    // Ref type locals
    VirtualString** temp0 = (VirtualString**)&amp;pThread-&gt;StackPointer[1];

    memset(&amp;pThread-&gt;StackPointer[1], 0, sizeof(void*) * 1);
    pThread-&gt;StackPointer &#43;= 1;

    // Value type locals
    Bool local0 = false;
    Char* temp1 = null;
    Char* temp2 = null;

IL_0000: // ldarg.0
IL_0001: // call Void .ctor()
    (*pThis)-&gt;VirtualObject::Ctor_VirtualObject(pThread, (VirtualObject**)pThis);

IL_0006: // nop
IL_0007: // nop
IL_0008: // ldarg.0
IL_0009: // ldarg.1
IL_000a: // stfld Char* m_staticBuffer
    (*pThis)-&gt;m_staticBuffer = pStr;

IL_000f: // ldarg.0
IL_0010: // ldc.i4.0
IL_0011: // stfld UInt16 m_length
    (*pThis)-&gt;m_length = 0;

IL_0016: // ldarg.0
IL_0017: // ldfld Char* m_staticBuffer
IL_001c: // ldc.i4.0
IL_001d: // conv.u
IL_001e: // ceq
IL_0020: // ldc.i4.0
IL_0021: // ceq
IL_0023: // stloc.0
    local0 = (((*pThis)-&gt;m_staticBuffer == (Int32)(UInt32)(0)) == 0);

IL_0024: // ldloc.0
IL_0025: // brtrue.s 2
    if (local0 != 0)
        goto IL_0029;

IL_0027: // br.s 36
    goto IL_004d;

IL_0029: // br.s 15
    goto IL_003a;

IL_002b: // ldarg.0
IL_002c: // dup
    (*temp0) = *(pThis);

IL_002d: // ldfld UInt16 m_length
IL_0032: // ldc.i4.1
IL_0033: // add
IL_0034: // conv.u2
IL_0035: // stfld UInt16 m_length
    (*pThis)-&gt;m_length = (Int32)(UInt16)(((Int32)(*temp0)-&gt;m_length &#43; 1));

IL_003a: // ldarg.1
IL_003b: // dup
    temp1 = pStr;

IL_003c: // ldc.i4.2
IL_003d: // conv.i
IL_003e: // add
IL_003f: // starg.s Char* pStr
    temp2 = pStr;
    pStr = (Char*)(((Int32)temp1 &#43; (Int32)2));

IL_0041: // ldind.u2
IL_0042: // ldc.i4.0
IL_0043: // ceq
IL_0045: // ldc.i4.0
IL_0046: // ceq
IL_0048: // stloc.0
    local0 = ((((UInt16)*(UInt16*)temp2) == 0) == 0);

IL_0049: // ldloc.0
IL_004a: // brtrue.s -33
    if (local0 != 0)
        goto IL_002b;

IL_004c: // nop
IL_004d: // ret
    goto Exit;

Exit:
    pThread-&gt;StackPointer -= 1;
}</pre></p><p>&nbsp;</p><p>Note at line IL_003f, a temp local is used to store the value of pStr before it is assigned a different value. At line IL_0048, that temp local is used instead of the now changed pStr. This fixes the bug with the off-by-one I was seeing previously.</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/74f733d2dd6b4c73baae9f3500595659#74f733d2dd6b4c73baae9f3500595659</link>
		<pubDate>Thu, 04 Aug 2011 05:25:16 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/74f733d2dd6b4c73baae9f3500595659#74f733d2dd6b4c73baae9f3500595659</guid>
		<dc:creator>BitFlipper</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/BitFlipper/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p>On a different but related topic...</p><p>I was wondering how to deal with debugging an application written for a microcontroller while using this .Net -&gt; C&#43;&#43; compiler. Previously I was thinking that I would try to figure out what the .Net Micro Framework does to enable debugging, but I think that is a big task since&nbsp;I'll probably need to create a VS debugging plugin etc. Also it would be difficult (although not impossible) to reliable get the state of all variables etc while in the debugger.</p><p>So I thought of a completely different way to enable debugging using this .Net -&gt; C&#43;&#43; compiler. Basically, the idea is to not even do the .Net -&gt; C&#43;&#43; compilation at all during debugging. Instead, there will be a &quot;core&quot; (or kernel) component running on the microcontroller that contains all of the &quot;internal&quot; calls that you can make to, say, set or get the state of an IO pin. I already implemented &quot;internal&quot; calls in my compiler (which is not the same as PInvoke of course). So basically I can create a class in C# called InOutPin, which allows you to get or set the state of a specific pin. Inside this class, I have a method called, say, &quot;GetPinState&quot;. I add a special attribute, like this:</p><p><pre class="brush: csharp">[VirtualCallAttribute(IsInternalCall = true, FunctionName = &quot;IOPins::GetState&quot;)]
bool GetPinState(int pinIndex)
{
    // Actual C# code that will execute while running in &quot;debug&quot; mode in VS.
    // This code will not be compiled to C&#43;&#43;, instead it will call the specified C&#43;&#43; function directly
}</pre></p><p>So what happens is that if you run the application inside VS, it will simply treat GetPinState&nbsp;like any other method and execute the code it contains. On the other hand, when that method gets compiled to C&#43;&#43; code, that attribute will tell the compiler that this is actually an internal call and will call the specified function mentioned in the FunctionName parameter. All of this is already implemented and works (I did a bunch of string functions, like creating, concatenating etc).</p><p>So my idea is to take advantage of that in the sense that I can add code into GetPinState (the C# version), that will make the same call into the microcontroller via a serial or USB port. So basically, when you start running the application in VS, the library you use will contain code to connect to the microcontroller which is running the kernel. That&nbsp;kernel will know when the debugger has connected and listen for any calls.&nbsp;Once the connection is made, if you then call GetPinState, the call will be remoted to the microcontroller which will then call the corresponding C&#43;&#43; function to get the pin's state.</p><p>I don't foresee any real reasons why such an approach won't work, but there are some pros and cons that I can think of:</p><p>Pros:</p><ul><li>You can use VS to debug, including using advanced features like edit and continue. As far as VS is concerned, it's just another <em>full</em> .Net application. </li><li>Compilation and debugging should be fast, just a like any other .Net application (at least the parts that aren't calling into the microcontroller). You don't need to wait for your code to be compiled and first downloaded the microcontroller like you do now. </li></ul><p>Cons:</p><ul><li>Remoted calls to the microcontroller might be slow (Netduino supposedly supports up to 3M baud). Not sure how slow this will be, but you probably won't be toggling pins at MHz speeds (the fastest speed you can toggle a pin in .Net MF on a Netduino is about 9KHz, compared to about 4-5MHz with native code on the same microcontroller). </li><li>You won't be debugging the compiled C&#43;&#43; code, you will be debugging the pre-compiled C# code. Because of this, you will be relying on the&nbsp;assumption that the .Net -&gt; C&#43;&#43; compiler&nbsp;won't introduce any bugs into your code. Which is unlikely. This may or may not be a problem. </li><li>You won't know that the code you are writing isn't going to work on the microcontroller until you actually try to compile it with the special Release build.&nbsp;You might be using a class for which there isn't a version available, and you&nbsp;might be happily using WCF, XNA&nbsp;or WPF but only realize later on that it can't be compiled to C&#43;&#43;. </li></ul><p>Anyway to me this solution sounds much easier to implement, and unless I'm missing something big, I don't see how it won't be able to work.</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/33e0b9ba0ccc4f5c9a189f350066d4b8#33e0b9ba0ccc4f5c9a189f350066d4b8</link>
		<pubDate>Thu, 04 Aug 2011 06:14:23 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/33e0b9ba0ccc4f5c9a189f350066d4b8#33e0b9ba0ccc4f5c9a189f350066d4b8</guid>
		<dc:creator>BitFlipper</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/BitFlipper/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p></p><blockquote><div class="quoteText">If so, I need to get a new temp variable and assigne it the value of the variable, and also replace the previous variable with the temp variable everywhere it shows up on the stack.</div></blockquote><p></p><p>Mmm, seems like a cool solution to me.</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/92604a85271e4fc899509f3500be7d52#92604a85271e4fc899509f3500be7d52</link>
		<pubDate>Thu, 04 Aug 2011 11:33:33 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/92604a85271e4fc899509f3500be7d52#92604a85271e4fc899509f3500be7d52</guid>
		<dc:creator>Dexter</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/Dexter/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p></p><blockquote><div class="quoteText"><p></p><p>The C&#43;&#43; compiler will not be able to optimize my ref types away (and it shouldn't), because I store them on the virtual stack. Creating large numbers of temp ref types is not ideal because that will give more work to the GC, in addition to requiring a larger virtual stack (memory is quite limited on a microcontroller).</p><p></p></div></blockquote><p></p><p>Then don't put them on a virtual stack. Why would adding more temporaries hurt the GC? If the C/C&#43;&#43; compiler detects that two temporary registers hold the same value then they alias them and you end up with fewer local variables. The C/C&#43;&#43; also agressively reuses registers and stack positions for variables that die before other ones become live on release build (this is the reason why debugging variables doesn't always work on release builds).</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/50a150590cbc49fa823b9f360085a919#50a150590cbc49fa823b9f360085a919</link>
		<pubDate>Fri, 05 Aug 2011 08:06:38 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/50a150590cbc49fa823b9f360085a919#50a150590cbc49fa823b9f360085a919</guid>
		<dc:creator>evildictaitor</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/evildictaitor/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p></p><blockquote><div class="quoteText"><p></p><p><a class="permalink" title="Post Permalink" href="/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/50a150590cbc49fa823b9f360085a919">15 hours&nbsp;ago</a>,<a href="/Niners/evildictaitor">evildictait​or</a> wrote</p><p>*snip*</p><p>Then don't put them on a virtual stack. Why would adding more temporaries hurt the GC? If the C/C&#43;&#43; compiler detects that two temporary registers hold the same value then they alias them and you end up with fewer local variables. The C/C&#43;&#43; also agressively reuses registers and stack positions for variables that die before other ones become live on release build (this is the reason why debugging variables doesn't always work on release builds).</p><p></p></div></blockquote><p></p><p>That won't work because the way the GC works is that it should be able to get to any object that is currently in use. If I create a new object, but don't put a reference to it&nbsp;on the virtual stack, and the GC does a Mark/Sweep operation, that object's Mark function&nbsp;will never be called (via enumerating the objects on the virtual stack), and hence&nbsp;it's Mark flag will never be set. Then during the Sweep phase, the object will be collected.</p><p>I don't believe the C&#43;&#43; compiler can or should optimize the ref types. Value types are fine, that&nbsp;can't cause any side-effects.</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/fa3419fa205e4112a6979f360188b500#fa3419fa205e4112a6979f360188b500</link>
		<pubDate>Fri, 05 Aug 2011 23:49:48 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/fa3419fa205e4112a6979f360188b500#fa3419fa205e4112a6979f360188b500</guid>
		<dc:creator>BitFlipper</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/BitFlipper/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p>OK things are going quite well (except for the problem mentioned below). I've implemented GC functionality up to but not including compacting. Basically you can now do this:</p><p><pre class="brush: csharp">for (var idx = 0; idx &lt; 10000000; idx&#43;&#43;)
{
    var obj = new SomeClass();
}</pre></p><p>The GC will&nbsp;dispose of the objects that are no longer rooted. It also makes a Finalize call into each object but right now it isn't yet hooked up to the class's destructor. That should be easy.</p><p>I was implementing boxing/unboxing but this exposed a flaw in my current compiler (boxing/unboxing works quite well). The problem is that code can branch somewhere into the &quot;groupings&quot; of instructions that ultimately becomes one of more lines of C&#43;&#43; code. While testing the following method:</p><p>&nbsp;</p><p><pre class="brush: csharp">static void Main(string[] args)
{
     var result = BoxTest(false);
}</pre></p><p><br><pre class="brush: csharp">private static int BoxTest(object obj)
{
    if (obj is bool)
        return (bool)obj ? 1 : 2;
            
    if (obj == null)
        return 3;
    else
        return 4;
}
</pre></p><p>&nbsp;</p><p>I found that my compiled C&#43;&#43; version was not doing the right thing. Here is the generated C&#43;&#43; code:&nbsp;</p><p><pre class="brush: cpp">Void Usr_Program::Usr_Main(VirtualThread* pThread, InternalArray&lt;VirtualString*&gt;** args)
{
    // Ref type locals
    VirtualObject** temp0 = (VirtualObject**)&amp;pThread-&gt;StackPointer[1];

    memset(&amp;pThread-&gt;StackPointer[1], 0, sizeof(void*) * 1);
    pThread-&gt;StackPointer &#43;= 1;

    // Value type locals
    Int32 local0 = 0;
    Int32 valueRetVal0 = 0;

IL_0000: // nop
IL_0001: // ldc.i4.0
IL_0002: // box System.Boolean
    pThread-&gt;AllocObject(sizeof(VirtualBox&lt;Bool&gt;), (VirtualObject**)temp0);
    new (*temp0) VirtualBox&lt;Bool&gt;(0x0005, 0);

IL_0007: // call Int32 BoxTest(System.Object)
    valueRetVal0 = Usr_Program::Usr_BoxTest(pThread, temp0);

IL_000c: // stloc.0
    local0 = valueRetVal0;

IL_000d: // ret
    goto Exit;

Exit:
    pThread-&gt;StackPointer -= 1;
}</pre></p><p>&nbsp;</p><p><pre class="brush: cpp">Int32 Usr_Program::Usr_BoxTest(VirtualThread* pThread, VirtualObject** obj)
{
    // Value type locals
    Int32 local0 = 0;
    Bool local1 = false;

IL_0000: // nop
IL_0001: // ldarg.0
IL_0002: // isinst System.Boolean
IL_0007: // ldnull
IL_0008: // cgt.un
IL_000a: // ldc.i4.0
IL_000b: // ceq
IL_000d: // stloc.1
    local1 = ((((obj &amp;&amp; (*obj)-&gt;IsInstanceOf(0x0005)) ? obj : null) &gt; null)) == (0);

IL_000e: // ldloc.1
IL_000f: // brtrue.s 15
    if (local1 != 0)
        goto IL_0020;

IL_0011: // ldarg.0
IL_0012: // unbox.any System.Boolean
IL_0017: // brtrue.s 3
    if ((((VirtualBox&lt;Bool&gt;*)(*obj))-&gt;Value) != 0)
        goto IL_001c;

IL_0019: // ldc.i4.2
IL_001a: // br.s 1
    goto IL_001d;

IL_001c: // ldc.i4.1
IL_001d: // stloc.0
    local0 = 1;

IL_001e: // br.s 19
    goto IL_0033;

IL_0020: // ldarg.0
IL_0021: // ldnull
IL_0022: // ceq
IL_0024: // ldc.i4.0
IL_0025: // ceq
IL_0027: // stloc.1
    local1 = ((obj) == (null)) == (0);

IL_0028: // ldloc.1
IL_0029: // brtrue.s 4
    if (local1 != 0)
        goto IL_002f;

IL_002b: // ldc.i4.3
IL_002c: // stloc.0
    local0 = 3;

IL_002d: // br.s 4
    goto IL_0033;

IL_002f: // ldc.i4.4
IL_0030: // stloc.0
    local0 = 4;

IL_0031: // br.s 0
    goto IL_0033;

IL_0033: // ldloc.0
IL_0034: // ret
    return local0;

}</pre></p><p>What I found was that the unboxing call at line IL_0017 was not being called at all. In fact, the compiler didn't even bother to compile that part of the code at all (it's completely missing from the disassembly). Closer inspection shows that as far as the test on line IL_0017 goes, it will always end up going to line IL_001d, hence it doesn't even bother.</p><p>Obviously this is the wrong end result, because in the C# version of the method, the&nbsp;check for true/false&nbsp;has a real result on the return value of the method.</p><p>I'm trying to think of ways to change the compiler to produce correct code, but so far I haven't thought of a good solution yet. This is obviously a solvable problem because all IL -&gt; native code compilers have solved this problem. There shouldn't be any reason why I can't create functional C&#43;&#43; code as opposed to functional&nbsp;native code (if anything it should be easier).</p><p>Anyway, one possible solution I've been thinking about is to take advantage of the fact that I've already done a pre-pass at this point and I know exactly which instructions are branch targets. I can use this information to break the instructions into smaller groups. The problem with this is that it is not always possible (or obvious) to break instructions into smaller groups. For instance, in this case I need to break the instructions between IL_001c and IL_001d (each one is a branch target). But how do I write IL_001c in C&#43;&#43; code?</p><p>I'm just curious, what method is used to compile IL to native code? I'm using an evaluation&nbsp;stack based approach that accumulates&nbsp;expressions until an instruction comes along that does some real work, like storing, comparing, branching etc, based on the&nbsp;evaluation stack contents. And only then it&nbsp;output the code to perform that operation.&nbsp;Is there a different approach? At least the evaluation stack seems logical to me since it follows the&nbsp;same evaluation stack based approach of the IL&nbsp;very closely.</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/d0f4691f4bf2463d801c9f37003f4c28#d0f4691f4bf2463d801c9f37003f4c28</link>
		<pubDate>Sat, 06 Aug 2011 03:50:27 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/d0f4691f4bf2463d801c9f37003f4c28#d0f4691f4bf2463d801c9f37003f4c28</guid>
		<dc:creator>BitFlipper</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/BitFlipper/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p></p><blockquote><div class="quoteText">Closer inspection shows that as far as the test on line IL_0017 goes, it will always end up going to line IL_001d, hence it doesn't even bother.</div></blockquote><p></p><p>The test is not the problem, the problem is that the ldc 2 at IL_0019 is nowhere to be found in the generated C&#43;&#43; code. My guess is that the reason for this bug is the following:</p><p></p><blockquote><div class="quoteText">I'm using an evaluation stack based approach that accumulates expressions until an instruction comes along that does some real work, like storing</div></blockquote><p></p><p>The value (expression) that gets stored here was defined in two different places. Somehow you lost track of one of those definitions and ended up always writing 1. IL_001D can be reached with 2 different stack states but the generated code accounts for only for one.</p><p></p><blockquote><div class="quoteText">I'm just curious, what method is used to compile IL to native code?</div></blockquote><p></p><p>I don't know exactly what CLR does but what I'd do is convert the IL to some intermediate representation where there's no stack and where all instruction operands are explicit instead of implicit. Such explicit representation are far more easy to reason about.</p><p>You may say that you aren't writing a compiler but getting familiar with some compiler techniques would be a good idea. Reading the code generation chapter(s) from the &quot;Dragon Book&quot; (<a href="http://dragonbook.stanford.edu/">http://dragonbook.stanford.edu/)</a> is advisable.</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/5b7f4620d4374d2f87b09f37008e4e5c#5b7f4620d4374d2f87b09f37008e4e5c</link>
		<pubDate>Sat, 06 Aug 2011 08:38:07 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/5b7f4620d4374d2f87b09f37008e4e5c#5b7f4620d4374d2f87b09f37008e4e5c</guid>
		<dc:creator>Dexter</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/Dexter/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p>@<a href="/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC#c5b7f4620d4374d2f87b09f37008e4e5c">Dexter</a>:</p><p></p><blockquote><div class="quoteText"><p></p><p><a class="permalink" title="Post Permalink" href="/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/5b7f4620d4374d2f87b09f37008e4e5c">5 hours&nbsp;ago</a>,<a href="/Niners/Dexter">Dexter</a> wrote</p><p>*snip*</p><p>The test is not the problem, the problem is that the ldc 2 at IL_0019 is nowhere to be found in the generated C&#43;&#43; code. My guess is that the reason for this bug is the following:</p><p>*snip*</p><p>The value (expression) that gets stored here was defined in two different places. Somehow you lost track of one of those definitions and ended up always writing 1. IL_001D can be reached with 2 different stack states but the generated code accounts for only for one.</p><p></p></div></blockquote>&nbsp;<p></p><p>Yes that is what I was trying to say, and I understand the problem in this case. The IL sees the two instructions as two distinct locations to jump to, while in the currently compiled C&#43;&#43; code, it translates to just one location, hence the C&#43;&#43; compiler rightly sees the test as superfluous and removes it.</p><p>Interestingly, if you run the debug version of ILSpy,&nbsp;in addition the the &quot;IL&quot; and &quot;C#&quot; decompile options, it has an additional 53 (yes, I counted them) decompile options of various stages of transforms and optimizations. Here is what the method looks like when selecting the decompile option &quot;<em>ILAst (after InlineVariables</em>)&quot;:</p><p><em>[sorry once again the C9 forum insists on putting everything on one line, so using plaintext]<br></em><em>--------------------------</em></p><p>arg_1D_0<br>var_0_1D : int32<br><br>&nbsp;&nbsp;&nbsp;&nbsp;brtrue(IL_20, ceq(cgt.un(isinst([mscorlib]System.Boolean, ldloc(obj)), ldnull()), ldc.i4(0)))<br>&nbsp;&nbsp;&nbsp;&nbsp;brtrue(IL_1C, unbox.any([mscorlib]System.Boolean, ldloc(obj)))<br><br>&nbsp;&nbsp;&nbsp;&nbsp;arg_1D_0 = ldc.i4(2)<br>&nbsp;&nbsp;&nbsp;&nbsp;br(IL_1D)<br><br>IL_1C:<br>&nbsp;&nbsp;&nbsp;&nbsp;arg_1D_0 = ldc.i4(1)<br><br>IL_1D:<br>&nbsp;&nbsp;&nbsp;&nbsp;stloc(var_0_1D, arg_1D_0)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;br(IL_33)<br><br>IL_20:<br>&nbsp;&nbsp;&nbsp;&nbsp;brtrue(IL_2F, ceq(ceq(ldloc(obj), ldnull()), ldc.i4(0)))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stloc(var_0_1D, ldc.i4(3))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;br(IL_33)<br><br>IL_2F:<br>&nbsp;&nbsp;&nbsp;&nbsp;stloc(var_0_1D, ldc.i4(4))<br><br>IL_33:<br>&nbsp;&nbsp;&nbsp;&nbsp;ret(ldloc(var_0_1D))</p><p><em>--------------------------</em></p><p>So it used a temp variable called IL_1D_0 to store the result of both&nbsp;expressions lldc.i4(2) and ldc.i4(1). So the variable was&nbsp;associated with the instruction at IL_1D. This is similar to what I was trying by assigning the expression to temp variables, all I have to do now is figure out how to know when to use the same temp variable as opposed to grabbing a new one each time.</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/5c04877e0ae24965998f9f3700ec3332#5c04877e0ae24965998f9f3700ec3332</link>
		<pubDate>Sat, 06 Aug 2011 14:19:58 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/5c04877e0ae24965998f9f3700ec3332#5c04877e0ae24965998f9f3700ec3332</guid>
		<dc:creator>BitFlipper</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/BitFlipper/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p>Hmm, did some benchmarks and got some interesting results. I have the following C# method:</p><p><pre class="brush: csharp">private static int PerformanceTest3()
{
    var result = 0;

    for (var idx1 = 0; idx1 &lt; 30000; idx1&#43;&#43;)
    {
        var strResult = &quot;&quot;;

        for (var idx2 = 0; idx2 &lt; 1000; idx2&#43;&#43;)
        {
            var intVal = 0;
            strResult = idx2.ToString();
            Int32.TryParse(strResult, out intVal);
            result &#43;= intVal;
        }
    }

    return result;
}</pre></p><p>The release build of this the .Net method takes about 7 seconds to&nbsp;complete on my system. When I compile this using my .Net -&gt; C&#43;&#43; compiler, the debug build takes about 45 seconds to complete, but the release build <em>only takes 3 seconds</em> to complete - more than twice as fast as the .Net version.</p><p>Initially I though some optimizations must have resulted in the code not doing the right thing, but I confirmed that even with the C&#43;&#43; version that runs for just 3 seconds, that the return value is correct (2100098112 in this case). There is no way the C&#43;&#43; compiler can optimize away the ToString and TryParse calls.</p><p>I am checking whether strResult is null in my Int32::TryParse call, and off the top of my head I can't see what else I should be checking. Also, I don't yet&nbsp;have a try/catch mechanism in place but I already have an idea how that will work and it should not add a lot of overhead.&nbsp;</p><p>My guess is that the .Net version is probably getting bogged down while dealing with culture related conversions when converting the value from int to string and back.</p><p>Anyway, quite encouraging results.</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/85c4bd9d432840fc93df9f3c018af56e#85c4bd9d432840fc93df9f3c018af56e</link>
		<pubDate>Thu, 11 Aug 2011 23:58:00 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/85c4bd9d432840fc93df9f3c018af56e#85c4bd9d432840fc93df9f3c018af56e</guid>
		<dc:creator>BitFlipper</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/BitFlipper/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p>To all participants on this thread, thanks for taking the time to post.&nbsp; Please continue.</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/57cc5095cc944f959ae29f3d0155d2a8#57cc5095cc944f959ae29f3d0155d2a8</link>
		<pubDate>Fri, 12 Aug 2011 20:44:32 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/57cc5095cc944f959ae29f3d0155d2a8#57cc5095cc944f959ae29f3d0155d2a8</guid>
		<dc:creator>Dave Williamson</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/davewill/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p>OK I spent a lot of time fixing various issues with the .Net -&gt; C&#43;&#43; compiler. Basically I ran into issues related to how different code paths through&nbsp;the same&nbsp;function can load different values onto the stack from different locations (and different variables), and hence I had to basically change my code so that each possible code path is evaluated. If two or more instructions load different values onto the stack, then a temp variable must be used, and then all places where that value can be popped must work back and ensure that all other places where that value gets pushed use the same temp variable.</p><p>I had to rewrite a lot of the code because it just wasn't flexible enough to handle these kinds of scenarios. The updated code allows one to go back and retroactively modify variables (change constants to temps, swap&nbsp;a set of&nbsp;stack values for a temp, etc).</p><p>This has complicated the code a lot but I guess that is typical of any type of&nbsp;compiler. Anyway, it seems to work fine now, and in the process it automatically fixed the issue mentioned above where the &quot;jump to&quot; location doesn't really exist and therefore the result could be incorrect.</p><p>Off to the next issue... I want to implement context switching, keeping in mind that ultimately this will run on a microcontroller that has just one thread. For now, I'll do this on x86 since I use it&nbsp;to test all of this stuff. Once I get it to work, I just need to have ifdef sections for the different supported processors.</p><p>For x86, I found <a href="https://charm.cs.illinois.edu/papers/migThreads.www/node24.html#fig:fastswitch">this old web page</a>.&nbsp;I'm not familiar with &quot;AT&amp;T assembly syntax&quot;, so I'm not 100% sure how to convert that to&nbsp;the Intel format that&nbsp;VS will understand. Here's my 1st attempt based on the linked page:</p><p><pre class="brush: cpp">void VirtualMachine::SwitchContext(VirtualThread* pOld, VirtualThread* pNew)
{
    Int32 oldStack = (Int32)pOld-&gt;NativeStack; 
    Int32 newStack = (Int32)pNew-&gt;NativeStack; 
    
    __asm
    {
        mov eax, oldStack;
        mov ecx, newStack;

        // Save registers
        push ebp
        push ebx
        push esi
        push edi

        // Save old stack
        mov eax, esp

        // Load new stack
        mov esp, ecx 

        // Restore registers
        pop edi
        pop esi
        pop ebx
        pop ebp
        ret
    }
}</pre></p><p>I'm a bit rusty on my x86 assembly, but what I don't understand is that the code is moving oldStack into eax, then a few lines later, esp is moved into eax. Is&nbsp;my translation of the original code&nbsp;even correct?</p><p>Also, there seems to be a bit of an chicken and egg problem here. Obviously this code should only be called to switch between two threads that have already been running previously. So what I'm missing right now is a way to set up these stacks for the initial run (in my simulated Thread.Start call, which is implemented except for the fact that it doesn't yet set up the native stack).</p><p>In addition, my assumption here is that my VirtualThread class will not only hold the &quot;virtual stack&quot;, but also this native stack that will be used to do context switching for each thread. Up until now there was only one &quot;thread&quot; so it was just using whatever the stack was of the running thread.</p><p>Interestingly, the compiler gives me this warning:</p><p><pre class="brush: text">warning C4731: 'VirtualMachine::SwitchContext' : frame pointer register 'ebp' modified by inline assembly code</pre></p><p>I assume this is a good thing because that is exactly what the intention was? Or is this a legit warning that I'm actually doing something wrong?</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/5f6dd097baad499880b49f3f01708bd2#5f6dd097baad499880b49f3f01708bd2</link>
		<pubDate>Sun, 14 Aug 2011 22:21:50 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/5f6dd097baad499880b49f3f01708bd2#5f6dd097baad499880b49f3f01708bd2</guid>
		<dc:creator>BitFlipper</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/BitFlipper/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p></p><blockquote><div class="quoteText">Interestingly, the compiler gives me this warning:</div></blockquote><p></p><p>I'll answer this first because the rest can't be done properly with this in the way. The compiler can generate prolog/epilog code for a function:</p><p>SwitchContext: <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;push ebp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; save the previous frame pointer<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mov&nbsp;&nbsp;ebp, esp&nbsp;&nbsp;&nbsp;&nbsp;; setup the frame pointer<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sub&nbsp;&nbsp;esp, 8&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;; space for local variables<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;; function code<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mov&nbsp;&nbsp;esp, ebp&nbsp;&nbsp;&nbsp;&nbsp;; restore the stack pointer<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pop&nbsp;&nbsp;ebp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; restore the frame pointer<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret</p><p><br>Now it should be obvious what's the warning about. The compiler uses ebp for its own purposes and warns you if you change it in inline asm. This compiler generated code can be a problem when you want to implement context switching because it affects the stack layout. You can implement SwitchContext even if such code is present but creating the stack for a new thread will be a problem because you don't know what stack layout SwitchContext expects.</p><p>A possible solution is to use __declspec(naked) (which prevents such code from being generated) and __fastcall (which causes the first 2 arguments of the function to be passed in registers ecx and edx).</p><p></p><blockquote><div class="quoteText">I'm a bit rusty on my x86 assembly, but what I don't understand is that the code is moving oldStack into eax, then a few lines later, esp is moved into eax. Is my translation of the original code even correct?</div></blockquote><p></p><p>Nope. In the original version there were some parathesis which you ignored. Something like mov %esp, (%eax) converts to mov [eax], esp.</p><p>Here's an example that uses __declspec(naked) and __fastcall):</p><p>__declspec(naked) void __fastcall SwitchContext(VirtualThread* pOld, VirtualThread* pNew)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;// N.B. the following code assumes that NativeStack is at offset 4 in VirtualThread. If that's not true<br>&nbsp;&nbsp;&nbsp;&nbsp;// then the appropiate offset needs to be used when storing/loading the stack.<br>&nbsp;&nbsp;&nbsp;&nbsp;__asm<br>&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Save registers<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;push ebp<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;push ebx<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;push esi<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;push edi<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Save old stack<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mov [ecx&#43;4], esp&nbsp;&nbsp;&nbsp;&nbsp;// store to pOld-&gt;NativeStack<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Load new stack<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mov esp, [edx&#43;4]&nbsp;&nbsp;&nbsp;&nbsp;// load from pNew-&gt;NativeStack<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Restore registers<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pop edi<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pop esi<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pop ebx<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pop ebp<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>}</p><p></p><blockquote><div class="quoteText">So what I'm missing right now is a way to set up these stacks for the initial run</div></blockquote><p></p><p>To create a new thread you have to allocate memory for its native stack and setup the stack exactly the same as in SwitchContext does. Once the thread stack is properly initialized you can simply call SwitchContext to start the new thread.</p><p></p><blockquote><div class="quoteText">In addition, my assumption here is that my VirtualThread class will not only hold the &quot;virtual stack&quot;, but also this native stack that will be used to do context switching for each thread.</div></blockquote><p></p><p>Yes, if you create thread you'll need to also allocate the native stacks yourself.</p><p>void InitializeContext(VirtualThread* pNew, void *startFunction)<br>{&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;int stackSize = 4096;<br>&nbsp;&nbsp;&nbsp;&nbsp;char *stack = reinterpret_cast&lt;char *&gt;(malloc(stackSize)); // allocate some space, malloc is just an example<br>&nbsp;&nbsp;&nbsp;&nbsp;stack &#43;= stackSize; // go to the top of the stack because the stack grows down<br>&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;__asm<br>&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mov ecx, esp // save current stack pointer<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mov esp, stack<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mov eax, startFunction<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;push eax&nbsp;&nbsp;&nbsp;&nbsp;// push the start function address as the return address (of SwitchContext)<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Save registers<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;xor eax, eax // let's always start a thread with zeroed registers<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;push eax<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;push eax<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;push eax<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;push eax<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mov stack, esp<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mov esp, ecx // restore the stack pointer<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;pNew-&gt;NativeStack = stack;<br>}</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/ecf9209938b142c4bc379f400091ef2d#ecf9209938b142c4bc379f400091ef2d</link>
		<pubDate>Mon, 15 Aug 2011 08:51:19 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/ecf9209938b142c4bc379f400091ef2d#ecf9209938b142c4bc379f400091ef2d</guid>
		<dc:creator>Dexter</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/Dexter/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p>@<a href="/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC#cecf9209938b142c4bc379f400091ef2d">Dexter</a>:</p><p>Most excellent, sir. I will try out your suggestions and let you know how it goes. Your help is greatly appreciated.</p><p>[EDIT] Just one observation... Since the native stack is growing down, I can probably share the same block of memory for both the virtual and native stack (so they'll be growing towards each other). Then I can easily do a check at strategic points to see how close the current virtual stack and native stack pointers are getting to each other. When they are within some predefined limit of each other, I can throw a stack overflow exception. This way I only need to deal with one area of &quot;wasted space&quot; per thread vs two, and a single check for stack overflow.</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/6bafc634c9894a51acee9f4000f993f2#6bafc634c9894a51acee9f4000f993f2</link>
		<pubDate>Mon, 15 Aug 2011 15:08:41 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/6bafc634c9894a51acee9f4000f993f2#6bafc634c9894a51acee9f4000f993f2</guid>
		<dc:creator>BitFlipper</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/BitFlipper/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p>Since I don't need anything else other than the native stack pointers in SwitchContext, I can probably just use the following and don't worry about the offset of NativeStack into VirtualThread:</p><p><pre class="brush: cpp">__declspec(naked) void __fastcall SwitchContext(void* pOld, void* pNew)
{
    __asm
    {        
        // Save registers
        push ebp
        push ebx
        push esi
        push edi
        // Save old stack
        mov [ecx], esp    // store to pOld-&gt;NativeStack
        // Load new stack
        mov esp, [edx]    // load from pNew-&gt;NativeStack
        // Restore registers
        pop edi
        pop esi
        pop ebx
        pop ebp
        ret
    }
}</pre></p><p>Then I just call it like this (where both pOld and pNew are VirtualThread):</p><p><pre class="brush: cpp">SwitchContext(&amp;pOld-&gt;NativeStack, &amp;pNew-&gt;NativeStack);</pre></p><p>EDIT: I changed the title to reflect the current part of the project I'm working on.</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/f624bb3ecb464208bf789f400104a6bb#f624bb3ecb464208bf789f400104a6bb</link>
		<pubDate>Mon, 15 Aug 2011 15:49:00 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/f624bb3ecb464208bf789f400104a6bb#f624bb3ecb464208bf789f400104a6bb</guid>
		<dc:creator>BitFlipper</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/BitFlipper/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p>OK, for my StartMainThread function, I came up with this:</p><p><pre class="brush: cpp">void NativePlatform::StartMainThread(RuntimeThread* pThread, void* pData, void *pStartAddress)
{    
    void* stack = pThread-&gt;NativeStack;

    __asm
    {        
        mov eax, pThread 
        mov ebx, pData
        mov ecx, pStartAddress
        mov esi, ebp
        mov edi, esp

        mov ebp, stack
        mov esp, ebp

        push esi
        push edi
        push ebx
        push eax

        call ecx

        pop eax
        pop ebx
        pop edi
        pop esi

        mov esp, edi
        mov ebp, esi
    }
}</pre></p><p>I need to pass in pThread and pData as two parameters into the start function. This <em>seemed</em> to work just fine until I started using std::wcout in my code, after which I get a heap corruption error when the application exits. If I call the start function directly without going through StartMainThread, then I don't get the corruption dialog when I exit. Obviously something is still wrong with the above asm code.</p><p>Any idea what I'm doing wrong?</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/369818b2c05542908ef99f4201229769#369818b2c05542908ef99f4201229769</link>
		<pubDate>Wed, 17 Aug 2011 17:38:00 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/369818b2c05542908ef99f4201229769#369818b2c05542908ef99f4201229769</guid>
		<dc:creator>BitFlipper</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/BitFlipper/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p>How is startAddress function declared?</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/95a1c8a43db24b9ba1fe9f42014045af#95a1c8a43db24b9ba1fe9f42014045af</link>
		<pubDate>Wed, 17 Aug 2011 19:26:04 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/95a1c8a43db24b9ba1fe9f42014045af#95a1c8a43db24b9ba1fe9f42014045af</guid>
		<dc:creator>Dexter</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/Dexter/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p>Like this:</p><p><pre class="brush: cpp">void (*m_startAddressData)(RuntimeThread*, VirtualObject**);</pre></p><p>You are thinking that maybe the calling convention is wrong?</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/d2767d643e424341bba89f420148127f#d2767d643e424341bba89f420148127f</link>
		<pubDate>Wed, 17 Aug 2011 19:54:28 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/d2767d643e424341bba89f420148127f#d2767d643e424341bba89f420148127f</guid>
		<dc:creator>BitFlipper</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/BitFlipper/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p>&quot;You are thinking that maybe the calling convention is wrong?&quot;</p><p>Unlikely. It can be wrong only if you changed the default from cdecl to stdcall or fastcall.</p><p>Hmm, the code looks correct. The 4 pops after the calls aren't really needed but they don't hurt.</p><p>Heap corruption &#43; stack allocated using malloc (I assume)... are you sure the intial native stack pointer is correct?</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/e310a9348a66451a9f9a9f42014aef47#e310a9348a66451a9f9a9f42014aef47</link>
		<pubDate>Wed, 17 Aug 2011 20:04:53 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/e310a9348a66451a9f9a9f42014aef47#e310a9348a66451a9f9a9f42014aef47</guid>
		<dc:creator>Dexter</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/Dexter/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p><strong>EDIT:</strong> <em>Nevermind, I found the problem. It seems that std::wcout uses quite a bit of stack space. I had the native stack too small, so once I increased the size to 16K or larger, the problem went away. I was initially keeping the stack size smaller because I thought the few calls I was making just didn't use that much space. What is weird is that I'm sure I increased the size of the stack to something like 512K at some point but I also found another bug in a vector class I was using, so maybe I didn't realize that the corrupted memory at that time was really caused by the vector class.</em></p><p>&nbsp;</p><p>OK I finally was able to get back to the heap corruption issue.&nbsp;In order to really test context switching, I needed to&nbsp;implement threading, which required me to implement delegates (including MultiCastDelegates while I was at it), and also TimeSpan and DateTime. Quite a tangent.</p><p>Anyway, so I was testing the StartMainThread call as shown a few messages above. I tried many different things, including giving NativeStack its own block of memory, but that block of memory is always corrupted. I carefully looked at the end of the block of memory (where the new thread will push and pop values), and indeed it pushes them within the boundary of the allocated block of memory (going downwards as expected).</p><p>The corrupted memory is always the size of the allocated block of memory plus 0x40. It is as if the stack switching code is doing something with the end of the block of memory. I even tried allocating a huge block of memory, and then setting the NativeStack to the middle of this block of memory - it still ends up corrupting the end of the block of memory. It is as if it known where the boundaries of the allocated block of memory is and then mucks around at 0x40 bytes past the end of it.</p><p>I confirmed that other code that allocates different blocks of memory aren't corrupting those blocks by allocating large dummy blocks inbetween those allocation calls so that the used&nbsp;blocks are not next to each other - it always&nbsp;comes back to the NativeStack block of memory as the one being corrupted.</p><p>Any ideas what could be going on here?</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/5712b2e5adc74612bfee9f46011d0f7a#5712b2e5adc74612bfee9f46011d0f7a</link>
		<pubDate>Sun, 21 Aug 2011 17:17:52 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/5712b2e5adc74612bfee9f46011d0f7a#5712b2e5adc74612bfee9f46011d0f7a</guid>
		<dc:creator>BitFlipper</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/BitFlipper/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p>Hmm, I guess this will be &quot;fun&quot; to debug. Couple more questions:</p><ol><li>you mentioned that it happens after using cout, what happens if you don't use it? </li><li>How many threads are you starting and from where? All from main thread? Or each thread starts another thread? </li></ol>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/0fdbfed9ccae4e1c9aba9f4601268f0c#0fdbfed9ccae4e1c9aba9f4601268f0c</link>
		<pubDate>Sun, 21 Aug 2011 17:52:27 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/0fdbfed9ccae4e1c9aba9f4601268f0c#0fdbfed9ccae4e1c9aba9f4601268f0c</guid>
		<dc:creator>Dexter</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/Dexter/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p></p><blockquote><div class="quoteText"><p></p><p><a class="permalink" title="Post Permalink" href="/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/0fdbfed9ccae4e1c9aba9f4601268f0c">45 seconds&nbsp;ago</a>,<a href="/Niners/Dexter">Dexter</a> wrote</p><p>Hmm, I guess this will be &quot;fun&quot; to debug. Couple more questions:</p><ol><li>you mentioned that it happens after using cout, what happens if you don't use it?</li><li>How many threads are you starting and from where? All from main thread? Or each thread starts another thread?</li></ol><p></p></div></blockquote><p></p><p>I found the problem (see edited message above). I really haven't started any additional threads at this point. I was just using the StartMainThread call to switch the stack of the main thread. It was the main thread (with its&nbsp;new stack) that was&nbsp;causing the corrupted memory due to the stack not being large enough.</p><p>Previously, without using wcout, there was no memory corruption which makes sense now that it is clear what the problem was.</p><p>I must say, working with C&#43;&#43; is really painful compared to C# (I used to do it a lot up to about 8 years ago when I started programming mainly in C#). Part of the problem is that the compiler tends to give you really obscure error messages when something goes wrong. Leave out a brace or semicolon somewhere, and it tells you some class in some unrelated file is undefined. Often you have to go the last error messages of dozens and dozens of others to figure out what the real problem is.</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/a9bdc8c5ff5a4031b9619f460129109c#a9bdc8c5ff5a4031b9619f460129109c</link>
		<pubDate>Sun, 21 Aug 2011 18:01:34 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/a9bdc8c5ff5a4031b9619f460129109c#a9bdc8c5ff5a4031b9619f460129109c</guid>
		<dc:creator>BitFlipper</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/BitFlipper/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p>He he, I was wondering about&nbsp;the stack size but I didn't expect cout to need&nbsp;that much. I'm glad it's working now.</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/e1b6cc6c1ae3466a87f29f46012a49ce#e1b6cc6c1ae3466a87f29f46012a49ce</link>
		<pubDate>Sun, 21 Aug 2011 18:06:02 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/e1b6cc6c1ae3466a87f29f46012a49ce#e1b6cc6c1ae3466a87f29f46012a49ce</guid>
		<dc:creator>Dexter</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/Dexter/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p>OK, next problem... The following doesn't work:</p><p><pre class="brush: cpp">__declspec(naked) void __fastcall SwitchContext(void* pOldStack, void* pNewStack)
{
    __asm
    {        
        // Save registers
        push ebp
        push ebx
        push esi
        push edi
            
        // Save old stack
        mov [ecx], esp    // store to pOldStack
            
        // Load new stack
        mov esp, [edx]    // load from pNewStack
        
        // Restore registers
        pop edi
        pop esi
        pop ebx
        pop ebp
        ret
    }
}</pre></p><p>My assumption here is that pOldStack and pNewStack&nbsp;should not the same as NativeStack for each thread, correct? NativeStack is really a constant value pointing to the top of the block of memory that was allocated for that thread's stack.</p><p>So instead, I need to have an additional&nbsp;void* in each thread&nbsp;whose address&nbsp;will be passed in to the SwitchContext call, correct? The question is, if this is the very first context switch, what should be stored at the pNewStack value? I assume this&nbsp;should be at&nbsp;some negative offset into that thread's NativeStack. Most likely I would need to calculate that value somewhere in the following call that prepares a thread for execution:</p><p><pre class="brush: cpp">// Set up the thread so that it is ready to run
void NativePlatform::InitializeThreadContext(RuntimeThread* pThread, VirtualObject** pData)
{    
    void* stack = pThread-&gt;NativeStack;
    void* startAddress = (void*)pThread-&gt;GetStartAddress();

    __asm
    {        
        mov ecx, esp    // Save current stack pointer
        mov esp, stack

        mov eax, startAddress
        push eax        // Push the start function address as the return address

        // Save registers
        xor eax, eax    // Let's always start a thread with zeroed registers
        push eax
        push eax
        push eax
        push eax

        mov stack, esp
        mov esp, ecx    // Restore the stack pointer
    }
}</pre></p><p>BTW, thanks for all of your help so far, it is greatly appreciated.</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/7eccc235d970486ca44e9f460148b6e7#7eccc235d970486ca44e9f460148b6e7</link>
		<pubDate>Sun, 21 Aug 2011 19:56:48 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/7eccc235d970486ca44e9f460148b6e7#7eccc235d970486ca44e9f460148b6e7</guid>
		<dc:creator>BitFlipper</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/BitFlipper/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p></p><blockquote><div class="quoteText">So instead, I need to have an additional void* in each thread whose address will be passed in to the SwitchContext call, correct?</div></blockquote><p></p><p>Yes, this value contains the current stack pointer for the thread. When you switch away from a thread its current stack pointer gets saved and the stack pointer of the new thread is loaded.</p><p></p><blockquote><div class="quoteText">The question is, if this is the very first context switch, what should be stored at the pNewStack value</div></blockquote><p></p><p>That's the role of InitializeContext, it sets up the initial stack so it looks similar to the one expected by SwitchContext. That's why the start address gets pushed on the stack, when SwitchContext will<strong>ret</strong>urn to what's stored on the stack, your start address. This might sound strange, the start function is not<strong>call</strong>ed but <strong>ret</strong>urned too, but it works fine as long as the stack is setup correctly. That's also the reason for those 4 push eax, they compensate the fact that SwitchContext pops edi, esi, ebp, ebx.</p><p></p><blockquote><div class="quoteText">I assume this should be at some negative offset into that thread's NativeStack</div></blockquote><p></p><p>The InitializeContext already computes the correct value but it looks like it doesn't store it correctly. Let's fix things a bit:</p><p>void NativePlatform::InitializeThreadContext(RuntimeThread* pThread, VirtualObject** pData) {<br>&nbsp;&nbsp;&nbsp;&nbsp;void* stack = pThread-&gt;NativeStack;<br>&nbsp;&nbsp;&nbsp;&nbsp;void* startAddress = (void*)pThread-&gt;GetStartAddress();<br><br>&nbsp;&nbsp;&nbsp;&nbsp;__asm {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Save current stack<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mov ecx, esp<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Switch to pThread's stack<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mov esp, stack<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Push arguments for the start function<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// It looks like your start function expects pThread and pData so:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mov eax, pData<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;push eax&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mov eax, pThread<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;push eax<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Push the start function address, SwitchContext will return to this address<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mov eax, startAddress<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;push eax<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Push 4 values to compensate for pop edi, esi, ebx, ebp in SwitchContext<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;xor eax, eax<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;push eax<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;push eax<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;push eax<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;push eax<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// At this point the stack is similar to what SwitchContext expects, save the stack pointer<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mov stack, esp<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Switch back to this thread's stack<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mov esp, ecx<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp; // save the thread's current stack pointer<br>&nbsp;&nbsp;&nbsp;&nbsp;pThread-&gt;CurrentStackPointer = stack;<br>}</p><p>I added some comments to make it more clear and also added arguments for your start function (my previous example didn't pass any arguments to the start function).</p><p>After InitializeContext runs you should be able to switch to the new thread by doing SwitchContext(&amp;currentThread-&gt;CurrentStackPointer, &amp;newThread-&gt;CurrentStackPointer).</p><p>Now there's another fun thing to solve. What happens when the thread exits? <img src='http://ecn.channel9.msdn.com/o9/content/images/emoticons/emotion-2.gif?v=c9' alt='Big Smile' /></p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/636f1689d6b6408b85dc9f46016aefea#636f1689d6b6408b85dc9f46016aefea</link>
		<pubDate>Sun, 21 Aug 2011 22:01:24 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/636f1689d6b6408b85dc9f46016aefea#636f1689d6b6408b85dc9f46016aefea</guid>
		<dc:creator>Dexter</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/Dexter/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p>I've been tweaking the asm code for quite some time today with <em>some</em> luck. I can get it to call into the correct function (startAddress), but I just can't get ESP and EBP to have the correct values and hence the stack is messed up.</p><p>I tried your code, and in that case it also successfully calls into startAddress, but&nbsp;EBP is null and so the stack is also messed up. I haven't yet been able to verify whether ESP is correct in this case.</p><p>That is kinda where I've been stuck, since I'm not 100% sure where to get the correct value to store for EBP. EBP is the last value it pops before executing the ret.</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/a6bbd7cab37b456d89499f4601752880#a6bbd7cab37b456d89499f4601752880</link>
		<pubDate>Sun, 21 Aug 2011 22:38:37 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/a6bbd7cab37b456d89499f4601752880#a6bbd7cab37b456d89499f4601752880</guid>
		<dc:creator>BitFlipper</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/BitFlipper/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p>Below is what I have so far. Note I need 4 versions, depending on whether it is a static or instance call, and whether it passes the extra data or not. Below is the static version with no data. As I said it successfully calls into startThread, but the stack is screwed up.</p><p><pre class="brush: cpp">void NativePlatform::InitializeThreadContext(RuntimeThread* pThread, VirtualObject** pData)
{    
    void* stack = pThread-&gt;NativeStack;
    void* callObj = pThread-&gt;GetCallObject();
    void* startAddress = (void*)pThread-&gt;GetStartAddress();

    if (!callObj &amp;&amp; !pData)
    {
        // Static call with no data
        __asm
        {        
            mov ecx, esp
            mov esi, startAddress
            mov eax, pThread
            mov esp, stack

            push eax
            push esi
            push esp

            // Save registers
            xor eax, eax             
            push eax
            push eax 
            push eax

            mov edi, esp
            mov esp, ecx

            mov stack, edi         
        }

        pThread-&gt;CurrentStackPointer = stack;
    }
    else if (!callObj &amp;&amp; pData)
    {
        // ...
    }
}</pre></p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/4e89b30d8c1941a2b7fe9f46017c9c37#4e89b30d8c1941a2b7fe9f46017c9c37</link>
		<pubDate>Sun, 21 Aug 2011 23:05:45 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/4e89b30d8c1941a2b7fe9f46017c9c37#4e89b30d8c1941a2b7fe9f46017c9c37</guid>
		<dc:creator>BitFlipper</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/BitFlipper/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p>I noticed that when I call directly&nbsp;into the destination function without using this context switching code, I notice that the difference between ESP and EBP is 216. I would have thought it would be much less,&nbsp;like 4 or 8. So that really confuses me because I was trying to see what the stack is supposed to look like on a good call, but this makes no sense to me.</p><p>About your observation related to how to handle the case when the thread exits. I was thinking about that too, and I think in that case it should trigger another context switch to another thread, and the context switch code just doesn't switch back to it after that. I could also push the necessary values onto the stack so that&nbsp;it&nbsp;ultimately &quot;returns&quot;&nbsp;into a function that causes a context switch, and hence switches to another thread.</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/f7a7ae19a23f421586849f46018addb7#f7a7ae19a23f421586849f46018addb7</link>
		<pubDate>Sun, 21 Aug 2011 23:57:39 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/f7a7ae19a23f421586849f46018addb7#f7a7ae19a23f421586849f46018addb7</guid>
		<dc:creator>BitFlipper</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/BitFlipper/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p></p><blockquote><div class="quoteText">but EBP is null and so the stack is also messed up</div></blockquote><p></p><p>Well, it's null because that's how InitializeContext initializes it. But why do you care about the contents of EBP? The start function doesn't expect a value in this register.</p><p></p><blockquote><div class="quoteText">Below is what I have so far</div></blockquote><p></p><p>I see you're pushing&nbsp;ESP, why? Again, this will be poped as EBP but you don't need EBP to have any particular value.</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/dae460b487254c11809b9f4700739b6a#dae460b487254c11809b9f4700739b6a</link>
		<pubDate>Mon, 22 Aug 2011 07:00:54 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/dae460b487254c11809b9f4700739b6a#dae460b487254c11809b9f4700739b6a</guid>
		<dc:creator>Dexter</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/Dexter/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p>@<a href="/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC#cdae460b487254c11809b9f4700739b6a">Dexter</a>:</p><p>OK I see what you are saying about EBP, although if I'm eventually going to put an additional&nbsp;return address on the stack to serve as a thread exit&nbsp;handler,&nbsp;I should probably have something meaningful in EBP.</p><p>But for now I'm not going to worry about EBP since the called function doesn't care about it, and instead try and figure out what else could be wrong here. As I said previously, once the called function is entered and I manually subtract 4 from EBP (after it was assigned from ESP in the prologue), the called function can see it's parameters properly.&nbsp;That&nbsp;might be a good clue as to where the problem could be.</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/534b1dd097ea421689a79f470079b894#534b1dd097ea421689a79f470079b894</link>
		<pubDate>Mon, 22 Aug 2011 07:23:10 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/534b1dd097ea421689a79f470079b894#534b1dd097ea421689a79f470079b894</guid>
		<dc:creator>BitFlipper</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/BitFlipper/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p>Stupid me, I'm talking about the way threads exit and I forget that the return address of the start function needs to be pushed onto the stack to. Even if the start function never returns because it does a SwitchContext you still need to push it because otherwise the start function can't find its arguments.</p><p>Between push eax and push esi you need to add another push for the return address. This can be 0 if you chose never to return from the start function or it can be the address of an &quot;exit function&quot; that calls SwitchContext to get away from the thread.</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/972ea52911f44c67af6e9f4700950723#972ea52911f44c67af6e9f4700950723</link>
		<pubDate>Mon, 22 Aug 2011 09:02:35 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/972ea52911f44c67af6e9f4700950723#972ea52911f44c67af6e9f4700950723</guid>
		<dc:creator>Dexter</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/Dexter/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p></p><blockquote><div class="quoteText">Note I need 4 versions, depending on whether it is a static or instance call, and whether it passes the extra data or not</div></blockquote><p></p><p>That sounds a bit excesive. Normally there is a single thread start function and this isn't the function you pass to the Thread constructor through a delegate. This start function is a special function that takes care of initializing the thread and then calls the delegate.</p><p>Also, the static/instance distinction is the job of the delegate, the thread start function should not be sensitive to this.</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/04081772010e44eab4da9f470099eea4#04081772010e44eab4da9f470099eea4</link>
		<pubDate>Mon, 22 Aug 2011 09:20:26 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/04081772010e44eab4da9f470099eea4#04081772010e44eab4da9f470099eea4</guid>
		<dc:creator>Dexter</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/Dexter/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p>@<a href="/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC#c04081772010e44eab4da9f470099eea4">Dexter</a>:</p><p>The four versions correspond to TreadStart and ParameterizedThreadStart where&nbsp;each of those can call a static or instance method. While the Thread constructor doesn't care about static vs instance, internally I need to handle those two cases. In this particular case, it determines how many parameters are pushed onto the stack. For instance functions, an additional &quot;this&quot; parameter will be pushed. In the generated C&#43;&#43; code, the four functions would look like this:</p><p><pre class="brush: cpp">Void ThreadTestClass::ThreadTestStaticNoData(RuntimeThread* pThread) {}

Void ThreadTestClass::ThreadTestStaticData(RuntimeThread* pThread, VirtualObject** data) {}

Void ThreadTestClass::ThreadTestInstanceNoData(RuntimeThread* pThread, ThreadTestClass** pThis) {}

Void ThreadTestClass::ThreadTestInstanceData(RuntimeThread* pThread, ThreadTestClass** pThis, VirtualObject** data) {}</pre></p><p>Those are the functions that the first context switch need to call into, and each have a different parameter signature.</p><p><strong>EDIT:</strong> You have a good point about the single start&nbsp;function, I didn't think about that. So&nbsp;this single start function is the one that cares about the four different versions, and calls the correct one. In addition, it could do the cleanup after the start function returns. At that point it would set the Exit flag on pThread, and then call the scheduler which would switch away to another thread.</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/bf1ad5377cc6489a9c7d9f4700fb5181#bf1ad5377cc6489a9c7d9f4700fb5181</link>
		<pubDate>Mon, 22 Aug 2011 15:15:01 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/bf1ad5377cc6489a9c7d9f4700fb5181#bf1ad5377cc6489a9c7d9f4700fb5181</guid>
		<dc:creator>BitFlipper</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/BitFlipper/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p>OK, but did you try the fix for the start function? Does it work?</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/bf8c9d8dfd794cea9c549f4701085b70#bf8c9d8dfd794cea9c549f4701085b70</link>
		<pubDate>Mon, 22 Aug 2011 16:02:29 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/bf8c9d8dfd794cea9c549f4701085b70#bf8c9d8dfd794cea9c549f4701085b70</guid>
		<dc:creator>Dexter</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/Dexter/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p>@<a href="/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC#cbf8c9d8dfd794cea9c549f4701085b70">Dexter</a>:</p><p>I just rewrote the code to use the single start function, but I have not yet fixed the off-by-4 bug. I have to&nbsp;leave for&nbsp;work right now&nbsp;so I'll have to wait to do that tonight maybe.</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/ee0384ff211c405da5589f47010d1112#ee0384ff211c405da5589f47010d1112</link>
		<pubDate>Mon, 22 Aug 2011 16:19:38 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/ee0384ff211c405da5589f47010d1112#ee0384ff211c405da5589f47010d1112</guid>
		<dc:creator>BitFlipper</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/BitFlipper/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p>This morning on my train commute I was able to try out your suggestion about adding the extra push for the return address, and it worked! I'm also now calling into the special start function and it then calls one of the four function types (the actual specified start function). Once that function returns, I set the Exited flag on the thread and call into the scheduler to switch to a different thread. This actually all started working&nbsp;correctly so I'm quite happy about that. Thanks for your help with his.</p><p>Next up is to implement Sleep and Join. Sleep should be easy in that all I need to do is set a future tick based on the specified millisecond value, then call into the scheduler to switch to a different thread. The scheduler will then enumerate through all threads and see which ones are ready to run, skipping those that have tick value set sometime in the future. BTW I'm using a counter on each thread that is incremented by the amount of its priority. Then the scheduler picks the thread with the highest counter value. When a thread is run, it's counter is set back to zero.</p><p>Join should also be easy in that it stores a pointer (or thread ID)&nbsp;to the thread it should &quot;join&quot;. The scheduler will check whether the other thread is still in a running state and then keep skipping the joining thread until the other thread's Exited flag is set.</p><p>If no thread is ready to run, then my thinking was that I would need to call the asm halt instruction. However reading up on the halt instruction indicates that it is a privileged instruction that can only be executed by the kernel. I guess for x86 right now I can just call Sleep(0). If this eventually runs on a microcontroller I will just call whatever the equivalent is for the halt instruction.</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/115eb951635d4b62ba759f470158b76f#115eb951635d4b62ba759f470158b76f</link>
		<pubDate>Mon, 22 Aug 2011 20:55:04 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/115eb951635d4b62ba759f470158b76f#115eb951635d4b62ba759f470158b76f</guid>
		<dc:creator>BitFlipper</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/BitFlipper/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p>What about a hashtable based on the tick, so you don't have enumerate every thread.?</p><p>&lt;Tick, LinkedList&lt;Thread&gt;&gt;&nbsp;</p><p>&nbsp;</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/d141853e7c844e9b8a479f470186b7a0#d141853e7c844e9b8a479f470186b7a0</link>
		<pubDate>Mon, 22 Aug 2011 23:42:33 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/d141853e7c844e9b8a479f470186b7a0#d141853e7c844e9b8a479f470186b7a0</guid>
		<dc:creator>Adam Speight</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/AdamSpeight2008/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p>@<a href="/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC#cd141853e7c844e9b8a479f470186b7a0">AdamSpeight2008</a>:</p><p>I think the problem in this case will be that there can be various ticks in the table, but the actual tick might&nbsp;fall inbetween those values. Then the earlier ticks would be skipped altogether. Let's say the ticks are 1000, 1010, 1030. Then when the scheduler gets called, the actual tick at that time is 1005. That means that the thread that is supposed to wake up at tick 1000 will be skipped and it will sleep forever.</p><p>I don't expect too many threads to be created, so I don't think this area would be a bottleneck. Also, the scheduler needs to enumerate through all threads anyway so it is pretty cheap to add an additional check in that loop to see whether the thread should be woken up.</p><p>I am thinking of ways to optimize this area at a later point, so I appreciate&nbsp;your suggestions.</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/5f029597cd89442da7129f4800f18511#5f029597cd89442da7129f4800f18511</link>
		<pubDate>Tue, 23 Aug 2011 14:39:20 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/5f029597cd89442da7129f4800f18511#5f029597cd89442da7129f4800f18511</guid>
		<dc:creator>BitFlipper</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/BitFlipper/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p>I ran into another problem with threading...</p><p>I have the main thread and 4 other threads that each outputs a&nbsp;console message in a loop and then&nbsp;Sleeps for a few hundred ms during each iteration. When each non-main thread's loop exits, it sets a flag and the main thread loops until all&nbsp;four flags are set.</p><p>Everything works fine when&nbsp;either the Debug or Release builds run in the debugger, but both the Debug and Release builds get access violations when run outside of the debugger. Obviously this makes it difficult to debug. I'm wondering whether the thread switching function is really saving enough registers. Maybe adding naked&nbsp;or fastcall to the function declaration/definition changes the assumptions about which registers need to be saved?</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/17c7554de36e4c13ad4a9f4801431010#17c7554de36e4c13ad4a9f4801431010</link>
		<pubDate>Tue, 23 Aug 2011 19:36:14 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/17c7554de36e4c13ad4a9f4801431010#17c7554de36e4c13ad4a9f4801431010</guid>
		<dc:creator>BitFlipper</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/BitFlipper/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p>Sorry for all the posts, but...</p><p>So apparently the exception that gets thrown when running the C&#43;&#43; app outside of the debugger is 0x40010006,&nbsp;which is DBG_PRINTEXCEPTION_C. When I comment out all OutputDebugString calls, the exception is no longer thrown and the application runs without problems.</p><p>According to the <a href="http://msdn.microsoft.com/en-us/library/aa363362(v=VS.85).aspx">MSDN documentation</a>, if the application is run outside of the debugger, OutputDebugString will output to the system debugger. If there is no system debugger, it does nothing. Except in my case it crashes the application.</p><p>I did increase the stack size a lot to ensure it isn't running out of stack space again.</p><p>Any ideas?</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/ffe944f815784d5a9ea49f490058ab92#ffe944f815784d5a9ea49f490058ab92</link>
		<pubDate>Wed, 24 Aug 2011 05:22:50 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/ffe944f815784d5a9ea49f490058ab92#ffe944f815784d5a9ea49f490058ab92</guid>
		<dc:creator>BitFlipper</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/BitFlipper/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p></p><blockquote><div class="quoteText">the exception that gets thrown when running the C&#43;&#43; app outside of the debugger is 0x40010006, which is DBG_PRINTEXCEPTION_C</div></blockquote><p></p><p>Hmm, I have the feeling that Windows won't always like this stack switching business.&nbsp;NT's structured exception handling relies on the stack and if you switch the stack... I'm not quite sure what can happen.</p><p></p><blockquote><div class="quoteText">I'm wondering whether the thread switching function is really saving enough registers</div></blockquote><p></p><p>It should be enough unless you use SSE. A normal kernel the relise on interrupts to switch threads has no choice but to save all registers because it doesn't know which registers are used. But what you're doing here is more like cooperative multithreading and more importantly, it's all done in C. The C/C&#43;&#43; compiler expects that a function will preserve those 4 registers (ebp, ebx, edi, esi), all other general purpose registers can be modified by the function as needed. Also, the FPU stack is supposed to be empty when a function is called so it doesn't contain anything that needs saving.</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/ac2a816c9db04a649c099f49009bc5ef#ac2a816c9db04a649c099f49009bc5ef</link>
		<pubDate>Wed, 24 Aug 2011 09:27:09 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/ac2a816c9db04a649c099f49009bc5ef#ac2a816c9db04a649c099f49009bc5ef</guid>
		<dc:creator>Dexter</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/Dexter/Discussions/RSS</wfw:commentRss>
	</item>
	<item>
		<title>Tech Off - IL to C++ compiler - Need advice on implementing context switching</title>
		<description><![CDATA[<p>@<a href="/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC#cac2a816c9db04a649c099f49009bc5ef">Dexter</a>:</p><p>Well so as it turns out the exception is thrown when you call OutputDebugString and there is no debugger available. This is not what the MSDN documentation says (it says the call does nothing),&nbsp;but this is actually used by hackers to test whether their malware is running under&nbsp;a debugger or not. If a debugger is present, no exception would be&nbsp;cought and they would exit in order to prevent reverse engineering.</p><p>Doing the following solved the problem:</p><p><pre class="brush: cpp">if (IsDebuggerPresent())
    OutputDebugString(text);</pre></p><p>Now the context switching works flawlessly.</p>]]></description>
		<link>http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/5404b7e3eb3c477298989f4900de329f#5404b7e3eb3c477298989f4900de329f</link>
		<pubDate>Wed, 24 Aug 2011 13:28:59 GMT</pubDate>
		<guid isPermaLink="false">http://channel9.msdn.com/Forums/TechOff/IL-to-C-compiler-Need-advice-on-implementing-a-GC/5404b7e3eb3c477298989f4900de329f#5404b7e3eb3c477298989f4900de329f</guid>
		<dc:creator>BitFlipper</dc:creator>
		<slash:comments>77</slash:comments>
		<wfw:commentRss>http://channel9.msdn.com/Niners/BitFlipper/Discussions/RSS</wfw:commentRss>
	</item>
</channel>
</rss>