2121#include " lldb/Symbol/VariableList.h"
2222#include " lldb/Utility/ArchSpec.h"
2323#include " lldb/Utility/ConstString.h"
24+ #include " lldb/Utility/DataBufferLLVM.h"
2425#include " lldb/Utility/FileSpecList.h"
2526#include " lldb/Utility/LLDBLog.h"
2627#include " lldb/Utility/Log.h"
2728#include " lldb/Utility/UUID.h"
2829#include " lldb/lldb-defines.h"
30+ #include " llvm/ADT/ScopeExit.h"
31+ #include " llvm/Support/FileUtilities.h"
2932
3033#if defined(_WIN32)
3134#include " lldb/Host/windows/PosixApi.h"
3235#endif
3336
3437#include " clang/Driver/Driver.h"
3538#include " llvm/ADT/StringRef.h"
39+ #include " llvm/CAS/CASConfiguration.h"
40+ #include " llvm/CAS/ObjectStore.h"
3641#include " llvm/Support/FileSystem.h"
3742#include " llvm/Support/Threading.h"
3843#include " llvm/Support/raw_ostream.h"
@@ -282,6 +287,32 @@ bool ModuleListProperties::GetSwiftEnableASTContext() const {
282287}
283288// END SWIFT
284289
290+ // START CAS
291+ FileSpec ModuleListProperties::GetCASOnDiskPath () const {
292+ const uint32_t idx = ePropertyCASOnDiskPath;
293+ return GetPropertyAtIndexAs<FileSpec>(idx, {});
294+ }
295+
296+ FileSpec ModuleListProperties::GetCASPluginPath () const {
297+ const uint32_t idx = ePropertyCASPluginPath;
298+ return GetPropertyAtIndexAs<FileSpec>(idx, {});
299+ }
300+
301+ std::vector<std::pair<std::string, std::string>>
302+ ModuleListProperties::GetCASPluginOptions () const {
303+ Args args;
304+ const uint32_t idx = ePropertyCASPluginOptions;
305+ m_collection_sp->GetPropertyAtIndexAsArgs (idx, args);
306+ std::vector<std::pair<std::string, std::string>> options;
307+ for (auto &arg : args) {
308+ llvm::StringRef opt = arg.c_str ();
309+ auto splitted = opt.split (" =" );
310+ options.emplace_back (splitted.first .str (), splitted.second .str ());
311+ }
312+ return options;
313+ }
314+ // END CAS
315+
285316FileSpec ModuleListProperties::GetLLDBIndexCachePath () const {
286317 const uint32_t idx = ePropertyLLDBIndexCachePath;
287318 return GetPropertyAtIndexAs<FileSpec>(idx, {});
@@ -1253,8 +1284,11 @@ class SharedModuleList {
12531284struct SharedModuleListInfo {
12541285 SharedModuleList module_list;
12551286 ModuleListProperties module_list_properties;
1287+ std::shared_ptr<llvm::cas::ObjectStore> cas_object_store;
1288+ std::mutex shared_lock;
12561289};
12571290}
1291+
12581292static SharedModuleListInfo &GetSharedModuleListInfo ()
12591293{
12601294 static SharedModuleListInfo *g_shared_module_list_info = nullptr ;
@@ -1273,6 +1307,47 @@ static SharedModuleList &GetSharedModuleList() {
12731307 return GetSharedModuleListInfo ().module_list ;
12741308}
12751309
1310+ std::optional<llvm::cas::CASConfiguration>
1311+ ModuleList::GetCASConfiguration (FileSpec CandidateConfigSearchPath) {
1312+ // Config CAS from properties.
1313+ llvm::cas::CASConfiguration cas_config;
1314+ cas_config.CASPath =
1315+ ModuleList::GetGlobalModuleListProperties ().GetCASOnDiskPath ().GetPath ();
1316+ cas_config.PluginPath =
1317+ ModuleList::GetGlobalModuleListProperties ().GetCASPluginPath ().GetPath ();
1318+ cas_config.PluginOptions =
1319+ ModuleList::GetGlobalModuleListProperties ().GetCASPluginOptions ();
1320+
1321+ if (!cas_config.CASPath .empty ())
1322+ return cas_config;
1323+
1324+ auto search_config = llvm::cas::CASConfiguration::createFromSearchConfigFile (
1325+ CandidateConfigSearchPath.GetPath ());
1326+ if (search_config)
1327+ return search_config->second ;
1328+
1329+ return std::nullopt ;
1330+ }
1331+
1332+ static llvm::Expected<std::shared_ptr<llvm::cas::ObjectStore>>
1333+ GetOrCreateCASStorage (FileSpec CandidateConfigSearchPath) {
1334+ auto &shared_module_list = GetSharedModuleListInfo ();
1335+ if (shared_module_list.cas_object_store )
1336+ return shared_module_list.cas_object_store ;
1337+
1338+ auto config = ModuleList::GetCASConfiguration (CandidateConfigSearchPath);
1339+ if (!config)
1340+ return nullptr ;
1341+
1342+ auto cas = config->createDatabases ();
1343+ if (!cas)
1344+ return cas.takeError ();
1345+
1346+ std::scoped_lock<std::mutex> lock (shared_module_list.shared_lock );
1347+ shared_module_list.cas_object_store = std::move (cas->first );
1348+ return shared_module_list.cas_object_store ;
1349+ }
1350+
12761351ModuleListProperties &ModuleList::GetGlobalModuleListProperties () {
12771352 return GetSharedModuleListInfo ().module_list_properties ;
12781353}
@@ -1544,6 +1619,55 @@ ModuleList::GetSharedModule(const ModuleSpec &module_spec, ModuleSP &module_sp,
15441619 return error;
15451620}
15461621
1622+ static llvm::Error loadModuleFromCAS (ConstString module_name,
1623+ llvm::StringRef cas_id, FileSpec cu_path,
1624+ ModuleSpec &module_spec) {
1625+ auto maybe_cas = GetOrCreateCASStorage (cu_path);
1626+ if (!maybe_cas)
1627+ return maybe_cas.takeError ();
1628+
1629+ auto cas = std::move (*maybe_cas);
1630+ if (!cas)
1631+ return llvm::createStringError (" CAS is not available" );
1632+
1633+ auto id = cas->parseID (cas_id);
1634+ if (!id)
1635+ return id.takeError ();
1636+
1637+ auto module_proxy = cas->getProxy (*id);
1638+ if (!module_proxy)
1639+ return module_proxy.takeError ();
1640+
1641+ auto file_buffer =
1642+ std::make_shared<DataBufferLLVM>(module_proxy->getMemoryBuffer ());
1643+ module_spec.SetData (std::move (file_buffer));
1644+
1645+ Log *log = GetLog (LLDBLog::Modules);
1646+ if (log != nullptr )
1647+ LLDB_LOGF (log, " loading module '%s' using CASID '%s'" ,
1648+ module_name.AsCString (), cas_id.str ().c_str ());
1649+
1650+ return llvm::Error::success ();
1651+ }
1652+
1653+ Status ModuleList::GetSharedModuleFromCAS (ConstString module_name,
1654+ llvm::StringRef cas_id,
1655+ FileSpec cu_path,
1656+ ModuleSpec &module_spec,
1657+ lldb::ModuleSP &module_sp) {
1658+ auto err = loadModuleFromCAS (module_name, cas_id, cu_path, module_spec);
1659+ if (err) {
1660+ auto error_str = toString (std::move (err));
1661+ LLDB_LOGF (GetLog (LLDBLog::Modules),
1662+ " skip loading module '%s' from CAS: %s" ,
1663+ module_name.AsCString (), error_str.c_str ());
1664+ return Status::FromErrorString (error_str.c_str ());
1665+ }
1666+
1667+ return GetSharedModule (module_spec, module_sp, nullptr , nullptr , nullptr ,
1668+ /* always_create=*/ true );
1669+ }
1670+
15471671bool ModuleList::RemoveSharedModule (lldb::ModuleSP &module_sp) {
15481672 return GetSharedModuleList ().Remove (module_sp);
15491673}
0 commit comments