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