2008-03-04 Mark Probst <mark.probst@gmail.com>
authorMark Probst <mark.probst@gmail.com>
Tue, 4 Mar 2008 16:56:35 +0000 (16:56 -0000)
committerMark Probst <mark.probst@gmail.com>
Tue, 4 Mar 2008 16:56:35 +0000 (16:56 -0000)
* domain-internals.h, domain.c: Replaced MonoGenericSharingContext
with a new structure, MonoGenericJitInfo, in the MonoJitInfo.  It
contains the location of "this", used for exception handling.

2008-03-04  Mark Probst  <mark.probst@gmail.com>

* mini.c: For shared methods of generic classes put the location
of "this" into the MonoGenericJitInfo.

* mini-x86.c, mini-amd64.c, mini.h: Added function for fetching a
register out of a MonoContext by register number.  Add the generic
sharing context as an argument to mono_arch_find_this_argument().

* mini-alpha.c, mini-arm.c, mini-hppa.c, mini-ia64.c, mini-mips.c,
mini-ppc.c, mini-s390.c, mini-s390x.c, mini-sparc.c: Added stub
for new arch function.

* mini-exception.c: Handle open exception clauses in shared
generic code.

* mini-trampolines.c: Supply additional argument to
mono_arch_find_this_argument().

2008-03-04  Mark Probst  <mark.probst@gmail.com>

* generics-sharing.2.c: Added test for open catch clauses in
shared generic code.

svn path=/trunk/mono/; revision=97322

21 files changed:
mono/metadata/ChangeLog
mono/metadata/domain-internals.h
mono/metadata/domain.c
mono/mini/ChangeLog
mono/mini/mini-alpha.c
mono/mini/mini-amd64.c
mono/mini/mini-arm.c
mono/mini/mini-exceptions.c
mono/mini/mini-hppa.c
mono/mini/mini-ia64.c
mono/mini/mini-mips.c
mono/mini/mini-ppc.c
mono/mini/mini-s390.c
mono/mini/mini-s390x.c
mono/mini/mini-sparc.c
mono/mini/mini-trampolines.c
mono/mini/mini-x86.c
mono/mini/mini.c
mono/mini/mini.h
mono/tests/ChangeLog
mono/tests/generics-sharing.2.cs

index fbf9f8225b2547c42dd3645aab8c3440e43bc06f..77f1e36d6f8ad87f33cbf8bc57fb9733e453535e 100644 (file)
@@ -1,3 +1,9 @@
+2008-03-04  Mark Probst  <mark.probst@gmail.com>
+
+       * domain-internals.h, domain.c: Replaced MonoGenericSharingContext
+       with a new structure, MonoGenericJitInfo, in the MonoJitInfo.  It
+       contains the location of "this", used for exception handling.
+
 2008-03-04  Zoltan Varga  <vargaz@gmail.com>
 
        * class.c (mono_class_layout_fields): Set the min alignment of small structs to
index 7497956229bda85d288fd49267f62e37891baf1e..1571b2994a0181268dfbd23755939d76aa5a1486 100644 (file)
@@ -80,6 +80,14 @@ typedef struct {
        int dummy;
 } MonoGenericSharingContext;
 
+typedef struct
+{
+       MonoGenericSharingContext *generic_sharing_context;
+       gint32 this_offset;
+       guint8 this_reg;
+       gboolean this_in_reg:1;
+} MonoGenericJitInfo;
+
 struct _MonoJitInfo {
        /* NOTE: These first two elements (method and
           next_jit_code_hash) must be in the same order and at the
@@ -100,9 +108,9 @@ struct _MonoJitInfo {
        gboolean    cas_method_assert:1;
        gboolean    cas_method_deny:1;
        gboolean    cas_method_permitonly:1;
-       gboolean    has_generic_sharing_context:1;
+       gboolean    has_generic_jit_info:1;
        MonoJitExceptionInfo clauses [MONO_ZERO_LEN_ARRAY];
-       /* There is an optional MonoGenericSharingContext* after the clauses */
+       /* There is an optional MonoGenericJitInfo after the clauses */
 };
 
 typedef struct {
@@ -224,6 +232,9 @@ mono_jit_info_table_remove (MonoDomain *domain, MonoJitInfo *ji) MONO_INTERNAL;
 void
 mono_jit_info_add_aot_module (MonoImage *image, gpointer start, gpointer end) MONO_INTERNAL;
 
+MonoGenericJitInfo*
+mono_jit_info_get_generic_jit_info (MonoJitInfo *ji) MONO_INTERNAL;
+
 MonoGenericSharingContext*
 mono_jit_info_get_generic_sharing_context (MonoJitInfo *ji) MONO_INTERNAL;
 
index 60b608ad685df34352bb905e8c26f2a937f671b0..d54c60e336195ab5c6ec19b2314890420925331f 100644 (file)
@@ -911,6 +911,15 @@ mono_jit_code_hash_init (MonoInternalHashTable *jit_code_hash)
                                       jit_info_next_value);
 }
 
