设计建议:llvm多个运行时上下文

时间:2012-03-29 23:00:29

标签: c++ llvm

我的应用程序需要在同一个(单线程)进程中运行许多单独的上下文。它们共享一个LLVMContext

该过程将运行许多上下文(在线程意义上);也就是说,每个都在基于boost::context的延续对象中运行一个函数(仍然在库中,预先批准的库),这意味着每个上下文都可以产生,但它们基本上在相同的单线程进程中运行。每个人应该基本上独立于另一个运行,更重要的是,每个人的编译错误不应该影响其他人的执行。

这些上下文中的每一个都将动态调用跨多个翻译单元(TU)的代码。一些翻译单元可以在许多这些上下文中共享。新的或修改的翻译单元中的编译错误不应影响其他上下文。

澄清编辑: 例如,T.U。 A可以在两个上下文中共享,上下文X和Y.仅仅为了拥有完整的图片,假设X也将运行来自其他翻译单元的代码,即B和D,而Y也将具有C.有一点,X决定对A做一个修改,所以它创建了一个新的TU A.1,它是A的副本,并在那里应用修改,所以这些不会影响上下文Y.希望这个例子清楚说明需求。

我最初的冲动是为每个上下文关联一个llvm::Module,但由于它在LLVM中未定义,对于处于中间编译状态的模块会发生什么,我决定为每个翻译添加一个llvm::Module unit(请参阅this question for the reason),以及我之前解释过的翻译单元本地发生在上下文时的写时复制策略,以避免修改影响其他上下文。

我遇到的主要双重问题是:

  • 如何将上下文中的不同模块链接在一起,以便将它们作为统一库调用?我正在使用C ++ api。我特别警惕影响此功能的this nasty, old bug。如果我使用ExecutionEngine::addModule()将所有模块的所有权转移到JIT,这个错误是否会影响我?

  • 翻译单元上的修改会强制更新其中一个模块后,需要执行哪些步骤?我是否需要删除/删除旧模块对象并创建一个新模块?是否有我尚未阅读的回收政策?

我对此提出的第二个问题是:

  • 我需要多少ExecutionEngine?整个申请一个?每个上下文一个?每个模块一个?

希望问题的范围不会过于庞大。

1 个答案:

答案 0 :(得分:1)

我认为你需要一个概念框架来“悬挂”你的想法。将各种执行位视为命令(甚至可能使用命令模式实现)将为您提供更明显的交互点集。话虽如此;您将需要一个上下文,用于您希望返回的每个离散执行。两个以上将要求您创建适当的簿记。我相信两个基本上是免费提供的 执行位之间的通信同样取决于您。创建一个跨执行上下文共享的状态(memento)是一个可以想到的解决方案。您可能已经在运行时内置了适当的状态,因此不需要额外的层。正如你所指出的,全局变量不是你在这些互动中的朋友。 版本控制和名称解析也是一个问题。保持执行位分离对解决这个问题大有帮助。解决协调问题后,更多的是跟踪已创建的位。这也意味着不需要回收,只需每次创建新的并且没有重新加载。一旦完成执行,您还必须管理这些位的寿命终止。 我建议每执行一位ExecutionEngine。不这样做意味着需要做更多的工作来试图“保护”工作代码免受错误代码的影响。我相信用一个引擎可以做到这一点,但风险要大得多。