Author: zoltan
Date: 2008-01-25 09:58:49 -0500 (Fri, 25 Jan 2008)
New Revision: 93903

Modified:
   trunk/mono/mono/mini/ChangeLog
   trunk/mono/mono/mini/Makefile.am
   trunk/mono/mono/mini/mini-s390.h
   trunk/mono/mono/mini/tramp-s390.c
Log:
2008-01-25  Zoltan Varga  <[EMAIL PROTECTED]>

        * mini-s390.h tramp-s390.c Makefile.am: Rework the s390 trampoline code 
to use
        the arch independent trampoline code in mini-trampolines.c.


Modified: trunk/mono/mono/mini/ChangeLog
===================================================================
--- trunk/mono/mono/mini/ChangeLog      2008-01-25 14:39:14 UTC (rev 93902)
+++ trunk/mono/mono/mini/ChangeLog      2008-01-25 14:58:49 UTC (rev 93903)
@@ -1,5 +1,8 @@
 2008-01-25  Zoltan Varga  <[EMAIL PROTECTED]>
 
+       * mini-s390.h tramp-s390.c Makefile.am: Rework the s390 trampoline code 
to use
+       the arch independent trampoline code in mini-trampolines.c.
+
        * mini-arm.c (mono_arch_emit_prolog): Fix build.
 
 2008-01-24  Zoltan Varga  <[EMAIL PROTECTED]>

Modified: trunk/mono/mono/mini/Makefile.am
===================================================================
--- trunk/mono/mono/mini/Makefile.am    2008-01-25 14:39:14 UTC (rev 93902)
+++ trunk/mono/mono/mini/Makefile.am    2008-01-25 14:58:49 UTC (rev 93903)
@@ -163,7 +163,8 @@
        mini-s390.c             \
        mini-s390.h             \
        exceptions-s390.c       \
-       tramp-s390.c
+       tramp-s390.c        \
+       mini-trampolines.c
 
 s390x_sources = \
        mini-s390x.c            \

Modified: trunk/mono/mono/mini/mini-s390.h
===================================================================
--- trunk/mono/mono/mini/mini-s390.h    2008-01-25 14:39:14 UTC (rev 93902)
+++ trunk/mono/mono/mini/mini-s390.h    2008-01-25 14:58:49 UTC (rev 93903)
@@ -160,6 +160,7 @@
 // #define MONO_ARCH_SIGSEGV_ON_ALTSTACK               1
 // #define MONO_ARCH_SIGNAL_STACK_SIZE         65536
 // #define MONO_ARCH_HAVE_THROW_CORLIB_EXCEPTION       1
+#define MONO_ARCH_HAVE_CREATE_SPECIFIC_TRAMPOLINE 1
 
 #define MONO_ARCH_USE_SIGACTION        1
 // #define CUSTOM_STACK_WALK           1

Modified: trunk/mono/mono/mini/tramp-s390.c
===================================================================
--- trunk/mono/mono/mini/tramp-s390.c   2008-01-25 14:39:14 UTC (rev 93902)
+++ trunk/mono/mono/mini/tramp-s390.c   2008-01-25 14:58:49 UTC (rev 93903)
@@ -29,10 +29,9 @@
 #define CREATE_STACK_SIZE      
(CREATE_LMF_OFFSET+2*sizeof(long)+sizeof(MonoLMF))
 
 /*------------------------------------------------------------------*/
-/* Method-specific trampoline code fragment sizes                  */
+/* Specific trampoline code fragment sizes                                 */
 /*------------------------------------------------------------------*/
-#define METHOD_TRAMPOLINE_SIZE 64
-#define JUMP_TRAMPOLINE_SIZE   64
+#define SPECIFIC_TRAMPOLINE_SIZE       64
 
 /*========================= End of Defines =========================*/
 
@@ -75,7 +74,7 @@
 
 /*------------------------------------------------------------------*/
 /*                                                                  */
-/* Name                - get_unbox_trampoline                              */
+/* Name                - mono_arch_get_unbox_trampoline                        
*/
 /*                                                                  */
 /* Function    - Return a pointer to a trampoline which does the   */
 /*               unboxing before calling the method.               */
@@ -88,19 +87,22 @@
 /*                                                                 */
 /*------------------------------------------------------------------*/
 
-static gpointer
-get_unbox_trampoline (MonoMethod *method, gpointer addr)
+gpointer
+mono_arch_get_unbox_trampoline (MonoMethod *method, gpointer addr)
 {
        guint8 *code, *start;
        int this_pos = s390_r2;
+       MonoDomain *domain = mono_domain_get ();
 
        start = addr;
        if ((!mono_method_signature (method)->ret->byref) && 
            (MONO_TYPE_ISSTRUCT (mono_method_signature (method)->ret)))
                this_pos = s390_r3;
-    
-       start = code = mono_global_codeman_reserve (28);
 
+       mono_domain_lock (domain);
+       start = code = mono_code_manager_reserve (domain->code_mp, 28);
+       mono_domain_unlock (domain);
+    
        s390_basr (code, s390_r13, 0);
        s390_j    (code, 4);
        s390_word (code, addr);
@@ -110,6 +112,8 @@
 
        g_assert ((code - start) <= 28);
 
+       mono_arch_flush_icache (start, code - start);
+
        return start;
 }
 
