-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Cache additional TypeRefBuilder operations #68255
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
Cache additional TypeRefBuilder operations #68255
Conversation
@swift-ci Please test |
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.
Looks great!
@@ -1043,6 +1052,30 @@ class TypeRefBuilder { | |||
ReflectionInfos.push_back(I); | |||
auto InfoID = ReflectionInfos.size() - 1; | |||
assert(InfoID <= UINT32_MAX && "ReflectionInfo ID overflow"); | |||
|
|||
for (auto BuiltinTypeDescriptor : I.Builtin) { |
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.
It might be good to make this lazy. I don't think leaks
et al will care, but swift-inspect
has paths that would never use this info and might benefit. We don't have to do that now, though.
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.
I'd be happy to do that in this PR.
Are you thinking something like this, using std::call_once()
?
In TypeRefBuilder.h
:
...
/// Cache for built-in type descriptor lookups.
std::unordered_map<std::string /* normalized name */,
RemoteRef<BuiltinTypeDescriptor>>
BuiltInTypeDescriptorCache;
/// Once flag for lazily initializing BuiltInTypeDescriptorCache.
std::once_flag BuiltInTypeDescriptorCacheInitOnceFlag;
...
And in TypeRefBuilder.cpp
:
...
RemoteRef<BuiltinTypeDescriptor>
TypeRefBuilder::getBuiltinTypeInfo(const TypeRef *TR) {
...
std::call_once(BuiltInTypeDescriptorCacheInitOnceFlag, []() {
for (auto Info : ReflectionInfos) {
for (auto BuiltinTypeDescriptor : Info.Builtin) {
< populate BuiltInTypeDescriptorCache >
}
}
});
if (const auto found = BuiltInTypeDescriptorCache.find(MangledName);
found != BuiltInTypeDescriptorCache.end()) {
return found->second;
}
return nullptr;
}
...
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.
I'm not sure if anything actually relies on this, but we'd want to keep the cache up to date when new reflection infos are added. I suggest tracking the index of the last reflection info that's been cached, like:
uint32_t NormalizedReflectionNameCacheLastReflectionInfoCached;
Then in getBuiltinTypeInfo
:
for(; NormalizedReflectionNameCacheLastReflectionInfoCached < ReflectionInfos.size(); NormalizedReflectionNameCacheLastReflectionInfoCached++)
...cache ReflectionInfos[NormalizedReflectionNameCacheLastReflectionInfoCached]...
...
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.
Ah, good point. I'll take a stab at that.
5cc28c9
to
aafa317
Compare
@swift-ci Please test |
…ditional calculations in TypeRefBuilder.
6bc15f6
to
f93f7ad
Compare
@swift-ci Please test |
Speed up Remote Mirror significantly by caching two additional calculations in TypeRefBuilder.
These changes shouldn't significantly impact the memory footprint of Remote Mirror. Testing against a large process which used plenty of Swift, I saw
BuiltInTypeDescriptorCache
contain only about 4000 entries, andNormalizedReflectionNameCache
only cache 3 MB of strings.Resolves rdar://111248508