1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 18:54:02 +01:00

[ORC] Refactor TrampolinePool to reduce virtual function calls.

Virtual function calls are now only made when the pool needs to be
grown to accommodate o new request.
This commit is contained in:
Lang Hames 2020-07-19 22:33:27 -07:00
parent 3b3d609a2b
commit 431c554507
6 changed files with 35 additions and 74 deletions

View File

@ -62,14 +62,33 @@ public:
JITTargetAddress TrampolineAddr, JITTargetAddress TrampolineAddr,
NotifyLandingResolvedFunction OnLandingResolved) const>; NotifyLandingResolvedFunction OnLandingResolved) const>;
virtual ~TrampolinePool() {} virtual ~TrampolinePool();
/// Get an available trampoline address. /// Get an available trampoline address.
/// Returns an error if no trampoline can be created. /// 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: /// Returns the given trampoline to the pool for re-use.
virtual void anchor(); 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. /// A trampoline pool for trampolines within the current process.
@ -90,26 +109,6 @@ public:
return std::move(LTP); 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: private:
static JITTargetAddress reenter(void *TrampolinePoolPtr, void *TrampolineId) { static JITTargetAddress reenter(void *TrampolinePoolPtr, void *TrampolineId) {
LocalTrampolinePool<ORCABI> *TrampolinePool = LocalTrampolinePool<ORCABI> *TrampolinePool =
@ -154,8 +153,8 @@ private:
} }
} }
Error grow() { Error grow() override {
assert(this->AvailableTrampolines.empty() && "Growing prematurely?"); assert(AvailableTrampolines.empty() && "Growing prematurely?");
std::error_code EC; std::error_code EC;
auto TrampolineBlock = auto TrampolineBlock =
@ -175,7 +174,7 @@ private:
pointerToJITTargetAddress(ResolverBlock.base()), NumTrampolines); pointerToJITTargetAddress(ResolverBlock.base()), NumTrampolines);
for (unsigned I = 0; I < NumTrampolines; ++I) for (unsigned I = 0; I < NumTrampolines; ++I)
this->AvailableTrampolines.push_back(pointerToJITTargetAddress( AvailableTrampolines.push_back(pointerToJITTargetAddress(
TrampolineMem + (I * ORCABI::TrampolineSize))); TrampolineMem + (I * ORCABI::TrampolineSize)));
if (auto EC = sys::Memory::protectMappedMemory( if (auto EC = sys::Memory::protectMappedMemory(
@ -189,10 +188,8 @@ private:
ResolveLandingFunction ResolveLanding; ResolveLandingFunction ResolveLanding;
std::mutex LTPMutex;
sys::OwningMemoryBlock ResolverBlock; sys::OwningMemoryBlock ResolverBlock;
std::vector<sys::OwningMemoryBlock> TrampolineBlocks; std::vector<sys::OwningMemoryBlock> TrampolineBlocks;
std::vector<JITTargetAddress> AvailableTrampolines;
}; };
/// Target-independent base class for compile callback management. /// Target-independent base class for compile callback management.

View File

@ -453,18 +453,6 @@ public:
public: public:
RemoteTrampolinePool(OrcRemoteTargetClient &Client) : Client(Client) {} 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: private:
Error grow() { Error grow() {
JITTargetAddress BlockAddr = 0; JITTargetAddress BlockAddr = 0;
@ -476,14 +464,12 @@ public:
uint32_t TrampolineSize = Client.getTrampolineSize(); uint32_t TrampolineSize = Client.getTrampolineSize();
for (unsigned I = 0; I < NumTrampolines; ++I) for (unsigned I = 0; I < NumTrampolines; ++I)
this->AvailableTrampolines.push_back(BlockAddr + (I * TrampolineSize)); AvailableTrampolines.push_back(BlockAddr + (I * TrampolineSize));
return Error::success(); return Error::success();
} }
std::mutex RTPMutex;
OrcRemoteTargetClient &Client; OrcRemoteTargetClient &Client;
std::vector<JITTargetAddress> AvailableTrampolines;
}; };
/// Remote compile callback manager. /// Remote compile callback manager.

