当前位置: 首页 > news >正文

LLJIT执行引擎:ExecutionSession与JITDylib详解

LLJIT执行引擎:ExecutionSession与JITDylib详解

核心架构概览

LLJIT整体架构

graph TBA[ExecutionSession] --> B[JITDylib Manager]B --> C[Main JITDylib]B --> D[Custom JITDylib 1]B --> E[Custom JITDylib 2]C --> F[Symbol Table]D --> G[Symbol Table]E --> H[Symbol Table]A --> I[Layer Stack]I --> J[IRTransformLayer]J --> K[IRCompileLayer]K --> L[ObjectLinkingLayer]L --> M[MemoryManager]

ExecutionSession:JIT会话管理核心

基本概念与职责

ExecutionSession 是ORC JIT架构的中央协调器,负责管理整个JIT会话的生命周期和状态。

class ExecutionSession {
public:// JITDylib管理JITDylib& createJITDylib(std::string Name);JITDylib* getJITDylibByName(StringRef Name);// 符号查找Expected<JITEvaluatedSymbol> lookup(const JITDylibSearchList &SearchOrder,SymbolStringPtr Name);// 会话生命周期Error runJITDispatchTask(std::unique_ptr<Task> T);Error endSession();private:std::map<std::string, std::unique_ptr<JITDylib>> JITDylibs;std::unique_ptr<SymbolStringPool> SSP;SessionLock SessionLock;
};

创建ExecutionSession

方式1:通过LLJIT间接创建(推荐)
#include "llvm/ExecutionEngine/Orc/LLJIT.h"// 创建LLJIT实例,内部自动创建ExecutionSession
auto JIT = cantFail(LLJITBuilder().create());// 获取内部的ExecutionSession引用
ExecutionSession& ES = JIT->getExecutionSession();// 使用ExecutionSession
JITDylib& MainJD = JIT->getMainJITDylib();
方式2:直接创建ExecutionSession(高级用法)
#include "llvm/ExecutionEngine/Orc/ExecutionSession.h"// 直接创建ExecutionSession(需要手动管理生命周期)
auto ES = std::make_unique<ExecutionSession>(std::make_unique<SymbolStringPool>());// 手动创建JITDylib
JITDylib& JD = ES->createJITDylib("main");// 需要手动设置层栈和其他组件...

ExecutionSession的核心功能

符号查找与解析
// 构建搜索路径
JITDylibSearchOrder SearchOrder;
SearchOrder.push_back({&MainJD, JITDylibLookupFlags::MatchExportedSymbolsOnly});// 执行符号查找
auto Symbol = ES.lookup(SearchOrder, ES.intern("myFunction"));if (auto Err = Symbol.takeError()) {// 处理查找错误logAllUnhandledErrors(std::move(Err), errs());return;
}// 使用找到的符号
void(*FuncPtr)() = (void(*)())Symbol->getAddress();
FuncPtr();
并发任务调度
// 提交任务到JIT调度器
auto Task = std::make_unique<MyCustomTask>();
if (auto Err = ES.runJITDispatchTask(std::move(Task))) {// 处理任务提交错误
}

JITDylib:符号容器与管理

JITDylib是包含符号定义的容器。需要通过ExecutionSession来创建或获取JITDylib,并将你的符号添加到其中。

JITDylib架构设计

class JITDylib {
public:// 符号管理Error add(ResourceTrackerSP RT, std::unique_ptr<MaterializationUnit> MU);void setGenerator(JITDylib::GeneratorFunction G);// 依赖管理void addToLinkOrder(JITDylib &Other);void setFallbackDefinitionGenerator(JITDylib::GeneratorFunction G);// 查询接口JITDylibSearchOrder getSearchOrder();SymbolLookupSet getRequestedSymbols();private:SymbolTable Symbols;std::vector<JITDylib*> LinkOrder;std::unique_ptr<GeneratorFunction> Generator;
};

JITDylib的创建与管理

