return method;
}
-static inline MonoClass*
+MonoClass*
mini_get_class (MonoMethod *method, guint32 token, MonoGenericContext *context)
{
MonoError error;
sp -= n;
+ if (cmethod && cmethod->klass->image == mono_defaults.corlib && !strcmp (cmethod->klass->name, "ThrowHelper"))
+ cfg->cbb->out_of_line = TRUE;
+
/*
* We have the `constrained.' prefix opcode.
*/
}
/* Common call */
- if (!(cmethod->iflags & METHOD_IMPL_ATTRIBUTE_AGGRESSIVE_INLINING))
+ if (!(method->iflags & METHOD_IMPL_ATTRIBUTE_AGGRESSIVE_INLINING) && !(cmethod->iflags & METHOD_IMPL_ATTRIBUTE_AGGRESSIVE_INLINING))
INLINE_FAILURE ("call");
ins = mono_emit_method_call_full (cfg, cmethod, fsig, tail_call, sp, virtual_ ? sp [0] : NULL,
imt_arg, vtable_arg);
token = read32 (ip + 1);
klass = mini_get_class (method, token, generic_context);
CHECK_TYPELOAD (klass);
- if (ins_flag & MONO_INST_VOLATILE) {
- /* Volatile stores have release semantics, see 12.6.7 in Ecma 335 */
- mini_emit_memory_barrier (cfg, MONO_MEMORY_BARRIER_REL);
- }
+
/* FIXME: should check item at sp [1] is compatible with the type of the store. */
- EMIT_NEW_STORE_MEMBASE_TYPE (cfg, ins, &klass->byval_arg, sp [0]->dreg, 0, sp [1]->dreg);
- ins->flags |= ins_flag;
- if (cfg->gen_write_barriers && cfg->method->wrapper_type != MONO_WRAPPER_WRITE_BARRIER &&
- generic_class_is_reference_type (cfg, klass) && !MONO_INS_IS_PCONST_NULL (sp [1])) {
- /* insert call to write barrier */
- mini_emit_write_barrier (cfg, sp [0], sp [1]);
- }
+ mini_emit_memory_store (cfg, &klass->byval_arg, sp [0], sp [1], ins_flag);
ins_flag = 0;
ip += 5;
inline_costs += 1;
ip += 6;
break;
case CEE_CPBLK:
- case CEE_INITBLK: {
- MonoInst *iargs [3];
CHECK_STACK (3);
sp -= 3;
-
- /* Skip optimized paths for volatile operations. */
- if ((ip [1] == CEE_CPBLK) && !(ins_flag & MONO_INST_VOLATILE) && (cfg->opt & MONO_OPT_INTRINS) && (sp [2]->opcode == OP_ICONST) && ((n = sp [2]->inst_c0) <= sizeof (gpointer) * 5)) {
- mini_emit_memcpy (cfg, sp [0]->dreg, 0, sp [1]->dreg, 0, sp [2]->inst_c0, 0);
- } else if ((ip [1] == CEE_INITBLK) && !(ins_flag & MONO_INST_VOLATILE) && (cfg->opt & MONO_OPT_INTRINS) && (sp [2]->opcode == OP_ICONST) && ((n = sp [2]->inst_c0) <= sizeof (gpointer) * 5) && (sp [1]->opcode == OP_ICONST) && (sp [1]->inst_c0 == 0)) {
- /* emit_memset only works when val == 0 */
- mini_emit_memset (cfg, sp [0]->dreg, 0, sp [2]->inst_c0, sp [1]->inst_c0, 0);
- } else {
- MonoInst *call;
- iargs [0] = sp [0];
- iargs [1] = sp [1];
- iargs [2] = sp [2];
- if (ip [1] == CEE_CPBLK) {
- /*
- * FIXME: It's unclear whether we should be emitting both the acquire
- * and release barriers for cpblk. It is technically both a load and
- * store operation, so it seems like that's the sensible thing to do.
- *
- * FIXME: We emit full barriers on both sides of the operation for
- * simplicity. We should have a separate atomic memcpy method instead.
- */
- MonoMethod *memcpy_method = mini_get_memcpy_method ();
-
- if (ins_flag & MONO_INST_VOLATILE)
- mini_emit_memory_barrier (cfg, MONO_MEMORY_BARRIER_SEQ);
-
- call = mono_emit_method_call (cfg, memcpy_method, iargs, NULL);
- call->flags |= ins_flag;
-
- if (ins_flag & MONO_INST_VOLATILE)
- mini_emit_memory_barrier (cfg, MONO_MEMORY_BARRIER_SEQ);
- } else {
- MonoMethod *memset_method = mini_get_memset_method ();
- if (ins_flag & MONO_INST_VOLATILE) {
- /* Volatile stores have release semantics, see 12.6.7 in Ecma 335 */
- mini_emit_memory_barrier (cfg, MONO_MEMORY_BARRIER_REL);
- }
- call = mono_emit_method_call (cfg, memset_method, iargs, NULL);
- call->flags |= ins_flag;
- }
- }
+ mini_emit_memory_copy_bytes (cfg, sp [0], sp [1], sp [2], ins_flag);
+ ip += 2;
+ ins_flag = 0;
+ inline_costs += 1;
+ break;
+ case CEE_INITBLK:
+ CHECK_STACK (3);
+ sp -= 3;
+ mini_emit_memory_init_bytes (cfg, sp [0], sp [1], sp [2], ins_flag);
ip += 2;
ins_flag = 0;
inline_costs += 1;
break;
- }
case CEE_NO_:
CHECK_OPSIZE (3);
if (ip [2] & 0x1)
* - create a helper function for allocating a stack slot, taking into account
* MONO_CFG_HAS_SPILLUP.
* - merge r68207.
- * - merge the ia64 switch changes.
* - optimize mono_regstate2_alloc_int/float.
* - fix the pessimistic handling of variables accessed in exception handler blocks.
* - need to write a tree optimization pass, but the creation of trees is difficult, i.e.