<?xml version="1.0"?>
<rss version="2.0.">
  <channel>
    <title>Advogato blog for lupus</title>
    <link>http://www.advogato.org/person/lupus/</link>
    <description>Advogato blog for lupus</description>
    <language>en-us</language>
    <generator>mod_virgule</generator>
    <pubDate>Sun, 20 Jul 2008 06:37:36 GMT</pubDate>
    <item>
      <pubDate>Tue, 19 Feb 2008 15:04:58 GMT</pubDate>
      <title>19 Feb 2008</title>
      <link>http://www.advogato.org/person/lupus/diary.html?start=26</link>
      <guid>http://www.advogato.org/person/lupus/diary.html?start=26</guid>
      <description>&lt;b&gt;Novell hack week&lt;/b&gt;&#xD;
&#xD;
&lt;p&gt; One of the things that have been sitting in my TODO list for&#xD;
a few years is to improve the performance of the Regex&#xD;
engine in Mono, both by speeding up the interpreter and by&#xD;
compiling the regular expressions to IL code so that the JIT&#xD;
could optimize it. This seemed like a good project for hack&#xD;
week and Zoltan joined me doing the implementation.&lt;p&gt;&#xD;
&#xD;
&lt;p&gt; I worked on a new compiler/interpreter combination that uses&#xD;
simplified opcodes, with the aim of making their execution&#xD;
faster and also making the translation to IL code easier. As&#xD;
an example, the old interpreter used a 'Char' opcode to&#xD;
match a single char, but this opcode has several runtime&#xD;
options to ignore the case, negate the assertion and go&#xD;
backward in the string. Each option required decoding and&#xD;
conditional branching at runtime, so removing this overhead&#xD;
should improve performance significantly.&lt;p&gt;&#xD;
Zoltan made a clever observation: he could reuse the new&#xD;
interpreter for bytecodes that the IL engine he was working&#xD;
on couldn't yet handle and so he used dynamic methods with&#xD;
the same signature as the method in the interpreter that&#xD;
evaluates the regex bytecode. This design has also the nice&#xD;
property that compiled regular expressions will be garbage&#xD;
collected (as opposed to the MS runtime that, at least in&#xD;
the 1.1 version, will leak in this case).&lt;p&gt;&#xD;
&#xD;
&lt;p&gt; IL-compiling regular expressions has several benefits: it&#xD;
completely removes dispatch and decoding overhead and the&#xD;
JIT will use very fast instructions like compare with&#xD;
immediate to implement the 'Char' bytecode.&lt;p&gt;&#xD;
&#xD;
&lt;p&gt; I used a few microbenchmarks to test the speed of the new&#xD;
engines, but I'll report here just the results of running&#xD;
the regexdna test from the language shootout: in other cases&#xD;
the speedup is even bigger.&#xD;
&lt;p&gt;&#xD;
&#xD;
&lt;p&gt; &lt;ul&gt;&#xD;
&lt;li&gt;Old interpreter: 10.1 seconds&#xD;
&lt;li&gt;New interpreter: 5.4 seconds&#xD;
&lt;li&gt;IL engine: 1.3 seconds.&#xD;
&lt;/ul&gt;&#xD;
&#xD;
&lt;p&gt; Most of the new code is in svn, though it's not enabled&#xD;
since it's still incomplete. We'd need another week or so to&#xD;
make it usable instead of the old engine and we haven't&#xD;
allocated the time yet to complete this work, but it sure&#xD;
looks promising.</description>
    </item>
    <item>
      <pubDate>Mon, 11 Feb 2008 17:49:45 GMT</pubDate>
      <title>11 Feb 2008</title>
      <link>http://www.advogato.org/person/lupus/diary.html?start=25</link>
      <guid>http://www.advogato.org/person/lupus/diary.html?start=25</guid>
      <description>&lt;b&gt;The future of C#&lt;/b&gt;&#xD;
