While debugging, this is something I see quite often. I didn’t find any trace in the docs and really curious about its function. Any pointer or hint is appreciated!
This has to do with ‘boxing’ data, which is e.g. required when the concrete type of some variable in a function body cannot be determined from the types of the inputs of a function (type instability). See https://docs.julialang.org/en/stable/manual/performance-tips/#Avoid-changing-the-type-of-a-variable-1 for an example (although Core.Box
doesn’t actually show up in the lowered code here). In this case, the actual type of the data is only known at runtime, and so Julia has to store a type tag identifying the runtime type along with the actual data. Boxed variables are heap-allocated and tracked by the garbage collector.
Seeing Core.Box
in the output of code_warntype
is usually a sign that inference can’t determine the concrete type of some variable, and can be a source of performance issues.
Here’s a case where Core.Box
shows up in lowered code in Julia 0.6.1 (from https://github.com/JuliaLang/julia/issues/19668#issuecomment-268523270):
julia> struct KWArg
x::Int
KWArg(;x::Int=1) = new(x)
end
julia> kwarg(;x::Int=1) = x
kwarg (generic function with 1 method)
julia> @code_lowered KWArg()
CodeInfo(:(begin
nothing
return ((Core.getfield)($(QuoteNode(Core.Box(#call#3))), :contents))(1, #self#)
end))
(Note: I actually found it hard to find cases where an explicit Core.Box
shows up in lowered code for functions on 0.6.1.)
This is where Core.Box
is defined on current master: https://github.com/JuliaLang/julia/blob/56b9593d8c25b839511e33e1fb06b58f95ce15df/base/boot.jl#L301-L305. Note the Any
type of the contents, and the @nospecialize
in the constructor.
No it’s totally unrelated to inference.
It’s added to the code when the frontend (parser) need a variable that can be mutated by multiple functions. (and in the case you show I’m 90% sure there was an issue for it). It does hurt inference but it is NOT caused by bad inference.
For the user, it’s basically the same as Base.RefValue{Any}
. You should not use it which is why it’s not in the document.
Thanks for clearing that up. I guess I was confusing the concept of boxing in general with Core.Box
.
Yeah, I linked to your issue comment.
Thanks!
Thanks too, buddy!