View File

@ -119,6 +119,8 @@ public:
/// Return a MemoryAccess object for the target process. /// Return a MemoryAccess object for the target process.
MemoryAccess &getMemoryAccess() const { return *MemAccess; } MemoryAccess &getMemoryAccess() const { return *MemAccess; }
/// Load the library at the given path.
protected: protected:
TargetProcessControl(Triple TT, unsigned PageSize); TargetProcessControl(Triple TT, unsigned PageSize);

View File

@ -54,8 +54,8 @@ private:
namespace llvm { namespace llvm {
namespace orc { namespace orc {
TrampolinePool::~TrampolinePool() {}
void IndirectStubsManager::anchor() {} void IndirectStubsManager::anchor() {}
void TrampolinePool::anchor() {}
Expected<JITTargetAddress> Expected<JITTargetAddress>
JITCompileCallbackManager::getCompileCallback(CompileFunction Compile) { JITCompileCallbackManager::getCompileCallback(CompileFunction Compile) {

View File

@ -37,20 +37,16 @@ class TPCTrampolinePool : public TrampolinePool {
public: public:
TPCTrampolinePool(TPCIndirectionUtils &TPCIU); TPCTrampolinePool(TPCIndirectionUtils &TPCIU);
Error deallocatePool(); Error deallocatePool();
Expected<JITTargetAddress> getTrampoline() override;
void releaseTrampoline(JITTargetAddress TrampolineAddr);
protected: protected:
Error grow(); Error grow() override;
using Allocation = jitlink::JITLinkMemoryManager::Allocation; using Allocation = jitlink::JITLinkMemoryManager::Allocation;
std::mutex TPMutex;
TPCIndirectionUtils &TPCIU; TPCIndirectionUtils &TPCIU;
unsigned TrampolineSize = 0; unsigned TrampolineSize = 0;
unsigned TrampolinesPerPage = 0; unsigned TrampolinesPerPage = 0;
std::vector<std::unique_ptr<Allocation>> TrampolineBlocks; std::vector<std::unique_ptr<Allocation>> TrampolineBlocks;
std::vector<JITTargetAddress> AvailableTrampolines;
}; };
class TPCIndirectStubsManager : public IndirectStubsManager, class TPCIndirectStubsManager : public IndirectStubsManager,
@ -96,26 +92,8 @@ Error TPCTrampolinePool::deallocatePool() {
return Err; 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() { Error TPCTrampolinePool::grow() {
assert(this->AvailableTrampolines.empty() && assert(AvailableTrampolines.empty() &&
"Grow called with trampolines still available"); "Grow called with trampolines still available");
auto ResolverAddress = TPCIU.getResolverBlockAddress(); auto ResolverAddress = TPCIU.getResolverBlockAddress();
@ -144,7 +122,7 @@ Error TPCTrampolinePool::grow() {
auto TargetAddr = (*Alloc)->getTargetMemory(TrampolinePagePermissions); auto TargetAddr = (*Alloc)->getTargetMemory(TrampolinePagePermissions);
for (unsigned I = 0; I < NumTrampolines; ++I) 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()) if (auto Err = (*Alloc)->finalize())
return Err; return Err;

View File

@ -16,10 +16,8 @@ using namespace llvm::orc;
namespace { namespace {
class DummyTrampolinePool : public orc::TrampolinePool { class DummyTrampolinePool : public orc::TrampolinePool {
public: protected:
Expected<JITTargetAddress> getTrampoline() override { Error grow() override { llvm_unreachable("Unimplemented"); }
llvm_unreachable("Unimplemented");
}
}; };
class DummyCallbackManager : public JITCompileCallbackManager { class DummyCallbackManager : public JITCompileCallbackManager {