@@ -117,123 +121,141 @@
 
 /*------------------------------------------------------------------*/
 /*                                                                  */
-/* Name                - s390_magic_trampoline                             */
+/* Name                - mono_arch_patch_callsite                              
*/
 /*                                                                  */
-/* Function    - This method is called by the function             */
-/*                "arch_create_jit_trampoline", which in turn is    */
-/*                called by the trampoline functions for virtual    */
-/*                methods. After having called the JIT compiler to  */
-/*                compile the method, it inspects the caller code   */
-/*                to find the address of the method-specific part   */
-/*                of the trampoline vtable slot for this method,    */
-/*                updates it with a fragment that calls the newly   */
-/*                compiled code and returns this address. The calls */
-/*                generated by mono for S/390 will look like either:*/
-/*                1. l     %r1,xxx(%rx)                             */
-/*                   bras  %r14,%r1                                 */
-/*                2. brasl %r14,xxxxxx                              */
+/* Function    - Patch a non-virtual callsite so it calls @addr.       */
 /*                                                                  */
-/* Parameters   - code   - Pointer into caller code                 */
-/*                method - The method to compile                    */
-/*                sp     - Stack pointer                            */
-/*                                                                  */
 /*------------------------------------------------------------------*/
 
-static gpointer
-s390_magic_trampoline (MonoMethod *method, guchar *code, char *sp)
+void
+mono_arch_patch_callsite (guint8 *orig_code, guint8 *addr)
 {
-       gpointer addr;
        gint32 displace;
-       int reg;
-       guchar* base;
        unsigned short opcode;
-       MonoJitInfo *codeJi, 
-                   *addrJi;
 
-       addr = mono_compile_method(method);
-       g_assert(addr);
+       opcode = *((unsigned short *) (orig_code - 6));
+       /* This should be a 'brasl' instruction */
+       g_assert (opcode ==  0xc0e5);
+       orig_code    -= 4;
+       displace = ((gint32) addr - (gint32) (orig_code - 2)) / 2;
+       s390_patch (orig_code, displace);
+       mono_arch_flush_icache (orig_code, 4);
+}
 
+/*========================= End of Function ========================*/
 