&#xD;
&lt;p&gt; C# as a programming language is still young and has evolved&#xD;
nicely in the last few years: most of the new features take&#xD;
it closer to a high-level language, allowing shorter and&#xD;
nicer code for common patterns. A language needs to be able&#xD;
to cover a wide spectrum of usages to be considered mature&#xD;
but there is one side of the spectrum that has been&#xD;
neglected in C# for far too long: the low level side close&#xD;
to IL code.&lt;p&gt;&#xD;
&#xD;
&lt;p&gt; Someone already hacked up a program that uses a preprocessor&#xD;
and ilasm to inject IL into C# code, but this approach has&#xD;
many drawbacks (too many to list them all here).&lt;p&gt;&#xD;
&#xD;
&lt;p&gt; Inline IL code should integrate with the rest of the C#&#xD;
program as closely as possible, allowing, for example, to&#xD;
reference labels defined in C# code from branches in IL code&#xD;
or using the names of local variables and arguments for&#xD;
opcodes like ldloc and ldarg.&lt;p&gt;&#xD;
&#xD;
&lt;p&gt; The proposal here is to allow IL code as a new statement in&#xD;
the form:&#xD;
&lt;pre&gt;&#xD;
  unsafe LITERAL_STRING;&#xD;
&lt;/pre&gt;&#xD;
This is similar to the traditional way inline assembly has&#xD;
been done (gcc's __asm__ ("code") statement), it's very&#xD;
unlikely to clash with other possible uses of the unsafe&#xD;
keyword and also conveys the notion that IL code may break&#xD;
type safety, IL language rules etc. It has also the added&#xD;
property that all the code needed to implement this support&#xD;
could be easily copied in a separate library and used in&#xD;
standalone programs to, say, simplify code emission for&#xD;
Reflection.Emit (this inline IL support has been implemented&#xD;
inside the Mono C# compiler, so it's C# code that uses&#xD;
Reflection.Emit as the backend).&lt;p&gt;&#xD;
&#xD;
&lt;p&gt; So, without further ado, the standard sample program written&#xD;
with inline IL:&#xD;
&#xD;
&lt;p&gt; &lt;pre&gt;&#xD;
class InlineIL {&#xD;
  static void Main () {&#xD;
    unsafe @"&#xD;
     ldstr ""Hello, world!""&#xD;
     call void class [mscorlib]System.Console::WriteLine(string)&#xD;
    ";&#xD;
  }&#xD;
}&#xD;
&lt;/pre&gt;&#xD;
Ok, that kind of code is written more easily in C# proper,&#xD;
so what about things that IL code can do, but that C# code&#xD;
can't? Ever wanted to be able to change the value of a boxed&#xD;
integer? In C# you can't, but this is very easy with inline IL:&#xD;
&lt;pre&gt;&#xD;
static void ChangeInt (object intval, int new_value) {&#xD;
  unsafe @"&#xD;
    ldarg.0&#xD;
    unbox [mscorlib]System.Int32&#xD;
    ldarg.1&#xD;
    stind.i4&#xD;
  ";&#xD;
}&#xD;
&lt;/pre&gt;&#xD;
The following code will print 2:&#xD;
&lt;pre&gt;&#xD;
  object boxed = 1;&#xD;
  ChangeInt (boxed, 2);&#xD;
  Console.WriteLine (boxed);&#xD;
&lt;/pre&gt;&#xD;
Of course you can access types and fields defined by the C#&#xD;
program currently being compiled, consider the following&#xD;
example:&#xD;
&lt;pre&gt;&#xD;
class InlineIL {&#xD;
  static int field1;&#xD;
  static void Main () {&#xD;
    int localvar = 1;&#xD;
    unsafe @"&#xD;
      ldloc localvar&#xD;
      stsfld int32 class InlineIL::field1&#xD;
    ";&#xD;
  }&#xD;
}&#xD;
&lt;/pre&gt;&#xD;
Note that in this case, the compiler won't emit warnings&#xD;
about field1 and localvar being never used and of course&#xD;
you'll get an error if you mispell the field name in IL code&#xD;
as you would in C# code.&lt;p&gt;&#xD;
&#xD;
&lt;p&gt; The main usage of the new feature would be for some corlib&#xD;
methods in mono or for more easily implementing test cases&#xD;
for the JIT and runtime test suites: some specific IL code&#xD;
patterns (that may not be expressed in C# or that there is&#xD;
no guarantee C# will compile to the effecting code) can be&#xD;
easily written while the rest of the boilerplate code needed&#xD;
by the unit testing program can be written in much more&#xD;
readable C#. That said, this opens many possibilities for a&#xD;
creative hacker, finally free of the constraints of C#.&lt;p&gt;&#xD;
&#xD;
&lt;p&gt; Happy hacking!</description>
    </item>
    <item>
      <pubDate>Mon, 15 Oct 2007 11:44:08 GMT</pubDate>
      <title>15 Oct 2007</title>
      <link>http://www.advogato.org/person/lupus/diary.html?start=24</link>
      <guid>http://www.advogato.org/person/lupus/diary.html?start=24</guid>
      <description>&lt;b&gt;Memory savings with magic trampolines in Mono&lt;/b&gt;&lt;p&gt;&#xD;
&#xD;
&lt;p&gt; Mono is a JIT compiler and as such it compiles a method only&#xD;
when needed: the moment the execution flow requires the&#xD;
method to execute. This mode of execution greatly improves&#xD;
startup time of applications and is implemented with a&#xD;
simple trick: when a method call is compiled, the generated&#xD;
native code can't transfer execution to the method's native&#xD;
code address, because it hasn't been compiled yet. Instead&#xD;
it will go through a magic trampoline: this chunk of code&#xD;
knows which method is going to be executed, so it will&#xD;
compile it and jump to the generated code.&lt;p&gt;&#xD;
&#xD;
&lt;p&gt; The way the trampoline knows which method to compile is&#xD;
pretty simple: for each method a small specific trampoline&#xD;
is created that will pass the pointer to the method to&#xD;
execute to the real worker, the magic trampoline.&lt;p&gt;&#xD;
&#xD;
&lt;p&gt; Different architectures implement this trampoline in&#xD;
different ways, but each with the aim to reduce its size:&#xD;
the reason is that many trampolines are generated and so&#xD;
they use quite a bit of memory.&lt;p&gt;&#xD;
&#xD;
&lt;p&gt; Mono in svn has quite a few improvements in this area&#xD;
compared to mono 1.2.5 which was released just a few weeks&#xD;
ago. I'll try to detail the major changes below.&lt;p&gt;&#xD;
&#xD;
&lt;p&gt; The first change is related to how the memory for the&#xD;
specific trampolines is allocated: this is executable memory&#xD;
so it is not allocated with malloc, but with a custom&#xD;
allocator, called Mono Code Manager. Since the code manager&#xD;
is used primarily for methods, it allocates chunks of memory&#xD;
that are aligned to multiples of 8 or 16 bytes depending on&#xD;
the architecture: this allows the cpu to fetch the&#xD;
instructions faster. But the specific trampolines are not&#xD;
performance critical (we'll spend lots of time JITting the&#xD;
method anyway), so they can tolerate a smaller alignment.&#xD;
Considering the fact that most trampolines are allocated one&#xD;
after the other and that in most architectures they are 10&#xD;
or 12 bytes, this change alone saved about 25% of the memory&#xD;
used (they used to be aligned up to 16 bytes).&lt;p&gt;&#xD;
&#xD;
&lt;p&gt; To give a rough idea of how many trampolines are generated&#xD;
I'll give a few examples:&#xD;
&lt;ul&gt;&#xD;
&lt;li&gt;MonoDevelop startup creates about 21 thousand trampolines&#xD;
&lt;li&gt;IronPython 2.0 running a benchmark creates about 17&#xD;
thousand trampolines&#xD;
&lt;li&gt;an "hello, world" style program about 800&#xD;
&lt;/ul&gt;&#xD;
This change in the first case saved more than 80 KB of&#xD;
memory (plus about the same because reviewing the code&#xD;
allowed me to fix also a related overallocation issue).&lt;p&gt;&#xD;
&#xD;
&lt;p&gt; So reducing the size of the trampolines is great, but it's&#xD;
really not possible to reduce them much further in size, if&#xD;
at all. The next step is trying just not to create them.&lt;br&gt;&#xD;
There are two primary ways a trampoline is generated: a&#xD;
direct call to the method is made or a virtual table slot is&#xD;
filled with a trampoline for the case when the method is&#xD;
invoked using a virtual call. I'll note here than in both&#xD;
cases, after compiling the method, the magic trampoline will&#xD;
 do the needed changes so that the trampoline is not&#xD;
executed again, but execution goes directly to the newly&#xD;
compiled code. In one case the callsite is changed so that&#xD;
the branch or call instruction will transfer control to the&#xD;
new address. In the virtual call case the magic trampoline&#xD;
will change the virtual table slot directly.&lt;br&gt;&#xD;
&#xD;
&lt;p&gt; The sequence of instructions used by the JIT to implement a&#xD;
virtual call are well-known and the magic trampoline&#xD;
(inspecting the registers and the code sequence) can easily&#xD;
get the virtual table slot that was used for the invocation.&#xD;
The idea here then is: if we know the virtual table slot we&#xD;
know also the method that is supposed to be compiled and&#xD;
executed, since each vtable slot is assigned a unique method&#xD;
by the class loader. This simple fact allows us to use a&#xD;
completely generic trampoline in the virtual table slots,&#xD;
avoiding the creation of many method-specific trampolines.&lt;p&gt;&#xD;
&#xD;
&lt;p&gt; In the cases above, the number of generated trampolines goes&#xD;
from 21000 to 7700 for MonoDevelop (saving 160 KB of&#xD;
memory), from 17000 to 5400 for the IronPython case and from&#xD;
800 to 150 for the hello world case.&lt;p&gt;&#xD;
&#xD;
&lt;p&gt; I'll describe more optimizations (both already committed and&#xD;
forthcoming) in the next blog posts.</description>
    </item>
    <item>
      <pubDate>Tue, 11 Sep 2007 16:25:16 GMT</pubDate>
      <title>11 Sep 2007</title>
      <link>http://www.advogato.org/person/lupus/diary.html?start=23</link>
      <guid>http://www.advogato.org/person/lupus/diary.html?start=23</guid>
      <description>&lt;b&gt;Mono GC updates &lt;/b&gt;&lt;p&gt;&#xD;
I guess some of you expected a blog entry about the&#xD;
generational GC in Mono, given the title. From my&#xD;
understanding many have the expectation that the new GC will&#xD;
solve all the issues they think are caused by the GC so they&#xD;
await with trepidation.&lt;br&gt;&#xD;
As a matter of fact, from my debugging of all or almost all&#xD;
those issues, the existing GC is not the culprit. Sometimes&#xD;
there is an unmanaged leak, sometimes a managed or unmanaged&#xD;
excessive retention of objects, but basically 80% of those&#xD;
issues that get attributed to the GC are not GC issues at&#xD;
all.&lt;br&gt;&#xD;
So, instead of waiting for the holy grail, provide test&#xD;
cases or as much data as you can for the bugs you&#xD;
experience, because chances are that the bug can be fixed&#xD;
relatively easily without waiting for the new GC to&#xD;
stabilize and get deployed.&lt;br&gt;&#xD;
Now, this is not to say that the new GC won't bring great&#xD;
improvements, but that those improvements are mainly in&#xD;
allocation speed and mean pause time, both of which, while&#xD;
measurable, are not bugs per-se and so are not part of the&#xD;
few issues that people hit with the current Boehm-GC based&#xD;
implementation.&lt;p&gt;&#xD;
&#xD;
&lt;p&gt; After the long introduction, let's go to the purpose of this&#xD;
entry: svn Mono now can perform an object allocation&#xD;
entirely in managed code. Let me explain why this is&#xD;
significant.&lt;p&gt;&#xD;
The Mono runtime (including the GC) is written in C code and&#xD;
this is called unmanaged code as opposed to managed code&#xD;
which is all the code that gets JITted from IL opcodes.&lt;br&gt;&#xD;
The JIT and the runtime cooperate so that managed code is&#xD;
compiled in a way that lets the runtime inspect it, inject&#xD;
exceptions, unwind the stack and so on. The unmanaged code,&#xD;
on the other hand, is compiled by the C compiler and on most&#xD;
systems and architectures, there is no info available on it&#xD;
that would allow the same operations. For this reason,&#xD;
whenever a program needs to make a transition from managed&#xD;
code to unmanaged (for example for an internal call&#xD;
implementation or for calling into the GC) the runtime needs&#xD;
to perform some additional bookeeping, which can be relatively&#xD;
expensive, especially if the amount of code to execute in&#xD;
unmanaged land is tiny.&lt;p&gt;&#xD;
Since a while we have made use of the Boehm GC's ability to&#xD;
allocate objects in a thread-local fast-path, but we&#xD;
couldn't take the full benefit of it because the cost of the&#xD;
managed to unmanaged and back transition was bigger than the&#xD;
allocation cost itself.&lt;br&gt;&#xD;
Now the runtime can create a managed method that performs&#xD;
the allocation fast-path entirely in managed code, avoiding&#xD;
the cost of the transition in most cases. This&#xD;
infrastructure will be also used for the generational GC&#xD;
where it will be more important: the allocation fast-path&#xD;
sequence there is 4-5 instructions vs the dozen or more of&#xD;
the Boehm GC thread local alloc.&lt;br&gt;&#xD;
&#xD;
&lt;p&gt; As for actual numbers, a benchmark that repeatedly allocates&#xD;
small objects is now more than 20% faster overall (overall&#xD;
includes the time spent collecting the garbage objects, the&#xD;
actual allocation speed increase is much bigger).</description>
    </item>
    <item>
      <pubDate>Thu, 30 Nov 2006 16:50:12 GMT</pubDate>
      <title>30 Nov 2006</title>
      <link>http://www.advogato.org/person/lupus/diary.html?start=22</link>
      <guid>http://www.advogato.org/person/lupus/diary.html?start=22</guid>
      <description>&lt;b&gt;Code coverage with Mono&lt;/b&gt;&lt;p&gt;&#xD;
I uploaded version 0.2 of the monocov coverage tool for Mono&#xD;
&lt;a&#xD;
href="http://primates.ximian.com/~lupus/monocov-0.2.tar.gz"&gt;here&lt;/a&gt;.&#xD;
It is also available from the monocov svn module from the&#xD;
usual Mono svn server.&lt;p&gt;&#xD;
The release features an improved Gtk# GUI, fixes to html&#xD;
rendering and other minor improvements.&lt;br&gt;&#xD;
The usage is pretty simple, just run you program or test&#xD;
suite with the following command after having installed monocov:&#xD;
&lt;pre&gt;&#xD;
   mono --debug --profile=monocov program.exe&#xD;
&lt;/pre&gt;&#xD;
The coverage information will be output to the&#xD;
program.exe.cov file. Now you can load this file in the GUI&#xD;
with:&#xD;
&lt;pre&gt;&#xD;
   monocov program.exe.cov&#xD;
&lt;/pre&gt;&#xD;
and browse the namespaces for interesting types you want to&#xD;
check code coverage for. Double clicking on a method will&#xD;
bring up a viewer with the source file of the method with&#xD;
the lines of code not reached by execution highlighted in&#xD;
red.&lt;p&gt;&#xD;
To limit the collection of data to a specific assembly you&#xD;
can specify it as an argument to the profiler. For example,&#xD;
to consider only the code in mscorlib, use:&#xD;
&lt;pre&gt;&#xD;
   mono --debug --profile=monocov:+[mscorlib] test-suite.exe&#xD;
&lt;/pre&gt;&#xD;
To be able to easily collect coverage information from the&#xD;
unit tests in the mono mcs directory you can also run the&#xD;
test suite as follows, for example in mcs/class/corlib:&#xD;
&lt;pre&gt;&#xD;
   make run-test&#xD;
RUNTIME_FLAGS="--profile=monocov:outfile=corlib.cov,+[mscorlib]"&#xD;
&lt;/pre&gt;&#xD;
Monocov can also generate a set of HTML pages that display&#xD;
the coverage data. &lt;a&#xD;
href="http://primates.ximian.com/~lupus/corlib-cov/project.html"&gt;Here&lt;/a&gt;&#xD;
are the files generated when running the nunit-based test&#xD;
suite for mono's mscorlib with the following command:&#xD;
&lt;pre&gt;&#xD;
    monocov --export-html=/tmp/corlib-cov corlib.cov&#xD;
&lt;/pre&gt;&#xD;
Hopefully this tool will help both new and old contributors&#xD;
to easily find untested spots in our libraries and&#xD;
contribute tests for them.&lt;br&gt;&#xD;
Happy testing!</description>
    </item>
    <item>
      <pubDate>Thu, 23 Nov 2006 17:10:36 GMT</pubDate>
      <title>23 Nov 2006</title>
      <link>http://www.advogato.org/person/lupus/diary.html?start=21</link>
      <guid>http://www.advogato.org/person/lupus/diary.html?start=21</guid>
      <description>&lt;b&gt;Debugging managed lock deadloacks in Mono&lt;/b&gt;&lt;p&gt;&#xD;
I just committed to svn a small function that can be used to&#xD;
help debug deadlocks that result from the incorrect use of&#xD;
managed locks.&lt;p&gt;&#xD;
Managed locks (implemented in the Monitor class and usually&#xD;
invoked with the lock () construct in C#) are subject to the&#xD;
same incorrect uses of normal locks, though they can be&#xD;
safely taken recursively by the same thread.&lt;p&gt;&#xD;
One of the obviously incorrect way to use locks is to have&#xD;
multiple locks and acquire them in different orders in&#xD;
different codepaths. Here is an example:&lt;p&gt;&#xD;
&lt;pre&gt;&#xD;
using System;&#xD;
using System.Threading;&#xD;
&#xD;
&lt;p&gt; class TestDeadlock {&#xD;
&#xD;
&lt;p&gt;     static object lockA = new object ();&#xD;
    static object lockB = new object ();&#xD;
&#xD;
&lt;p&gt;     static void normal_order () {&#xD;
        lock (lockA) {&#xD;
             Console.WriteLine ("took lock A");&#xD;
             // make the deadlock more likely&#xD;
             Thread.Sleep (500);&#xD;
             lock (lockB) {&#xD;
                  Console.WriteLine ("took lock B");&#xD;
             }&#xD;
        }&#xD;
    }&#xD;
    static void reverse_order () {&#xD;
        lock (lockB) {&#xD;
             Console.WriteLine ("took lock B");&#xD;
             // make the deadlock more likely&#xD;
             Thread.Sleep (500);&#xD;
             lock (lockA) {&#xD;
                  Console.WriteLine ("took lock A");&#xD;
             }&#xD;
        }&#xD;
    }&#xD;
    static void Main () {&#xD;
        TestDeadlock td = new TestDeadlock ();&#xD;
        lock (td) {&#xD;
            lock (td) { // twice for testing the nest level&#xD;
                 Thread t1 = new Thread (&#xD;
                       new ThreadStart (normal_order));&#xD;
                 Thread t2 = new Thread (&#xD;
                       new ThreadStart (reverse_order));&#xD;
                 t1.Start ();&#xD;
                 t2.Start ();&#xD;
                 t1.Join ();&#xD;
                 t2.Join ();&#xD;
            }&#xD;
       }&#xD;
   }&#xD;
}&#xD;
&lt;/pre&gt;&#xD;
I added an explicit Sleep () call to make the race condition&#xD;
happen almost every time you run such a program. The issue&#xD;
with such deadlocks is that usually the race time window is&#xD;
very small and it will go unnoticed during testing. The new&#xD;
feature in the mono runtime is designed to help find the&#xD;
issue when a process is stuck and we don't know why.&lt;p&gt;&#xD;
Now you can attach to the stuck process using gdb and issue&#xD;
the following command:&lt;p&gt;&#xD;
&lt;pre&gt;&#xD;
(gdb) call mono_locks_dump (0)&#xD;
&lt;/pre&gt;&#xD;
which results in output like this:&#xD;
&lt;pre&gt;&#xD;
Lock 0x824f108 in object 0x2ffd8 held by thread 0xb7d496c0,&#xD;
nest level: 2&#xD;
Lock 0x824f150 in object 0x2ffe8 held by thread 0xb7356bb0,&#xD;
nest level: 1&#xD;
        Waiting on semaphore 0x40e: 1&#xD;
Lock 0x824f1b0 in object 0x2ffe0 held by thread 0xb7255bb0,&#xD;
nest level: 1&#xD;
        Waiting on semaphore 0x40d: 1&#xD;
Total locks (in 1 array(s)): 16, used: 8, on freelist: 8, to&#xD;
recycle: 0&#xD;
&lt;/pre&gt;&#xD;
We can see that there are three locks currently held by&#xD;
three different threads. The first has been recursively&#xD;
acquired 2 times. The other two are more interesting because&#xD;
they each have a thread waiting on a semaphore associated&#xD;
with the lock structure: they must be the ones involved in&#xD;
the deadlock.&lt;p&gt;&#xD;
Once we know the threads that are deadlocking and the&#xD;
objects that hold the lock we might have a better idea of&#xD;
where exactly to look in the code for incorrect ordering of&#xD;
lock statements.&lt;p&gt;&#xD;
In this particular case it's pretty easy since the objects&#xD;
used for locking are static fields. The easy way to get the&#xD;
class is to notice that the object which is locked twice&#xD;
(0x2ffd8) is of the same class as the static fields:&#xD;
&lt;pre&gt;&#xD;
(gdb) call mono_object_describe (0x2ffd8)&#xD;
TestDeadlock object at 0x2ffd8 (klass: 0x820922c)&#xD;
&lt;/pre&gt;&#xD;
Now we know the class (0x820922c) and we can get a list of&#xD;
the static fields and their values and correlate with the&#xD;
objects locked in the mono_locks_dump () list:&#xD;
&lt;pre&gt;&#xD;
(gdb) call mono_class_describe_statics (0x820922c)&#xD;
At 0x26fd0 (ofs:  0) lockA: System.Object object at 0x2ffe8&#xD;
(klass: 0x820beac)&#xD;
At 0x26fd4 (ofs:  4) lockB: System.Object object at 0x2ffe0&#xD;
(klass: 0x820beac)&#xD;
&lt;/pre&gt;&#xD;
Note that the lockA and lockB objects are the ones listed&#xD;
above as deadlocking.</description>
    </item>
    <item>
      <pubDate>Mon, 20 Nov 2006 17:55:10 GMT</pubDate>
      <title>20 Nov 2006</title>
      <link>http://www.advogato.org/person/lupus/diary.html?start=20</link>
      <guid>http://www.advogato.org/person/lupus/diary.html?start=20</guid>
      <description>&lt;b&gt;Mono on the Nokia 770 OS 2006&lt;/b&gt;&lt;p&gt;&#xD;
Starting with Mono version 1.2.1, the Mono JIT supports the&#xD;
new ARM ABI (also called gnueabi or armel). This is the same&#xD;
ABI used by the 2006 OS update of the Nokia 770 and it&#xD;
should be good news for all the people that asked me about&#xD;
having Mono run on their newly-flashed devices.&lt;p&gt;&#xD;
The changes involved enhancing the JIT to support soft-float&#xD;
targets (this work will also help people porting mono to&#xD;
other embedded architectures without a hardware floating&#xD;
point instruction set) as well as the ARM-specific call&#xD;
convention changes. There was also some hair-pulling&#xD;
involved, since the gcc version provided with scratchbox&#xD;
goes into an infinite loop while compiling the changed&#xD;
mini.c sources when optimizations are enabled, but I'm sure&#xD;
you don't want to know the details...&lt;p&gt;&#xD;
This was not enough, though, to be able to run Gtk#&#xD;
applications on the Nokia 770. When I first ran a simple&#xD;
Gtk# test app I got a SIGILL &lt;em&gt;inside&lt;/em&gt; gtk_init() in a&#xD;
seemlingly simple instruction. Since this happened inside a&#xD;
gcc-compiled binary I had no idea what the JIT could have&#xD;
been doing wrong. Then this morning I noticed that the&#xD;
instructions in gtk_init() were two bytes long: everything&#xD;
became clear again, I needed to implement interworking with&#xD;
Thumb code in the JIT. This required a few changes in how&#xD;
the call instructions are emitted and at callsite patching.&#xD;
The result is that now Mono can P/Invoke shared libraries&#xD;
compiled in Thumb mode (mono itself must still be compiled&#xD;
in ARM mode: this should be easy to fix, but there is no&#xD;
immediate need now for it). Note that this change didn't&#xD;
make it to the mono 1.2.1 release, you'll have to use mono&#xD;
from svn.&lt;p&gt;&#xD;
As part of this work, I also added an option to mono's&#xD;
configure to disable the compilation of the mcs/ directory,&#xD;
which would require running mono in emulation by qemu inside&#xD;
scratchbox. The new option is --disable-mcs-build. This can&#xD;
also be useful when building the runtime on slow boxes, if&#xD;
the building of the mcs/ dir is not needed (common for&#xD;
embedded environments where the managed assemblies are&#xD;
simply copied from an x86 box).&lt;p&gt;&#xD;
There are not yet packages ready for the Nokia 770, though&#xD;
I'll provide a rough tarball of binaries soon: the issue is&#xD;
that at least my version of scratchbox has a qemu build that&#xD;
fails to emulate some syscalls used by mono, so it's hard to&#xD;
build packages that require mono or mcs to be run inside&#xD;
scratchbox. I'm told this bug&#xD;
has been fixed in more recent versions, so I'll report how&#xD;
well jitted code runs in qemu when I'll install a new&#xD;
scratchbox. This is not the best way to handle this, though,&#xD;
because even if qemu can&#xD;
emulate everything mono does, it would be very slow and&#xD;
silly to run it&#xD;
that way: we should run mono on the host, just like we run&#xD;
the cross-compiling gcc on the host from inside scratchbox&#xD;
and make it appear as a native compiler. From a quick look&#xD;
at the documentation, it should be possible to build a mono&#xD;
devkit for scratchbox that does exactly this. This would be&#xD;
very nice for building packages like Gtk# that involve both&#xD;
managed assemblies and unmanaged shared libraries (the Gtk#&#xD;
I used for testing required lots of painful switches between&#xD;
scratchbox for compiling with gcc and another terminal for&#xD;
running the C#-based build helper tools and mcs...). So, if&#xD;
anyone has time and skills to develop such a devkit, it&#xD;
will be much appreciated! Alternatively, we could wait for&#xD;
debian packages to be built as part of the debian project's&#xD;
port to armel, which will use armel build boxes.</description>
    </item>
    <item>
      <pubDate>Fri, 10 Mar 2006 18:38:14 GMT</pubDate>
      <title>10 Mar 2006</title>
      <link>http://www.advogato.org/person/lupus/diary.html?start=19</link>
      <guid>http://www.advogato.org/person/lupus/diary.html?start=19</guid>
      <description>This afternoon Jonathan Pryor pasted on the mono IRC channel an interesting benchmarklet that showed interesting results.
It came from Rico Mariani at http://blogs.msdn.com/ricom/archive/2006/03/09/548097.aspx as a performance quiz. The results are non-intuitive, since it makes it appear that using a simple array is slower than using the List&amp;lt;T&amp;gt; generic implementation (which internally is supposed to use an array itself).&lt;p&gt;
On mono, using the simple array was about 3 times slower than using the generics implementation, so I ran the profiler to find out why.&lt;p&gt;
It turns out that in the implementation of the IList&amp;lt;T&amp;gt; interface methods we used a special generic internal call to access the array elements: this internal call is implemented by a C function that needs to cope with any array element type. But since it is an internal call and the JIT knows what it is supposed to do, I quickly wrote the support to recognize it and inline the instructions to access the array elements. This makes the two versions of the code run with about the same speed (with mono from svn, of course).&lt;p&gt;
The interesting fact is that the MS runtime behaves similarly, with the simple array test running about 3 times slower than the IList&amp;lt;T&amp;gt; implementation. If you're curious about why the MS implementation is so slow, follow the link above: I guess sooner or later some MS people will explain it.</description>
    </item>
    <item>
      <pubDate>Tue, 20 Sep 2005 21:20:43 GMT</pubDate>
      <title>20 Sep 2005</title>
      <link>http://www.advogato.org/person/lupus/diary.html?start=18</link>
      <guid>http://www.advogato.org/person/lupus/diary.html?start=18</guid>
      <description>&lt;b&gt;Mono for ARM/Nokia 770 binaries&lt;/b&gt;&lt;br&gt;
I made tarballs of binaries for use on Linux/ARM systems, including the Nokia 770. And, yes, Gtk# apps work fine on it:-).&lt;br&gt;
Happy hacking, you'll find them &lt;a href="http://primates.ximian.com/~lupus/mono-nokia.tgz" &gt;here&lt;/a&gt;.</description>
    </item>
    <item>
      <pubDate>Mon, 19 Sep 2005 16:49:17 GMT</pubDate>
      <title>19 Sep 2005</title>
      <link>http://www.advogato.org/person/lupus/diary.html?start=17</link>
      <guid>http://www.advogato.org/person/lupus/diary.html?start=17</guid>
      <description>&lt;b&gt;Mono on the Nokia 770&lt;/b&gt;&lt;br&gt;
After the Mono JIT port was done using a desktop little-endian ARM computer, Geoff just recompiled it and run it on a Linksys NSLU2 (which runs a ARM processor in big-endian mode).&lt;br&gt;
That was pretty cool. I wonder if it is as cool as
running mono on a Nokia 770 (no recompilation necessary, just copied the binary from my Debian box). Here it is running &lt;a href="http://primates.ximian.com/~lupus/nokia-770-mono-small.jpeg" &gt; our hello world app&lt;/a&gt;.&lt;br&gt;
Many thanks to the fine folks at Nokia for sending me a prototype so quickly.</description>
    </item>
  </channel>
</rss>
