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:
parent
3b3d609a2b
commit
431c554507
@ -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.
|
||||||
|
@ -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.
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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) {
|
||||||
|
@ -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;
|
||||||
|
@ -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 {
|
||||||
|
Loading…
Reference in New Issue
Block a user