+MonoGenericJitInfo*
+mono_jit_info_get_generic_jit_info (MonoJitInfo *ji)
+{
+       if (ji->has_generic_jit_info)
+               return (MonoGenericJitInfo*)&ji->clauses [ji->num_clauses];
+       else
+               return NULL;
+}
+
 /*
  * mono_jit_info_get_generic_sharing_context:
  * @ji: a jit info
@@ -921,8 +930,10 @@ mono_jit_code_hash_init (MonoInternalHashTable *jit_code_hash)
 MonoGenericSharingContext*
 mono_jit_info_get_generic_sharing_context (MonoJitInfo *ji)
 {
-       if (ji->has_generic_sharing_context)
-               return *((MonoGenericSharingContext**)&ji->clauses [ji->num_clauses]);
+       MonoGenericJitInfo *gi = mono_jit_info_get_generic_jit_info (ji);
+
+       if (gi)
+               return gi->generic_sharing_context;
        else
                return NULL;
 }
@@ -938,9 +949,11 @@ mono_jit_info_get_generic_sharing_context (MonoJitInfo *ji)
 void
 mono_jit_info_set_generic_sharing_context (MonoJitInfo *ji, MonoGenericSharingContext *gsctx)
 {
-       g_assert (ji->has_generic_sharing_context);
+       MonoGenericJitInfo *gi = mono_jit_info_get_generic_jit_info (ji);
+
+       g_assert (gi);
 
-       *((MonoGenericSharingContext**)&ji->clauses [ji->num_clauses]) = gsctx;
+       gi->generic_sharing_context = gsctx;
 }
 
 /**
index ae6d94104496bd1ac75f57c2524ccddb3fbeca88..0c8798b6178e93a00d5af9895a6499f7ac0148dd 100644 (file)
@@ -1,3 +1,22 @@
+2008-03-04  Mark Probst  <mark.probst@gmail.com>
+
+       * mini.c: For shared methods of generic classes put the location
+       of "this" into the MonoGenericJitInfo.
+
+       * mini-x86.c, mini-amd64.c, mini.h: Added function for fetching a
+       register out of a MonoContext by register number.  Add the generic
+       sharing context as an argument to mono_arch_find_this_argument().
+
+       * mini-alpha.c, mini-arm.c, mini-hppa.c, mini-ia64.c, mini-mips.c,
+       mini-ppc.c, mini-s390.c, mini-s390x.c, mini-sparc.c: Added stub
+       for new arch function.
+
+       * mini-exception.c: Handle open exception clauses in shared
+       generic code.
+
+       * mini-trampolines.c: Supply additional argument to
+       mono_arch_find_this_argument().
+
 2008-03-04  Zoltan Varga  <vargaz@gmail.com>
 
        * Makefile.am (regtests): Run the bench.exe tests last.
index 3eb3fc1cdda6d595bd6c2e3fac346cd77a0463d1..33e39004b587afac23f4bea1325a2f5b5030b8a1 100644 (file)
@@ -5904,3 +5904,9 @@ mono_arch_get_patch_offset (guint8 *code)
   return 3;
 }
 
+gpointer
+mono_arch_context_get_int_reg (MonoContext *ctx, int reg)
+{
+       /* FIXME: implement */
+       g_assert_not_reached ();
+}
index e72ea3304ab3e25d12b0956714e2660a8950d970..96a1ede46a57fb4a7438b638e3919b2bca997702 100644 (file)
@@ -5944,7 +5944,7 @@ mono_arch_find_imt_method (gpointer *regs, guint8 *code)
 }
 
 MonoObject*
-mono_arch_find_this_argument (gpointer *regs, MonoMethod *method)
+mono_arch_find_this_argument (gpointer *regs, MonoMethod *method, MonoGenericSharingContext *gsctx)
 {
        return mono_arch_get_this_arg_from_call (mono_method_signature (method), (gssize*)regs, NULL);
 }
@@ -6051,3 +6051,24 @@ MonoInst* mono_arch_get_thread_intrinsic (MonoCompile* cfg)
        ins->inst_offset = thread_tls_offset;
        return ins;
 }
