Author: mprobst
Date: 2008-02-05 14:47:33 -0500 (Tue, 05 Feb 2008)
New Revision: 94932

Modified:
   trunk/mono/mono/metadata/ChangeLog
   trunk/mono/mono/metadata/marshal.c
   trunk/mono/mono/metadata/marshal.h
   trunk/mono/mono/mini/ChangeLog
   trunk/mono/mono/mini/mini-trampolines.c
   trunk/mono/mono/mini/tramp-amd64.c
   trunk/mono/mono/mini/tramp-x86.c
Log:
2008-02-05  Mark Probst  <[EMAIL PROTECTED]>

        * tramp-amd64.c, tramp-x86.c, mini-trampolines.c: Added a check in
        the generic class init trampoline to return quickly if the class
        is already inited.

2008-02-05  Mark Probst  <[EMAIL PROTECTED]>

        * marshal.c, marshal.h (mono_marshal_find_bitfield_offset,
        mono_marshal_find_nonzero_bit_offset): Added macro and function
        for finding the byte- and bit-offset of a bitfield within a
        struct.


Modified: trunk/mono/mono/metadata/ChangeLog
===================================================================
--- trunk/mono/mono/metadata/ChangeLog  2008-02-05 19:28:29 UTC (rev 94931)
+++ trunk/mono/mono/metadata/ChangeLog  2008-02-05 19:47:33 UTC (rev 94932)
@@ -1,3 +1,10 @@
+2008-02-05  Mark Probst  <[EMAIL PROTECTED]>
+
+       * marshal.c, marshal.h (mono_marshal_find_bitfield_offset,
+       mono_marshal_find_nonzero_bit_offset): Added macro and function
+       for finding the byte- and bit-offset of a bitfield within a
+       struct.
+
 2008-02-05  Zoltan Varga  <[EMAIL PROTECTED]>
 
        * marshal.c (mono_marshal_get_ptr_to_struct): Make the signature 
non-pinvoke.

Modified: trunk/mono/mono/metadata/marshal.c
===================================================================
--- trunk/mono/mono/metadata/marshal.c  2008-02-05 19:28:29 UTC (rev 94931)
+++ trunk/mono/mono/metadata/marshal.c  2008-02-05 19:47:33 UTC (rev 94932)
@@ -11798,3 +11798,24 @@
 {
        return MONO_E_NOTIMPL;
 }
+
+void
+mono_marshal_find_nonzero_bit_offset (guint8 *buf, int len, int *byte_offset, 
guint8 *bitmask)
+{
+       int i;
+       guint8 byte;
+
+       for (i = 0; i < len; ++i)
+               if (buf [i])
+                       break;
+
+       g_assert (i < len);
+
+       byte = buf [i];
+       while (byte && !(byte & 1))
+               byte >>= 1;
+       g_assert (byte == 1);
+
+       *byte_offset = i;
+       *bitmask = buf [i];
+}

Modified: trunk/mono/mono/metadata/marshal.h
===================================================================
--- trunk/mono/mono/metadata/marshal.h  2008-02-05 19:28:29 UTC (rev 94931)
+++ trunk/mono/mono/metadata/marshal.h  2008-02-05 19:47:33 UTC (rev 94932)
@@ -18,6 +18,14 @@
 #include <mono/metadata/opcodes.h>
 #include <mono/metadata/reflection.h>
 
+#define mono_marshal_find_bitfield_offset(type, elem, byte_offset, bitmask) \
+       do { \
+               type tmp; \
+               memset (&tmp, 0, sizeof (tmp)); \
+               tmp.elem = 1; \
+               mono_marshal_find_nonzero_bit_offset ((guint8*)&tmp, sizeof 
(tmp), (byte_offset), (bitmask)); \
+       } while (0)
+
 G_BEGIN_DECLS
 
 /* marshaling helper functions */
@@ -365,6 +373,9 @@
 void
 mono_win32_compat_ZeroMemory (gpointer dest, gsize length);
 
+void
+mono_marshal_find_nonzero_bit_offset (guint8 *buf, int len, int *byte_offset, 
guint8 *bitmask) MONO_INTERNAL;
+
 G_END_DECLS
 
 #endif /* __MONO_MARSHAL_H__ */

