From 035550b4f720cd44f63b7046c25c160c0b0ab877 Mon Sep 17 00:00:00 2001 From: Jude Melton-Houghton Date: Mon, 19 Sep 2022 14:30:26 -0400 Subject: [PATCH] Use constant metatable if it already exists This helps in the case of o:a() o.a(o) But not in the case of o.a(o) o:a() --- src/lj_record.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/lj_record.c b/src/lj_record.c index fbaafead..5b475efa 100644 --- a/src/lj_record.c +++ b/src/lj_record.c @@ -1060,6 +1060,7 @@ int lj_record_mm_lookup(jit_State *J, RecordIndex *ix, MMS mm) { RecordIndex mix; GCtab *mt; + TRef kmt; if (tref_istab(ix->tab)) { mt = tabref(tabV(&ix->tabv)->metatable); mix.tab = emitir(IRT(IR_FLOAD, IRT_TAB), ix->tab, IRFL_TAB_META); @@ -1104,8 +1105,22 @@ int lj_record_mm_lookup(jit_State *J, RecordIndex *ix, MMS mm) GG_OFS(g.gcroot[GCROOT_BASEMT+itypemap(&ix->tabv)])); goto nocheck; } - if (ix->mtspec && mt) { - TRef kmt = lj_ir_ktab(J, mt); + kmt = 0; + if (mt) { + /* Constify metatable or try to find existing constant. */ + if (ix->mtspec) { + kmt = lj_ir_ktab(J, mt); + } else { + IRRef ref; + for (ref = J->chain[IR_KGC]; ref; ref = J->cur.ir[ref].prev) { + if (ir_kgc(&J->cur.ir[ref]) == obj2gco(mt)) { + kmt = TREF(ref, IRT_TAB); + break; + } + } + } + } + if (kmt) { emitir(IRTG(IR_EQ, IRT_TAB), mix.tab, kmt); mix.tab = kmt; ix->mt = kmt;