[Mono-list] Announce: A .NET assembly -> native code generationtool (ala ngen for MONO)

Zoltan.2.Varga@nokia.com Zoltan.2.Varga@nokia.com
Mon, 29 Jul 2002 15:30:14 +0200

					Hi All,

> -----Original Message-----
> From: ext Dietmar Maurer [mailto:dietmar@ximian.com]
> Sent: 29. July 2002 14:16
> To: Paolo Molaro; Varga Zoltan.2 (NMP/Budapest)
> Cc: Mono List
> Subject: Re: [Mono-list] Announce: A .NET assembly -> native code
> generationtool (ala ngen for MONO)
> On Mon, 2002-07-29 at 12:34, Paolo Molaro wrote:
> > On 07/29/02 Dietmar Maurer wrote:
> > >         1. It does not work with exceptions: The current code is
> > >            incorrect because it does not save/restore the LMF when
> > >            calling precompiled methods - but 
> saving/restoring the LMF
> > >            would lead to serious performance problems.
> > 
> > As long as the native code doesn't handle exceptions, the only info
> > needed is registering the method code address and size, 
> there is no need
> > to save/restore the LMF, right? I saw the code that uses objdump, so
> > maybe this is already handled.
> > Actually, if this turns out to work, we may want to use it 
> also for the
> > internalcalls.
> Ok, if we trust such code we can use the objdump hack. Although
> restoring the registers is still a big hack.

It is :(. In fact, I just fixed a bug which caused the enum2.exe test to fail: Enum::Parse used so much stack space that
gcc generated a sub <IMM32>, %esp opcode into the prelude, which my exception handling code couldn't handle. 
I use objdump because I found no other way to determine the size of the compiled functions. 

> > 
> > > > What I wanted to look into was to use the JIT to 
> generate code that
> > > > would end up in a library, basically reusing the JIT, 
> but turning on all
> > > > the optimizations for this.
> > > This approach would also avoid much code duplication. 
> > > 
> > > So IMO we should first check if we gain anything by using 
> gcc, and of
> > > course we need a solution for the exception problem? 
> > 
> > I think the approach of using gcc is certainly interesting 
> even if the
> > first snapshot has limitations.
> > The primary purpouse of ngen-ed assemblies is to reduce 
> startup and JIT
> > costs (microsoft itself documents ngen-assemblies being 
> slower code-wise
> > than jitted code...). Of course, performance is an bonus:-), but I'm
> > very impressed with the first snapshot.
> > 
> > The gain in mcs compilation times, for example, seems to match
> > pretty well with the jit overhead as measured with mono --profile.
> > And, of course, mcs is not a good benchmark for native code quality.
> > 
> > Of the current limitations, the .ovf opcodes seems only a matter of
> > (boring) programming, mostly. The exception handling stuff 
> is certainly
> > harder and if done using the C++ exception tables, it will
> > require porting efforts between different compilers. However, I just
> > checked and methods with exception tables are less than 7% 
> in mcs and
> > less than 2% in corlib, so even if 5% of the methods still 
> need to be
> > jitted, it's not a big problem.
> good news ;-)
> > 
> > My main concern with using gcc is that we might not be able 
> to constrain
> > the gcc optimizer to obey the CLR rules (Zoltan notes the 
> problem with
> > division by 0, for example). Using the JIT to output the 
> code would give
> > us better control on such issues, but researching these 
> issues is the
> > only way to find out if the concept works:-)
> So I think everybody agrees that it would be nice to have a 
> native code
> generator, so integrating that code into the sources should 
> be the goal.
> All I am concerned about it to avoid code duplication, which makes it
> hard to maintain that code. I would like to share as much code as
> possible with the JIT.

If there is concern whenever this will be the 'real' MONO ngen, I would gladly name it something else. Any ideas?

> Unfortunately the current patch is much to large to integrate. What we
> need is a bunch of smaller patches which we can integrate into our
> codebase.

I plan on maintaining the code whenever its integrated into MONO CVS or not. The current patch is 600 lines long 
(this includes the context added by diff) + the two new files (ngen-runtime.{c,h}). It includes the following:

  ngen-runtime.{c,h} - this does the loading and linking in of native assemblies
  appdomain.h        - adds a new field to MonoJitInfo
  assembly.{c,h}     - adds a callback function which will be called when an assembly is loaded
  exception.c        - adds exception handling for native methods (hackish)
  mono.c             - adds additional command line arguments + installs the native assembly loading callback
  trampoline.c       - adds a new trampoline which can be called by the native methods + adds a new argument to
                       x86_magic_trampoline so it can read the receiver off the stack
  There are two bug fixes/improvements in the patch:
   reflection.c      - speed up mono_type_get_object which seems to be called a lot
   trampoline.c      - the arch_get_trampoline function sometimes returns a pointer to JIT generated code instead of a 
			     trampoline. This is wrong if the returned pointer is put into a vtable. This is not happening 				     currently, but I think it is by coincidence not by design :).



> - Dietmar