[mono][interp] Optimize box+unbox to no-op (#40017)
authorEgor Bogatov <egorbo@gmail.com>
Fri, 7 Aug 2020 13:07:56 +0000 (16:07 +0300)
committerGitHub <noreply@github.com>
Fri, 7 Aug 2020 13:07:56 +0000 (16:07 +0300)
src/mono/mono/mini/interp/transform.c

index 1fd13dd..b81d5f9 100644 (file)
@@ -4941,6 +4941,20 @@ generate_code (TransformData *td, MonoMethod *method, MonoMethodHeader *header,
                        klass = mini_get_class (method, token, generic_context);
                        CHECK_TYPELOAD (klass);
 
+                       // Common in generic code:
+                       // box T + unbox.any T -> nop
+            if ((td->last_ins->opcode == MINT_BOX || td->last_ins->opcode == MINT_BOX_VT) &&
+                (td->sp - 1)->klass == klass && !td->is_bb_start[in_offset]) {
+                gboolean is_vt = td->last_ins->opcode == MINT_BOX_VT;
+                interp_clear_ins(td, td->last_ins);
+                if (is_vt)
+                    PUSH_VT(td, mono_class_value_size(klass, NULL));
+                int mt = mint_type(m_class_get_byval_arg(klass));
+                SET_TYPE(td->sp - 1, stack_type[mt], klass);
+                td->ip += 5;
+                break;
+            }
+
                        if (mini_type_is_reference (m_class_get_byval_arg (klass))) {
                                int mt = mint_type (m_class_get_byval_arg (klass));
                                interp_handle_isinst (td, klass, FALSE);