@@ -173,30 +173,40 @@ class DiscoveredModule {
173173 // / The kind of module that's been discovered.
174174 const Kind kind;
175175
176- DiscoveredModule (StringRef path, Kind kind): kind(kind), path(path) {}
176+ DiscoveredModule (StringRef path, Kind kind,
177+ std::unique_ptr<llvm::MemoryBuffer> moduleBuffer)
178+ : kind(kind), moduleBuffer(std::move(moduleBuffer)), path(path) {}
179+
177180public:
181+ // / The contents of the .swiftmodule, if we've read it while validating
182+ // / dependencies.
183+ std::unique_ptr<llvm::MemoryBuffer> moduleBuffer;
184+
178185 // / The path to the discovered serialized .swiftmodule on disk.
179186 const std::string path;
180187
181188 // / Creates a \c Normal discovered module.
182- static DiscoveredModule normal (StringRef path) {
183- return { path, Kind::Normal };
189+ static DiscoveredModule normal (StringRef path,
190+ std::unique_ptr<llvm::MemoryBuffer> moduleBuffer) {
191+ return { path, Kind::Normal, std::move (moduleBuffer) };
184192 }
185193
186194 // / Creates a \c Prebuilt discovered module.
187- static DiscoveredModule prebuilt (StringRef path) {
188- return { path, Kind::Prebuilt };
195+ static DiscoveredModule prebuilt (
196+ StringRef path, std::unique_ptr<llvm::MemoryBuffer> moduleBuffer) {
197+ return { path, Kind::Prebuilt, std::move (moduleBuffer) };
189198 }
190199
191200 // / Creates a \c Forwarded discovered module, whose dependencies have been
192201 // / externally validated by a \c ForwardingModule.
193- static DiscoveredModule forwarded (StringRef path) {
194- return { path, Kind::Forwarded };
202+ static DiscoveredModule forwarded (
203+ StringRef path, std::unique_ptr<llvm::MemoryBuffer> moduleBuffer) {
204+ return { path, Kind::Forwarded, std::move (moduleBuffer) };
195205 }
196206
197207 bool isNormal () const { return kind == Kind::Normal; }
198208 bool isPrebuilt () const { return kind == Kind::Prebuilt; }
199- bool isForwarding () const { return kind == Kind::Forwarded; }
209+ bool isForwarded () const { return kind == Kind::Forwarded; }
200210};
201211
202212} // end anonymous namespace
@@ -453,7 +463,8 @@ class swift::ParseableInterfaceBuilder {
453463 return subInvocation;
454464 }
455465
456- bool buildSwiftModule (StringRef OutPath, bool ShouldSerializeDeps) {
466+ bool buildSwiftModule (StringRef OutPath, bool ShouldSerializeDeps,
467+ std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer) {
457468 bool SubError = false ;
458469 bool RunSuccess = llvm::CrashRecoveryContext ().RunSafelyOnThread ([&] {
459470 // Note that we don't assume cachePath is the same as the Clang
@@ -559,7 +570,10 @@ class swift::ParseableInterfaceBuilder {
559570 if (ShouldSerializeDeps)
560571 SerializationOpts.Dependencies = Deps;
561572 SILMod->setSerializeSILAction ([&]() {
562- serialize (Mod, SerializationOpts, SILMod.get ());
573+ // We don't want to serialize module docs in the cache -- they
574+ // will be serialized beside the interface file.
575+ serializeToBuffers (Mod, SerializationOpts, ModuleBuffer,
576+ /* ModuleDocBuffer*/ nullptr , SILMod.get ());
563577 });
564578
565579 LLVM_DEBUG (llvm::dbgs () << " Running SIL processing passes\n " );
@@ -717,22 +731,23 @@ class ParseableInterfaceModuleLoaderImpl {
717731
718732 // Check that the output .swiftmodule file is at least as new as all the
719733 // dependencies it read when it was built last time.
720- bool swiftModuleIsUpToDate (StringRef modulePath,
721- SmallVectorImpl<FileDependency> &AllDeps) {
734+ bool swiftModuleIsUpToDate (
735+ StringRef modulePath, SmallVectorImpl<FileDependency> &AllDeps,
736+ std::unique_ptr<llvm::MemoryBuffer> &moduleBuffer) {
722737 auto OutBuf = fs.getBufferForFile (modulePath);
723738 if (!OutBuf)
724739 return false ;
725- return serializedASTBufferIsUpToDate (*OutBuf.get (), AllDeps);
740+ moduleBuffer = std::move (*OutBuf);
741+ return serializedASTBufferIsUpToDate (*moduleBuffer, AllDeps);
726742 }
727743
728744 // Check that a "forwarding" .swiftmodule file is at least as new as all the
729745 // dependencies it read when it was built last time. Requires that the
730746 // forwarding module has been loaded from disk.
731- bool forwardingModuleIsUpToDate (const ForwardingModule &fwd,
732- SmallVectorImpl<FileDependency> &deps) {
747+ bool forwardingModuleIsUpToDate (
748+ const ForwardingModule &fwd, SmallVectorImpl<FileDependency> &deps,
749+ std::unique_ptr<llvm::MemoryBuffer> &moduleBuffer) {
733750 // First, make sure the underlying module path exists and is valid.
734- // FIXME: We should preserve this buffer, rather than opening it again
735- // when loading the module.
736751 auto modBuf = fs.getBufferForFile (fwd.underlyingModulePath );
737752 if (!modBuf || !serializedASTLooksValid (*modBuf.get ()))
738753 return false ;
@@ -743,7 +758,11 @@ class ParseableInterfaceModuleLoaderImpl {
743758 FileDependency::modTimeBased (
744759 dep.path , dep.size , dep.lastModificationTime ));
745760 }
746- return dependenciesAreUpToDate (deps);
761+ if (!dependenciesAreUpToDate (deps))
762+ return false ;
763+
764+ moduleBuffer = std::move (*modBuf);
765+ return true ;
747766 }
748767
749768 Optional<StringRef>
@@ -809,22 +828,25 @@ class ParseableInterfaceModuleLoaderImpl {
809828 // First, check the cached module path. Whatever's in this cache represents
810829 // the most up-to-date knowledge we have about the module.
811830 if (auto cachedBufOrError = fs.getBufferForFile (cachedOutputPath)) {
812- auto & buf = *cachedBufOrError. get ( );
831+ auto buf = std::move ( *cachedBufOrError);
813832
814833 // Check to see if the module is a serialized AST. If it's not, then we're
815834 // probably dealing with a Forwarding Module, which is a YAML file.
816835 bool isForwardingModule =
817- !serialization::isSerializedAST (buf. getBuffer ());
836+ !serialization::isSerializedAST (buf-> getBuffer ());
818837
819838 // If it's a forwarding module, load the YAML file from disk and check
820839 // if it's up-to-date.
821840 if (isForwardingModule) {
822- auto modOrErr = ForwardingModule::load (buf);
823- if (modOrErr && forwardingModuleIsUpToDate (*modOrErr, deps))
824- return DiscoveredModule::forwarded (modOrErr->underlyingModulePath );
841+ if (auto forwardingModule = ForwardingModule::load (*buf)) {
842+ std::unique_ptr<llvm::MemoryBuffer> moduleBuffer;
843+ if (forwardingModuleIsUpToDate (*forwardingModule, deps, moduleBuffer))
844+ return DiscoveredModule::forwarded (
845+ forwardingModule->underlyingModulePath , std::move (moduleBuffer));
846+ }
825847 // Otherwise, check if the AST buffer itself is up to date.
826- } else if (serializedASTBufferIsUpToDate (buf, deps)) {
827- return DiscoveredModule::normal (cachedOutputPath);
848+ } else if (serializedASTBufferIsUpToDate (* buf, deps)) {
849+ return DiscoveredModule::normal (cachedOutputPath, std::move (buf) );
828850 }
829851 }
830852
@@ -835,9 +857,10 @@ class ParseableInterfaceModuleLoaderImpl {
835857 // from the SDK.
836858 if (!prebuiltCacheDir.empty ()) {
837859 llvm::SmallString<256 > scratch;
860+ std::unique_ptr<llvm::MemoryBuffer> moduleBuffer;
838861 auto path = computePrebuiltModulePath (scratch);
839- if (path && swiftModuleIsUpToDate (*path, deps))
840- return DiscoveredModule::prebuilt (*path);
862+ if (path && swiftModuleIsUpToDate (*path, deps, moduleBuffer ))
863+ return DiscoveredModule::prebuilt (*path, std::move (moduleBuffer) );
841864 }
842865
843866 // Finally, if there's a module adjacent to the .swiftinterface that we can
@@ -899,10 +922,12 @@ class ParseableInterfaceModuleLoaderImpl {
899922 });
900923 }
901924
902- // / Looks up the best module to load for a given interface. See the main
903- // / comment in \c ParseableInterfaceModuleLoader.h for an explanation of
904- // / the module loading strategy.
905- llvm::ErrorOr<std::string> findOrBuildLoadableModule () {
925+ // / Looks up the best module to load for a given interface, and returns a
926+ // / buffer of the module's contents. See the main comment in
927+ // / \c ParseableInterfaceModuleLoader.h for an explanation of the module
928+ // / loading strategy.
929+ llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
930+ findOrBuildLoadableModule () {
906931
907932 // Set up a builder if we need to build the module. It'll also set up
908933 // the subinvocation we'll need to use to compute the cache paths.
@@ -927,24 +952,27 @@ class ParseableInterfaceModuleLoaderImpl {
927952 moduleOrErr.getError () != std::errc::no_such_file_or_directory)
928953 return moduleOrErr.getError ();
929954
930- // We discovered a module! Return the module's path so we know what to load.
955+ // We discovered a module! Return that module's buffer so we can load it .
931956 if (moduleOrErr) {
932- auto &module = *moduleOrErr;
957+ auto module = std::move (moduleOrErr.get ());
958+
933959 // If it's prebuilt, use this time to generate a forwarding module.
934960 if (module .isPrebuilt ())
935961 if (writeForwardingModule (module , cachedOutputPath, allDeps))
936962 return std::make_error_code (std::errc::not_supported);
937963
938- // FIXME: return and load module buffer directly
939- return module .path ;
964+ return std::move (module .moduleBuffer );
940965 }
941966
967+ std::unique_ptr<llvm::MemoryBuffer> moduleBuffer;
942968 // We didn't discover a module corresponding to this interface. Build one.
943- if (builder.buildSwiftModule (cachedOutputPath, /* shouldSerializeDeps*/ true ))
969+ if (builder.buildSwiftModule (cachedOutputPath, /* shouldSerializeDeps*/ true ,
970+ &moduleBuffer))
944971 return std::make_error_code (std::errc::invalid_argument);
945972
946- // FIXME: return and load module buffer directly
947- return cachedOutputPath.str ();
973+ assert (moduleBuffer &&
974+ " failed to write module buffer but returned success?" );
975+ return std::move (moduleBuffer);
948976 }
949977};
950978
@@ -984,26 +1012,24 @@ std::error_code ParseableInterfaceModuleLoader::findModuleFilesInDirectory(
9841012
9851013 // Ask the impl to find us a module that we can load or give us an error
9861014 // telling us that we couldn't load it.
987- auto PathOrErr = Impl.findOrBuildLoadableModule ();
988- if (!PathOrErr )
989- return PathOrErr .getError ();
990- std::string FinalPath = std::move (*PathOrErr);
991-
992- // Finish off by delegating back up to the SerializedModuleLoaderBase
993- // routine that can load the recently-manufactured serialized module.
994- LLVM_DEBUG ( llvm::dbgs () << " Loading " << FinalPath
995- << " via normal module loader \n " );
1015+ auto ModuleBufferOrErr = Impl.findOrBuildLoadableModule ();
1016+ if (!ModuleBufferOrErr )
1017+ return ModuleBufferOrErr .getError ();
1018+
1019+ if (ModuleBuffer) {
1020+ *ModuleBuffer = std::move (*ModuleBufferOrErr);
1021+ }
1022+
1023+ // Delegate back to the serialized module loader to load the module doc.
9961024 llvm::SmallString<256 > DocPath{DirPath};
9971025 path::append (DocPath, ModuleDocFilename);
998- auto ErrorCode = SerializedModuleLoaderBase::openModuleFiles (
999- ModuleID, FinalPath, DocPath, ModuleBuffer, ModuleDocBuffer);
1000- LLVM_DEBUG (llvm::dbgs () << " Loaded " << FinalPath
1001- << " via normal module loader" );
1002- if (ErrorCode) {
1003- LLVM_DEBUG (llvm::dbgs () << " with error: " << ErrorCode.message ());
1004- }
1005- LLVM_DEBUG (llvm::dbgs () << " \n " );
1006- return ErrorCode;
1026+ auto DocLoadErr =
1027+ SerializedModuleLoaderBase::openModuleDocFile (ModuleID, DocPath,
1028+ ModuleDocBuffer);
1029+ if (DocLoadErr)
1030+ return DocLoadErr;
1031+
1032+ return std::error_code ();
10071033}
10081034
10091035
@@ -1018,5 +1044,6 @@ bool ParseableInterfaceModuleLoader::buildSwiftModuleFromSwiftInterface(
10181044 // make them relocatable (SDK-relative) if we want to ship the built
10191045 // swiftmodules to another machine. Just track them as absolute paths
10201046 // for now, so we can test the dependency tracking locally.
1021- return builder.buildSwiftModule (OutPath, /* shouldSerializeDeps*/ true );
1047+ return builder.buildSwiftModule (OutPath, /* shouldSerializeDeps*/ true ,
1048+ /* ModuleBuffer*/ nullptr );
10221049}
0 commit comments