mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[deserialization] Enable lazy deserialization of witness tables.
This patch adds in the necessary infrastructure for lazily deserializing witness tables. This is done by following the same approach as the deserialization/serialization of SILFunction. Now if one calls SILModule::lookUpWitnessTable and the given witness table is a definition, the SILModule will attempt to deserialize it from one of the other modules. Swift SVN r15403
This commit is contained in:
@@ -61,6 +61,10 @@ class SILModule::SerializationCallback : public SerializedSILLoader::Callback {
|
||||
//updateLinkage(vtable);
|
||||
}
|
||||
|
||||
void didDeserialize(Module *M, SILWitnessTable *wt) override {
|
||||
updateLinkage(wt);
|
||||
}
|
||||
|
||||
template <class T> void updateLinkage(T *decl) {
|
||||
switch (decl->getLinkage()) {
|
||||
case SILLinkage::Public:
|
||||
@@ -160,26 +164,43 @@ SILModule::lookUpWitnessTable(const ProtocolConformance *C) {
|
||||
|
||||
// Attempt to lookup the witness table from the table.
|
||||
auto found = WitnessTableLookupCache.find(NormalC);
|
||||
if (found != WitnessTableLookupCache.end())
|
||||
return {found->second, Subs};
|
||||
|
||||
if (found == WitnessTableLookupCache.end()) {
|
||||
#ifndef NDEBUG
|
||||
// Make sure that all witness tables are in the witness table lookup
|
||||
// cache.
|
||||
//
|
||||
// This code should not be hit normally since we add witness tables to the
|
||||
// lookup cache when we create them. We don't just assert here since there is
|
||||
// the potential for a conformance without a witness table to be passed to
|
||||
// this function.
|
||||
for (SILWitnessTable &WT : witnessTables)
|
||||
assert(WT.getConformance() != NormalC && "Found witness table that is not"
|
||||
" in the witness table lookup cache.");
|
||||
// Make sure that all witness tables are in the witness table lookup
|
||||
// cache.
|
||||
//
|
||||
// This code should not be hit normally since we add witness tables to the
|
||||
// lookup cache when we create them. We don't just assert here since there
|
||||
// is the potential for a conformance without a witness table to be passed
|
||||
// to this function.
|
||||
for (SILWitnessTable &WT : witnessTables)
|
||||
assert(WT.getConformance() != NormalC &&
|
||||
"Found witness table that is not"
|
||||
" in the witness table lookup cache.");
|
||||
#endif
|
||||
return {nullptr, Subs};
|
||||
}
|
||||
|
||||
return {nullptr, Subs};
|
||||
SILWitnessTable *wT = found->second;
|
||||
assert(wT != nullptr && "Should never map a conformance to a null witness"
|
||||
" table.");
|
||||
|
||||
// If we have a definition, return it.
|
||||
if (wT->isDefinition())
|
||||
return {wT, Subs};
|
||||
|
||||
// Otherwise try to deserialize it. If we succeed return the deserialized
|
||||
// function.
|
||||
//
|
||||
// *NOTE* In practice, wT will be deserializedTable, but I do not want to rely
|
||||
// on that behavior for now.
|
||||
if (auto deserializedTable = SILLoader->lookupWitnessTable(wT))
|
||||
return {deserializedTable, Subs};
|
||||
|
||||
// If we fail, just return the declaration.
|
||||
return {wT, Subs};
|
||||
}
|
||||
|
||||
|
||||
SILFunction *SILModule::getOrCreateSharedFunction(SILLocation loc,
|
||||
StringRef name,
|
||||
CanSILFunctionType type,
|
||||
|
||||
Reference in New Issue
Block a user