@@ -4601,7 +4601,7 @@ inline_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsig,
4601
4601
guint32 prev_cil_offset_to_bb_len ;
4602
4602
MonoMethod * prev_current_method ;
4603
4603
MonoGenericContext * prev_generic_context ;
4604
- gboolean ret_var_set , prev_ret_var_set , prev_disable_inline , virtual_ = FALSE;
4604
+ gboolean ret_var_set , prev_ret_var_set , prev_disable_inline , emit_check_this = FALSE;
4605
4605
MonoProfilerCoverageInfo * prev_coverage_info ;
4606
4606
4607
4607
g_assert (cfg -> exception_type == MONO_EXCEPTION_NONE );
@@ -4681,10 +4681,15 @@ inline_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsig,
4681
4681
cfg -> ret_var_set = FALSE;
4682
4682
cfg -> inline_depth ++ ;
4683
4683
4684
- if (ip && * ip == CEE_CALLVIRT && !(cmethod -> flags & METHOD_ATTRIBUTE_STATIC ))
4685
- virtual_ = TRUE;
4684
+ if (ip && * ip == CEE_CALLVIRT && !(cmethod -> flags & METHOD_ATTRIBUTE_STATIC ) &&
4685
+ // Only perform a null check on 'this' arguments for methods on:
4686
+ // 1. Reference types
4687
+ // 2. System.ValueType and System.Enum as those will have a boxed 'this' argument.
4688
+ // NOTE: klass->valuetype is FALSE for System.ValueType so we only need to check System.Enum.
4689
+ (!m_class_is_valuetype (cmethod -> klass ) || m_class_is_enumtype (cmethod -> klass )))
4690
+ emit_check_this = TRUE;
4686
4691
4687
- costs = mono_method_to_ir (cfg , cmethod , sbblock , ebblock , rvar , sp , real_offset , virtual_ );
4692
+ costs = mono_method_to_ir (cfg , cmethod , sbblock , ebblock , rvar , sp , real_offset , emit_check_this );
4688
4693
4689
4694
ret_var_set = cfg -> ret_var_set ;
4690
4695
@@ -6116,7 +6121,7 @@ mono_opcode_decode (guchar *ip, guint op_size, MonoOpcodeEnum il_op, MonoOpcodeP
6116
6121
* @return_var: if not NULL, the place where the return value is stored, used during inlining.
6117
6122
* @inline_args: if not NULL, contains the arguments to the inline call
6118
6123
* @inline_offset: if not zero, the real offset from the inline call, or zero otherwise.
6119
- * @is_virtual_call : whether this method is being called as a result of a call to callvirt
6124
+ * @emit_check_this : whether this method needs to perform an explicit this null check.
6120
6125
*
6121
6126
* This method is used to turn ECMA IL into Mono's internal Linear IR
6122
6127
* reprensetation. It is used both for entire methods, as well as
@@ -6129,7 +6134,7 @@ mono_opcode_decode (guchar *ip, guint op_size, MonoOpcodeEnum il_op, MonoOpcodeP
6129
6134
int
6130
6135
mono_method_to_ir (MonoCompile * cfg , MonoMethod * method , MonoBasicBlock * start_bblock , MonoBasicBlock * end_bblock ,
6131
6136
MonoInst * return_var , MonoInst * * inline_args ,
6132
- guint inline_offset , gboolean is_virtual_call )
6137
+ guint inline_offset , gboolean emit_check_this )
6133
6138
{
6134
6139
ERROR_DECL (error );
6135
6140
// Buffer to hold parameters to mono_new_array, instead of varargs.
@@ -6603,7 +6608,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
6603
6608
}
6604
6609
6605
6610
/* add a check for this != NULL to inlined methods */
6606
- if (is_virtual_call ) {
6611
+ if (emit_check_this ) {
6607
6612
MonoInst * arg_ins ;
6608
6613
6609
6614
NEW_ARGLOAD (cfg , arg_ins , 0 );
0 commit comments