获取主JITDylib
// 通过LLJIT获取主JITDylib(最常用)
auto JIT = cantFail(LLJITBuilder().create());
JITDylib& MainJD = JIT->getMainJITDylib();// 主JITDylib已经预先配置了基本符号解析器
创建自定义JITDylib
// 创建新的JITDylib
JITDylib& MathLib = JIT->getExecutionSession().createJITDylib("math");// 设置库依赖关系(类似动态链接)
MathLib.addToLinkOrder(MainJD);  // math库可以访问主库的符号// 创建具有特定搜索顺序的库
JITDylib& CustomLib = ES.createJITDylib("custom");
JITDylibSearchOrder CustomOrder;
CustomOrder.push_back({&CustomLib, JITDylibLookupFlags::MatchAllSymbols});
CustomOrder.push_back({&MainJD, JITDylibLookupFlags::MatchExportedSymbolsOnly});

符号解析策略配置

默认符号解析器
// LLJIT自动为主JITDylib配置的解析器包含:
// 1. JIT内部符号查找
// 2. 进程内符号查找(dlsym)
// 3. 标准库符号查找// 自定义解析器示例
auto CustomResolver = createSymbolResolver([](const SymbolMap &Symbols) -> Expected<SymbolMap> {SymbolMap Result;for (const auto &[Name, Sym] : Symbols) {// 自定义符号解析逻辑if (auto Addr = lookupInCustomLocation(Name)) {Result[Name] = JITEvaluatedSymbol(Addr, JITSymbolFlags::Exported);}}return Result;});MainJD.setGenerator(std::move(CustomResolver));
分层符号解析
// 创建多层符号解析策略
auto createLayeredResolver() {return [](JITDylib& JD, const SymbolNameSet& Names) {SymbolMap Result;SymbolNameSet Unresolved = Names;// 第一层:JIT内部查找for (const auto& Name : Names) {if (auto Sym = JD.lookup(Name)) {Result[Name] = *Sym;Unresolved.erase(Name);}}// 第二层:系统库查找for (const auto& Name : Unresolved) {if (auto Addr = sys::DynamicLibrary::SearchForAddressOfSymbol(Name)) {Result[Name] = JITEvaluatedSymbol(Addr, JITSymbolFlags::Exported);Unresolved.erase(Name);}}// 第三层:自定义查找if (!Unresolved.empty()) {// 处理剩余未解析符号handleUnresolvedSymbols(Unresolved);}return Result;};
}

完整的LLJIT初始化流程

标准初始化模式

#include "llvm/ExecutionEngine/Orc/LLJIT.h"
#include "llvm/ExecutionEngine/Orc/ThreadSafeModule.h"Error initializeJIT() {// 1. 创建LLJIT构建器LLJITBuilder Builder;// 2. 配置JIT选项Builder.setJITTargetMachineBuilder(cantFail(JITTargetMachineBuilder::detectHost()));Builder.setNumCompileThreads(4);  // 设置编译线程数// 3. 创建LLJIT实例auto JIT = cantFail(Builder.create());// 4. 获取ExecutionSession和主JITDylibExecutionSession& ES = JIT->getExecutionSession();JITDylib& MainJD = JIT->getMainJITDylib();// 5. 创建LLVM模块auto Ctx = std::make_unique<LLVMContext>();auto M = std::make_unique<Module>("MyModule", *Ctx);// 6. 生成IR内容// ... 填充模块内容 ...// 7. 创建线程安全模块ThreadSafeModule TSM(std::move(M), std::move(Ctx));// 8. 将模块添加到JITDylibif (auto Err = JIT->addIRModule(MainJD, std::move(TSM))) {return Err;}// 9. 查找并执行符号auto Addr = cantFail(JIT->lookup("main"));auto Main = Addr.toPtr<int(*)(void)>();return Main();
}

多JITDylib管理示例

class MultiLibraryJIT {std::unique_ptr<LLJIT> JIT;std::map<std::string, JITDylib*> Libraries;public:Error initialize() {// 创建JIT实例auto JITOrErr = LLJITBuilder().create();if (!JITOrErr) return JITOrErr.takeError();JIT = std::move(*JITOrErr);// 获取主库引用Libraries["main"] = &JIT->getMainJITDylib();return Error::success();}Error loadLibrary(const std::string& Name, ThreadSafeModule TSM) {// 创建新的JITDylibauto& JD = JIT->getExecutionSession().createJITDylib(Name);// 设置依赖关系:新库可以访问主库符号JD.addToLinkOrder(*Libraries["main"]);// 添加模块到新库if (auto Err = JIT->addIRModule(JD, std::move(TSM))) {return Err;}Libraries[Name] = &JD;return Error::success();}Expected<JITEvaluatedSymbol> lookup(const std::string& LibName, const std::string& SymbolName) {auto It = Libraries.find(LibName);if (It == Libraries.end()) {return make_error<StringError>("Library not found", inconvertibleErrorCode());}return JIT->lookup(*It->second, SymbolName);}
};

高级特性与最佳实践

资源管理与生命周期

资源跟踪器
// 创建资源跟踪器,用于管理模块生命周期
auto RT = MainJD.getDefaultResourceTracker();// 添加模块时指定资源跟踪器
if (auto Err = JIT->addIRModule(RT, std::move(TSM))) {// 处理错误
}// 移除模块释放资源
if (auto Err = RT->remove()) {// 处理移除错误
}
自定义内存管理
// 创建自定义内存管理器
class CustomMemoryManager : public JITLinkMemoryManager {
public:Expected<std::unique_ptr<Allocation>>allocate(const JITLinkDylib* JD, const SegmentsRequestMap& Request) override {// 自定义内存分配逻辑auto Alloc = std::make_unique<CustomAllocation>();// ... 实现分配细节 ...return std::move(Alloc);}
};// 在LLJIT构建器中设置自定义内存管理器
Builder.setObjectLinkingLayerCreator([&](ExecutionSession& ES, const Triple& TT) {return std::make_unique<ObjectLinkingLayer>(ES, std::make_unique<CustomMemoryManager>());});

错误处理模式

全面的错误处理
Error runJITProcess() {// 使用cantFail处理已知安全的操作auto JIT = cantFail(LLJITBuilder().create());// 使用Expected处理可能失败的操作if (auto Symbol = JIT->lookup("myFunction")) {// 成功找到符号auto Func = Symbol->toPtr<void(*)()>();Func();} else {// 处理查找错误auto Err = Symbol.takeError();logAllUnhandledErrors(std::move(Err), errs());return make_error<StringError>("Symbol lookup failed", inconvertibleErrorCode());}return Error::success();
}// 顶层错误处理
int main() {InitLLVM X;  // 初始化LLVMif (auto Err = runJITProcess()) {logAllUnhandledErrors(std::move(Err), errs());return 1;}return 0;
}

实际应用案例

案例1:插件系统

class PluginManager {std::unique_ptr<LLJIT> JIT;ExecutionSession& ES;public:PluginManager() : JIT(cantFail(LLJITBuilder().create())), ES(JIT->getExecutionSession()) {}Error loadPlugin(const std::string& PluginName, const std::string& IRFilePath) {// 读取IR文件auto Ctx = std::make_unique<LLVMContext>();SMDiagnostic Err;auto M = parseIRFile(IRFilePath, Err, *Ctx);if (!M) return make_error<StringError>("Failed to parse IR", inconvertibleErrorCode());// 为插件创建独立的JITDylibauto& PluginJD = ES.createJITDylib(PluginName);PluginJD.addToLinkOrder(JIT->getMainJITDylib());// 添加插件模块ThreadSafeModule TSM(std::move(M), std::move(Ctx));return JIT->addIRModule(PluginJD, std::move(TSM));}template<typename FuncPtr>Expected<FuncPtr> getPluginFunction(const std::string& PluginName,const std::string& FuncName) {auto Sym = JIT->lookup(PluginName, FuncName);if (!Sym) return Sym.takeError();return Sym->toPtr<FuncPtr>();}
};

案例2:动态代码热更新

class HotSwappableJIT {std::unique_ptr<LLJIT> JIT;JITDylib& MainJD;std::atomic<ResourceTrackerSP> CurrentVersionRT;public:HotSwappableJIT() : JIT(cantFail(LLJITBuilder().create())),MainJD(JIT->getMainJITDylib()) {CurrentVersionRT = MainJD.getDefaultResourceTracker();}Error updateCode(ThreadSafeModule NewModule) {// 创建新版本资源跟踪器auto NewRT = MainJD.createResourceTracker();// 添加新版本模块if (auto Err = JIT->addIRModule(NewRT, std::move(NewModule))) {return Err;}// 原子交换资源跟踪器auto OldRT = CurrentVersionRT.exchange(NewRT);// 异步移除旧版本(避免阻塞)std::thread([OldRT]() {if (auto Err = OldRT->remove()) {// 记录错误但不阻塞主线程logAllUnhandledErrors(std::move(Err), errs());}}).detach();return Error::success();}
};

性能优化与调试

性能监控

class JITProfiler {ExecutionSession& ES;std::map<std::string, std::chrono::microseconds> CompileTimes;public:void recordCompileTime(const std::string& FuncName, std::chrono::microseconds Duration) {CompileTimes[FuncName] = Duration;}void printStats() {for (const auto& [Name, Time] : CompileTimes) {dbgs() << "Function " << Name << ": " << Time.count() << "μs\n";}}
};// 集成到编译层
auto ProfilingLayer = std::make_unique<IRTransformLayer>(ES, IRCompileLayer,[&](ThreadSafeModule TSM, const MaterializationResponsibility& R) {auto Start = std::chrono::high_resolution_clock::now();// 执行编译...auto End = std::chrono::high_resolution_clock::now();auto Duration = std::chrono::duration_cast<std::chrono::microseconds>(End - Start);Profiler.recordCompileTime(R.getSymbols().begin()->first, Duration);return TSM;});

通过深入理解ExecutionSession和JITDylib的工作原理,您可以构建出高度灵活和强大的JIT编译系统,满足各种复杂的动态代码执行需求。

http://www.dtcms.com/a/398841.html

相关文章:

  • 小九源码-springboot038-基于springboot的中医院问诊系统
  • 【linux内核驱动day01】
  • 网站开发人员趋势外贸网站和内贸
  • 2025最新超详细FreeRTOS入门教程:第二十四章 FreeRTOS与低功耗设计
  • 如何做有效的Bug管理?
  • Metal - 4.深入剖析顶点函数(Vertex Function)
  • 收费网站开发百度关键词优化策略
  • 营销型企业网站群策略网站建设维护与推广
  • 【JNA】JAVA使用JNA调用C++ dll文件(2)JNA 对接代理DLL
  • 新网 主办网站已备案建站系统做网站
  • 网站备案 历史seo流量排行榜神器
  • C++ 中的 static 关键字:类成员、局部变量与单例模式
  • 【 设计模式 | 行为型模式 观察者模式 】
  • seo 网站案例怀化优化网站排名
  • Rust 最小可行 MQ 架构实现指南
  • 公司网站设计报价电商网站建设设计报告总结
  • 【Python】迭代器
  • 【数据迁移】:MySQL 环境下【大表定义变更】一致性保障与数据迁移优化方案
  • 织梦禁止网站右击重庆企业
  • 金融系统的“防火墙”:数字孪生如何模拟风险攻击
  • 埃拉托斯特尼筛法(Sieve of Eratosthenes)——原理、复杂度与多种 C++ 实现
  • 【大模型-金融】Trading-R1 多阶段课程学习
  • 建网站知乎怎么样上传网站资料
  • jupyter notebook 使用集锦(持续更新)
  • 部署开源PPTagent 生成工具
  • Python的大杀器:Jupyter Notebook处理.ipynb文件
  • 物流网站建设与管理规划书七牛wordpress插件
  • 【同源策略】跨域问题解决方法(多种)
  • 【数据结构】链表 --- 单链表
  • ArcGIS JSAPI 高级教程 - 自由绘制线段、多边形