static void jl_typemap_list_insert_sorted(jl_typemap_entry_t **pml, jl_value_t *parent, jl_typemap_entry_t *newrec, const struct jl_typemap_info *tparams) { jl_typemap_entry_t *l, **pl; pl = pml; l = *pml; jl_value_t *pa = parent; while (l != (void*)jl_nothing) { if (!l->isleafsig) { // quickly ignore all of the leafsig entries (these were handled by caller) if (jl_args_morespecific((jl_value_t*)newrec->sig, (jl_value_t*)l->sig)) { if (l->simplesig == (void*)jl_nothing || newrec->simplesig != (void*)jl_nothing || !sigs_eq((jl_value_t*)l->sig, (jl_value_t*)newrec->sig, 1)) { // might need to insert multiple entries for a lookup differing only by their simplesig // when simplesig contains a kind // TODO: make this test more correct or figure out a better way to compute this break; } } } pl = &l->next; pa = (jl_value_t*)l; l = l->next; } JL_SIGATOMIC_BEGIN(); newrec->next = l; jl_gc_wb(newrec, l); *pl = newrec; jl_gc_wb(pa, newrec); // if this contains Union types, methods after it might actually be // more specific than it. we need to re-sort them. if (has_unions(newrec->sig)) { jl_value_t *item_parent = (jl_value_t*)newrec; jl_value_t *next_parent = 0; jl_typemap_entry_t *item = newrec->next, *next; jl_typemap_entry_t **pitem = &newrec->next, **pnext; while (item != (void*)jl_nothing) { pl = pml; l = *pml; pa = parent; next = item->next; pnext = &item->next; next_parent = (jl_value_t*)item; while (l != newrec->next) { if (jl_args_morespecific((jl_value_t*)item->sig, (jl_value_t*)l->sig)) { // reinsert item earlier in the list *pitem = next; jl_gc_wb(item_parent, next); item->next = l; jl_gc_wb(item, item->next); *pl = item; jl_gc_wb(pa, item); pnext = pitem; next_parent = item_parent; break; } pl = &l->next; pa = (jl_value_t*)l; l = l->next; } item = next; pitem = pnext; item_parent = next_parent; } } JL_SIGATOMIC_END(); return; }
static void jl_typemap_list_insert_sorted(jl_typemap_entry_t **pml, jl_value_t *parent, jl_typemap_entry_t *newrec, const struct jl_typemap_info *tparams) { jl_typemap_entry_t *l, **pl; pl = pml; l = *pml; jl_value_t *pa = parent; while (l != (void*)jl_nothing) { if (!l->isleafsig) { if (jl_args_morespecific((jl_value_t*)newrec->sig, (jl_value_t*)l->sig)) break; } pl = &l->next; pa = (jl_value_t*)l; l = l->next; } JL_SIGATOMIC_BEGIN(); newrec->next = l; jl_gc_wb(newrec, l); *pl = newrec; jl_gc_wb(pa, newrec); // if this contains Union types, methods after it might actually be // more specific than it. we need to re-sort them. if (has_unions(newrec->sig)) { jl_value_t *item_parent = (jl_value_t*)newrec; jl_value_t *next_parent = 0; jl_typemap_entry_t *item = newrec->next, *next; jl_typemap_entry_t **pitem = &newrec->next, **pnext; while (item != (void*)jl_nothing) { pl = pml; l = *pml; pa = parent; next = item->next; pnext = &item->next; next_parent = (jl_value_t*)item; while (l != newrec->next) { if (jl_args_morespecific((jl_value_t*)item->sig, (jl_value_t*)l->sig)) { // reinsert item earlier in the list *pitem = next; jl_gc_wb(item_parent, next); item->next = l; jl_gc_wb(item, item->next); *pl = item; jl_gc_wb(pa, item); pnext = pitem; next_parent = item_parent; break; } pl = &l->next; pa = (jl_value_t*)l; l = l->next; } item = next; pitem = pnext; item_parent = next_parent; } } JL_SIGATOMIC_END(); return; }