static void print_obj_profile(void) { jl_value_t *errstream = jl_get_global(jl_base_module, jl_symbol("stderr_stream")); JL_TRY { if (errstream) jl_set_current_output_stream_obj(errstream); ios_t *s = jl_current_output_stream(); for(int i=0; i < obj_counts.size; i+=2) { if (obj_counts.table[i+1] != HT_NOTFOUND) { ios_printf(s, "%d ", obj_counts.table[i+1]-1); jl_show(obj_counts.table[i]); ios_printf(s, "\n"); } } } JL_CATCH { } }
/* warn about ambiguous method priorities the relative priority of A and B is ambiguous if !subtype(A,B) && !subtype(B,A) && no corresponding tuple elements are disjoint. for example, (AbstractArray, AbstractMatrix) and (AbstractMatrix, AbstractArray) are ambiguous. however, (AbstractArray, AbstractMatrix, Foo) and (AbstractMatrix, AbstractArray, Bar) are fine since Foo and Bar are disjoint, so there would be no confusion over which one to call. There is also this kind of ambiguity: foo{T,S}(T, S) vs. foo(Any,Any) In this case jl_types_equal() is true, but one is jl_type_morespecific or jl_type_match_morespecific than the other. To check this, jl_types_equal_generic needs to be more sophisticated so (T,T) is not equivalent to (Any,Any). (TODO) */ static void check_ambiguous(jl_methlist_t *ml, jl_tuple_t *type, jl_tuple_t *sig, jl_sym_t *fname) { // we know !jl_args_morespecific(type, sig) if ((type->length==sig->length || (type->length==sig->length+1 && is_va_tuple(type)) || (type->length+1==sig->length && is_va_tuple(sig))) && !jl_args_morespecific((jl_value_t*)sig, (jl_value_t*)type)) { jl_value_t *isect = jl_type_intersection((jl_value_t*)type, (jl_value_t*)sig); if (isect == (jl_value_t*)jl_bottom_type) return; JL_GC_PUSH(&isect); jl_methlist_t *l = ml; while (l != NULL) { if (sigs_eq(isect, (jl_value_t*)l->sig)) goto done_chk_amb; // ok, intersection is covered l = l->next; } char *n = fname->name; jl_value_t *errstream = jl_get_global(jl_system_module, jl_symbol("stderr_stream")); JL_TRY { if (errstream) jl_set_current_output_stream_obj(errstream); ios_t *s = jl_current_output_stream(); ios_printf(s, "Warning: New definition %s", n); jl_show((jl_value_t*)type); ios_printf(s, " is ambiguous with %s", n); jl_show((jl_value_t*)sig); ios_printf(s, ".\n Make sure %s", n); jl_show(isect); ios_printf(s, " is defined first.\n"); } JL_CATCH { jl_raise(jl_exception_in_transit); } done_chk_amb: JL_GC_POP(); }