+
+#define _CTX_REG(ctx,fld,i) ((gpointer)((&ctx->fld)[i]))
+
+gpointer
+mono_arch_context_get_int_reg (MonoContext *ctx, int reg)
+{
+       switch (reg) {
+       case AMD64_RCX: return (gpointer)ctx->rcx;
+       case AMD64_RDX: return (gpointer)ctx->rdx;
+       case AMD64_RBX: return (gpointer)ctx->rbx;
+       case AMD64_RBP: return (gpointer)ctx->rbp;
+       case AMD64_RSP: return (gpointer)ctx->rsp;
+       default:
+               if (reg < 8)
+                       return _CTX_REG (ctx, rax, reg);
+               else if (reg >= 12)
+                       return _CTX_REG (ctx, r12, reg - 12);
+               else
+                       g_assert_not_reached ();
+       }
+}
index eb8de794c0dd3b0c94c38cb90f537870c429a04d..816c8079d5dcf0b494c56c5deafc4fc84df4b6e1 100644 (file)
@@ -3875,7 +3875,7 @@ mono_arch_find_imt_method (gpointer *regs, guint8 *code)
 }
 
 MonoObject*
-mono_arch_find_this_argument (gpointer *regs, MonoMethod *method)
+mono_arch_find_this_argument (gpointer *regs, MonoMethod *method, MonoGenericSharingContext *gsctx)
 {
        return mono_arch_get_this_arg_from_call (mono_method_signature (method), (gssize*)regs, NULL);
 }
@@ -4039,4 +4039,9 @@ mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckI
 
 #endif
 
-
+gpointer
+mono_arch_context_get_int_reg (MonoContext *ctx, int reg)
+{
+       /* FIXME: implement */
+       g_assert_not_reached ();
+}
index 916fe2930f064c967a155f2b0e62ab27deda83e5..f1137ee814011b715a2ee7c6f9b54d03c9d79cde 100644 (file)
@@ -581,6 +581,48 @@ ves_icall_System_Security_SecurityFrame_GetSecurityStack (gint32 skip)
 
 #ifndef CUSTOM_EXCEPTION_HANDLING
 
+static MonoClass*
+get_exception_catch_class (MonoJitExceptionInfo *ei, MonoJitInfo *ji, MonoContext *ctx)
+{
+       MonoClass *catch_class = ei->data.catch_class;
+
+       if (ji->has_generic_jit_info) {
+               MonoGenericJitInfo *gi = mono_jit_info_get_generic_jit_info (ji);
+               gpointer info;
+               MonoClass *class;
+               MonoType *inflated_type;
+
+               if (gi->this_in_reg)
+                       info = mono_arch_context_get_int_reg (ctx, gi->this_reg);
+               else
+                       info = *(gpointer*)((char*)mono_arch_context_get_int_reg (ctx, gi->this_reg) +
+                                       gi->this_offset);
+
+               if (ji->method->flags & METHOD_ATTRIBUTE_STATIC) {
+                       MonoRuntimeGenericContext *rgctx = info;
+
+                       class = rgctx->vtable->klass;
+               } else {
+                       MonoObject *this = info;
+
+                       class = this->vtable->klass;
+               }
+
+               /* FIXME: we shouldn't inflate but instead put the
+                  type in the rgctx and fetch it from there.  It
+                  might be a good idea to do this lazily, i.e. only
+                  when the exception is actually thrown, so as not to
+                  waste space for exception clauses which might never
+                  be encountered. */
+               inflated_type = mono_class_inflate_generic_type (&catch_class->byval_arg,
+                               mini_class_get_context (class));
+               catch_class = mono_class_from_mono_type (inflated_type);
+               g_free (inflated_type);
+       }
+
+       return catch_class;
+}
+
 /**
  * mono_handle_exception_internal:
  * @ctx: saved processor state
@@ -739,6 +781,7 @@ mono_handle_exception_internal (MonoContext *ctx, gpointer obj, gpointer origina
 #endif
                                            MONO_CONTEXT_GET_IP (ctx) <= ei->try_end) { 
                                                /* catch block */
