documentation updates
authorDietmar Maurer <dietmar@mono-cvs.ximian.com>
Fri, 15 Mar 2002 08:23:34 +0000 (08:23 -0000)
committerDietmar Maurer <dietmar@mono-cvs.ximian.com>
Fri, 15 Mar 2002 08:23:34 +0000 (08:23 -0000)
svn path=/trunk/mono/; revision=3126

docs/exceptions
docs/jit-thoughts
docs/jit-trampolines [new file with mode: 0644]
docs/object-layout
docs/unmanaged-calls

index ab0f2dec94ad67ae47efeea238dd671a02b28553..3bf2e6068124f4f7f89d55e36027f4183226ee46 100644 (file)
@@ -1,3 +1,6 @@
+Author: Dietmar Maurer (dietmar@ximian.com)
+(C) 2001 Ximian, Inc.
+
 Exception implementation (jit):
 ===============================
 
@@ -8,8 +11,15 @@ We record the code address (start_address, size) of all methods. That way it is
 possible to map an instruction pointer (IP) to the method information needed
 for unwinding the stack:
 
+We also save a Last Managed Frame (LMF) structure at each call from managed to
+unmanaged code. That way we can recover from exceptions inside unmanaged code.
+
 void handle_exception ((struct sigcontext *ctx, gpointer obj)
 {
+        if (ctx->ip < mono_end_of_stack) {
+               /* unhandled exception */
+               abort ();
+       }
 
        info = mono_jit_info_table_find (mono_jit_info_table, ctx->ip);
 
@@ -21,14 +31,20 @@ void handle_exception ((struct sigcontext *ctx, gpointer obj)
                execute_all_finally_handler ();
 
                // restore register, including IP and Frame pointer
-               restore_caller_saved_registers (ji, ctx);
+               ctx = restore_caller_saved_registers_from_ctx (ji, ctx);
 
                // continue unwinding
                handle_exception (ctx, obj);
 
        } else {
 
-               // not implemented 
+               lmf = get_last_managed_frame ();
+               
+               // restore register, including IP and Frame pointer
+               ctx = restore_caller_saved_registers_from_lmf (ji, lmf);
+               
+               // continue unwinding
+               handle_exception (ctx, obj);
        }
 }
 
index 90cf4785523d9f562172fb42417b75a936d7cdae..cb50d0ecd05d3bb6bf30aceb7a7fc83eafbe5a3a 100644 (file)
@@ -11,48 +11,6 @@ We are designing a JIT compiler, so we have to consider two things:
 The current approach is to keep the JITer as simple as possible, and thus as
 fast as possible. The generated code quality will suffer from that.
 
-Register allocation is first done inside the trees of the forest, and each
-tree can use the full set of registers. We simply split a tree if we get out of
-registers, for example the following tree:
-
-
-              add(R0)
-             /   \
-            /     \
-           a(R0)  add(R1)
-                 /   \
-                /     \
-               b(R1)  add(R2)
-                     /   \
-                    /     \
-                   c(R2)   b(R3)
-
-can be transformed to:
-
-
-       stloc(t1)         add(R0)
-         |              /   \
-         |             /     \
-        add(R0)       a(R0)  add(R1)
-       /   \                /   \
-      /     \              /     \
-     c(R0)   b(R1)        b(R1)  t1(R2)
-
-
-Please notice that the split trees use less registers than the original
-tree. 
-
-Triggering JIT compilation:
-===========================
-
-The current approach is to call functions indirectly. The address to call is
-stored in the MonoMethod structure. For each method we create a trampoline
-function. When called, this function does the JIT compilation and replaces the
-trampoline with the compiled method address.
-
-We should consider using the CACAO approach, they do not use a trampoline at
-all.
-
 Register Allocation:
 ====================
 
@@ -61,15 +19,6 @@ allocation. For example this is needed by call, which return the value always
 in EAX on x86. The current implementation works without such system, due to
 special forest generation.
 
-X86 Register Allocation:
-========================
-
-We can use 8bit or 16bit registers on the x86. If we use that feature we have
-more registers to allocate, which maybe prevents some register spills. We
-currently ignore that ability and always allocate 32 bit registers, because I
-think we would gain very little from that optimisation and it would complicate
-the code.
-
 Different Register Sets:
 ========================
 
@@ -86,11 +35,10 @@ call class methods for ALU operations like add or sub. Sure, this method will
 be be a bit inefficient.
 
 The more performant solution is to allocate two 32bit registers for each 64bit
-value. We add a new non terminal to the monoburg grammar called long_reg. The
+value. We add a new non terminal to the monoburg grammar called "lreg". The
 register allocation routines takes care of this non terminal and allocates two
 32 bit registers for them.
 
-
 Forest generation:
 ==================
 
@@ -157,14 +105,6 @@ STLOC(ADD (LDLOC, LDLOC))
 
 This is what lcc is doing, if I understood 12.8, page 342, 343?
 
-Value Types:
-============
-
-The only CLI instructions which can handle value types are loads and stores,
-either to local variable, to the stack or to array elements. Value types with a
-size smaller than sizeof(int) are handled like any other basic type. For other
-value types we load the base address and emit block copies to store them. 
-
 Possible Optimisations:
 =======================
 
@@ -180,3 +120,6 @@ else for (i = 0; i < N; i++) { check_range (a, i); a [i] = X; }
 
 The "else" is only to keep original semantics (exception handling).
 
+We need loop detection logic in order to implement this (dominator tree).
+
+AFAIK CACAO also implements this.
\ No newline at end of file
diff --git a/docs/jit-trampolines b/docs/jit-trampolines
new file mode 100644 (file)
index 0000000..d8b80b5
--- /dev/null
@@ -0,0 +1,52 @@
+Author: Dietmar Maurer (dietmar@ximian.com)
+(C) 2001 Ximian, Inc.
+Howto trigger JIT compilation
+=============================
+
+The JIT translates CIL code to native code on a per method basis. For example
+if you have this simple program:
+
+public class Test {
+       public static void Main () {            
+               System.Console.WriteLine ("Hello");
+       }
+}
+
+the JIT first compiles the Main function. Unfortunately Main() contains another
+reference to System.Console.WriteLine(), so the JIT also needs the address for
+WriteLine() to generate a call instruction.
+
+The simplest solution would be to JIT compile System.Console.WriteLine()
+to generate that address. But that would mean that we JIT compile half of our
+class library at once, since WriteLine() uses many other classes and function,
+and we have to call the JIT for each of them. Even worse there is the
+possibility of cyclic references, and we would end up in an endless loop.
+
+Thus we need some kind of trampoline function for JIT compilation. Such a
+trampoline first calls the JIT compiler to create native code, and then jumps
+directly into that code. Whenever the JIT needs the address of a function (to
+emit a call instruction) it uses the address of those trampoline functions.
+
+One drawback of this approach is that it requires an additional indirection. We
+always call the trampoline. Inside the trampoline we need to check if the
+method is already compiled or not, and when not compiled we start JIT
+compilation. After that we call the code. This process is quite time consuming
+and shows very bad performance.
+
+The solution is to add some logic to the trampoline function to detect from
+where it is called. It is then possible for the JIT to patch the call
+instruction in the caller, so that it directly calls the JIT compiled code
+next time.
+
+Implementation for x86
+======================
+
+emit-x86.c (arch_create_jit_trampoline): return the JIT trampoline function
+
+emit-x86.c (x86_magic_trampoline): contains the code to detect the caller and
+patch the call instruction.
+
+emit-x86.c (arch_compile_method): JIT compile a method
+
+
index 8135ca2805f8d46f013f22e49ad5d7923a265e3c..4916751d1e73c97948d51b8c792cb400e500d397 100644 (file)
@@ -1,3 +1,6 @@
+Author: Dietmar Maurer (dietmar@ximian.com)
+(C) 2001 Ximian, Inc.
+
 Object and VTable layout
 ========================
 
index 55c38ea4561147f711c6ef99f395fb8abd19389d..7542623166bb74c22d1dd7e14bafcf13b229dafe 100644 (file)
@@ -1,3 +1,6 @@
+Author: Dietmar Maurer (dietmar@ximian.com)
+(C) 2001 Ximian, Inc.
+
 More about PInvoke and Internal calls
 =====================================