Skip to content

Commit

Permalink
[ORC] Refactor TrampolinePool to reduce virtual function calls.
Browse files Browse the repository at this point in the history
Virtual function calls are now only made when the pool needs to be
grown to accommodate o new request.
  • Loading branch information
lhames committed Jul 20, 2020
1 parent fd50e7c commit 0d944e0
Show file tree
Hide file tree
Showing 6 changed files with 35 additions and 74 deletions.
55 changes: 26 additions & 29 deletions llvm/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h
Expand Up @@ -62,14 +62,33 @@ class TrampolinePool {
JITTargetAddress TrampolineAddr,
NotifyLandingResolvedFunction OnLandingResolved) const>;

virtual ~TrampolinePool() {}
virtual ~TrampolinePool();

/// Get an available trampoline address.
/// Returns an error if no trampoline can be created.
virtual Expected<JITTargetAddress> getTrampoline() = 0;
Expected<JITTargetAddress> getTrampoline() {
std::lock_guard<std::mutex> Lock(TPMutex);
if (AvailableTrampolines.empty()) {
if (auto Err = grow())
return std::move(Err);
}
assert(!AvailableTrampolines.empty() && "Failed to grow trampoline pool");
auto TrampolineAddr = AvailableTrampolines.back();
AvailableTrampolines.pop_back();
return TrampolineAddr;
}

private:
virtual void anchor();
/// Returns the given trampoline to the pool for re-use.
void releaseTrampoline(JITTargetAddress TrampolineAddr) {
std::lock_guard<std::mutex> Lock(TPMutex);
AvailableTrampolines.push_back(TrampolineAddr);
}

protected:
virtual Error grow() = 0;

std::mutex TPMutex;
std::vector<JITTargetAddress> AvailableTrampolines;
};

/// A trampoline pool for trampolines within the current process.
Expand All @@ -90,26 +109,6 @@ template <typename ORCABI> class LocalTrampolinePool : public TrampolinePool {
return std::move(LTP);
}

/// Get a free trampoline. Returns an error if one can not be provided (e.g.
/// because the pool is empty and can not be grown).
Expected<JITTargetAddress> getTrampoline() override {
std::lock_guard<std::mutex> Lock(LTPMutex);
if (AvailableTrampolines.empty()) {
if (auto Err = grow())
return std::move(Err);
}
assert(!AvailableTrampolines.empty() && "Failed to grow trampoline pool");
auto TrampolineAddr = AvailableTrampolines.back();
AvailableTrampolines.pop_back();
return TrampolineAddr;
}

/// Returns the given trampoline to the pool for re-use.
void releaseTrampoline(JITTargetAddress TrampolineAddr) {
std::lock_guard<std::mutex> Lock(LTPMutex);
AvailableTrampolines.push_back(TrampolineAddr);
}

private:
static JITTargetAddress reenter(void *TrampolinePoolPtr, void *TrampolineId) {
LocalTrampolinePool<ORCABI> *TrampolinePool =
Expand Down Expand Up @@ -154,8 +153,8 @@ template <typename ORCABI> class LocalTrampolinePool : public TrampolinePool {
}
}

