From: Zoltan Varga Date: Sun, 13 Dec 2009 14:50:31 +0000 (-0000) Subject: 2009-12-13 Zoltan Varga X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=commitdiff_plain;h=d00161b0bd790d99a789549c2cb0f9d1b610e656;p=mono.git 2009-12-13 Zoltan Varga * 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 --- diff --git a/mono/mini/ChangeLog b/mono/mini/ChangeLog index 99b9ff54b25..a0f74c235aa 100644 --- a/mono/mini/ChangeLog +++ b/mono/mini/ChangeLog @@ -1,5 +1,18 @@ 2009-12-13 Zoltan Varga + * 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. diff --git a/mono/mini/ir-emit.h b/mono/mini/ir-emit.h index 34223df22d6..e1d05752db5 100644 --- a/mono/mini/ir-emit.h +++ b/mono/mini/ir-emit.h @@ -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 diff --git a/mono/mini/method-to-ir.c b/mono/mini/method-to-ir.c index 784d1268792..2b31195117a 100644 --- a/mono/mini/method-to-ir.c +++ b/mono/mini/method-to-ir.c @@ -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 && diff --git a/mono/mini/mini-llvm.c b/mono/mini/mini-llvm.c index f16d407a699..41b4629f203 100644 --- a/mono/mini/mini-llvm.c +++ b/mono/mini/mini-llvm.c @@ -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; diff --git a/mono/mini/mini-ops.h b/mono/mini/mini-ops.h index 0a6a08d9bb3..2f76fd211fa 100644 --- a/mono/mini/mini-ops.h +++ b/mono/mini/mini-ops.h @@ -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)