2009-12-13 Zoltan Varga <vargaz@gmail.com>
authorZoltan Varga <vargaz@gmail.com>
Sun, 13 Dec 2009 14:50:31 +0000 (14:50 -0000)
committerZoltan Varga <vargaz@gmail.com>
Sun, 13 Dec 2009 14:50:31 +0000 (14:50 -0000)
* mini-ops.h (OP_IMPLICIT_EXCEPTION): New opcode marking the place where an
implicit exception can occur.

* ir-emit.h (MONO_EMIT_NEW_IMPLICIT_EXCEPTION): New macro to emit an
OP_IMPLICIT_EXCEPTION instruction.

* ir-emit.h (MONO_EMIT_NEW_CHECK_THIS): New macro.

* method-to-ir.c: Use MONO_EMIT_NEW_CHECK_THIS in a few places.

* mini-llvm.c: Handle OP_IMPLICIT_EXCEPTION by disabling llvm if it occurs
inside a protected block.

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

mono/mini/ChangeLog
mono/mini/ir-emit.h
mono/mini/method-to-ir.c
mono/mini/mini-llvm.c
mono/mini/mini-ops.h

index 99b9ff54b253ab3638424cbf2d7b77ae6a332455..a0f74c235aa5fac2eed4b8503caf662351b6454c 100644 (file)
@@ -1,5 +1,18 @@
 2009-12-13  Zoltan Varga  <vargaz@gmail.com>
 
+       * mini-ops.h (OP_IMPLICIT_EXCEPTION): New opcode marking the place where an
+       implicit exception can occur.
+
+       * ir-emit.h (MONO_EMIT_NEW_IMPLICIT_EXCEPTION): New macro to emit an
+       OP_IMPLICIT_EXCEPTION instruction.
+
+       * ir-emit.h (MONO_EMIT_NEW_CHECK_THIS): New macro.
+
+       * method-to-ir.c: Use MONO_EMIT_NEW_CHECK_THIS in a few places.
+
+       * mini-llvm.c: Handle OP_IMPLICIT_EXCEPTION by disabling llvm if it occurs
+       inside a protected block.
+
        * mini-llvm.c: Revert the last change, the signature of monitor entry/exit
        trampolines doesn't include the argument.
 
index 34223df22d6be66b1a111361c7af68944b50c4e0..e1d05752db5fd08503fbb10280a34dc58f7d6adc 100644 (file)
@@ -725,6 +725,20 @@ static int ccount = 0;
            (cfg)->cbb = (bblock); \
     } while (0)
 
+/* This marks a place in code where an implicit exception could be thrown */
+#define MONO_EMIT_NEW_IMPLICIT_EXCEPTION(cfg) do { \
+               if (COMPILE_LLVM ((cfg))) {                                                                     \
+                       MONO_EMIT_NEW_UNALU (cfg, OP_IMPLICIT_EXCEPTION, -1, -1);       \
+               } \
+       } while (0)
+
+#define MONO_EMIT_NEW_CHECK_THIS(cfg, sreg) do { \
+       cfg->flags |= MONO_CFG_HAS_CHECK_THIS; \
+       MONO_EMIT_NEW_IMPLICIT_EXCEPTION (cfg); \
+       MONO_EMIT_NEW_UNALU (cfg, OP_CHECK_THIS, -1, sreg); \
+       MONO_EMIT_NEW_UNALU (cfg, OP_NOT_NULL, -1, sreg);       \
+       } while (0)
+
 /*Object Model related macros*/
 
 #ifndef MONO_ARCH_EMIT_BOUNDS_CHECK
@@ -741,6 +755,7 @@ static int ccount = 0;
                        MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, (reg), 0); \
                        MONO_EMIT_NEW_COND_EXC (cfg, EQ, "NullReferenceException"); \
                }                                                                                                                               \
+               MONO_EMIT_NEW_IMPLICIT_EXCEPTION (cfg); \
        } while (0)
 
 /* cfg is the MonoCompile been used
index 784d126879268affd4414664da37c316e815a7cf..2b31195117ade2001f43f1bd7056546c0217acbe 100644 (file)
@@ -2314,11 +2314,8 @@ mono_emit_method_call_full (MonoCompile *cfg, MonoMethod *method, MonoMethodSign
                                method = call->method = mono_marshal_get_remoting_invoke_with_check (method);
                        }
 
-                       if (!method->string_ctor) {
-                               cfg->flags |= MONO_CFG_HAS_CHECK_THIS;
-                               MONO_EMIT_NEW_UNALU (cfg, OP_CHECK_THIS, -1, this_reg);
-                               MONO_EMIT_NEW_UNALU (cfg, OP_NOT_NULL, -1, this_reg);
-                       }
+                       if (!method->string_ctor)
+                               MONO_EMIT_NEW_CHECK_THIS (cfg, this_reg);
 
                        call->inst.opcode = callvirt_to_call (call->inst.opcode);
 
@@ -2333,9 +2330,7 @@ mono_emit_method_call_full (MonoCompile *cfg, MonoMethod *method, MonoMethodSign
                         * it's class or the method itself are sealed.
                         * But first we need to ensure it's not a null reference.
                         */
