diff --git a/src/6model/reprs/MVMMultiCache.c b/src/6model/reprs/MVMMultiCache.c index 69e0124030..6473180c1c 100644 --- a/src/6model/reprs/MVMMultiCache.c +++ b/src/6model/reprs/MVMMultiCache.c @@ -448,7 +448,9 @@ MVMObject * MVM_multi_cache_find_callsite_args(MVMThreadContext *tc, MVMObject * } /* Do a multi cache lookup based upon spesh arg facts. */ -MVMObject * MVM_multi_cache_find_spesh(MVMThreadContext *tc, MVMObject *cache_obj, MVMSpeshCallInfo *arg_info) { +MVMObject * MVM_multi_cache_find_spesh(MVMThreadContext *tc, MVMObject *cache_obj, + MVMSpeshCallInfo *arg_info, + MVMSpeshStatsType *type_tuple) { MVMMultiCacheBody *cache; MVMMultiCacheNode *tree; MVMint32 cur_node; @@ -483,7 +485,36 @@ MVMObject * MVM_multi_cache_find_spesh(MVMThreadContext *tc, MVMObject *cache_ob MVMuint64 arg_idx = arg_match & MVM_MULTICACHE_ARG_IDX_FILTER; MVMuint64 type_id = arg_match & MVM_MULTICACHE_TYPE_ID_FILTER; MVMSpeshFacts *facts = arg_info->arg_facts[arg_idx]; - if (facts) { + if (type_tuple) { + MVMuint64 tt_offset = arg_idx >= arg_info->cs->num_pos + ? (arg_idx - arg_info->cs->num_pos) / 2 + : arg_idx; + MVMuint32 is_rw = type_tuple[tt_offset].rw_cont; + MVMSTable *known_type_st; + MVMuint32 is_conc; + if (type_tuple[tt_offset].decont_type) { + known_type_st = type_tuple[tt_offset].decont_type->st; + is_conc = type_tuple[tt_offset].decont_type_concrete; + } + else { + known_type_st = type_tuple[tt_offset].type->st; + is_conc = type_tuple[tt_offset].type_concrete; + } + + /* Now check if what we have matches what we need. */ + if (known_type_st->type_cache_id == type_id) { + MVMuint32 need_concrete = (arg_match & MVM_MULTICACHE_ARG_CONC_FILTER) ? 1 : 0; + if (is_conc == need_concrete) { + MVMuint32 need_rw = (arg_match & MVM_MULTICACHE_ARG_RW_FILTER) ? 1 : 0; + if (need_rw == is_rw) { + cur_node = tree[cur_node].match; + continue; + } + } + } + cur_node = tree[cur_node].no_match; + } + else if (facts) { /* Figure out type, concreteness, and rw-ness from facts. */ MVMSTable *known_type_st; MVMuint32 is_conc; diff --git a/src/6model/reprs/MVMMultiCache.h b/src/6model/reprs/MVMMultiCache.h index 805365bc40..a9d9ae6af8 100644 --- a/src/6model/reprs/MVMMultiCache.h +++ b/src/6model/reprs/MVMMultiCache.h @@ -82,4 +82,4 @@ MVMObject * MVM_multi_cache_add(MVMThreadContext *tc, MVMObject *cache, MVMObjec MVMObject * MVM_multi_cache_find(MVMThreadContext *tc, MVMObject *cache, MVMObject *capture); MVMObject * MVM_multi_cache_find_callsite_args(MVMThreadContext *tc, MVMObject *cache, MVMCallsite *cs, MVMRegister *args); -MVMObject * MVM_multi_cache_find_spesh(MVMThreadContext *tc, MVMObject *cache, MVMSpeshCallInfo *arg_info); +MVMObject * MVM_multi_cache_find_spesh(MVMThreadContext *tc, MVMObject *cache, MVMSpeshCallInfo *arg_info, MVMSpeshStatsType *type_tuple); diff --git a/src/spesh/optimize.c b/src/spesh/optimize.c index e8d03f1e88..3197ee2f8d 100644 --- a/src/spesh/optimize.c +++ b/src/spesh/optimize.c @@ -1299,7 +1299,8 @@ static void optimize_call(MVMThreadContext *tc, MVMSpeshGraph *g, MVMSpeshBB *bb is->md_class_handle, is->md_cache_attr_name, is->md_cache_hint, &dest, MVM_reg_obj); if (!MVM_is_null(tc, dest.o)) { - MVMObject *found = MVM_multi_cache_find_spesh(tc, dest.o, arg_info); + MVMObject *found = MVM_multi_cache_find_spesh(tc, dest.o, + arg_info, stable_type_tuple); if (found) { /* Found it. Is it a code object already, or do we * have futher unpacking to do? */