-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
split SourceInfo out of LambdaInfo #18413
Conversation
c7bfdd7
to
094c7f6
Compare
jl_methtable_t *mt; | ||
jl_sym_t *name; | ||
jl_method_t *m = NULL; | ||
JL_GC_PUSH2(&f, &m); | ||
jl_tupletype_t *argtype = jl_apply_tuple_type(atypes); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why the change to make the tuple type here instead of in the front end? The method signature needs to be a type in any case, and in the future could be other kinds of types --- soon to be UnionAll types for methods with static parameters, and possibly later any type that's a subtype of Tuple.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The argument names and isva are directly mapped from the atypes svec. The translation to a tuple type in some cases is not information preserving (in particular with Vararg), so it is not an equivalent (or at least reversible) representation of the source information. In those cases this function becomes unable to form the map from the input argument list to the function argument number that stores contains value. I added a test for this case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug acknowledged (and I'm very glad to get rid of the awful jl_is_rest_arg
), but I don't think this is necessary to fix it. We could instead call jl_is_va_tuple
on the tuple type. The natural interface for adding a method is to specify a type and a function body. In fact, any code that tries to manually take apart types will increasingly be wrong or buggy. For example Union{Tuple{A,B}, Tuple{C,D}}
could be the type of a method, and you'll need to ask the type system to do something non-trivial to determine whether it is varargs, what the type of the nth argument is, etc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isvararg != isvatuple. one such counter example is NTuple
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok that's true, but long term, this needs to be a type.
Also: do we want f(x::T)
to be varargs based on whether T
evaluates to Vararg{...}
? That seems like a misfeature to me. And since as you point out Tuple{Int,Int}
and Tuple{Vararg{Int,2}}
are equal types, the presence of Vararg
is not a good basis for identifying varargs functions. It seems like this needs to be syntax-based and passed as a separate flag, since it's not really a property of the signature but of how argument names are bound to argument values. I suppose we can deal with that later though.
We should think about the names of the types a bit.
It's also a bit hard to understand what a |
Perhaps |
|
Semantically, to some extent, "unspecialized" is a specialization (just not a leaf one). But point taken. I'm reluctant use use "Function" in the name, since I think that nomenclature is already sufficiently taken (and brings back memories of the old generic function / anonymous function confusion for new users). I agree calling this a |
How about |
I'm not sure that's really its key attribute. I think really the only key property is that it contains a specTypes key, since it basically exists just to merge a bunch of independent caches that could instead have been in independent TypeMaps (or computed directly from sig). How about |
I do think it's significant that it contains actual function pointers. It's very nearly a traditional symbol table entry, mapping a name (or type in our case) to an address. |
|
That sounds good. I think that also helps indicate that this is a singleton, which is also good. |
9d0034a
to
7fec8c4
Compare
7fec8c4
to
1b22b61
Compare
Will merge once the CI build finishes (so I can resume work on #265 PR). |
does this need more deprecations? was it properly reviewed considering how much code it changes? |
s = ccall(:jl_copy_code_info, Ref{CodeInfo}, (Any,), s) | ||
s.code = ccall(:jl_uncompress_ast, Array{Any,1}, (Any, Any), m, s.code) | ||
end | ||
return s |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is the maybe-aliasing here potentially an issue?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the callee doesn't own this return value. we would need to make a deepcopy if that's your concern, but this is not new.
and if we're serious about performance tracking, any significant changes like this should run through @nanosoldier |
jl_finalize_function(F, collector ? collector : m.get()); | ||
static void jl_merge_recursive(Module *m, Module *collector) | ||
{ | ||
// probably not many unresolved declarations, but be sure iterate over their Names, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
be sure to iterate
Your benchmark job has completed - possible performance regressions were detected. A full report can be found here. cc @jrevels |
1b22b61
to
ae32538
Compare
cool, @nanosoldier |
due to other recent changes, LambdaInfo is now much more expensive to create and difficult to destroy it is also hard to keep track of where modification is allowed the SourceInfo type represents an atomic chunk of information that needs to be immutable after construction this sets up some of the work needed for #265, and decreases the size of the sysimg :)
this lets us avoid needing atomic operations to order the reads of fptr and jlcall_api since both will be null-initialized, set-once while the codegen lock is held
allows removing inCompile, which wasn't necessarily entirely accurate anyways for complex recursive calls from type-inference, it theoretically could have compiled part of a cycle, but not the whole cycle, and failed when it tried to finalize it, without realizing part of the cycle was still being compiled
…od idea this is required by the threadcall function
0c70f14
to
88122b3
Compare
Your benchmark job has completed - possible performance regressions were detected. A full report can be found here. cc @jrevels |
|
||
``ftpr`` - The generic jlcall entry point | ||
|
||
``jlcall_api`` - The ABI to use when calling ``fptr``. Some significant ones include: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
api vs abi still confusing terminology
Probably introduced after #18413. Re-uses the unused 'thunk' root.
Probably introduced after #18413. Re-uses the unused 'thunk' root.
A number of recent changes to the system subtly broke the definition of LambdaInfo (most recently culminating in #18191), this aims to rectify that shift in identity by revising the way this data is passed around the system. And I expect this to be useful for fix #265, since the current issue I'm running into there is the possibility the system will try to duplicate an existing LambdaInfo (for example to re-infer it:
julia/base/inference.jl
Lines 1601 to 1621 in 424b3c5
Major changes:
code
field of LambdaInfo is gone, replaced byinferred
and which is usuallynull
. This fixes two of the lock priority inversion bugs, as now no Julia code needs to get run to create a LambdaInfo. And it should make it easier to delete the code (as that's a return to the default state rather than the presence of a third rare state), so that's done more aggressively now.jlcall_api
has been incremented by 1 to make it thread-safe to read without needing a lock or atomics ops in the fast-path of jl_call_method_internal (exceptjlcall_api = 2
, which remains unchanged)expand
,code_lowered
,code_typed
, etc.) is corrected / improved / fixed, since it is no longer ambiguous whether to print the source or the signature