-                       cfg->flags |= MONO_CFG_HAS_CHECK_THIS;
-                       MONO_EMIT_NEW_UNALU (cfg, OP_CHECK_THIS, -1, this_reg);
-                       MONO_EMIT_NEW_UNALU (cfg, OP_NOT_NULL, -1, this_reg);
+                       MONO_EMIT_NEW_CHECK_THIS (cfg, this_reg);
 
                        call->inst.opcode = callvirt_to_call (call->inst.opcode);
                        MONO_ADD_INS (cfg->cbb, (MonoInst*)call);
@@ -5767,9 +5762,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
 
                NEW_ARGLOAD (cfg, arg_ins, 0);
                MONO_ADD_INS (cfg->cbb, arg_ins);
-               cfg->flags |= MONO_CFG_HAS_CHECK_THIS;
-               MONO_EMIT_NEW_UNALU (cfg, OP_CHECK_THIS, -1, arg_ins->dreg);
-               MONO_EMIT_NEW_UNALU (cfg, OP_NOT_NULL, -1, arg_ins->dreg);
+               MONO_EMIT_NEW_CHECK_THIS (cfg, arg_ins->dreg);
        }
 
        /* we use a spare stack slot in SWITCH and NEWOBJ and others */
@@ -6448,13 +6441,8 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                                        cmethod, MONO_RGCTX_INFO_METHOD);
                        }
 
-                       if (check_this) {
-                               MonoInst *check;
-
-                               MONO_INST_NEW (cfg, check, OP_CHECK_THIS);
-                               check->sreg1 = sp [0]->dreg;
-                               MONO_ADD_INS (cfg->cbb, check);
-                       }
+                       if (check_this)
+                               MONO_EMIT_NEW_CHECK_THIS (cfg, sp [0]->dreg);
 
                        /* Calling virtual generic methods */
                        if (cmethod && virtual && 
index f16d407a6995daedd0d2d83ce9b4f8dd361c7275..41b4629f2036a756a098279c9af9f8febadc069c 100644 (file)
@@ -1258,6 +1258,8 @@ emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder, int *pindexes)
                }
        }
 
+       if (cfg->vret_addr)
+               emit_volatile_store (ctx, cfg->vret_addr->dreg);
        if (sig->hasthis)
                emit_volatile_store (ctx, cfg->args [0]->dreg);
        for (i = 0; i < sig->param_count; ++i)
@@ -3143,6 +3145,11 @@ mono_llvm_emit_method (MonoCompile *cfg)
                        /*
                         * EXCEPTION HANDLING
                         */
+                       case OP_IMPLICIT_EXCEPTION:
+                               /* This marks a place where an implicit exception can happen */
+                               if (bb->region != -1)
+                                       LLVM_FAILURE (ctx, "implicit-exception");
+                               break;
                        case OP_THROW: {
                                MonoMethodSignature *throw_sig;
                                LLVMValueRef callee, arg;
index 0a6a08d9bb30c79d3209247e6942e0a1b641a6f8..2f76fd211fa16319660994a330e9ebcb0ef91718 100644 (file)
@@ -26,6 +26,7 @@ MINI_OP(OP_LOCALLOC, "localloc", IREG, IREG, NONE)
 MINI_OP(OP_LOCALLOC_IMM, "localloc_imm", IREG, NONE, NONE)
 MINI_OP(OP_CHECK_THIS, "checkthis", NONE, IREG, NONE)
 MINI_OP(OP_SEQ_POINT, "seq_point", NONE, NONE, NONE)
+MINI_OP(OP_IMPLICIT_EXCEPTION, "implicit_exception", NONE, NONE, NONE)
 
 MINI_OP(OP_VOIDCALL,   "voidcall", NONE, NONE, NONE)
 MINI_OP(OP_VOIDCALLVIRT,       "voidcallvirt", NONE, NONE, NONE)