-       if (code) {
+void
+mono_arch_patch_plt_entry (guint8 *code, guint8 *addr)
+{
+       g_assert_not_reached ();
+}
 
-               /* The top bit needs to be ignored on S/390 */
-               code = (guchar*)((guint32)code & 0x7fffffff);
+/*========================= End of Function ========================*/
 
-               codeJi = mono_jit_info_table_find (mono_domain_get(), code);
-               addrJi = mono_jit_info_table_find (mono_domain_get(), addr);
-               if (mono_method_same_domain (codeJi, addrJi)) {
+/*------------------------------------------------------------------*/
+/*                                                                  */
+/* Name                - mono_arch_nullify_class_init_trampoline               
*/
+/*                                                                  */
+/* Function    - Nullify a call which calls a class init trampoline    */
+/*                                                                  */
+/*------------------------------------------------------------------*/
 
-                       opcode = *((unsigned short *) (code - 6));
-                       switch (opcode) {
-                       case 0x5810 :
-                               /* This is a bras r14,r1 instruction */
-                               code    -= 4;
-                               reg      = *code >> 4;
-                               displace = *((short *)code) & 0x0fff;
-                               if (reg > 5) 
-                                       base = *((guchar **) (sp + 
S390_REG_SAVE_OFFSET+
-                                                              
sizeof(int)*(reg-6)));
-                               else
-                                       base = *((guchar **) ((sp - 
CREATE_STACK_SIZE) + 
-                                                              CREATE_GR_OFFSET 
+
-                                                              
sizeof(int)*(reg-2)));
+void
+mono_arch_nullify_class_init_trampoline (guint8 *code, gssize *regs)
+{
+       char patch[6] = {0x47, 0x00, 0x00, 0x00, 0x07, 0x00};
 
-                               if ((method->klass->valuetype) && 
-                                   (!mono_aot_is_got_entry(code, base))) 
-                                       addr = get_unbox_trampoline(method, 
addr);
+       code = code - 6;
 
-                               code = base + displace;
-                               if 
(mono_domain_owns_vtable_slot(mono_domain_get(), 
-                                                                code))
-                                       s390_patch(code, (guint32) addr);
-                               break;
-                       case 0xc0e5 :
-                               /* This is the 'brasl' instruction */
-                               code    -= 4;
-                               displace = ((gint32) addr - (gint32) (code - 
2)) / 2;
-                               if (mono_method_same_domain (codeJi, addrJi)) {
-                                       s390_patch (code, displace);
-                                       mono_arch_flush_icache (code, 4);
-                               }
-                               break;
-                       default :
-                               g_error("Unable to patch instruction prior to 
%p",code);
-                       }
-               }
-       }
+       memcpy(code, patch, sizeof(patch));
+}
 
+/*========================= End of Function ========================*/
 
-       return addr;
+void
+mono_arch_nullify_plt_entry (guint8 *code)
+{
+       g_assert_not_reached ();
 }
 
 /*========================= End of Function ========================*/
 
 /*------------------------------------------------------------------*/
 /*                                                                  */
-/* Name                - s390_class_init_trampoline                        */
+/* Name                - mono_arch_get_vcall_slot                              
*/
 /*                                                                  */
-/* Function    - Initialize a class and then no-op the call to     */
-/*                the trampoline.                                   */
+/* Function    - This method is called by the arch independent         */
+/*            trampoline code to determine the vtable slot used by  */
+/*            the call which invoked the trampoline.                */
+/*                The calls                                         */
+/*                generated by mono for S/390 will look like either:*/
+/*                1. l     %r1,xxx(%rx)                             */
+/*                   bras  %r14,%r1                                 */
+/*                2. brasl %r14,xxxxxx                              */
 /*                                                                  */
+/* Parameters   - code   - Pointer into caller code                 */
+/*                regs   - Register state at the point of the call  */
+/*                displacement - Out parameter which will receive   */
+/*                the displacement of the vtable slot               */
+/*                                                                  */
 /*------------------------------------------------------------------*/
 
-static void
-s390_class_init_trampoline (void *vtable, guchar *code, char *sp)
+gpointer
+mono_arch_get_vcall_slot (guint8 *code, gpointer *regs, int *displacement)
 {
-       char patch[6] = {0x47, 0x00, 0x00, 0x00, 0x07, 0x00};
+       int reg;
+       guchar* base;
+       unsigned short opcode;
+       char *sp;
 
-       mono_runtime_class_init (vtable);
+       // We are passed sp instead of the register array
+       sp = (char*)regs;
 
-       code = code - 6;
+       *displacement = 0;
 
-       memcpy(code, patch, sizeof(patch));
+       opcode = *((unsigned short *) (code - 6));
+       switch (opcode) {
+       case 0x5810 :
+               /* This is a bras r14,r1 instruction */
+               code    -= 4;
+               reg      = *code >> 4;
+               *displacement = *((short *)code) & 0x0fff;
+               if (reg > 5) 
+                       base = *((guchar **) (sp + S390_REG_SAVE_OFFSET+
+                                                                 
sizeof(int)*(reg-6)));
+               else
+                       base = *((guchar **) ((sp - CREATE_STACK_SIZE) + 
+                                                                 
CREATE_GR_OFFSET +
+                                                                 
sizeof(int)*(reg-2)));
+               return base;
+       case 0xc0e5 :
+               /* This is the 'brasl' instruction */
+               return NULL;
+       default :
+               g_error("Unable to patch instruction prior to %p",code);
+       }
+
+       return NULL;
 }
 
 /*========================= End of Function ========================*/
 
+gpointer*
+mono_arch_get_vcall_slot_addr (guint8* code, gpointer *regs)
+{
+       gpointer vt;
+       int displacement;
+       vt = mono_arch_get_vcall_slot (code, regs, &displacement);
+       if (!vt)
+               return NULL;
+       return (gpointer*)((char*)vt + displacement);
+}
+
+/*========================= End of Function ========================*/
+
 /*------------------------------------------------------------------*/
 /*                                                                  */
-/* Name                - mono_arch_create_trampoline_code                      
      */
+/* Name                - mono_arch_create_trampoline_code                      
*/
 /*                                                                  */
 /* Function    - Create the designated type of trampoline according*/
 /*                to the 'tramp_type' parameter.                    */
@@ -244,183 +266,188 @@
 mono_arch_create_trampoline_code (MonoTrampolineType tramp_type)
 {
 
-       guint8 *buf, *code = NULL;
+       guint8 *buf, *tramp, *code;
        int i, offset, lmfOffset;
 
-       if(!code) {
-               /* Now we'll create in 'buf' the S/390 trampoline code. This
-                is the trampoline code common to all methods  */
+       /* Now we'll create in 'buf' the S/390 trampoline code. This
+          is the trampoline code common to all methods  */
                
-               code = buf = mono_global_codeman_reserve(512);
+       code = buf = mono_global_codeman_reserve (512);
                
-               /*-----------------------------------------------------------
-               STEP 0: First create a non-standard function prologue with a
-               stack size big enough to save our registers.
-               -----------------------------------------------------------*/
+       /*-----------------------------------------------------------
+         STEP 0: First create a non-standard function prologue with a
+         stack size big enough to save our registers.
+         -----------------------------------------------------------*/
                
-               s390_stm  (buf, s390_r6, s390_r14, STK_BASE, 
S390_REG_SAVE_OFFSET);
-               s390_lr   (buf, s390_r11, s390_r15);
-               s390_ahi  (buf, STK_BASE, -CREATE_STACK_SIZE);
-               s390_st   (buf, s390_r11, 0, STK_BASE, 0);
-               s390_st   (buf, s390_r1, 0, STK_BASE, METHOD_SAVE_OFFSET);
-               s390_stm  (buf, s390_r2, s390_r5, STK_BASE, CREATE_GR_OFFSET);
+       s390_stm  (buf, s390_r6, s390_r14, STK_BASE, S390_REG_SAVE_OFFSET);
+       s390_lr   (buf, s390_r11, s390_r15);
+       s390_ahi  (buf, STK_BASE, -CREATE_STACK_SIZE);
+       s390_st   (buf, s390_r11, 0, STK_BASE, 0);
+       s390_st   (buf, s390_r1, 0, STK_BASE, METHOD_SAVE_OFFSET);
+       s390_stm  (buf, s390_r2, s390_r5, STK_BASE, CREATE_GR_OFFSET);
 
-               /* Save the FP registers */
-               offset = CREATE_FP_OFFSET;
-               for (i = s390_f0; i <= s390_f15; ++i) {
-                       s390_std  (buf, i, 0, STK_BASE, offset);
-                       offset += 8;
-               }
+       /* Save the FP registers */
+       offset = CREATE_FP_OFFSET;
+       for (i = s390_f0; i <= s390_f15; ++i) {
+               s390_std  (buf, i, 0, STK_BASE, offset);
+               offset += 8;
+       }
 
-               /*----------------------------------------------------------
-               STEP 1: call 'mono_get_lmf_addr()' to get the address of our
-               LMF. We'll need to restore it after the call to
-               's390_magic_trampoline' and before the call to the native
-               method.
-               ----------------------------------------------------------*/
+       /*----------------------------------------------------------
+         STEP 1: call 'mono_get_lmf_addr()' to get the address of our
+         LMF. We'll need to restore it after the call to
+         's390_magic_trampoline' and before the call to the native
+         method.
+         ----------------------------------------------------------*/
                                
-               s390_basr (buf, s390_r13, 0);
-               s390_j    (buf, 4);
-               s390_word (buf, mono_get_lmf_addr);
-               s390_l    (buf, s390_r1, 0, s390_r13, 4);
-               s390_basr (buf, s390_r14, s390_r1);
+       s390_basr (buf, s390_r13, 0);
+       s390_j    (buf, 4);
+       s390_word (buf, mono_get_lmf_addr);
+       s390_l    (buf, s390_r1, 0, s390_r13, 4);
+       s390_basr (buf, s390_r14, s390_r1);
 
-               
/*---------------------------------------------------------------*/
-               /* we build the MonoLMF structure on the stack - see 
mini-s390.h */
-               /* Keep in sync with the code in mono_arch_emit_prolog          
 */
-               
/*---------------------------------------------------------------*/
-               lmfOffset = CREATE_STACK_SIZE - sizeof(MonoLMF);
+       /*---------------------------------------------------------------*/
+       /* we build the MonoLMF structure on the stack - see mini-s390.h */
+       /* Keep in sync with the code in mono_arch_emit_prolog           */
+       /*---------------------------------------------------------------*/
+       lmfOffset = CREATE_STACK_SIZE - sizeof(MonoLMF);
                                                                                
        
-               s390_lr    (buf, s390_r13, STK_BASE);
-               s390_ahi   (buf, s390_r13, lmfOffset);  
+       s390_lr    (buf, s390_r13, STK_BASE);
+       s390_ahi   (buf, s390_r13, lmfOffset);  
                                                                                
        
-               
/*---------------------------------------------------------------*/     
-               /* Set lmf.lmf_addr = jit_tls->lmf                              
 */     
-               
/*---------------------------------------------------------------*/     
-               s390_st    (buf, s390_r2, 0, s390_r13,                          
+       /*---------------------------------------------------------------*/     
+       /* Set lmf.lmf_addr = jit_tls->lmf                               */     
+       /*---------------------------------------------------------------*/     
+       s390_st    (buf, s390_r2, 0, s390_r13,                          
                            G_STRUCT_OFFSET(MonoLMF, lmf_addr));                
        
                                                                                
        
-               
/*---------------------------------------------------------------*/     
-               /* Get current lmf                                              
 */     
-               
/*---------------------------------------------------------------*/     
-               s390_l     (buf, s390_r0, 0, s390_r2, 0);                       
        
+       /*---------------------------------------------------------------*/     
+       /* Get current lmf                                               */     
+       /*---------------------------------------------------------------*/     
+       s390_l     (buf, s390_r0, 0, s390_r2, 0);                               
                                                                                
        
-               
/*---------------------------------------------------------------*/     
-               /* Set our lmf as the current lmf                               
 */     
-               
/*---------------------------------------------------------------*/     
-               s390_st    (buf, s390_r13, 0, s390_r2, 0);                      
        
+       /*---------------------------------------------------------------*/     
+       /* Set our lmf as the current lmf                                */     
+       /*---------------------------------------------------------------*/     
+       s390_st    (buf, s390_r13, 0, s390_r2, 0);                              
                                                                                
        
-               
/*---------------------------------------------------------------*/     
-               /* Have our lmf.previous_lmf point to the last lmf              
 */     
-               
/*---------------------------------------------------------------*/     
-               s390_st    (buf, s390_r0, 0, s390_r13,                          
+       /*---------------------------------------------------------------*/     
+       /* Have our lmf.previous_lmf point to the last lmf               */     
+       /*---------------------------------------------------------------*/     
+       s390_st    (buf, s390_r0, 0, s390_r13,                          
                            G_STRUCT_OFFSET(MonoLMF, previous_lmf));            
        
                                                                                
        
-               
/*---------------------------------------------------------------*/     
-               /* save method info                                             
 */     
-               
/*---------------------------------------------------------------*/     
-               s390_l     (buf, s390_r1, 0, STK_BASE, METHOD_SAVE_OFFSET);
-               s390_st    (buf, s390_r1, 0, s390_r13,                          
+       /*---------------------------------------------------------------*/     
+       /* save method info                                              */     
+       /*---------------------------------------------------------------*/     
+       s390_l     (buf, s390_r1, 0, STK_BASE, METHOD_SAVE_OFFSET);
+       s390_st    (buf, s390_r1, 0, s390_r13,                          
                            G_STRUCT_OFFSET(MonoLMF, method));                  
        
                                                                        
-               
/*---------------------------------------------------------------*/     
-               /* save the current SP                                          
 */     
-               
/*---------------------------------------------------------------*/     
-               s390_l     (buf, s390_r1, 0, STK_BASE, 0);
-               s390_st    (buf, s390_r1, 0, s390_r13, G_STRUCT_OFFSET(MonoLMF, 
ebp));  
+       /*---------------------------------------------------------------*/     
+       /* save the current SP                                           */     
+       /*---------------------------------------------------------------*/     
+       s390_l     (buf, s390_r1, 0, STK_BASE, 0);
+       s390_st    (buf, s390_r1, 0, s390_r13, G_STRUCT_OFFSET(MonoLMF, ebp));  
                                                                        
-               
/*---------------------------------------------------------------*/     
-               /* save the current IP                                          
 */     
-               
/*---------------------------------------------------------------*/     
-               if (tramp_type == MONO_TRAMPOLINE_JUMP) {
-                       s390_lhi   (buf, s390_r1, 0);
-               } else {
-                       s390_l     (buf, s390_r1, 0, s390_r1, 
S390_RET_ADDR_OFFSET);
-                       s390_la    (buf, s390_r1, 0, s390_r1, 0);
-               }
-               s390_st    (buf, s390_r1, 0, s390_r13, G_STRUCT_OFFSET(MonoLMF, 
eip));  
+       /*---------------------------------------------------------------*/     
+       /* save the current IP                                           */     
+       /*---------------------------------------------------------------*/     
+       if (tramp_type == MONO_TRAMPOLINE_JUMP) {
+               s390_lhi   (buf, s390_r1, 0);
+       } else {
+               s390_l     (buf, s390_r1, 0, s390_r1, S390_RET_ADDR_OFFSET);
+               s390_la    (buf, s390_r1, 0, s390_r1, 0);
+       }
+       s390_st    (buf, s390_r1, 0, s390_r13, G_STRUCT_OFFSET(MonoLMF, eip));  
                                                                                
        
-               
/*---------------------------------------------------------------*/     
-               /* Save general and floating point registers                    
 */     
-               
/*---------------------------------------------------------------*/     
-               s390_stm   (buf, s390_r2, s390_r12, s390_r13,                   
        
+       /*---------------------------------------------------------------*/     
+       /* Save general and floating point registers                     */     
+       /*---------------------------------------------------------------*/     
+       s390_stm   (buf, s390_r2, s390_r12, s390_r13,                           
                            G_STRUCT_OFFSET(MonoLMF, gregs[2]));                
        
-               for (i = 0; i < 16; i++) {                                      
        
-                       s390_std  (buf, i, 0, s390_r13,                         
        
+       for (i = 0; i < 16; i++) {                                              
+               s390_std  (buf, i, 0, s390_r13,                                 
                                   G_STRUCT_OFFSET(MonoLMF, fregs[i]));         
        
-               }                                                               
        
+       }
 
-               
/*---------------------------------------------------------------*/
-               /* STEP 2: call 's390_magic_trampoline()', who will compile the 
 */
-               /* code and fix the method vtable entry for us                  
 */
-               
/*---------------------------------------------------------------*/
+       /*---------------------------------------------------------------*/
+       /* STEP 2: call the C trampoline function                        */
+       /*---------------------------------------------------------------*/
                                
-               /* Set arguments */
+       /* Set arguments */
+
+       /* Arg 1: gssize *regs. We pass sp instead */
+       s390_lr   (buf, s390_r2, STK_BASE);
+       s390_ahi  (buf, s390_r2, CREATE_STACK_SIZE);
                
-               /* Arg 1: MonoMethod *method. It was put in r1 by the
-               method-specific trampoline code, and then saved before the call
-               to mono_get_lmf_addr()'. */
-               s390_l  (buf, s390_r2, 0, STK_BASE, METHOD_SAVE_OFFSET);
-               
-               /* Arg 2: code (next address to the instruction that called us) 
*/
-               if (tramp_type == MONO_TRAMPOLINE_JUMP) {
-                       s390_lhi (buf, s390_r3, 0);
-               } else {
-                       s390_l  (buf, s390_r3, 0, s390_r11, 
S390_RET_ADDR_OFFSET);
-               }
-               
-               /* Arg 3: stack pointer */
-               s390_lr   (buf, s390_r4, STK_BASE);
-               s390_ahi  (buf, s390_r4, CREATE_STACK_SIZE);
-               
-               /* Calculate call address and call
-               's390_magic_trampoline'. Return value will be in r2 */
+       /* Arg 2: code (next address to the instruction that called us) */
+       if (tramp_type == MONO_TRAMPOLINE_JUMP) {
+               s390_lhi (buf, s390_r3, 0);
+       } else {
+               s390_l  (buf, s390_r3, 0, s390_r11, S390_RET_ADDR_OFFSET);
+
+               /* Mask out bit 31 */
                s390_basr (buf, s390_r13, 0);
                s390_j    (buf, 4);
-               if (tramp_type == MONO_TRAMPOLINE_CLASS_INIT) {
-                       s390_word (buf, s390_class_init_trampoline);
-               } else {
-                       s390_word (buf, s390_magic_trampoline);
-               }
-               s390_l    (buf, s390_r1, 0, s390_r13, 4);
-               s390_basr (buf, s390_r14, s390_r1);
+               s390_word (buf, (~(1 << 31)));
+               s390_n (buf, s390_r3, 0, s390_r13, 4);
+       }
                
-               /* OK, code address is now on r2. Move it to r1, so that we
-               can restore r2 and use it from r1 later */
-               s390_lr   (buf, s390_r1, s390_r2);
+       /* Arg 3: MonoMethod *method. It was put in r1 by the
+          method-specific trampoline code, and then saved before the call
+          to mono_get_lmf_addr()'. */
+       s390_l  (buf, s390_r4, 0, STK_BASE, METHOD_SAVE_OFFSET);
 
-               /*----------------------------------------------------------
-               STEP 3: Restore the LMF
-               ----------------------------------------------------------*/
-               restoreLMF(buf, STK_BASE, CREATE_STACK_SIZE);
+       /* Arg 4: trampoline address. Ignore for now */
+               
+       /* Calculate call address and call the C trampoline. Return value will 
be in r2 */
+       s390_basr (buf, s390_r13, 0);
+       s390_j    (buf, 4);
+       tramp = (guint8*)mono_get_trampoline_func (tramp_type);
+       s390_word (buf, tramp);
+       s390_l    (buf, s390_r1, 0, s390_r13, 4);
+       s390_basr (buf, s390_r14, s390_r1);
+               
+       /* OK, code address is now on r2. Move it to r1, so that we
+          can restore r2 and use it from r1 later */
+       s390_lr   (buf, s390_r1, s390_r2);
+
+       /*----------------------------------------------------------
+         STEP 3: Restore the LMF
+         ----------------------------------------------------------*/
+       restoreLMF(buf, STK_BASE, CREATE_STACK_SIZE);
        
-               /*----------------------------------------------------------
-               STEP 4: call the compiled method
-               ----------------------------------------------------------*/
+       /*----------------------------------------------------------
+         STEP 4: call the compiled method
+         ----------------------------------------------------------*/
                
-               /* Restore registers */
+       /* Restore registers */
 
-               s390_lm   (buf, s390_r2, s390_r5, STK_BASE, CREATE_GR_OFFSET);
+       s390_lm   (buf, s390_r2, s390_r5, STK_BASE, CREATE_GR_OFFSET);
                
-               /* Restore the FP registers */
-               offset = CREATE_FP_OFFSET;
-               for (i = s390_f0; i <= s390_f15; ++i) {
-                       s390_ld  (buf, i, 0, STK_BASE, offset);
-                       offset += 8;
-               }
+       /* Restore the FP registers */
+       offset = CREATE_FP_OFFSET;
+       for (i = s390_f0; i <= s390_f15; ++i) {
+               s390_ld  (buf, i, 0, STK_BASE, offset);
+               offset += 8;
+       }
 
-               /* Restore stack pointer and jump to the code - 
-                  R14 contains the return address to our caller */
-               s390_lr   (buf, STK_BASE, s390_r11);
-               s390_lm   (buf, s390_r6, s390_r14, STK_BASE, 
S390_REG_SAVE_OFFSET);
+       /* Restore stack pointer and jump to the code - 
+          R14 contains the return address to our caller */
+       s390_lr   (buf, STK_BASE, s390_r11);
+       s390_lm   (buf, s390_r6, s390_r14, STK_BASE, S390_REG_SAVE_OFFSET);
+
+       if (tramp_type == MONO_TRAMPOLINE_CLASS_INIT || tramp_type == 
MONO_TRAMPOLINE_GENERIC_CLASS_INIT)
+               s390_br (buf, s390_r14);
+       else
                s390_br   (buf, s390_r1);
 
-               /* Flush instruction cache, since we've generated code */
-               mono_arch_flush_icache (code, buf - code);
+       /* Flush instruction cache, since we've generated code */
+       mono_arch_flush_icache (code, buf - code);
        
-               /* Sanity check */
-               g_assert ((buf - code) <= 512);
-       }
+       /* Sanity check */
+       g_assert ((buf - code) <= 512);
 
        return code;
 }
@@ -429,172 +456,47 @@
 
 /*------------------------------------------------------------------*/
 /*                                                                  */
-/* Name                - mono_arch_create_jump_trampoline                  */
+/* Name                - mono_arch_create_specific_trampoline                  
*/
 /*                                                                  */
-/* Function    - Create the designated type of trampoline according*/
-/*                to the 'tramp_type' parameter.                    */
+/* Function    - Creates the given kind of specific trampoline         */
 /*                                                                  */
 /*------------------------------------------------------------------*/
 
-MonoJitInfo *
-mono_arch_create_jump_trampoline (MonoMethod *method)
-{
-       guint8 *code, *buf, *tramp = NULL;
-       MonoJitInfo *ji;
-       MonoDomain *domain = mono_domain_get();
-       gint32 displace;
-
-       tramp = mono_get_trampoline_code (MONO_TRAMPOLINE_JUMP);
-
-       mono_domain_lock (domain);
-       code = buf = mono_code_manager_reserve (domain->code_mp, 
METHOD_TRAMPOLINE_SIZE);
-       mono_domain_unlock (domain);
-
-       s390_basr (buf, s390_r1, 0);
-       s390_j    (buf, 4);
-       s390_word (buf, method);
-       s390_l    (buf, s390_r1, 0, s390_r1, 4);
-       displace = (tramp - buf) / 2;
-       s390_jcl  (buf, S390_CC_UN, displace);
-
-       mono_arch_flush_icache (code, buf-code);
-
-       g_assert ((buf - code) <= JUMP_TRAMPOLINE_SIZE);
-       
-       ji              = g_new0 (MonoJitInfo, 1);
-       ji->method      = method;
-       ji->code_start  = code;
-       ji->code_size   = buf - code;
-       
-       mono_jit_stats.method_trampolines++;
-
-       return ji;
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/*                                                                  */
-/* Name                - mono_arch_create_jit_trampoline                   */
-/*                                                                  */
-/* Function    - Creates a trampoline function for virtual methods.*/
-/*                If the created code is called it first starts JIT */
-/*                compilation and then calls the newly created      */
-/*                method. It also replaces the corresponding vtable */
-/*                entry (see s390_magic_trampoline).                */
-/*                                                                  */
-/*                A trampoline consists of two parts: a main        */
-/*                fragment, shared by all method trampolines, and   */
-/*                and some code specific to each method, which      */
-/*                hard-codes a reference to that method and then    */
-/*                calls the main fragment.                          */
-/*                                                                  */
-/*                The main fragment contains a call to              */
-/*                's390_magic_trampoline', which performs a call    */
-/*                to the JIT compiler and substitutes the method-   */
-/*                specific fragment with some code that directly    */
-/*                calls the JIT-compiled method.                    */
-/*                                                                  */
-/* Parameter    - method - Pointer to the method information        */
-/*                                                                  */
-/* Returns      - A pointer to the newly created code               */
-/*                                                                  */
-/*------------------------------------------------------------------*/
-
 gpointer
-mono_arch_create_jit_trampoline (MonoMethod *method)
+mono_arch_create_specific_trampoline (gpointer arg1, MonoTrampolineType 
tramp_type, MonoDomain *domain, guint32 *code_len)
 {
-       guint8 *code, *buf;
-       static guint8 *vc = NULL;
+       guint8 *code, *buf, *tramp;
        gint32 displace;
 
-       vc = mono_get_trampoline_code (MONO_TRAMPOLINE_GENERIC);
+       tramp = mono_get_trampoline_code (tramp_type);
 
        /*----------------------------------------------------------*/
        /* This is the method-specific part of the trampoline. Its  */
        /* purpose is to provide the generic part with the          */
        /* MonoMethod *method pointer. We'll use r1 to keep it.     */
        /*----------------------------------------------------------*/
-       code = buf = mono_global_codeman_reserve(METHOD_TRAMPOLINE_SIZE);
+       mono_domain_lock (domain);
+       code = buf = mono_code_manager_reserve (domain->code_mp, 
SPECIFIC_TRAMPOLINE_SIZE);
+       mono_domain_unlock (domain);
 
        s390_basr (buf, s390_r1, 0);
        s390_j    (buf, 4);
-       s390_word (buf, method);
+       s390_word (buf, arg1);
        s390_l    (buf, s390_r1, 0, s390_r1, 4);
-       displace = (vc - buf) / 2;
+       displace = (tramp - buf) / 2;
        s390_jcl  (buf, S390_CC_UN, displace);
 
        /* Flush instruction cache, since we've generated code */
        mono_arch_flush_icache (code, buf - code);
-               
-       /* Sanity check */
-       g_assert ((buf - code) <= METHOD_TRAMPOLINE_SIZE);
-       
-       return code;
-}
 
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/*                                                                  */
-/* Name                - mono_arch_create_class_init_trampoline            */
-/*                                                                  */
-/* Function    - Creates a trampoline function to run a type init- */
-/*                ializer. If the trampoline is called, it calls    */
-/*                mono_runtime_class_init with the given vtable,    */
-/*                then patches the caller code so it does not get   */
-/*                called any more.                                  */
-/*                                                                  */
-/* Parameter    - vtable - The type to initialize                   */
-/*                                                                  */
-/* Returns      - A pointer to the newly created code               */
-/*                                                                  */
-/*------------------------------------------------------------------*/
-
-gpointer
-mono_arch_create_class_init_trampoline (MonoVTable *vtable)
-{
-       guint8 *code, *buf, *tramp;
-
-       tramp = mono_get_trampoline_code (MONO_TRAMPOLINE_CLASS_INIT);
-
-       /*-----------------------------------------------------------*/
-       /* This is the method-specific part of the trampoline. Its   */
-       /* purpose is to provide the generic part with the MonoMethod*/
-       /* *method pointer. We'll use r11 to keep that value, for    */
-       /* instance. However, the generic part of the trampoline     */
-       /* relies on r11 having the same value it had before coming  */
-       /* here, so we must save it before.                          */
-       /*-----------------------------------------------------------*/
-       code = buf = mono_global_codeman_reserve(METHOD_TRAMPOLINE_SIZE);
-
-       s390_st   (buf, s390_r14, 0, STK_BASE, S390_RET_ADDR_OFFSET);
-       s390_ahi  (buf, STK_BASE, -S390_MINIMAL_STACK_SIZE);
-
-       s390_basr (buf, s390_r1, 0);
-       s390_j    (buf, 6);
-       s390_word (buf, vtable);
-        s390_word (buf, s390_class_init_trampoline);
-       s390_lr   (buf, s390_r3, s390_r14);
-       s390_l    (buf, s390_r2, 0, s390_r1, 4);
-       s390_lhi  (buf, s390_r4, 0);
-       s390_l    (buf, s390_r1, 0, s390_r1, 8);
-       s390_basr (buf, s390_r14, s390_r1);
-
-       s390_ahi  (buf, STK_BASE, S390_MINIMAL_STACK_SIZE);
-       s390_l    (buf, s390_r14, 0, STK_BASE, S390_RET_ADDR_OFFSET);
-       s390_br   (buf, s390_r14);
-
-       /* Flush instruction cache, since we've generated code */
-       mono_arch_flush_icache (code, buf - code);
-               
        /* Sanity check */
-       g_assert ((buf - code) <= METHOD_TRAMPOLINE_SIZE);
+       g_assert ((buf - code) <= SPECIFIC_TRAMPOLINE_SIZE);
 
-       mono_jit_stats.method_trampolines++;
-
+       if (code_len)
+               *code_len = buf - code;
+       
        return code;
-}
+}      
 
 /*========================= End of Function ========================*/
 

_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches

Reply via email to