Modified: trunk/mono/mono/mini/ChangeLog
===================================================================
--- trunk/mono/mono/mini/ChangeLog      2008-02-05 19:28:29 UTC (rev 94931)
+++ trunk/mono/mono/mini/ChangeLog      2008-02-05 19:47:33 UTC (rev 94932)
@@ -1,3 +1,9 @@
+2008-02-05  Mark Probst  <[EMAIL PROTECTED]>
+
+       * tramp-amd64.c, tramp-x86.c, mini-trampolines.c: Added a check in
+       the generic class init trampoline to return quickly if the class
+       is already inited.
+
 2008-02-04  Zoltan Varga  <[EMAIL PROTECTED]>
 
        * tramp-amd64.c (mono_arch_patch_callsite): Add some diagnostics to 
help debug

Modified: trunk/mono/mono/mini/mini-trampolines.c
===================================================================
--- trunk/mono/mono/mini/mini-trampolines.c     2008-02-05 19:28:29 UTC (rev 
94931)
+++ trunk/mono/mono/mini/mini-trampolines.c     2008-02-05 19:47:33 UTC (rev 
94932)
@@ -303,6 +303,10 @@
 {
        //g_print ("generic class init for class %s.%s\n", 
vtable->klass->name_space, vtable->klass->name);
 
+#if defined(__i386__) || defined(__x86_64__)
+       g_assert (!vtable->initialized);
+#endif
+
        mono_runtime_class_init (vtable);
 
        //g_print ("done initing generic\n");

Modified: trunk/mono/mono/mini/tramp-amd64.c
===================================================================
--- trunk/mono/mono/mini/tramp-amd64.c  2008-02-05 19:28:29 UTC (rev 94931)
+++ trunk/mono/mono/mini/tramp-amd64.c  2008-02-05 19:47:33 UTC (rev 94932)
@@ -204,6 +204,24 @@
 
        offset = 0;
 
+       if (tramp_type == MONO_TRAMPOLINE_GENERIC_CLASS_INIT) {
+               static int byte_offset = -1;
+               static guint8 bitmask;
+
+               guint8 *jump;
+
+               if (byte_offset < 0)
+                       mono_marshal_find_bitfield_offset (MonoVTable, 
initialized, &byte_offset, &bitmask);
+
+               amd64_test_membase_imm_size (code, MONO_ARCH_VTABLE_REG, 
byte_offset, bitmask, 1);
+               jump = code;
+               amd64_branch8 (code, X86_CC_Z, -1, 1);
+
+               amd64_ret (code);
+
+               x86_patch (jump, code);
+       }
+
        /*
         * The generic class init trampoline is called directly by JITted code, 
there is no
         * specific trampoline.

Modified: trunk/mono/mono/mini/tramp-x86.c
===================================================================
--- trunk/mono/mono/mini/tramp-x86.c    2008-02-05 19:28:29 UTC (rev 94931)
+++ trunk/mono/mono/mini/tramp-x86.c    2008-02-05 19:47:33 UTC (rev 94932)
@@ -192,10 +192,28 @@
         */
 
        /* If this is a generic class init the argument is not on the
-        * stack yet but in MONO_ARCH_VTABLE_REG.
+        * stack yet but in MONO_ARCH_VTABLE_REG.  We first check
+        * whether the vtable is already initialized in which case we
+        * just return.  Otherwise we push it and continue.
         */
-       if (tramp_type == MONO_TRAMPOLINE_GENERIC_CLASS_INIT)
+       if (tramp_type == MONO_TRAMPOLINE_GENERIC_CLASS_INIT) {
+               static int byte_offset = -1;
+               static guint8 bitmask;
+
+               guint8 *jump;
+
+               if (byte_offset < 0)
+                       mono_marshal_find_bitfield_offset (MonoVTable, 
initialized, &byte_offset, &bitmask);
+
+               x86_test_membase_imm (buf, MONO_ARCH_VTABLE_REG, byte_offset, 
bitmask);
+               jump = buf;
+               x86_branch8 (buf, X86_CC_Z, -1, 1);
+
+               x86_ret (buf);
+
+               x86_patch (jump, buf);
                x86_push_reg (buf, MONO_ARCH_VTABLE_REG);
+       }
 
        /* Put all registers into an array on the stack
         * If this code is changed, make sure to update the offset value in

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

Reply via email to