Skip to content

Commit

Permalink
union-types: use insertion (stable) sort instead of qsort
Browse files Browse the repository at this point in the history
Different platforms implement qsort differently, leading to
platform-specific errors. This is a quick port of the ml_matches
algorithm for use instead. For small unions (almost always), this should
also be slightly faster, though insignificant.

Refs #45874
  • Loading branch information
vtjnash committed Jul 1, 2022
1 parent bd7bd5e commit 4d90a04
Showing 1 changed file with 25 additions and 10 deletions.
35 changes: 25 additions & 10 deletions src/jltypes.c
Original file line number Diff line number Diff line change
Expand Up @@ -420,10 +420,8 @@ static int datatype_name_cmp(jl_value_t *a, jl_value_t *b) JL_NOTSAFEPOINT

// sort singletons first, then DataTypes, then UnionAlls,
// ties broken alphabetically including module name & type parameters
static int union_sort_cmp(const void *ap, const void *bp) JL_NOTSAFEPOINT
static int union_sort_cmp(jl_value_t *a, jl_value_t *b) JL_NOTSAFEPOINT
{
jl_value_t *a = *(jl_value_t**)ap;
jl_value_t *b = *(jl_value_t**)bp;
if (a == NULL)
return b == NULL ? 0 : 1;
if (b == NULL)
Expand Down Expand Up @@ -458,16 +456,33 @@ static int union_sort_cmp(const void *ap, const void *bp) JL_NOTSAFEPOINT
}
}

static void isort_union(jl_value_t **a, size_t len) JL_NOTSAFEPOINT
{
size_t i, j;
for (i = 1; i < len; i++) {
jl_value_t *m1 = a[i];
for (j = i; j > 0; j--) {
jl_value_t *m2 = a[j - 1];
if (union_sort_cmp(m1, m2) > 0)
break;
a[j] = m2;
}
a[j] = m1;
}
}

JL_DLLEXPORT jl_value_t *jl_type_union(jl_value_t **ts, size_t n)
{
if (n == 0) return (jl_value_t*)jl_bottom_type;
if (n == 0)
return (jl_value_t*)jl_bottom_type;
size_t i;
for(i=0; i < n; i++) {
for (i = 0; i < n; i++) {
jl_value_t *pi = ts[i];
if (!(jl_is_type(pi) || jl_is_typevar(pi)))
jl_type_error("Union", (jl_value_t*)jl_type_type, pi);
}
if (n == 1) return ts[0];
if (n == 1)
return ts[0];

size_t nt = count_union_components(ts, n);
jl_value_t **temp;
Expand All @@ -476,9 +491,9 @@ JL_DLLEXPORT jl_value_t *jl_type_union(jl_value_t **ts, size_t n)
flatten_type_union(ts, n, temp, &count);
assert(count == nt);
size_t j;
for(i=0; i < nt; i++) {
int has_free = temp[i]!=NULL && jl_has_free_typevars(temp[i]);
for(j=0; j < nt; j++) {
for (i = 0; i < nt; i++) {
int has_free = temp[i] != NULL && jl_has_free_typevars(temp[i]);
for (j = 0; j < nt; j++) {
if (j != i && temp[i] && temp[j]) {
if (temp[i] == jl_bottom_type ||
temp[j] == (jl_value_t*)jl_any_type ||
Expand All @@ -490,7 +505,7 @@ JL_DLLEXPORT jl_value_t *jl_type_union(jl_value_t **ts, size_t n)
}
}
}
qsort(temp, nt, sizeof(jl_value_t*), union_sort_cmp);
isort_union(temp, nt);
jl_value_t **ptu = &temp[nt];
*ptu = jl_bottom_type;
int k;
Expand Down

0 comments on commit 4d90a04

Please sign in to comment.