Skip to content

Conversation

@KristofferC
Copy link
Member

This avoids invalidating

  precompile(Tuple{typeof(Artifacts.artifact_slash_lookup), String, Base.Dict{String, Any}, String, Base.BinaryPlatforms.Platform})
  precompile(Tuple{typeof(Artifacts._artifact_str), Module, String, Base.SubString{String}, String, Base.Dict{String, Any}, Base.SHA1, Base.BinaryPlatforms.Platform, Any})

when loading a JLL that uses platform augmentation after e.g. Symbolics.jl which defines a bunch of core methods (==, hash, etc) on new types that are <: Function.

In general, the Artifacts and BinaryPlatform modules feels quite "under typed". I wonder if it would be worth doing the TOML parsing in one single place and produce type stable outputs from that one place instead of passing around Dicts to so many functions.

@KristofferC KristofferC requested review from staticfloat and vtjnash May 2, 2023 11:31
tags::Dict{String,String}
# The "compare strategy" allows selective overriding on how a tag is compared
compare_strategies::Dict{String,Function}
compare_strategies::IdDict{String,Function}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dict should be better here, since the key is a String

for x in meta
x::Dict{String}
dl_dict[unpack_platform(x, name, artifacts_toml)] = x
y = x::Dict{String}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This type assert seems somewhat expensive, since you don't know the key

meta === nothing && return nothing
# If it's NOT a dict, complain
elseif !isa(meta, Dict)
if !isa(meta, Dict{String})
Copy link
Member

@vtjnash vtjnash May 2, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this makes the isa check more expensive, since we have a fast path for unparameterized types, but it cannot optimize partially parameterized types

Copy link
Member

@vtjnash vtjnash left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RSLGTM. Someone else might know this code a lot better

Comment on lines +1092 to +1093
# @invokelatest here to not get invalidated by new defs of `==(::Function, ::Function)`
return @invokelatest getindex(download_info, first(ps))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So if I understand the compiler properly, what this does is pays a constant penalty (unable to inline getindex()) on every invocation, in order to avoid paying an infrequent but huge penalty (recompiling all callers of this function upon invalidation)? Where the "best" solution where we pay no penalty (separate compilation) would have the (arguable) downside of not reacting to said invalidations?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that is a fair summary yes.

function parse_mapping(mapping::Dict, name::String, _::String)
d = Dict{String, Any}()
for (k, v) in mapping
d[k] = parse_mapping(v, name)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
d[k] = parse_mapping(v, name)
d[k] = parse_mapping(v, name, _)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fact that this is not caught by the test suite is a little worrying.

# If this mapping is the empty string, un-override it
if mapping == ""
delete!(overrides[:hash], hash)
overrides_hash = overrides[:hash]::Dict{SHA1,Union{String,SHA1}}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the idea of having one dictionary keyed by a symbol is just fundamentally sloppy. I should have instead just tracked two separate dicts that can be properly inferred.

overrides_hash[hash] = mapping
end
elseif isa(mapping, Dict)
elseif isa(mapping, Dict{String})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment here for the slow isa check here.

@KristofferC
Copy link
Member Author

Thanks for the reviews. This PR was a bit "spray and pray". I'll try cut down the changes to the bare minimum to still make the original motivating cause work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants