Improve how QueryCache/QueryState/QueryEngine are stored#152835
Improve how QueryCache/QueryState/QueryEngine are stored#152835nnethercote wants to merge 4 commits intorust-lang:mainfrom
QueryCache/QueryState/QueryEngine are stored#152835Conversation
|
|
|
@bors try @rust-timer queue |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Improve how `QueryCache`s and `QueryState`s are stored
|
Putting the state and cache directly in the vtable is not a possibility I had considered. It stretches the concept of “vtable” a bit, and it gives up on being able to treat the vtable as mere metadata, but it does have advantages for actually looking up the state/cache given a vtable reference. Genuinely unsure how to feel about this overall. It doesn’t jump out to me as something obviously-good or obviously-bad; the tradeoffs are more subtle. |
|
I agree about stretching the meaning of "vtable". Beyond that I think it's a clear win. The offset code is ridiculous, it screams "something went wrong here". More generally, it makes more sense to have a struct containing |
|
This PR also touches on some areas that I haven’t been able to work on because they’re still waiting for #152747 to be merged, so having this PR also interfere with that is starting to feel overwhelming. |
This comment has been minimized.
This comment has been minimized.
|
Finished benchmarking commit (6efacd9): comparison URL. Overall result: ✅ improvements - no action neededBenchmarking this pull request means it may be perf-sensitive – we'll automatically label it not fit for rolling up. You can override this, but we strongly advise not to, due to possible changes in compiler perf. @bors rollup=never Instruction countOur most reliable metric. Used to determine the overall result above. However, even this metric can be noisy.
Max RSS (memory usage)Results (secondary -3.2%)A less reliable metric. May be of interest, but not used to determine the overall result above.
CyclesResults (primary 2.1%)A less reliable metric. May be of interest, but not used to determine the overall result above.
Binary sizeThis benchmark run did not return any relevant results for this metric. Bootstrap: 487.064s -> 482.434s (-0.95%) |
|
I've been asking you for a lot of reviews; I'm happy to ask a different reviewer if you want a break. |
This comment has been minimized.
This comment has been minimized.
|
I was skeptical of this PR at first, because it was unclear to me whether moving state/cache into the vtable was a good idea overall, and I wasn't convinced by the motivation of wanting to get rid of the unsafe offset fields (even though I don't like the offset fields). However, after some more consideration, I'm coming around to the idea that putting per-query state/caches in the vtable is a fine idea in its own right. So now I'm pretty happy with the direction of this PR. I have some remarks to write up, and I'll want to do another pass, but overall this PR looks good to me. |
|
Pointers to fields can be done safely using say |
Even so, that's (a) a new third-party crate, and (b) it's very non-idiomatic and strongly suggests a suboptimal data layout. |
bc792c2 to
d13ad56
Compare
This comment has been minimized.
This comment has been minimized.
|
I have updated. Thanks for the great suggestions! |
This comment has been minimized.
This comment has been minimized.
d13ad56 to
271ad55
Compare
This comment has been minimized.
This comment has been minimized.
| /// Used when reporting query cycle errors and similar problems. | ||
| pub description_fn: fn(TyCtxt<'tcx>, C::Key) -> String, | ||
|
|
||
| pub execute_query_fn: fn(TyCtxt<'tcx>, Span, C::Key, QueryMode) -> Option<C::Value>, |
There was a problem hiding this comment.
Remark (pre-existing): This field could really use some docs and maybe a better name, because what it does and doesn't do is fairly subtle. But that's a pre-existing concern, so I don't want to block this PR on it.
There was a problem hiding this comment.
If you want to suggest a comment I can drop it in.
There was a problem hiding this comment.
I don’t have something prepared, but I’ll add it to my TODO list to come back and look at this for a follow-up PR.
|
Looking at this PR again, I realised that it's going to need some minor fixups after the dispatcher→vtable changes in #152791, which should combine for some nice little simplifications. |
This comment has been minimized.
This comment has been minimized.
271ad55 to
f362d0e
Compare
|
This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed. Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers. |
QueryCaches and QueryStates are storedQueryCache/QueryState/QueryEngine are stored
|
Commit message nit: The first commit no longer needs to mention |
|
r=me with commit message nit addressed. |
`QuerySystem` has these fields: ``` pub states: QueryStates<'tcx>, pub caches: QueryCaches<'tcx>, pub query_vtables: PerQueryVTables<'tcx>, ``` Each one has an entry for each query. Some methods that take a query-specific `QueryVTable` need to access the corresponding query-specific states and/or caches. So `QueryVTable` stores the *byte offset* to the relevant fields within `states` and `caches`, and uses that to (with `unsafe`) access the fields. This is bizarre, and I hope it made sense in the past when the code was structured differently. This commit moves `QueryState` and `QueryCache` inside `QueryVTable`. As a result, the query-specific states and/or caches are directly accessible, and no unsafe offset computations are required. Much simpler and more normal. Also, `QueryCaches` and `QueryStates` are no longer needed, which makes `define_callbacks!` a bit simpler. The commit also rename the fields and their getters to `states` and `caches`.
Currently type variables that impl `QueryCache` are called either `C` or `Cache`. I find the former clearer because single char type variables names are very common and longer type variable names are easy to mistake for type or trait names -- e.g. I find the trait bound `C: QueryCache` much easier and faster to read than `Cache: QueryCache`.
`QueryEngine` is a struct with one function pointer per query. This commit removes it by moving each function pointer into the relevant query's vtable, which is already a collection of function pointers for that query. This makes things simpler.
The `Per` isn't really necessary.
f362d0e to
7df5249
Compare
|
I fixed the comment. @bors r=Zalathar |
We used to use that crate before #136201, but removed it as it is not compatible with strict provenance. |
|
☔ The latest upstream changes (presumably #153047) made this pull request unmergeable. Please resolve the merge conflicts. This pull request was unapproved. |
View all comments
QueryVTablehas two fieldsquery_stateandquery_cachethat are byte offsets of fields in other structs. They are used inunsafecombination withbyte_addandcastto access said fields. I don't like this at all and this PR replaces them with something sensible.r? @Zalathar