Error grow() {
assert(this->AvailableTrampolines.empty() && "Growing prematurely?");
Error grow() override {
assert(AvailableTrampolines.empty() && "Growing prematurely?");

std::error_code EC;
auto TrampolineBlock =
Expand All @@ -175,7 +174,7 @@ template <typename ORCABI> class LocalTrampolinePool : public TrampolinePool {
pointerToJITTargetAddress(ResolverBlock.base()), NumTrampolines);

for (unsigned I = 0; I < NumTrampolines; ++I)
this->AvailableTrampolines.push_back(pointerToJITTargetAddress(
AvailableTrampolines.push_back(pointerToJITTargetAddress(
TrampolineMem + (I * ORCABI::TrampolineSize)));

if (auto EC = sys::Memory::protectMappedMemory(
Expand All @@ -189,10 +188,8 @@ template <typename ORCABI> class LocalTrampolinePool : public TrampolinePool {

ResolveLandingFunction ResolveLanding;

std::mutex LTPMutex;
sys::OwningMemoryBlock ResolverBlock;
std::vector<sys::OwningMemoryBlock> TrampolineBlocks;
std::vector<JITTargetAddress> AvailableTrampolines;
};

/// Target-independent base class for compile callback management.
Expand Down
16 changes: 1 addition & 15 deletions llvm/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h
Expand Up @@ -453,18 +453,6 @@ class OrcRemoteTargetClient
public:
RemoteTrampolinePool(OrcRemoteTargetClient &Client) : Client(Client) {}

Expected<JITTargetAddress> getTrampoline() override {
std::lock_guard<std::mutex> Lock(RTPMutex);
if (AvailableTrampolines.empty()) {
if (auto Err = grow())
return std::move(Err);
}
assert(!AvailableTrampolines.empty() && "Failed to grow trampoline pool");
auto TrampolineAddr = AvailableTrampolines.back();
AvailableTrampolines.pop_back();
return TrampolineAddr;
}

private:
Error grow() {
JITTargetAddress BlockAddr = 0;
Expand All @@ -476,14 +464,12 @@ class OrcRemoteTargetClient

uint32_t TrampolineSize = Client.getTrampolineSize();
for (unsigned I = 0; I < NumTrampolines; ++I)
this->AvailableTrampolines.push_back(BlockAddr + (I * TrampolineSize));
AvailableTrampolines.push_back(BlockAddr + (I * TrampolineSize));

return Error::success();
}

std::mutex RTPMutex;
OrcRemoteTargetClient &Client;
std::vector<JITTargetAddress> AvailableTrampolines;
};

/// Remote compile callback manager.
Expand Down
2 changes: 2 additions & 0 deletions llvm/include/llvm/ExecutionEngine/Orc/TargetProcessControl.h
Expand Up @@ -119,6 +119,8 @@ class TargetProcessControl {
/// Return a MemoryAccess object for the target process.
MemoryAccess &getMemoryAccess() const { return *MemAccess; }

/// Load the library at the given path.

protected:
TargetProcessControl(Triple TT, unsigned PageSize);

Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp
Expand Up @@ -54,8 +54,8 @@ class CompileCallbackMaterializationUnit : public orc::MaterializationUnit {
namespace llvm {
namespace orc {

TrampolinePool::~TrampolinePool() {}
void IndirectStubsManager::anchor() {}
void TrampolinePool::anchor() {}

Expected<JITTargetAddress>
JITCompileCallbackManager::getCompileCallback(CompileFunction Compile) {
Expand Down
28 changes: 3 additions & 25 deletions llvm/lib/ExecutionEngine/Orc/TPCIndirectionUtils.cpp
Expand Up @@ -37,20 +37,16 @@ class TPCTrampolinePool : public TrampolinePool {
public:
TPCTrampolinePool(TPCIndirectionUtils &TPCIU);
Error deallocatePool();
Expected<JITTargetAddress> getTrampoline() override;
void releaseTrampoline(JITTargetAddress TrampolineAddr);

protected:
Error grow();
Error grow() override;

using Allocation = jitlink::JITLinkMemoryManager::Allocation;

std::mutex TPMutex;
TPCIndirectionUtils &TPCIU;
unsigned TrampolineSize = 0;
unsigned TrampolinesPerPage = 0;
std::vector<std::unique_ptr<Allocation>> TrampolineBlocks;
std::vector<JITTargetAddress> AvailableTrampolines;
};

class TPCIndirectStubsManager : public IndirectStubsManager,
Expand Down Expand Up @@ -96,26 +92,8 @@ Error TPCTrampolinePool::deallocatePool() {
return Err;
}

Expected<JITTargetAddress> TPCTrampolinePool::getTrampoline() {
std::lock_guard<std::mutex> Lock(TPMutex);
if (AvailableTrampolines.empty()) {
if (auto Err = grow())
return std::move(Err);
}

assert(!AvailableTrampolines.empty() && "Failed to grow trampoline pool");
auto TrampolineAddr = AvailableTrampolines.back();
AvailableTrampolines.pop_back();
return TrampolineAddr;
}

void TPCTrampolinePool::releaseTrampoline(JITTargetAddress TrampolineAddr) {
std::lock_guard<std::mutex> Lock(TPMutex);
AvailableTrampolines.push_back(TrampolineAddr);
}

Error TPCTrampolinePool::grow() {
assert(this->AvailableTrampolines.empty() &&
assert(AvailableTrampolines.empty() &&
"Grow called with trampolines still available");

auto ResolverAddress = TPCIU.getResolverBlockAddress();
Expand Down Expand Up @@ -144,7 +122,7 @@ Error TPCTrampolinePool::grow() {

auto TargetAddr = (*Alloc)->getTargetMemory(TrampolinePagePermissions);
for (unsigned I = 0; I < NumTrampolines; ++I)
this->AvailableTrampolines.push_back(TargetAddr + (I * TrampolineSize));
AvailableTrampolines.push_back(TargetAddr + (I * TrampolineSize));

if (auto Err = (*Alloc)->finalize())
return Err;
Expand Down
Expand Up @@ -16,10 +16,8 @@ using namespace llvm::orc;
namespace {

class DummyTrampolinePool : public orc::TrampolinePool {
public:
Expected<JITTargetAddress> getTrampoline() override {
llvm_unreachable("Unimplemented");
}
protected:
Error grow() override { llvm_unreachable("Unimplemented"); }
};

class DummyCallbackManager : public JITCompileCallbackManager {
Expand Down

0 comments on commit 0d944e0

Please sign in to comment.