From 169205813b7d8f75a435edc092c8aa6678754711 Mon Sep 17 00:00:00 2001 From: Jay Krell Date: Tue, 20 Aug 2019 06:53:25 -0700 Subject: [PATCH] [interp] Outline box_nullable. (#16356) Without being entirely scientific about it, this case seems to be one that uses more than typical locals and therefore be on a sort of critical path to reduce frame size. I have a change that reduces frame to 0x78 bytes (albeit not yet working) and to achieve that, in this case I refetched the locals after function calls. This achieves similar but perhaps more elegantly. If we rest at larger frame size then this case might not be on the critical path. https://github.com/mono/mono/issues/16172. --- mono/mini/interp/interp.c | 40 +++++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/mono/mini/interp/interp.c b/mono/mini/interp/interp.c index e7a2bd5140f..6f3a4a3a238 100644 --- a/mono/mini/interp/interp.c +++ b/mono/mini/interp/interp.c @@ -3178,6 +3178,26 @@ mono_interp_enum_hasflag (stackval* sp, MonoClass* klass) sp->data.i = (a_val & b_val) == b_val; } +static MONO_NEVER_INLINE int +mono_interp_box_nullable (InterpFrame* frame, const guint16* ip, stackval* sp, MonoError* error) +{ + InterpMethod* const imethod = frame->imethod; + MonoClass* const c = (MonoClass*)imethod->data_items [* (guint16 *)(ip + 1)]; + + int size = mono_class_value_size (c, NULL); + + guint16 offset = * (guint16 *)(ip + 2); + gboolean pop_vt_sp = !(offset & BOX_NOT_CLEAR_VT_SP); + offset &= ~BOX_NOT_CLEAR_VT_SP; + + sp [-1 - offset].data.o = mono_nullable_box (sp [-1 - offset].data.p, c, error); + mono_error_cleanup (error); /* FIXME: don't swallow the error */ + + size = ALIGN_TO (size, MINT_VT_ALIGNMENT); + + return pop_vt_sp ? size : 0; +} + /* * If EXIT_AT_FINALLY is not -1, exit after exiting the finally clause with that index. * If BASE_FRAME is not NULL, copy arguments/locals from BASE_FRAME. @@ -5333,26 +5353,12 @@ main_loop: ip += 3; MINT_IN_BREAK; } - MINT_IN_CASE(MINT_BOX_NULLABLE) { - MonoClass* const c = (MonoClass*)imethod->data_items [* (guint16 *)(ip + 1)]; - - int size = mono_class_value_size (c, NULL); - - guint16 offset = * (guint16 *)(ip + 2); - gboolean pop_vt_sp = !(offset & BOX_NOT_CLEAR_VT_SP); - offset &= ~BOX_NOT_CLEAR_VT_SP; - - sp [-1 - offset].data.o = mono_nullable_box (sp [-1 - offset].data.p, c, error); - mono_error_cleanup (error); /* FIXME: don't swallow the error */ - - size = ALIGN_TO (size, MINT_VT_ALIGNMENT); - - if (pop_vt_sp) - vt_sp -= size; + MINT_IN_CASE(MINT_BOX_NULLABLE) + vt_sp -= mono_interp_box_nullable (frame, ip, sp, error); ip += 3; MINT_IN_BREAK; - } + MINT_IN_CASE(MINT_NEWARR) { MonoVTable *vtable = (MonoVTable*)imethod->data_items[*(guint16 *)(ip + 1)]; sp [-1].data.o = (MonoObject*) mono_array_new_specific_checked (vtable, sp [-1].data.i, error); -- 2.11.4.GIT