[Serialization] Delay all actions in the same module together. (#8123)

Back in December DougG added code to delay the formation of generic
environments until all declarations from a particular module had been
deserialized, to avoid circular dependencies caused by too-eager
deserialization of protocol members. This worked great for fully-built
modules, but still had some problems with module merging, the phase of
multi-file compilation where the "partial" swiftmodules that
correspond to each source file in a target are loaded and remitted as
a single swiftmodule. Fix this by picking one of the partial
swiftmodules as the representative one for delayed actions, and wait
until deserialization is complete for /all/ of the serialized ASTs in
the same target to form the generic environments.

rdar://problem/30984417
This commit is contained in:
Jordan Rose
2017-03-16 15:22:06 -07:00
committed by GitHub
parent e78445b437
commit a8e4e72270
10 changed files with 62 additions and 19 deletions

View File

@@ -285,7 +285,24 @@ static bool skipRecord(llvm::BitstreamCursor &cursor, unsigned recordKind) {
#endif
}
ModuleFile &ModuleFile::getModuleFileForDelayedActions() {
assert(FileContext && "cannot delay actions before associating with a file");
ModuleDecl *associatedModule = getAssociatedModule();
// Check for the common case.
if (associatedModule->getFiles().size() == 1)
return *this;
for (FileUnit *file : associatedModule->getFiles())
if (auto *serialized = dyn_cast<SerializedASTFile>(file))
return serialized->File;
llvm_unreachable("should always have FileContext in the list of files");
}
void ModuleFile::finishPendingActions() {
assert(&getModuleFileForDelayedActions() == this &&
"wrong module used for delayed actions");
while (!DelayedGenericEnvironments.empty()) {
// Force completion of the last generic environment.
auto genericEnvDC = DelayedGenericEnvironments.back();
@@ -990,7 +1007,8 @@ void ModuleFile::configureGenericEnvironment(
// creation.
if (auto genericSig = sigOrEnv.dyn_cast<GenericSignature *>()) {
genericDecl->setLazyGenericEnvironment(this, genericSig, envID);
DelayedGenericEnvironments.push_back(genericDecl);
ModuleFile &delayedActionFile = getModuleFileForDelayedActions();
delayedActionFile.DelayedGenericEnvironments.push_back(genericDecl);
return;
}