+                                               MonoClass *catch_class = get_exception_catch_class (ei, ji, ctx);
 
                                                if ((ei->flags == MONO_EXCEPTION_CLAUSE_NONE) || (ei->flags == MONO_EXCEPTION_CLAUSE_FILTER)) {
                                                        /* store the exception object in bp + ei->exvar_offset */
@@ -763,7 +806,7 @@ mono_handle_exception_internal (MonoContext *ctx, gpointer obj, gpointer origina
                                                }
 
                                                if ((ei->flags == MONO_EXCEPTION_CLAUSE_NONE && 
-                                                    mono_object_isinst (obj, ei->data.catch_class)) || filtered) {
+                                                    mono_object_isinst (obj, catch_class)) || filtered) {
                                                        if (test_only) {
                                                                if (mono_ex && !initial_trace_ips) {
                                                                        trace_ips = g_list_reverse (trace_ips);
index dfc7938e602f8bbc8140328ee02129715f844b0c..0043c12f6962343aa40752695b158fdd1d398efa 100644 (file)
@@ -2914,3 +2914,10 @@ MonoInst* mono_arch_get_thread_intrinsic (MonoCompile* cfg)
 {
        return NULL;
 }
+
+gpointer
+mono_arch_context_get_int_reg (MonoContext *ctx, int reg)
+{
+       /* FIXME: implement */
+       g_assert_not_reached ();
+}
index ed4876b3518c3f1deb1a850962219e15bb42e504..3b37010a399eed3bd9c349827867e3eda87bb70b 100644 (file)
@@ -4637,7 +4637,7 @@ mono_arch_get_this_arg_from_call (MonoMethodSignature *sig, gssize *regs, guint8
 }
 
 MonoObject*
-mono_arch_find_this_argument (gpointer *regs, MonoMethod *method)
+mono_arch_find_this_argument (gpointer *regs, MonoMethod *method, MonoGenericSharingContext *gsctx)
 {
        return mono_arch_get_this_arg_from_call (mono_method_signature (method), (gssize*)regs, NULL);
 }
@@ -4733,3 +4733,10 @@ MonoInst* mono_arch_get_thread_intrinsic (MonoCompile* cfg)
        ins->inst_offset = thread_tls_offset;
        return ins;
 }
+
+gpointer
+mono_arch_context_get_int_reg (MonoContext *ctx, int reg)
+{
+       /* FIXME: implement */
+       g_assert_not_reached ();
+}
index ecc1a21332f25b072c89a3414db03d9abb4cb082..6c0a3a87728ae51e38d56d6d4365896c5b32271c 100644 (file)
@@ -4033,3 +4033,9 @@ mono_arch_get_thread_intrinsic (MonoCompile* cfg)
        return ins;
 }
 
+gpointer
+mono_arch_context_get_int_reg (MonoContext *ctx, int reg)
+{
+       /* FIXME: implement */
+       g_assert_not_reached ();
+}
index b6a197c900a36d642480d828a82c539bb07e11c8..7ebde628522c171091f36b9ac7aba00cafd47dec 100644 (file)
@@ -3991,7 +3991,7 @@ mono_arch_find_imt_method (gpointer *regs, guint8 *code)
 }
 
 MonoObject*
-mono_arch_find_this_argument (gpointer *regs, MonoMethod *method)
+mono_arch_find_this_argument (gpointer *regs, MonoMethod *method, MonoGenericSharingContext *gsctx)
 {
        return mono_arch_get_this_arg_from_call (mono_method_signature (method), (gssize*)regs, NULL);
 }
@@ -4044,3 +4044,9 @@ mono_arch_get_thread_intrinsic (MonoCompile* cfg)
        return ins;
 }
 
+gpointer
+mono_arch_context_get_int_reg (MonoContext *ctx, int reg)
+{
+       /* FIXME: implement */
+       g_assert_not_reached ();
+}
index 5d64313152bbb5f5b01bc8b6a7341db955f758d0..30ff3bf010aa444b6d48ed63c89a82b83e100db0 100644 (file)
@@ -4987,3 +4987,10 @@ mono_arch_get_patch_offset (guint8 *code)
 }
 
 /*========================= End of Function ========================*/
+
+gpointer
+mono_arch_context_get_int_reg (MonoContext *ctx, int reg)
+{
+       /* FIXME: implement */
+       g_assert_not_reached ();
+}
index 47c516b547ca532d973c66a7c0ea2c985033f368..b69f8fb28d48dbbf7f013f17857ad3fdc3c0a337 100644 (file)
@@ -5163,3 +5163,10 @@ mono_arch_get_patch_offset (guint8 *code)
 }
 
 /*========================= End of Function ========================*/
+
+gpointer
+mono_arch_context_get_int_reg (MonoContext *ctx, int reg)
+{
+       /* FIXME: implement */
+       g_assert_not_reached ();
+}
index 59936b0c4ae92829940e3586ae38259d51472712..32f0ba1e28223f59c40ef2052d2b5fc0e04e035a 100644 (file)
@@ -2291,7 +2291,7 @@ mono_arch_find_imt_method (gpointer *regs, guint8 *code)
 }
 
 MonoObject*
