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, {});
@@ -1257,8 +1288,11 @@ class SharedModuleList {
12571288struct SharedModuleListInfo {
12581289 SharedModuleList module_list;
12591290 ModuleListProperties module_list_properties;
1291+ std::shared_ptr<llvm::cas::ObjectStore> cas_object_store;
1292+ std::mutex shared_lock;
12601293};
12611294}
1295+
12621296static SharedModuleListInfo &GetSharedModuleListInfo ()
12631297{
12641298 static SharedModuleListInfo *g_shared_module_list_info = nullptr ;
@@ -1277,6 +1311,47 @@ static SharedModuleList &GetSharedModuleList() {
12771311 return GetSharedModuleListInfo ().module_list ;
12781312}
12791313
1314+ std::optional<llvm::cas::CASConfiguration>
1315+ ModuleList::GetCASConfiguration (FileSpec CandidateConfigSearchPath) {
1316+ // Config CAS from properties.
1317+ llvm::cas::CASConfiguration cas_config;
1318+ cas_config.CASPath =
1319+ ModuleList::GetGlobalModuleListProperties ().GetCASOnDiskPath ().GetPath ();
1320+ cas_config.PluginPath =
1321+ ModuleList::GetGlobalModuleListProperties ().GetCASPluginPath ().GetPath ();
1322+ cas_config.PluginOptions =
1323+ ModuleList::GetGlobalModuleListProperties ().GetCASPluginOptions ();
1324+
1325+ if (!cas_config.CASPath .empty ())
1326+ return cas_config;
1327+
1328+ auto search_config = llvm::cas::CASConfiguration::createFromSearchConfigFile (
1329+ CandidateConfigSearchPath.GetPath ());
1330+ if (search_config)
1331+ return search_config->second ;
1332+
1333+ return std::nullopt ;
1334+ }
1335+
1336+ static llvm::Expected<std::shared_ptr<llvm::cas::ObjectStore>>
1337+ GetOrCreateCASStorage (FileSpec CandidateConfigSearchPath) {
1338+ auto &shared_module_list = GetSharedModuleListInfo ();
1339+ if (shared_module_list.cas_object_store )
1340+ return shared_module_list.cas_object_store ;
1341+
1342+ auto config = ModuleList::GetCASConfiguration (CandidateConfigSearchPath);
1343+ if (!config)
1344+ return nullptr ;
1345+
1346+ auto cas = config->createDatabases ();
1347+ if (!cas)
1348+ return cas.takeError ();
1349+
1350+ std::scoped_lock<std::mutex> lock (shared_module_list.shared_lock );
1351+ shared_module_list.cas_object_store = std::move (cas->first );
1352+ return shared_module_list.cas_object_store ;
1353+ }
1354+
12801355ModuleListProperties &ModuleList::GetGlobalModuleListProperties () {
12811356 return GetSharedModuleListInfo ().module_list_properties ;
12821357}
@@ -1548,6 +1623,55 @@ ModuleList::GetSharedModule(const ModuleSpec &module_spec, ModuleSP &module_sp,
15481623 return error;
15491624}
15501625
1626+ static llvm::Error loadModuleFromCAS (ConstString module_name,
1627+ llvm::StringRef cas_id, FileSpec cu_path,
1628+ ModuleSpec &module_spec) {
1629+ auto maybe_cas = GetOrCreateCASStorage (cu_path);
1630+ if (!maybe_cas)
1631+ return maybe_cas.takeError ();
1632+
1633+ auto cas = std::move (*maybe_cas);
1634+ if (!cas)
1635+ return llvm::createStringError (" CAS is not available" );
1636+
1637+ auto id = cas->parseID (cas_id);
1638+ if (!id)
1639+ return id.takeError ();
1640+
1641+ auto module_proxy = cas->getProxy (*id);
1642+ if (!module_proxy)
1643+ return module_proxy.takeError ();
1644+
1645+ auto file_buffer =
1646+ std::make_shared<DataBufferLLVM>(module_proxy->getMemoryBuffer ());
1647+ module_spec.SetData (std::move (file_buffer));
1648+
1649+ Log *log = GetLog (LLDBLog::Modules);
1650+ if (log != nullptr )
1651+ LLDB_LOGF (log, " loading module '%s' using CASID '%s'" ,
1652+ module_name.AsCString (), cas_id.str ().c_str ());
1653+
1654+ return llvm::Error::success ();
1655+ }
1656+
1657+ Status ModuleList::GetSharedModuleFromCAS (ConstString module_name,
1658+ llvm::StringRef cas_id,
1659+ FileSpec cu_path,
1660+ ModuleSpec &module_spec,
1661+ lldb::ModuleSP &module_sp) {
1662+ auto err = loadModuleFromCAS (module_name, cas_id, cu_path, module_spec);
1663+ if (err) {
1664+ auto error_str = toString (std::move (err));
1665+ LLDB_LOGF (GetLog (LLDBLog::Modules),
1666+ " skip loading module '%s' from CAS: %s" ,
1667+ module_name.AsCString (), error_str.c_str ());
1668+ return Status::FromErrorString (error_str.c_str ());
1669+ }
1670+
1671+ return GetSharedModule (module_spec, module_sp, nullptr , nullptr , nullptr ,
1672+ /* always_create=*/ true );
1673+ }
1674+
15511675bool ModuleList::RemoveSharedModule (lldb::ModuleSP &module_sp) {
15521676 return GetSharedModuleList ().Remove (module_sp);
15531677}
0 commit comments