namespace llvm {
namespace orc {
-/// @brief Target-independent base class JITCompileCallbackManager.
-class JITCompileCallbackManagerBase {
+/// @brief Target-independent base class for compile callback management.
+class JITCompileCallbackManager {
public:
typedef std::function<TargetAddress()> CompileFtor;
CompileFtor &Compile;
};
- /// @brief Construct a JITCompileCallbackManagerBase.
+ /// @brief Construct a JITCompileCallbackManager.
/// @param ErrorHandlerAddress The address of an error handler in the target
/// process to be used if a compile callback fails.
- JITCompileCallbackManagerBase(TargetAddress ErrorHandlerAddress)
+ JITCompileCallbackManager(TargetAddress ErrorHandlerAddress)
: ErrorHandlerAddress(ErrorHandlerAddress) {}
- virtual ~JITCompileCallbackManagerBase() {}
+ virtual ~JITCompileCallbackManager() {}
/// @brief Execute the callback for the given trampoline id. Called by the JIT
/// to compile functions on demand.
}
/// @brief Reserve a compile callback.
- virtual CompileCallbackInfo getCompileCallback() = 0;
+ CompileCallbackInfo getCompileCallback() {
+ TargetAddress TrampolineAddr = getAvailableTrampolineAddr();
+ auto &Compile = this->ActiveTrampolines[TrampolineAddr];
+ return CompileCallbackInfo(TrampolineAddr, Compile);
+ }
/// @brief Get a CompileCallbackInfo for an existing callback.
CompileCallbackInfo getCompileCallbackInfo(TargetAddress TrampolineAddr) {
std::vector<TargetAddress> AvailableTrampolines;
private:
+
+ TargetAddress getAvailableTrampolineAddr() {
+ if (this->AvailableTrampolines.empty())
+ grow();
+ assert(!this->AvailableTrampolines.empty() &&
+ "Failed to grow available trampolines.");
+ TargetAddress TrampolineAddr = this->AvailableTrampolines.back();
+ this->AvailableTrampolines.pop_back();
+ return TrampolineAddr;
+ }
+
+ // Create new trampolines - to be implemented in subclasses.
+ virtual void grow() = 0;
+
virtual void anchor();
};
-/// @brief Manage compile callbacks.
+/// @brief Manage compile callbacks for in-process JITs.
template <typename TargetT>
-class JITCompileCallbackManager : public JITCompileCallbackManagerBase {
+class LocalJITCompileCallbackManager : public JITCompileCallbackManager {
public:
- /// @brief Construct a JITCompileCallbackManager.
+ /// @brief Construct a InProcessJITCompileCallbackManager.
/// @param ErrorHandlerAddress The address of an error handler in the target
/// process to be used if a compile callback fails.
- JITCompileCallbackManager(TargetAddress ErrorHandlerAddress)
- : JITCompileCallbackManagerBase(ErrorHandlerAddress) {
+ LocalJITCompileCallbackManager(TargetAddress ErrorHandlerAddress)
+ : JITCompileCallbackManager(ErrorHandlerAddress) {
/// Set up the resolver block.
std::error_code EC;
sys::Memory::MF_WRITE, EC));
assert(!EC && "Failed to allocate resolver block");
- TargetT::writeResolverCode(static_cast<uint8_t*>(ResolverBlock.base()),
- &reenter, this);
+ TargetT::writeResolverCode(static_cast<uint8_t *>(ResolverBlock.base()),
+ &reenter, this);
EC = sys::Memory::protectMappedMemory(ResolverBlock.getMemoryBlock(),
- sys::Memory::MF_READ |
- sys::Memory::MF_EXEC);
+ sys::Memory::MF_READ |
+ sys::Memory::MF_EXEC);
assert(!EC && "Failed to mprotect resolver block");
}
- /// @brief Get/create a compile callback with the given signature.
- CompileCallbackInfo getCompileCallback() final {
- TargetAddress TrampolineAddr = getAvailableTrampolineAddr();
- auto &Compile = this->ActiveTrampolines[TrampolineAddr];
- return CompileCallbackInfo(TrampolineAddr, Compile);
- }
-
private:
static TargetAddress reenter(void *CCMgr, void *TrampolineId) {
reinterpret_cast<uintptr_t>(TrampolineId)));
}
- TargetAddress getAvailableTrampolineAddr() {
- if (this->AvailableTrampolines.empty())
- grow();
- assert(!this->AvailableTrampolines.empty() &&
- "Failed to grow available trampolines.");
- TargetAddress TrampolineAddr = this->AvailableTrampolines.back();
- this->AvailableTrampolines.pop_back();
- return TrampolineAddr;
- }
-
- void grow() {
+ void grow() override {
assert(this->AvailableTrampolines.empty() && "Growing prematurely?");
std::error_code EC;
uint8_t *TrampolineMem = static_cast<uint8_t*>(TrampolineBlock.base());
TargetT::writeTrampolines(TrampolineMem, ResolverBlock.base(),
- NumTrampolines);
+ NumTrampolines);
for (unsigned I = 0; I < NumTrampolines; ++I)
this->AvailableTrampolines.push_back(
- static_cast<TargetAddress>(
- reinterpret_cast<uintptr_t>(
- TrampolineMem + (I * TargetT::TrampolineSize))));
+ static_cast<TargetAddress>(reinterpret_cast<uintptr_t>(
+ TrampolineMem + (I * TargetT::TrampolineSize))));
EC = sys::Memory::protectMappedMemory(TrampolineBlock.getMemoryBlock(),
- sys::Memory::MF_READ |
- sys::Memory::MF_EXEC);
+ sys::Memory::MF_READ |
+ sys::Memory::MF_EXEC);
assert(!EC && "Failed to mprotect trampoline block");
-
+
TrampolineBlocks.push_back(std::move(TrampolineBlock));
}
};
/// @brief Base class for managing collections of named indirect stubs.
-class IndirectStubsManagerBase {
+class IndirectStubsManager {
public:
/// @brief Map type for initializing the manager. See init.
typedef StringMap<std::pair<TargetAddress, JITSymbolFlags>> StubInitsMap;
- virtual ~IndirectStubsManagerBase() {}
+ virtual ~IndirectStubsManager() {}
/// @brief Create a single stub with the given name, target address and flags.
virtual std::error_code createStub(StringRef StubName, TargetAddress StubAddr,
/// @brief IndirectStubsManager implementation for a concrete target, e.g.
/// OrcX86_64. (See OrcTargetSupport.h).
template <typename TargetT>
-class IndirectStubsManager : public IndirectStubsManagerBase {
+class LocalIndirectStubsManager : public IndirectStubsManager {
public:
std::error_code createStub(StringRef StubName, TargetAddress StubAddr,
ValueMaterializer *Materializer = nullptr,
GlobalVariable *NewGV = nullptr);
-/// @brief Clone
+/// @brief Clone
GlobalAlias* cloneGlobalAliasDecl(Module &Dst, const GlobalAlias &OrigA,
ValueToValueMapTy &VMap);