-mono_arch_find_this_argument (gpointer *regs, MonoMethod *method)
+mono_arch_find_this_argument (gpointer *regs, MonoMethod *method, MonoGenericSharingContext *gsctx)
 {
        mono_sparc_flushw ();
 
@@ -4299,3 +4299,10 @@ MonoInst* mono_arch_get_thread_intrinsic (MonoCompile* cfg)
 {
        return NULL;
 }
+
+gpointer
+mono_arch_context_get_int_reg (MonoContext *ctx, int reg)
+{
+       /* FIXME: implement */
+       g_assert_not_reached ();
+}
index 5de1c2536771a28c0e4692e158d33047a9e5b4fe..77280f01c24e5ecb462f1588f4ee2a66edea6383 100644 (file)
 #include "mini.h"
 #include "debug-mini.h"
 
+static MonoGenericSharingContext*
+get_generic_context (guint8 *code)
+{
+       MonoJitInfo *jit_info = mono_jit_info_table_find (mono_domain_get (), (char*)code);
+
+       g_assert (jit_info);
+
+       return mono_jit_info_get_generic_sharing_context (jit_info);
+}
+
 #ifdef MONO_ARCH_HAVE_IMT
 
 static gpointer*
 mono_convert_imt_slot_to_vtable_slot (gpointer* slot, gpointer *regs, guint8 *code, MonoMethod *method, MonoMethod **impl_method)
 {
-       MonoObject *this_argument = mono_arch_find_this_argument (regs, method);
+       MonoGenericSharingContext *gsctx = get_generic_context (code);
+       MonoObject *this_argument = mono_arch_find_this_argument (regs, method, gsctx);
        MonoVTable *vt = this_argument->vtable;
        int displacement = slot - ((gpointer*)vt);
-       
+
        if (displacement > 0) {
                /* slot is in the vtable, not in the IMT */
 #if DEBUG_IMT
index bd008f86f91988ebd6496a59f61917cd3955416d..2a0b71439cca616cf45d09f7fc74db64bcb8f633 100644 (file)
@@ -263,14 +263,13 @@ add_valuetype (MonoGenericSharingContext *gsctx, MonoMethodSignature *sig, ArgIn
  * For x86 win32, see ???.
  */
 static CallInfo*
-get_call_info (MonoCompile *cfg, MonoMemPool *mp, MonoMethodSignature *sig, gboolean is_pinvoke)
+get_call_info (MonoGenericSharingContext *gsctx, MonoMemPool *mp, MonoMethodSignature *sig, gboolean is_pinvoke)
 {
        guint32 i, gr, fr;
        MonoType *ret_type;
        int n = sig->hasthis + sig->param_count;
        guint32 stack_size = 0;
        CallInfo *cinfo;
-       MonoGenericSharingContext *gsctx = cfg ? cfg->generic_sharing_context : NULL;
 
        if (mp)
                cinfo = mono_mempool_alloc0 (mp, sizeof (CallInfo) + (sizeof (ArgInfo) * n));
@@ -804,7 +803,7 @@ mono_arch_allocate_vars (MonoCompile *cfg)
        header = mono_method_get_header (cfg->method);
        sig = mono_method_signature (cfg->method);
 
-       cinfo = get_call_info (cfg, cfg->mempool, sig, FALSE);
+       cinfo = get_call_info (cfg->generic_sharing_context, cfg->mempool, sig, FALSE);
 
        cfg->frame_reg = MONO_ARCH_BASEREG;
        offset = 0;
@@ -924,7 +923,7 @@ mono_arch_create_vars (MonoCompile *cfg)
 
        sig = mono_method_signature (cfg->method);
 
-       cinfo = get_call_info (cfg, cfg->mempool, sig, FALSE);
+       cinfo = get_call_info (cfg->generic_sharing_context, cfg->mempool, sig, FALSE);
 
        if (cinfo->ret.storage == ArgValuetypeInReg)
                cfg->ret_var_is_local = TRUE;
@@ -1012,7 +1011,7 @@ mono_arch_call_opcode (MonoCompile *cfg, MonoBasicBlock* bb, MonoCallInst *call,
        sig = call->signature;
        n = sig->param_count + sig->hasthis;
 
-       cinfo = get_call_info (cfg, cfg->mempool, sig, FALSE);
+       cinfo = get_call_info (cfg->generic_sharing_context, cfg->mempool, sig, FALSE);
 
        if (!sig->pinvoke && (sig->call_convention == MONO_CALL_VARARG))
                sentinelpos = sig->sentinelpos + (is_virtual ? 1 : 0);
@@ -1964,7 +1963,7 @@ emit_move_return_value (MonoCompile *cfg, MonoInst *ins, guint8 *code)
        case OP_VCALL:
        case OP_VCALL_REG:
        case OP_VCALL_MEMBASE:
-               cinfo = get_call_info (cfg, cfg->mempool, ((MonoCallInst*)ins)->signature, FALSE);
+               cinfo = get_call_info (cfg->generic_sharing_context, cfg->mempool, ((MonoCallInst*)ins)->signature, FALSE);
                if (cinfo->ret.storage == ArgValuetypeInReg) {
                        /* Pop the destination address from the stack */
                        x86_pop_reg (code, X86_ECX);
@@ -2046,7 +2045,7 @@ emit_load_volatile_arguments (MonoCompile *cfg, guint8 *code)
 
        sig = mono_method_signature (method);
 
-       cinfo = get_call_info (cfg, cfg->mempool, sig, FALSE);
+       cinfo = get_call_info (cfg->generic_sharing_context, cfg->mempool, sig, FALSE);
        
        /* This is the opposite of the code in emit_prolog */
 
@@ -4058,7 +4057,7 @@ mono_arch_emit_epilog (MonoCompile *cfg)
        }
 
        /* Load returned vtypes into registers if needed */
-       cinfo = get_call_info (cfg, cfg->mempool, sig, FALSE);
+       cinfo = get_call_info (cfg->generic_sharing_context, cfg->mempool, sig, FALSE);
        if (cinfo->ret.storage == ArgValuetypeInReg) {
                for (quad = 0; quad < 2; quad ++) {
                        switch (cinfo->ret.pair_storage [quad]) {
@@ -4268,7 +4267,7 @@ void
 mono_arch_emit_this_vret_args (MonoCompile *cfg, MonoCallInst *inst, int this_reg, int this_type, int vt_reg)
 {
        MonoCallInst *call = (MonoCallInst*)inst;
-       CallInfo *cinfo = get_call_info (cfg, cfg->mempool, inst->signature, FALSE);
+       CallInfo *cinfo = get_call_info (cfg->generic_sharing_context, cfg->mempool, inst->signature, FALSE);
 
        /* add the this argument */
        if (this_reg != -1) {
@@ -4433,10 +4432,10 @@ mono_arch_find_imt_method (gpointer *regs, guint8 *code)
 }
 
 MonoObject*
-mono_arch_find_this_argument (gpointer *regs, MonoMethod *method)
+mono_arch_find_this_argument (gpointer *regs, MonoMethod *method, MonoGenericSharingContext *gsctx)
 {
        MonoMethodSignature *sig = mono_method_signature (method);
-       CallInfo *cinfo = get_call_info (NULL, NULL, sig, FALSE);
+       CallInfo *cinfo = get_call_info (gsctx, NULL, sig, FALSE);
        int this_argument_offset;
        MonoObject *this_argument;
 
@@ -4779,3 +4778,15 @@ mono_arch_get_delegate_invoke_impl (MonoMethodSignature *sig, gboolean has_targe
 
        return start;
 }
+
+gpointer
+mono_arch_context_get_int_reg (MonoContext *ctx, int reg)
+{
+       switch (reg) {
+       case X86_ECX: return (gpointer)ctx->ecx;
+       case X86_EDX: return (gpointer)ctx->edx;
+       case X86_EBP: return (gpointer)ctx->ebp;
+       case X86_ESP: return (gpointer)ctx->esp;
+       default: return ((gpointer)(&ctx->eax)[reg]);
+       }
+}
index 4d0f43a45ef2000dd55b4abf9aad929b1614fc31..74d34cbb9e53b0e4a149b2f649f4e8c8314efae5 100644 (file)
@@ -4672,6 +4672,17 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                for (i = 0; i < header->num_clauses; ++i) {
                        MonoBasicBlock *try_bb;
                        MonoExceptionClause *clause = &header->clauses [i];
+
+                       /* We can't handle open exception clauses in
+                        * static methods yet.
+                        */
+                       if ((method->flags & METHOD_ATTRIBUTE_STATIC) &&
+                                       clause->flags != MONO_EXCEPTION_CLAUSE_FILTER &&
+                                       clause->data.catch_class &&
+                                       mono_class_check_context_used (clause->data.catch_class)) {
+                               GENERIC_SHARING_FAILURE (CEE_NOP);
+                       }
+
                        GET_BBLOCK (cfg, try_bb, ip + clause->try_offset);
                        try_bb->real_offset = clause->try_offset;
                        GET_BBLOCK (cfg, tblock, ip + clause->handler_offset);
@@ -11491,7 +11502,7 @@ remove_critical_edges (MonoCompile *cfg) {
 MonoCompile*
 mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, gboolean run_cctors, gboolean compile_aot, int parts)
 {
-       MonoMethodHeader *header = mono_method_get_header (method);
+       MonoMethodHeader *header;
        guint8 *ip;
        MonoCompile *cfg;
        MonoJitInfo *jinfo;
@@ -11499,7 +11510,7 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, gbool
        gboolean deadce_has_run = FALSE;
        gboolean try_generic_shared;
        MonoMethod *method_to_compile;
-       int gsctx_size;
+       int generic_info_size;
 
        mono_jit_stats.methods_compiled++;
        if (mono_profiler_get_events () & MONO_PROFILE_JIT_COMPILATION)
@@ -11556,6 +11567,8 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, gbool
        if (try_generic_shared)
                cfg->generic_sharing_context = (MonoGenericSharingContext*)&cfg->generic_sharing_context;
        cfg->token_info_hash = g_hash_table_new (NULL, NULL);
+
+       header = mono_method_get_header (method_to_compile);
        if (!header) {
                cfg->exception_type = MONO_EXCEPTION_INVALID_PROGRAM;
                cfg->exception_message = g_strdup_printf ("Missing or incorrect header for method %s", cfg->method->name);
@@ -11808,19 +11821,19 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, gbool
        }
 
        if (cfg->generic_sharing_context)
-               gsctx_size = sizeof (MonoGenericSharingContext*);
+               generic_info_size = sizeof (MonoGenericJitInfo);
        else
-               gsctx_size = 0;
+               generic_info_size = 0;
 
        if (cfg->method->dynamic) {
                jinfo = g_malloc0 (sizeof (MonoJitInfo) + (header->num_clauses * sizeof (MonoJitExceptionInfo)) +
-                               gsctx_size);
+                               generic_info_size);
        } else {
                /* we access cfg->domain->mp */
                mono_domain_lock (cfg->domain);
                jinfo = mono_mempool_alloc0 (cfg->domain->mp, sizeof (MonoJitInfo) +
                                (header->num_clauses * sizeof (MonoJitExceptionInfo)) +
-                               gsctx_size);
+                               generic_info_size);
                mono_domain_unlock (cfg->domain);
        }
 
@@ -11832,9 +11845,41 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, gbool
        jinfo->cas_inited = FALSE; /* initialization delayed at the first stalk walk using this method */
        jinfo->num_clauses = header->num_clauses;
 
-       if (cfg->generic_sharing_context) {
-               jinfo->has_generic_sharing_context = 1;
-               mono_jit_info_set_generic_sharing_context (jinfo, cfg->generic_sharing_context);
+       if (cfg->generic_sharing_context && !(method_to_compile->flags & METHOD_ATTRIBUTE_STATIC)) {
+               MonoInst *inst;
+               MonoGenericJitInfo *gi;
+
+               jinfo->has_generic_jit_info = 1;
+
+               gi = mono_jit_info_get_generic_jit_info (jinfo);
+               g_assert (gi);
+
+               gi->generic_sharing_context = cfg->generic_sharing_context;
+
+               g_assert (!(method_to_compile->flags & METHOD_ATTRIBUTE_STATIC));
+
+               inst = cfg->varinfo [0];
+
+               if (inst->opcode == OP_REGVAR) {
+                       gi->this_in_reg = 1;
+                       gi->this_reg = inst->dreg;
+
+                       //g_print ("this in reg %d\n", inst->dreg);
+               } else {
+                       g_assert (inst->opcode == OP_REGOFFSET);
+#ifdef __i386__
+                       g_assert (inst->inst_basereg == X86_EBP);
+#elif defined(__x86_64__)
+                       g_assert (inst->inst_basereg == X86_EBP || inst->inst_basereg == X86_ESP);
+#endif
+                       g_assert (inst->inst_offset >= G_MININT32 && inst->inst_offset <= G_MAXINT32);
+
+                       gi->this_in_reg = 0;
+                       gi->this_reg = inst->inst_basereg;
+                       gi->this_offset = inst->inst_offset;
+
+                       //g_print ("this at offset %d\n", inst->inst_offset);
+               }
        }
 
        if (header->num_clauses) {
index 50572e0dc3709718a0adb411bcd0d444190ba203..c568ff977bd189e45731caad8267e650bb51a629 100644 (file)
@@ -1223,6 +1223,7 @@ void     mono_arch_handle_altstack_exception    (void *sigctx, gpointer fault_ad
 gpointer mono_arch_ip_from_context              (void *sigctx) MONO_INTERNAL;
 void     mono_arch_sigctx_to_monoctx            (void *sigctx, MonoContext *ctx) MONO_INTERNAL;
 void     mono_arch_monoctx_to_sigctx            (MonoContext *mctx, void *ctx) MONO_INTERNAL;
+gpointer mono_arch_context_get_int_reg         (MonoContext *ctx, int reg) MONO_INTERNAL;
 void     mono_arch_flush_register_windows       (void) MONO_INTERNAL;
 gboolean mono_arch_is_inst_imm                  (gint64 imm) MONO_INTERNAL;
 MonoInst* mono_arch_get_domain_intrinsic        (MonoCompile* cfg) MONO_INTERNAL;
@@ -1246,7 +1247,7 @@ gpointer mono_arch_get_delegate_invoke_impl     (MonoMethodSignature *sig, gbool
 gpointer mono_arch_create_specific_trampoline   (gpointer arg1, MonoTrampolineType tramp_type, MonoDomain *domain, guint32 *code_len) MONO_INTERNAL;
 void        mono_arch_emit_imt_argument         (MonoCompile *cfg, MonoCallInst *call) MONO_INTERNAL;
 MonoMethod* mono_arch_find_imt_method           (gpointer *regs, guint8 *code) MONO_INTERNAL;
-MonoObject* mono_arch_find_this_argument        (gpointer *regs, MonoMethod *method) MONO_INTERNAL;
+MonoObject* mono_arch_find_this_argument        (gpointer *regs, MonoMethod *method, MonoGenericSharingContext *gsctx) MONO_INTERNAL;
 gpointer    mono_arch_build_imt_thunk           (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckItem **imt_entries, int count) MONO_INTERNAL;
 void    mono_arch_notify_pending_exc (void) MONO_INTERNAL;
 
index 93b5da43696b22952635ec07d929b13aa96dbf6a..198a6e2bcb65d6752a345b52a9719f107ea7c35f 100644 (file)
@@ -1,3 +1,8 @@
+2008-03-04  Mark Probst  <mark.probst@gmail.com>
+
+       * generics-sharing.2.c: Added test for open catch clauses in
+       shared generic code.
+
 2008-02-27  Zoltan Varga  <vargaz@gmail.com>
 
        * Makefile.am: Compile and run all tests using the 2.0 profile.
index 19faeee1b2327a86c9711b8f99af80b2244882fa..ced7ada8fdbcf11cf51b06628f35bdb98f6831e8 100644 (file)
@@ -5,8 +5,14 @@ public class ClassA {}
 public class ClassB {}
 public class ClassC {}
 
+public class GenExc<T> : Exception {}
+
 public class NonGen {
        public static int field = 123;
+
+       public static void doThrow () {
+               throw new GenExc<ClassA> ();
+       }
 }
 
 public class GenA<T> {
@@ -66,6 +72,16 @@ public class GenA<T> {
        public T cast (Object obj) {
                return (T)obj;
        }
+
+       public void except () {
+               try {
+                       NonGen.doThrow();
+               }
+               catch (GenExc<T>)
+               {
+                       //Console.WriteLine("exception thrown");
+               }
+       }
 }
 
 public class GenB<T> {
@@ -213,7 +229,7 @@ public class main {
                        error ("object from " + method + " should have type " + t.ToString () + " but has type " + obj.GetType ().ToString ());
        }
 
-       public static void work<T> (T obj) {
+       public static void work<T> (T obj, bool mustCatch) {
                EqualityComparer<T> comp = EqualityComparer<T>.Default;
 
                GenA<T> ga = new GenA<T> ();
@@ -242,6 +258,20 @@ public class main {
 
                new GenADeriv<T> ();
 
+               if (mustCatch) {
+                       bool didCatch = false;
+
+                       try {
+                               ga.except ();
+                       } catch (GenExc<ClassA>) {
+                               didCatch = true;
+                       }
+
+                       if (!didCatch)
+                               error ("except");
+               } else
+                       ga.except ();
+
                MyDict<T, ClassB> dtb = new MyDict<T, ClassB> (obj, new ClassB ());
 
                typeCheck ("MyPair", dtb.p, typeof (MyPair<T, ClassB>));
@@ -299,12 +329,12 @@ public class main {
 
        public static int Main ()
        {
-               work<ClassA> (new ClassA ());
-               work<ClassB> (new ClassB ());
-               work<ClassC> (new ClassC ());
-               work<GenA<ClassA>> (new GenA<ClassA> ());
-               work<int[]> (new int[3]);
-               work<int> (123);
+               work<ClassA> (new ClassA (), false);
+               work<ClassB> (new ClassB (), true);
+               work<ClassC> (new ClassC (), true);
+               work<GenA<ClassA>> (new GenA<ClassA> (), true);
+               work<int[]> (new int[3], true);
+               work<int> (123, true);
 
                StaticTest<ClassA> sa = new StaticTest<ClassA> (1234);
                StaticTest<ClassB> sb = new StaticTest<ClassB> (2345);