[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:
Michael Gottesman
2014-03-24 09:16:09 +00:00
parent 59a44ca1f2
commit f4bb049bfc
8 changed files with 140 additions and 50 deletions

View File

@@ -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,