mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-28 06:00:28 +00:00
[ORC] clang-format code that was touched in r267457. NFC.
Commit r267457 made a lot of type-substitutions threw off code formatting and alignment. This patch should tidy those changes up. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@267475 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
02e4498043
commit
3869f2a5ab
@ -32,15 +32,11 @@ extern "C" {
|
|||||||
typedef struct LLVMOrcOpaqueJITStack *LLVMOrcJITStackRef;
|
typedef struct LLVMOrcOpaqueJITStack *LLVMOrcJITStackRef;
|
||||||
typedef uint32_t LLVMOrcModuleHandle;
|
typedef uint32_t LLVMOrcModuleHandle;
|
||||||
typedef uint64_t LLVMOrcTargetAddress;
|
typedef uint64_t LLVMOrcTargetAddress;
|
||||||
typedef uint64_t (*LLVMOrcSymbolResolverFn)(const char *Name,
|
typedef uint64_t (*LLVMOrcSymbolResolverFn)(const char *Name, void *LookupCtx);
|
||||||
void *LookupCtx);
|
|
||||||
typedef uint64_t (*LLVMOrcLazyCompileCallbackFn)(LLVMOrcJITStackRef JITStack,
|
typedef uint64_t (*LLVMOrcLazyCompileCallbackFn)(LLVMOrcJITStackRef JITStack,
|
||||||
void *CallbackCtx);
|
void *CallbackCtx);
|
||||||
|
|
||||||
typedef enum {
|
typedef enum { LLVMOrcErrSuccess = 0, LLVMOrcErrGeneric } LLVMOrcErrorCode;
|
||||||
LLVMOrcErrSuccess = 0,
|
|
||||||
LLVMOrcErrGeneric
|
|
||||||
} LLVMOrcErrorCode;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an ORC JIT stack.
|
* Create an ORC JIT stack.
|
||||||
@ -114,10 +110,10 @@ LLVMOrcAddLazilyCompiledIR(LLVMOrcJITStackRef JITStack, LLVMModuleRef Mod,
|
|||||||
/**
|
/**
|
||||||
* Add an object file.
|
* Add an object file.
|
||||||
*/
|
*/
|
||||||
LLVMOrcModuleHandle
|
LLVMOrcModuleHandle LLVMOrcAddObjectFile(LLVMOrcJITStackRef JITStack,
|
||||||
LLVMOrcAddObjectFile(LLVMOrcJITStackRef JITStack, LLVMObjectFileRef Obj,
|
LLVMObjectFileRef Obj,
|
||||||
LLVMOrcSymbolResolverFn SymbolResolver,
|
LLVMOrcSymbolResolverFn SymbolResolver,
|
||||||
void *SymbolResolverCtx);
|
void *SymbolResolverCtx);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove a module set from the JIT.
|
* Remove a module set from the JIT.
|
||||||
|
@ -29,7 +29,6 @@ namespace orc {
|
|||||||
/// @brief Target-independent base class for compile callback management.
|
/// @brief Target-independent base class for compile callback management.
|
||||||
class JITCompileCallbackManager {
|
class JITCompileCallbackManager {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
typedef std::function<TargetAddress()> CompileFtor;
|
typedef std::function<TargetAddress()> CompileFtor;
|
||||||
|
|
||||||
/// @brief Handle to a newly created compile callback. Can be used to get an
|
/// @brief Handle to a newly created compile callback. Can be used to get an
|
||||||
@ -38,12 +37,13 @@ public:
|
|||||||
class CompileCallbackInfo {
|
class CompileCallbackInfo {
|
||||||
public:
|
public:
|
||||||
CompileCallbackInfo(TargetAddress Addr, CompileFtor &Compile)
|
CompileCallbackInfo(TargetAddress Addr, CompileFtor &Compile)
|
||||||
: Addr(Addr), Compile(Compile) {}
|
: Addr(Addr), Compile(Compile) {}
|
||||||
|
|
||||||
TargetAddress getAddress() const { return Addr; }
|
TargetAddress getAddress() const { return Addr; }
|
||||||
void setCompileAction(CompileFtor Compile) {
|
void setCompileAction(CompileFtor Compile) {
|
||||||
this->Compile = std::move(Compile);
|
this->Compile = std::move(Compile);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TargetAddress Addr;
|
TargetAddress Addr;
|
||||||
CompileFtor &Compile;
|
CompileFtor &Compile;
|
||||||
@ -53,7 +53,7 @@ public:
|
|||||||
/// @param ErrorHandlerAddress The address of an error handler in the target
|
/// @param ErrorHandlerAddress The address of an error handler in the target
|
||||||
/// process to be used if a compile callback fails.
|
/// process to be used if a compile callback fails.
|
||||||
JITCompileCallbackManager(TargetAddress ErrorHandlerAddress)
|
JITCompileCallbackManager(TargetAddress ErrorHandlerAddress)
|
||||||
: ErrorHandlerAddress(ErrorHandlerAddress) {}
|
: ErrorHandlerAddress(ErrorHandlerAddress) {}
|
||||||
|
|
||||||
virtual ~JITCompileCallbackManager() {}
|
virtual ~JITCompileCallbackManager() {}
|
||||||
|
|
||||||
@ -69,8 +69,10 @@ public:
|
|||||||
// Found a callback handler. Yank this trampoline out of the active list and
|
// Found a callback handler. Yank this trampoline out of the active list and
|
||||||
// put it back in the available trampolines list, then try to run the
|
// put it back in the available trampolines list, then try to run the
|
||||||
// handler's compile and update actions.
|
// handler's compile and update actions.
|
||||||
// Moving the trampoline ID back to the available list first means there's at
|
// Moving the trampoline ID back to the available list first means there's
|
||||||
// least one available trampoline if the compile action triggers a request for
|
// at
|
||||||
|
// least one available trampoline if the compile action triggers a request
|
||||||
|
// for
|
||||||
// a new one.
|
// a new one.
|
||||||
auto Compile = std::move(I->second);
|
auto Compile = std::move(I->second);
|
||||||
ActiveTrampolines.erase(I);
|
ActiveTrampolines.erase(I);
|
||||||
@ -116,7 +118,6 @@ protected:
|
|||||||
std::vector<TargetAddress> AvailableTrampolines;
|
std::vector<TargetAddress> AvailableTrampolines;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
TargetAddress getAvailableTrampolineAddr() {
|
TargetAddress getAvailableTrampolineAddr() {
|
||||||
if (this->AvailableTrampolines.empty())
|
if (this->AvailableTrampolines.empty())
|
||||||
grow();
|
grow();
|
||||||
@ -137,20 +138,17 @@ private:
|
|||||||
template <typename TargetT>
|
template <typename TargetT>
|
||||||
class LocalJITCompileCallbackManager : public JITCompileCallbackManager {
|
class LocalJITCompileCallbackManager : public JITCompileCallbackManager {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// @brief Construct a InProcessJITCompileCallbackManager.
|
/// @brief Construct a InProcessJITCompileCallbackManager.
|
||||||
/// @param ErrorHandlerAddress The address of an error handler in the target
|
/// @param ErrorHandlerAddress The address of an error handler in the target
|
||||||
/// process to be used if a compile callback fails.
|
/// process to be used if a compile callback fails.
|
||||||
LocalJITCompileCallbackManager(TargetAddress ErrorHandlerAddress)
|
LocalJITCompileCallbackManager(TargetAddress ErrorHandlerAddress)
|
||||||
: JITCompileCallbackManager(ErrorHandlerAddress) {
|
: JITCompileCallbackManager(ErrorHandlerAddress) {
|
||||||
|
|
||||||
/// Set up the resolver block.
|
/// Set up the resolver block.
|
||||||
std::error_code EC;
|
std::error_code EC;
|
||||||
ResolverBlock =
|
ResolverBlock = sys::OwningMemoryBlock(sys::Memory::allocateMappedMemory(
|
||||||
sys::OwningMemoryBlock(
|
TargetT::ResolverCodeSize, nullptr,
|
||||||
sys::Memory::allocateMappedMemory(TargetT::ResolverCodeSize, nullptr,
|
sys::Memory::MF_READ | sys::Memory::MF_WRITE, EC));
|
||||||
sys::Memory::MF_READ |
|
|
||||||
sys::Memory::MF_WRITE, EC));
|
|
||||||
assert(!EC && "Failed to allocate resolver block");
|
assert(!EC && "Failed to allocate resolver block");
|
||||||
|
|
||||||
TargetT::writeResolverCode(static_cast<uint8_t *>(ResolverBlock.base()),
|
TargetT::writeResolverCode(static_cast<uint8_t *>(ResolverBlock.base()),
|
||||||
@ -163,13 +161,11 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
static TargetAddress reenter(void *CCMgr, void *TrampolineId) {
|
static TargetAddress reenter(void *CCMgr, void *TrampolineId) {
|
||||||
JITCompileCallbackManager *Mgr =
|
JITCompileCallbackManager *Mgr =
|
||||||
static_cast<JITCompileCallbackManager*>(CCMgr);
|
static_cast<JITCompileCallbackManager *>(CCMgr);
|
||||||
return Mgr->executeCompileCallback(
|
return Mgr->executeCompileCallback(
|
||||||
static_cast<TargetAddress>(
|
static_cast<TargetAddress>(reinterpret_cast<uintptr_t>(TrampolineId)));
|
||||||
reinterpret_cast<uintptr_t>(TrampolineId)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void grow() override {
|
void grow() override {
|
||||||
@ -177,18 +173,16 @@ private:
|
|||||||
|
|
||||||
std::error_code EC;
|
std::error_code EC;
|
||||||
auto TrampolineBlock =
|
auto TrampolineBlock =
|
||||||
sys::OwningMemoryBlock(
|
sys::OwningMemoryBlock(sys::Memory::allocateMappedMemory(
|
||||||
sys::Memory::allocateMappedMemory(sys::Process::getPageSize(), nullptr,
|
sys::Process::getPageSize(), nullptr,
|
||||||
sys::Memory::MF_READ |
|
sys::Memory::MF_READ | sys::Memory::MF_WRITE, EC));
|
||||||
sys::Memory::MF_WRITE, EC));
|
|
||||||
assert(!EC && "Failed to allocate trampoline block");
|
assert(!EC && "Failed to allocate trampoline block");
|
||||||
|
|
||||||
|
|
||||||
unsigned NumTrampolines =
|
unsigned NumTrampolines =
|
||||||
(sys::Process::getPageSize() - TargetT::PointerSize) /
|
(sys::Process::getPageSize() - TargetT::PointerSize) /
|
||||||
TargetT::TrampolineSize;
|
TargetT::TrampolineSize;
|
||||||
|
|
||||||
uint8_t *TrampolineMem = static_cast<uint8_t*>(TrampolineBlock.base());
|
uint8_t *TrampolineMem = static_cast<uint8_t *>(TrampolineBlock.base());
|
||||||
TargetT::writeTrampolines(TrampolineMem, ResolverBlock.base(),
|
TargetT::writeTrampolines(TrampolineMem, ResolverBlock.base(),
|
||||||
NumTrampolines);
|
NumTrampolines);
|
||||||
|
|
||||||
@ -212,7 +206,6 @@ private:
|
|||||||
/// @brief Base class for managing collections of named indirect stubs.
|
/// @brief Base class for managing collections of named indirect stubs.
|
||||||
class IndirectStubsManager {
|
class IndirectStubsManager {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// @brief Map type for initializing the manager. See init.
|
/// @brief Map type for initializing the manager. See init.
|
||||||
typedef StringMap<std::pair<TargetAddress, JITSymbolFlags>> StubInitsMap;
|
typedef StringMap<std::pair<TargetAddress, JITSymbolFlags>> StubInitsMap;
|
||||||
|
|
||||||
@ -236,6 +229,7 @@ public:
|
|||||||
|
|
||||||
/// @brief Change the value of the implementation pointer for the stub.
|
/// @brief Change the value of the implementation pointer for the stub.
|
||||||
virtual Error updatePointer(StringRef Name, TargetAddress NewAddr) = 0;
|
virtual Error updatePointer(StringRef Name, TargetAddress NewAddr) = 0;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual void anchor();
|
virtual void anchor();
|
||||||
};
|
};
|
||||||
@ -245,9 +239,8 @@ private:
|
|||||||
template <typename TargetT>
|
template <typename TargetT>
|
||||||
class LocalIndirectStubsManager : public IndirectStubsManager {
|
class LocalIndirectStubsManager : public IndirectStubsManager {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Error createStub(StringRef StubName, TargetAddress StubAddr,
|
Error createStub(StringRef StubName, TargetAddress StubAddr,
|
||||||
JITSymbolFlags StubFlags) override {
|
JITSymbolFlags StubFlags) override {
|
||||||
if (auto Err = reserveStubs(1))
|
if (auto Err = reserveStubs(1))
|
||||||
return Err;
|
return Err;
|
||||||
|
|
||||||
@ -275,7 +268,7 @@ public:
|
|||||||
void *StubAddr = IndirectStubsInfos[Key.first].getStub(Key.second);
|
void *StubAddr = IndirectStubsInfos[Key.first].getStub(Key.second);
|
||||||
assert(StubAddr && "Missing stub address");
|
assert(StubAddr && "Missing stub address");
|
||||||
auto StubTargetAddr =
|
auto StubTargetAddr =
|
||||||
static_cast<TargetAddress>(reinterpret_cast<uintptr_t>(StubAddr));
|
static_cast<TargetAddress>(reinterpret_cast<uintptr_t>(StubAddr));
|
||||||
auto StubSymbol = JITSymbol(StubTargetAddr, I->second.second);
|
auto StubSymbol = JITSymbol(StubTargetAddr, I->second.second);
|
||||||
if (ExportedStubsOnly && !StubSymbol.isExported())
|
if (ExportedStubsOnly && !StubSymbol.isExported())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -290,7 +283,7 @@ public:
|
|||||||
void *PtrAddr = IndirectStubsInfos[Key.first].getPtr(Key.second);
|
void *PtrAddr = IndirectStubsInfos[Key.first].getPtr(Key.second);
|
||||||
assert(PtrAddr && "Missing pointer address");
|
assert(PtrAddr && "Missing pointer address");
|
||||||
auto PtrTargetAddr =
|
auto PtrTargetAddr =
|
||||||
static_cast<TargetAddress>(reinterpret_cast<uintptr_t>(PtrAddr));
|
static_cast<TargetAddress>(reinterpret_cast<uintptr_t>(PtrAddr));
|
||||||
return JITSymbol(PtrTargetAddr, I->second.second);
|
return JITSymbol(PtrTargetAddr, I->second.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -299,12 +292,11 @@ public:
|
|||||||
assert(I != StubIndexes.end() && "No stub pointer for symbol");
|
assert(I != StubIndexes.end() && "No stub pointer for symbol");
|
||||||
auto Key = I->second.first;
|
auto Key = I->second.first;
|
||||||
*IndirectStubsInfos[Key.first].getPtr(Key.second) =
|
*IndirectStubsInfos[Key.first].getPtr(Key.second) =
|
||||||
reinterpret_cast<void*>(static_cast<uintptr_t>(NewAddr));
|
reinterpret_cast<void *>(static_cast<uintptr_t>(NewAddr));
|
||||||
return Error::success();
|
return Error::success();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Error reserveStubs(unsigned NumStubs) {
|
Error reserveStubs(unsigned NumStubs) {
|
||||||
if (NumStubs <= FreeStubs.size())
|
if (NumStubs <= FreeStubs.size())
|
||||||
return Error::success();
|
return Error::success();
|
||||||
@ -312,8 +304,8 @@ private:
|
|||||||
unsigned NewStubsRequired = NumStubs - FreeStubs.size();
|
unsigned NewStubsRequired = NumStubs - FreeStubs.size();
|
||||||
unsigned NewBlockId = IndirectStubsInfos.size();
|
unsigned NewBlockId = IndirectStubsInfos.size();
|
||||||
typename TargetT::IndirectStubsInfo ISI;
|
typename TargetT::IndirectStubsInfo ISI;
|
||||||
if (auto Err = TargetT::emitIndirectStubsBlock(ISI, NewStubsRequired,
|
if (auto Err =
|
||||||
nullptr))
|
TargetT::emitIndirectStubsBlock(ISI, NewStubsRequired, nullptr))
|
||||||
return Err;
|
return Err;
|
||||||
for (unsigned I = 0; I < ISI.getNumStubs(); ++I)
|
for (unsigned I = 0; I < ISI.getNumStubs(); ++I)
|
||||||
FreeStubs.push_back(std::make_pair(NewBlockId, I));
|
FreeStubs.push_back(std::make_pair(NewBlockId, I));
|
||||||
@ -326,7 +318,7 @@ private:
|
|||||||
auto Key = FreeStubs.back();
|
auto Key = FreeStubs.back();
|
||||||
FreeStubs.pop_back();
|
FreeStubs.pop_back();
|
||||||
*IndirectStubsInfos[Key.first].getPtr(Key.second) =
|
*IndirectStubsInfos[Key.first].getPtr(Key.second) =
|
||||||
reinterpret_cast<void*>(static_cast<uintptr_t>(InitAddr));
|
reinterpret_cast<void *>(static_cast<uintptr_t>(InitAddr));
|
||||||
StubIndexes[StubName] = std::make_pair(Key, StubFlags);
|
StubIndexes[StubName] = std::make_pair(Key, StubFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -341,12 +333,12 @@ private:
|
|||||||
///
|
///
|
||||||
/// Usage example: Turn a trampoline address into a function pointer constant
|
/// Usage example: Turn a trampoline address into a function pointer constant
|
||||||
/// for use in a stub.
|
/// for use in a stub.
|
||||||
Constant* createIRTypedAddress(FunctionType &FT, TargetAddress Addr);
|
Constant *createIRTypedAddress(FunctionType &FT, TargetAddress Addr);
|
||||||
|
|
||||||
/// @brief Create a function pointer with the given type, name, and initializer
|
/// @brief Create a function pointer with the given type, name, and initializer
|
||||||
/// in the given Module.
|
/// in the given Module.
|
||||||
GlobalVariable* createImplPointer(PointerType &PT, Module &M,
|
GlobalVariable *createImplPointer(PointerType &PT, Module &M, const Twine &Name,
|
||||||
const Twine &Name, Constant *Initializer);
|
Constant *Initializer);
|
||||||
|
|
||||||
/// @brief Turn a function declaration into a stub function that makes an
|
/// @brief Turn a function declaration into a stub function that makes an
|
||||||
/// indirect call using the given function pointer.
|
/// indirect call using the given function pointer.
|
||||||
@ -371,7 +363,7 @@ void makeAllSymbolsExternallyAccessible(Module &M);
|
|||||||
/// modules with these utilities, all decls should be cloned (and added to a
|
/// modules with these utilities, all decls should be cloned (and added to a
|
||||||
/// single VMap) before any bodies are moved. This will ensure that references
|
/// single VMap) before any bodies are moved. This will ensure that references
|
||||||
/// between functions all refer to the versions in the new module.
|
/// between functions all refer to the versions in the new module.
|
||||||
Function* cloneFunctionDecl(Module &Dst, const Function &F,
|
Function *cloneFunctionDecl(Module &Dst, const Function &F,
|
||||||
ValueToValueMapTy *VMap = nullptr);
|
ValueToValueMapTy *VMap = nullptr);
|
||||||
|
|
||||||
/// @brief Move the body of function 'F' to a cloned function declaration in a
|
/// @brief Move the body of function 'F' to a cloned function declaration in a
|
||||||
@ -387,7 +379,7 @@ void moveFunctionBody(Function &OrigF, ValueToValueMapTy &VMap,
|
|||||||
Function *NewF = nullptr);
|
Function *NewF = nullptr);
|
||||||
|
|
||||||
/// @brief Clone a global variable declaration into a new module.
|
/// @brief Clone a global variable declaration into a new module.
|
||||||
GlobalVariable* cloneGlobalVariableDecl(Module &Dst, const GlobalVariable &GV,
|
GlobalVariable *cloneGlobalVariableDecl(Module &Dst, const GlobalVariable &GV,
|
||||||
ValueToValueMapTy *VMap = nullptr);
|
ValueToValueMapTy *VMap = nullptr);
|
||||||
|
|
||||||
/// @brief Move global variable GV from its parent module to cloned global
|
/// @brief Move global variable GV from its parent module to cloned global
|
||||||
@ -404,7 +396,7 @@ void moveGlobalVariableInitializer(GlobalVariable &OrigGV,
|
|||||||
GlobalVariable *NewGV = nullptr);
|
GlobalVariable *NewGV = nullptr);
|
||||||
|
|
||||||
/// @brief Clone
|
/// @brief Clone
|
||||||
GlobalAlias* cloneGlobalAliasDecl(Module &Dst, const GlobalAlias &OrigA,
|
GlobalAlias *cloneGlobalAliasDecl(Module &Dst, const GlobalAlias &OrigA,
|
||||||
ValueToValueMapTy &VMap);
|
ValueToValueMapTy &VMap);
|
||||||
|
|
||||||
} // End namespace orc.
|
} // End namespace orc.
|
||||||
|
@ -28,19 +28,19 @@ class DirectBufferWriter {
|
|||||||
public:
|
public:
|
||||||
DirectBufferWriter() = default;
|
DirectBufferWriter() = default;
|
||||||
DirectBufferWriter(const char *Src, TargetAddress Dst, uint64_t Size)
|
DirectBufferWriter(const char *Src, TargetAddress Dst, uint64_t Size)
|
||||||
: Src(Src), Dst(Dst), Size(Size) {}
|
: Src(Src), Dst(Dst), Size(Size) {}
|
||||||
|
|
||||||
const char *getSrc() const { return Src; }
|
const char *getSrc() const { return Src; }
|
||||||
TargetAddress getDst() const { return Dst; }
|
TargetAddress getDst() const { return Dst; }
|
||||||
uint64_t getSize() const { return Size; }
|
uint64_t getSize() const { return Size; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const char *Src;
|
const char *Src;
|
||||||
TargetAddress Dst;
|
TargetAddress Dst;
|
||||||
uint64_t Size;
|
uint64_t Size;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline Error serialize(RPCChannel &C,
|
inline Error serialize(RPCChannel &C, const DirectBufferWriter &DBW) {
|
||||||
const DirectBufferWriter &DBW) {
|
|
||||||
if (auto EC = serialize(C, DBW.getDst()))
|
if (auto EC = serialize(C, DBW.getDst()))
|
||||||
return EC;
|
return EC;
|
||||||
if (auto EC = serialize(C, DBW.getSize()))
|
if (auto EC = serialize(C, DBW.getSize()))
|
||||||
@ -48,15 +48,14 @@ inline Error serialize(RPCChannel &C,
|
|||||||
return C.appendBytes(DBW.getSrc(), DBW.getSize());
|
return C.appendBytes(DBW.getSrc(), DBW.getSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Error deserialize(RPCChannel &C,
|
inline Error deserialize(RPCChannel &C, DirectBufferWriter &DBW) {
|
||||||
DirectBufferWriter &DBW) {
|
|
||||||
TargetAddress Dst;
|
TargetAddress Dst;
|
||||||
if (auto EC = deserialize(C, Dst))
|
if (auto EC = deserialize(C, Dst))
|
||||||
return EC;
|
return EC;
|
||||||
uint64_t Size;
|
uint64_t Size;
|
||||||
if (auto EC = deserialize(C, Size))
|
if (auto EC = deserialize(C, Size))
|
||||||
return EC;
|
return EC;
|
||||||
char *Addr = reinterpret_cast<char*>(static_cast<uintptr_t>(Dst));
|
char *Addr = reinterpret_cast<char *>(static_cast<uintptr_t>(Dst));
|
||||||
|
|
||||||
DBW = DirectBufferWriter(0, Dst, Size);
|
DBW = DirectBufferWriter(0, Dst, Size);
|
||||||
|
|
||||||
@ -65,7 +64,6 @@ inline Error deserialize(RPCChannel &C,
|
|||||||
|
|
||||||
class OrcRemoteTargetRPCAPI : public RPC<RPCChannel> {
|
class OrcRemoteTargetRPCAPI : public RPC<RPCChannel> {
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
class ResourceIdMgr {
|
class ResourceIdMgr {
|
||||||
public:
|
public:
|
||||||
typedef uint64_t ResourceId;
|
typedef uint64_t ResourceId;
|
||||||
@ -87,16 +85,13 @@ protected:
|
|||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// FIXME: Remove constructors once MSVC supports synthesizing move-ops.
|
// FIXME: Remove constructors once MSVC supports synthesizing move-ops.
|
||||||
OrcRemoteTargetRPCAPI() = default;
|
OrcRemoteTargetRPCAPI() = default;
|
||||||
OrcRemoteTargetRPCAPI(const OrcRemoteTargetRPCAPI&) = delete;
|
OrcRemoteTargetRPCAPI(const OrcRemoteTargetRPCAPI &) = delete;
|
||||||
OrcRemoteTargetRPCAPI& operator=(const OrcRemoteTargetRPCAPI&) = delete;
|
OrcRemoteTargetRPCAPI &operator=(const OrcRemoteTargetRPCAPI &) = delete;
|
||||||
|
|
||||||
OrcRemoteTargetRPCAPI(OrcRemoteTargetRPCAPI&&) {}
|
OrcRemoteTargetRPCAPI(OrcRemoteTargetRPCAPI &&) {}
|
||||||
OrcRemoteTargetRPCAPI& operator=(OrcRemoteTargetRPCAPI&&) {
|
OrcRemoteTargetRPCAPI &operator=(OrcRemoteTargetRPCAPI &&) { return *this; }
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum JITFuncId : uint32_t {
|
enum JITFuncId : uint32_t {
|
||||||
InvalidId = RPCFunctionIdTraits<JITFuncId>::InvalidId,
|
InvalidId = RPCFunctionIdTraits<JITFuncId>::InvalidId,
|
||||||
@ -127,80 +122,78 @@ public:
|
|||||||
|
|
||||||
typedef Function<CallIntVoidId, int32_t(TargetAddress Addr)> CallIntVoid;
|
typedef Function<CallIntVoidId, int32_t(TargetAddress Addr)> CallIntVoid;
|
||||||
|
|
||||||
typedef Function<CallMainId, int32_t(TargetAddress Addr,
|
typedef Function<CallMainId,
|
||||||
std::vector<std::string> Args)>
|
int32_t(TargetAddress Addr, std::vector<std::string> Args)>
|
||||||
CallMain;
|
CallMain;
|
||||||
|
|
||||||
typedef Function<CallVoidVoidId, void(TargetAddress FnAddr)> CallVoidVoid;
|
typedef Function<CallVoidVoidId, void(TargetAddress FnAddr)> CallVoidVoid;
|
||||||
|
|
||||||
typedef Function<CreateRemoteAllocatorId,
|
typedef Function<CreateRemoteAllocatorId,
|
||||||
void(ResourceIdMgr::ResourceId AllocatorID)>
|
void(ResourceIdMgr::ResourceId AllocatorID)>
|
||||||
CreateRemoteAllocator;
|
CreateRemoteAllocator;
|
||||||
|
|
||||||
typedef Function<CreateIndirectStubsOwnerId,
|
typedef Function<CreateIndirectStubsOwnerId,
|
||||||
void(ResourceIdMgr::ResourceId StubOwnerID)>
|
void(ResourceIdMgr::ResourceId StubOwnerID)>
|
||||||
CreateIndirectStubsOwner;
|
CreateIndirectStubsOwner;
|
||||||
|
|
||||||
typedef Function<DeregisterEHFramesId,
|
typedef Function<DeregisterEHFramesId,
|
||||||
void(TargetAddress Addr, uint32_t Size)>
|
void(TargetAddress Addr, uint32_t Size)>
|
||||||
DeregisterEHFrames;
|
DeregisterEHFrames;
|
||||||
|
|
||||||
typedef Function<DestroyRemoteAllocatorId,
|
typedef Function<DestroyRemoteAllocatorId,
|
||||||
void(ResourceIdMgr::ResourceId AllocatorID)>
|
void(ResourceIdMgr::ResourceId AllocatorID)>
|
||||||
DestroyRemoteAllocator;
|
DestroyRemoteAllocator;
|
||||||
|
|
||||||
typedef Function<DestroyIndirectStubsOwnerId,
|
typedef Function<DestroyIndirectStubsOwnerId,
|
||||||
void(ResourceIdMgr::ResourceId StubsOwnerID)>
|
void(ResourceIdMgr::ResourceId StubsOwnerID)>
|
||||||
DestroyIndirectStubsOwner;
|
DestroyIndirectStubsOwner;
|
||||||
|
|
||||||
/// EmitIndirectStubs result is (StubsBase, PtrsBase, NumStubsEmitted).
|
/// EmitIndirectStubs result is (StubsBase, PtrsBase, NumStubsEmitted).
|
||||||
typedef Function<EmitIndirectStubsId,
|
typedef Function<EmitIndirectStubsId,
|
||||||
std::tuple<TargetAddress, TargetAddress, uint32_t>(
|
std::tuple<TargetAddress, TargetAddress, uint32_t>(
|
||||||
ResourceIdMgr::ResourceId StubsOwnerID,
|
ResourceIdMgr::ResourceId StubsOwnerID,
|
||||||
uint32_t NumStubsRequired)>
|
uint32_t NumStubsRequired)>
|
||||||
EmitIndirectStubs;
|
EmitIndirectStubs;
|
||||||
|
|
||||||
typedef Function<EmitResolverBlockId, void()> EmitResolverBlock;
|
typedef Function<EmitResolverBlockId, void()> EmitResolverBlock;
|
||||||
|
|
||||||
/// EmitTrampolineBlock result is (BlockAddr, NumTrampolines).
|
/// EmitTrampolineBlock result is (BlockAddr, NumTrampolines).
|
||||||
typedef Function<EmitTrampolineBlockId,
|
typedef Function<EmitTrampolineBlockId, std::tuple<TargetAddress, uint32_t>()>
|
||||||
std::tuple<TargetAddress, uint32_t>()> EmitTrampolineBlock;
|
EmitTrampolineBlock;
|
||||||
|
|
||||||
typedef Function<GetSymbolAddressId, TargetAddress(std::string SymbolName)>
|
typedef Function<GetSymbolAddressId, TargetAddress(std::string SymbolName)>
|
||||||
GetSymbolAddress;
|
GetSymbolAddress;
|
||||||
|
|
||||||
/// GetRemoteInfo result is (Triple, PointerSize, PageSize, TrampolineSize,
|
/// GetRemoteInfo result is (Triple, PointerSize, PageSize, TrampolineSize,
|
||||||
/// IndirectStubsSize).
|
/// IndirectStubsSize).
|
||||||
typedef Function<GetRemoteInfoId,
|
typedef Function<GetRemoteInfoId, std::tuple<std::string, uint32_t, uint32_t,
|
||||||
std::tuple<std::string, uint32_t, uint32_t, uint32_t,
|
uint32_t, uint32_t>()>
|
||||||
uint32_t>()> GetRemoteInfo;
|
GetRemoteInfo;
|
||||||
|
|
||||||
typedef Function<ReadMemId,
|
typedef Function<ReadMemId,
|
||||||
std::vector<char>(TargetAddress Src, uint64_t Size)>
|
std::vector<char>(TargetAddress Src, uint64_t Size)>
|
||||||
ReadMem;
|
ReadMem;
|
||||||
|
|
||||||
typedef Function<RegisterEHFramesId,
|
typedef Function<RegisterEHFramesId, void(TargetAddress Addr, uint32_t Size)>
|
||||||
void(TargetAddress Addr, uint32_t Size)>
|
|
||||||
RegisterEHFrames;
|
RegisterEHFrames;
|
||||||
|
|
||||||
typedef Function<ReserveMemId,
|
typedef Function<ReserveMemId,
|
||||||
TargetAddress(ResourceIdMgr::ResourceId AllocID,
|
TargetAddress(ResourceIdMgr::ResourceId AllocID,
|
||||||
uint64_t Size, uint32_t Align)>
|
uint64_t Size, uint32_t Align)>
|
||||||
ReserveMem;
|
ReserveMem;
|
||||||
|
|
||||||
typedef Function<RequestCompileId,
|
typedef Function<RequestCompileId,
|
||||||
TargetAddress(TargetAddress TrampolineAddr)>
|
TargetAddress(TargetAddress TrampolineAddr)>
|
||||||
RequestCompile;
|
RequestCompile;
|
||||||
|
|
||||||
typedef Function<SetProtectionsId,
|
typedef Function<SetProtectionsId,
|
||||||
void(ResourceIdMgr::ResourceId AllocID, TargetAddress Dst,
|
void(ResourceIdMgr::ResourceId AllocID, TargetAddress Dst,
|
||||||
uint32_t ProtFlags)>
|
uint32_t ProtFlags)>
|
||||||
SetProtections;
|
SetProtections;
|
||||||
|
|
||||||
typedef Function<TerminateSessionId, void()> TerminateSession;
|
typedef Function<TerminateSessionId, void()> TerminateSession;
|
||||||
|
|
||||||
typedef Function<WriteMemId, void(DirectBufferWriter DB)>
|
typedef Function<WriteMemId, void(DirectBufferWriter DB)> WriteMem;
|
||||||
WriteMem;
|
|
||||||
|
|
||||||
typedef Function<WritePtrId, void(TargetAddress Dst, TargetAddress Val)>
|
typedef Function<WritePtrId, void(TargetAddress Dst, TargetAddress Val)>
|
||||||
WritePtr;
|
WritePtr;
|
||||||
|
@ -327,25 +327,24 @@ template <typename ChannelT, typename FunctionIdT = uint32_t,
|
|||||||
typename SequenceNumberT = uint16_t>
|
typename SequenceNumberT = uint16_t>
|
||||||
class RPC : public RPCBase {
|
class RPC : public RPCBase {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// RPC default constructor.
|
/// RPC default constructor.
|
||||||
RPC() = default;
|
RPC() = default;
|
||||||
|
|
||||||
/// RPC instances cannot be copied.
|
/// RPC instances cannot be copied.
|
||||||
RPC(const RPC&) = delete;
|
RPC(const RPC &) = delete;
|
||||||
|
|
||||||
/// RPC instances cannot be copied.
|
/// RPC instances cannot be copied.
|
||||||
RPC& operator=(const RPC&) = delete;
|
RPC &operator=(const RPC &) = delete;
|
||||||
|
|
||||||
/// RPC move constructor.
|
/// RPC move constructor.
|
||||||
// FIXME: Remove once MSVC can synthesize move ops.
|
// FIXME: Remove once MSVC can synthesize move ops.
|
||||||
RPC(RPC &&Other)
|
RPC(RPC &&Other)
|
||||||
: SequenceNumberMgr(std::move(Other.SequenceNumberMgr)),
|
: SequenceNumberMgr(std::move(Other.SequenceNumberMgr)),
|
||||||
OutstandingResults(std::move(Other.OutstandingResults)) {}
|
OutstandingResults(std::move(Other.OutstandingResults)) {}
|
||||||
|
|
||||||
/// RPC move assignment.
|
/// RPC move assignment.
|
||||||
// FIXME: Remove once MSVC can synthesize move ops.
|
// FIXME: Remove once MSVC can synthesize move ops.
|
||||||
RPC& operator=(RPC &&Other) {
|
RPC &operator=(RPC &&Other) {
|
||||||
SequenceNumberMgr = std::move(Other.SequenceNumberMgr);
|
SequenceNumberMgr = std::move(Other.SequenceNumberMgr);
|
||||||
OutstandingResults = std::move(Other.OutstandingResults);
|
OutstandingResults = std::move(Other.OutstandingResults);
|
||||||
return *this;
|
return *this;
|
||||||
@ -408,7 +407,7 @@ public:
|
|||||||
createOutstandingResult<Func>(std::move(Promise));
|
createOutstandingResult<Func>(std::move(Promise));
|
||||||
|
|
||||||
if (auto Err = CallHelper<ChannelT, SequenceNumberT, Func>::call(C, SeqNo,
|
if (auto Err = CallHelper<ChannelT, SequenceNumberT, Func>::call(C, SeqNo,
|
||||||
Args...)) {
|
Args...)) {
|
||||||
abandonOutstandingResults();
|
abandonOutstandingResults();
|
||||||
return std::move(Err);
|
return std::move(Err);
|
||||||
} else
|
} else
|
||||||
@ -435,7 +434,7 @@ public:
|
|||||||
/// std::future<Optional<T>> (or a future<bool> for void functions).
|
/// std::future<Optional<T>> (or a future<bool> for void functions).
|
||||||
template <typename Func, typename... ArgTs>
|
template <typename Func, typename... ArgTs>
|
||||||
Expected<AsyncCallResult<Func>> appendCallAsync(ChannelT &C,
|
Expected<AsyncCallResult<Func>> appendCallAsync(ChannelT &C,
|
||||||
const ArgTs &... Args) {
|
const ArgTs &... Args) {
|
||||||
auto ResAndSeqOrErr = appendCallAsyncWithSeq<Func>(C, Args...);
|
auto ResAndSeqOrErr = appendCallAsyncWithSeq<Func>(C, Args...);
|
||||||
if (ResAndSeqOrErr)
|
if (ResAndSeqOrErr)
|
||||||
return std::move(ResAndSeqOrErr->first);
|
return std::move(ResAndSeqOrErr->first);
|
||||||
@ -445,7 +444,8 @@ public:
|
|||||||
/// The same as appendCallAsync, except that it calls C.send to flush the
|
/// The same as appendCallAsync, except that it calls C.send to flush the
|
||||||
/// channel after serializing the call.
|
/// channel after serializing the call.
|
||||||
template <typename Func, typename... ArgTs>
|
template <typename Func, typename... ArgTs>
|
||||||
Expected<AsyncCallResult<Func>> callAsync(ChannelT &C, const ArgTs &... Args) {
|
Expected<AsyncCallResult<Func>> callAsync(ChannelT &C,
|
||||||
|
const ArgTs &... Args) {
|
||||||
auto ResAndSeqOrErr = callAsyncWithSeq<Func>(C, Args...);
|
auto ResAndSeqOrErr = callAsyncWithSeq<Func>(C, Args...);
|
||||||
if (ResAndSeqOrErr)
|
if (ResAndSeqOrErr)
|
||||||
return std::move(ResAndSeqOrErr->first);
|
return std::move(ResAndSeqOrErr->first);
|
||||||
|
@ -7,8 +7,8 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "llvm/ADT/Triple.h"
|
|
||||||
#include "llvm/ExecutionEngine/Orc/OrcArchitectureSupport.h"
|
#include "llvm/ExecutionEngine/Orc/OrcArchitectureSupport.h"
|
||||||
|
#include "llvm/ADT/Triple.h"
|
||||||
#include "llvm/Support/Process.h"
|
#include "llvm/Support/Process.h"
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
@ -18,62 +18,62 @@ void OrcX86_64::writeResolverCode(uint8_t *ResolverMem, JITReentryFn ReentryFn,
|
|||||||
void *CallbackMgr) {
|
void *CallbackMgr) {
|
||||||
|
|
||||||
const uint8_t ResolverCode[] = {
|
const uint8_t ResolverCode[] = {
|
||||||
// resolver_entry:
|
// resolver_entry:
|
||||||
0x55, // 0x00: pushq %rbp
|
0x55, // 0x00: pushq %rbp
|
||||||
0x48, 0x89, 0xe5, // 0x01: movq %rsp, %rbp
|
0x48, 0x89, 0xe5, // 0x01: movq %rsp, %rbp
|
||||||
0x50, // 0x04: pushq %rax
|
0x50, // 0x04: pushq %rax
|
||||||
0x53, // 0x05: pushq %rbx
|
0x53, // 0x05: pushq %rbx
|
||||||
0x51, // 0x06: pushq %rcx
|
0x51, // 0x06: pushq %rcx
|
||||||
0x52, // 0x07: pushq %rdx
|
0x52, // 0x07: pushq %rdx
|
||||||
0x56, // 0x08: pushq %rsi
|
0x56, // 0x08: pushq %rsi
|
||||||
0x57, // 0x09: pushq %rdi
|
0x57, // 0x09: pushq %rdi
|
||||||
0x41, 0x50, // 0x0a: pushq %r8
|
0x41, 0x50, // 0x0a: pushq %r8
|
||||||
0x41, 0x51, // 0x0c: pushq %r9
|
0x41, 0x51, // 0x0c: pushq %r9
|
||||||
0x41, 0x52, // 0x0e: pushq %r10
|
0x41, 0x52, // 0x0e: pushq %r10
|
||||||
0x41, 0x53, // 0x10: pushq %r11
|
0x41, 0x53, // 0x10: pushq %r11
|
||||||
0x41, 0x54, // 0x12: pushq %r12
|
0x41, 0x54, // 0x12: pushq %r12
|
||||||
0x41, 0x55, // 0x14: pushq %r13
|
0x41, 0x55, // 0x14: pushq %r13
|
||||||
0x41, 0x56, // 0x16: pushq %r14
|
0x41, 0x56, // 0x16: pushq %r14
|
||||||
0x41, 0x57, // 0x18: pushq %r15
|
0x41, 0x57, // 0x18: pushq %r15
|
||||||
0x48, 0x81, 0xec, 0x08, 0x02, 0x00, 0x00, // 0x1a: subq 0x208, %rsp
|
0x48, 0x81, 0xec, 0x08, 0x02, 0x00, 0x00, // 0x1a: subq 0x208, %rsp
|
||||||
0x48, 0x0f, 0xae, 0x04, 0x24, // 0x21: fxsave64 (%rsp)
|
0x48, 0x0f, 0xae, 0x04, 0x24, // 0x21: fxsave64 (%rsp)
|
||||||
0x48, 0xbf, // 0x26: movabsq <CBMgr>, %rdi
|
0x48, 0xbf, // 0x26: movabsq <CBMgr>, %rdi
|
||||||
|
|
||||||
// 0x28: Callback manager addr.
|
// 0x28: Callback manager addr.
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
|
||||||
0x48, 0x8b, 0x75, 0x08, // 0x30: movq 8(%rbp), %rsi
|
0x48, 0x8b, 0x75, 0x08, // 0x30: movq 8(%rbp), %rsi
|
||||||
0x48, 0x83, 0xee, 0x06, // 0x34: subq $6, %rsi
|
0x48, 0x83, 0xee, 0x06, // 0x34: subq $6, %rsi
|
||||||
0x48, 0xb8, // 0x38: movabsq <REntry>, %rax
|
0x48, 0xb8, // 0x38: movabsq <REntry>, %rax
|
||||||
|
|
||||||
// 0x3a: JIT re-entry fn addr:
|
// 0x3a: JIT re-entry fn addr:
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
|
||||||
0xff, 0xd0, // 0x42: callq *%rax
|
0xff, 0xd0, // 0x42: callq *%rax
|
||||||
0x48, 0x89, 0x45, 0x08, // 0x44: movq %rax, 8(%rbp)
|
0x48, 0x89, 0x45, 0x08, // 0x44: movq %rax, 8(%rbp)
|
||||||
0x48, 0x0f, 0xae, 0x0c, 0x24, // 0x48: fxrstor64 (%rsp)
|
0x48, 0x0f, 0xae, 0x0c, 0x24, // 0x48: fxrstor64 (%rsp)
|
||||||
0x48, 0x81, 0xc4, 0x08, 0x02, 0x00, 0x00, // 0x4d: addq 0x208, %rsp
|
0x48, 0x81, 0xc4, 0x08, 0x02, 0x00, 0x00, // 0x4d: addq 0x208, %rsp
|
||||||
0x41, 0x5f, // 0x54: popq %r15
|
0x41, 0x5f, // 0x54: popq %r15
|
||||||
0x41, 0x5e, // 0x56: popq %r14
|
0x41, 0x5e, // 0x56: popq %r14
|
||||||
0x41, 0x5d, // 0x58: popq %r13
|
0x41, 0x5d, // 0x58: popq %r13
|
||||||
0x41, 0x5c, // 0x5a: popq %r12
|
0x41, 0x5c, // 0x5a: popq %r12
|
||||||
0x41, 0x5b, // 0x5c: popq %r11
|
0x41, 0x5b, // 0x5c: popq %r11
|
||||||
0x41, 0x5a, // 0x5e: popq %r10
|
0x41, 0x5a, // 0x5e: popq %r10
|
||||||
0x41, 0x59, // 0x60: popq %r9
|
0x41, 0x59, // 0x60: popq %r9
|
||||||
0x41, 0x58, // 0x62: popq %r8
|
0x41, 0x58, // 0x62: popq %r8
|
||||||
0x5f, // 0x64: popq %rdi
|
0x5f, // 0x64: popq %rdi
|
||||||
0x5e, // 0x65: popq %rsi
|
0x5e, // 0x65: popq %rsi
|
||||||
0x5a, // 0x66: popq %rdx
|
0x5a, // 0x66: popq %rdx
|
||||||
0x59, // 0x67: popq %rcx
|
0x59, // 0x67: popq %rcx
|
||||||
0x5b, // 0x68: popq %rbx
|
0x5b, // 0x68: popq %rbx
|
||||||
0x58, // 0x69: popq %rax
|
0x58, // 0x69: popq %rax
|
||||||
0x5d, // 0x6a: popq %rbp
|
0x5d, // 0x6a: popq %rbp
|
||||||
0xc3, // 0x6b: retq
|
0xc3, // 0x6b: retq
|
||||||
};
|
};
|
||||||
|
|
||||||
const unsigned ReentryFnAddrOffset = 0x3a;
|
const unsigned ReentryFnAddrOffset = 0x3a;
|
||||||
const unsigned CallbackMgrAddrOffset = 0x28;
|
const unsigned CallbackMgrAddrOffset = 0x28;
|
||||||
|
|
||||||
memcpy(ResolverMem, ResolverCode, sizeof(ResolverCode));
|
memcpy(ResolverMem, ResolverCode, sizeof(ResolverCode));
|
||||||
memcpy(ResolverMem + ReentryFnAddrOffset, &ReentryFn, sizeof(ReentryFn));
|
memcpy(ResolverMem + ReentryFnAddrOffset, &ReentryFn, sizeof(ReentryFn));
|
||||||
memcpy(ResolverMem + CallbackMgrAddrOffset, &CallbackMgr,
|
memcpy(ResolverMem + CallbackMgrAddrOffset, &CallbackMgr,
|
||||||
@ -81,13 +81,13 @@ void OrcX86_64::writeResolverCode(uint8_t *ResolverMem, JITReentryFn ReentryFn,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void OrcX86_64::writeTrampolines(uint8_t *TrampolineMem, void *ResolverAddr,
|
void OrcX86_64::writeTrampolines(uint8_t *TrampolineMem, void *ResolverAddr,
|
||||||
unsigned NumTrampolines) {
|
unsigned NumTrampolines) {
|
||||||
|
|
||||||
unsigned OffsetToPtr = NumTrampolines * TrampolineSize;
|
unsigned OffsetToPtr = NumTrampolines * TrampolineSize;
|
||||||
|
|
||||||
memcpy(TrampolineMem + OffsetToPtr, &ResolverAddr, sizeof(void*));
|
memcpy(TrampolineMem + OffsetToPtr, &ResolverAddr, sizeof(void *));
|
||||||
|
|
||||||
uint64_t *Trampolines = reinterpret_cast<uint64_t*>(TrampolineMem);
|
uint64_t *Trampolines = reinterpret_cast<uint64_t *>(TrampolineMem);
|
||||||
uint64_t CallIndirPCRel = 0xf1c40000000015ff;
|
uint64_t CallIndirPCRel = 0xf1c40000000015ff;
|
||||||
|
|
||||||
for (unsigned I = 0; I < NumTrampolines; ++I, OffsetToPtr -= TrampolineSize)
|
for (unsigned I = 0; I < NumTrampolines; ++I, OffsetToPtr -= TrampolineSize)
|
||||||
@ -126,36 +126,32 @@ Error OrcX86_64::emitIndirectStubsBlock(IndirectStubsInfo &StubsInfo,
|
|||||||
|
|
||||||
// Allocate memory for stubs and pointers in one call.
|
// Allocate memory for stubs and pointers in one call.
|
||||||
std::error_code EC;
|
std::error_code EC;
|
||||||
auto StubsMem =
|
auto StubsMem = sys::OwningMemoryBlock(sys::Memory::allocateMappedMemory(
|
||||||
sys::OwningMemoryBlock(
|
2 * NumPages * PageSize, nullptr,
|
||||||
sys::Memory::allocateMappedMemory(2 * NumPages * PageSize, nullptr,
|
sys::Memory::MF_READ | sys::Memory::MF_WRITE, EC));
|
||||||
sys::Memory::MF_READ |
|
|
||||||
sys::Memory::MF_WRITE,
|
|
||||||
EC));
|
|
||||||
|
|
||||||
if (EC)
|
if (EC)
|
||||||
return errorCodeToError(EC);
|
return errorCodeToError(EC);
|
||||||
|
|
||||||
// Create separate MemoryBlocks representing the stubs and pointers.
|
// Create separate MemoryBlocks representing the stubs and pointers.
|
||||||
sys::MemoryBlock StubsBlock(StubsMem.base(), NumPages * PageSize);
|
sys::MemoryBlock StubsBlock(StubsMem.base(), NumPages * PageSize);
|
||||||
sys::MemoryBlock PtrsBlock(static_cast<char*>(StubsMem.base()) +
|
sys::MemoryBlock PtrsBlock(static_cast<char *>(StubsMem.base()) +
|
||||||
NumPages * PageSize,
|
NumPages * PageSize,
|
||||||
NumPages * PageSize);
|
NumPages * PageSize);
|
||||||
|
|
||||||
// Populate the stubs page stubs and mark it executable.
|
// Populate the stubs page stubs and mark it executable.
|
||||||
uint64_t *Stub = reinterpret_cast<uint64_t*>(StubsBlock.base());
|
uint64_t *Stub = reinterpret_cast<uint64_t *>(StubsBlock.base());
|
||||||
uint64_t PtrOffsetField =
|
uint64_t PtrOffsetField = static_cast<uint64_t>(NumPages * PageSize - 6)
|
||||||
static_cast<uint64_t>(NumPages * PageSize - 6) << 16;
|
<< 16;
|
||||||
for (unsigned I = 0; I < NumStubs; ++I)
|
for (unsigned I = 0; I < NumStubs; ++I)
|
||||||
Stub[I] = 0xF1C40000000025ff | PtrOffsetField;
|
Stub[I] = 0xF1C40000000025ff | PtrOffsetField;
|
||||||
|
|
||||||
if (auto EC = sys::Memory::protectMappedMemory(StubsBlock,
|
if (auto EC = sys::Memory::protectMappedMemory(
|
||||||
sys::Memory::MF_READ |
|
StubsBlock, sys::Memory::MF_READ | sys::Memory::MF_EXEC))
|
||||||
sys::Memory::MF_EXEC))
|
|
||||||
return errorCodeToError(EC);
|
return errorCodeToError(EC);
|
||||||
|
|
||||||
// Initialize all pointers to point at FailureAddress.
|
// Initialize all pointers to point at FailureAddress.
|
||||||
void **Ptr = reinterpret_cast<void**>(PtrsBlock.base());
|
void **Ptr = reinterpret_cast<void **>(PtrsBlock.base());
|
||||||
for (unsigned I = 0; I < NumStubs; ++I)
|
for (unsigned I = 0; I < NumStubs; ++I)
|
||||||
Ptr[I] = InitialPtrVal;
|
Ptr[I] = InitialPtrVal;
|
||||||
|
|
||||||
@ -168,37 +164,38 @@ void OrcI386::writeResolverCode(uint8_t *ResolverMem, JITReentryFn ReentryFn,
|
|||||||
void *CallbackMgr) {
|
void *CallbackMgr) {
|
||||||
|
|
||||||
const uint8_t ResolverCode[] = {
|
const uint8_t ResolverCode[] = {
|
||||||
// resolver_entry:
|
// resolver_entry:
|
||||||
0x55, // 0x00: pushl %ebp
|
0x55, // 0x00: pushl %ebp
|
||||||
0x89, 0xe5, // 0x01: movl %esp, %ebp
|
0x89, 0xe5, // 0x01: movl %esp, %ebp
|
||||||
0x54, // 0x03: pushl %esp
|
0x54, // 0x03: pushl %esp
|
||||||
0x83, 0xe4, 0xf0, // 0x04: andl $-0x10, %esp
|
0x83, 0xe4, 0xf0, // 0x04: andl $-0x10, %esp
|
||||||
0x50, // 0x07: pushl %eax
|
0x50, // 0x07: pushl %eax
|
||||||
0x53, // 0x08: pushl %ebx
|
0x53, // 0x08: pushl %ebx
|
||||||
0x51, // 0x09: pushl %ecx
|
0x51, // 0x09: pushl %ecx
|
||||||
0x52, // 0x0a: pushl %edx
|
0x52, // 0x0a: pushl %edx
|
||||||
0x56, // 0x0b: pushl %esi
|
0x56, // 0x0b: pushl %esi
|
||||||
0x57, // 0x0c: pushl %edi
|
0x57, // 0x0c: pushl %edi
|
||||||
0x81, 0xec, 0x18, 0x02, 0x00, 0x00, // 0x0d: subl $0x218, %esp
|
0x81, 0xec, 0x18, 0x02, 0x00, 0x00, // 0x0d: subl $0x218, %esp
|
||||||
0x0f, 0xae, 0x44, 0x24, 0x10, // 0x13: fxsave 0x10(%esp)
|
0x0f, 0xae, 0x44, 0x24, 0x10, // 0x13: fxsave 0x10(%esp)
|
||||||
0x8b, 0x75, 0x04, // 0x18: movl 0x4(%ebp), %esi
|
0x8b, 0x75, 0x04, // 0x18: movl 0x4(%ebp), %esi
|
||||||
0x83, 0xee, 0x05, // 0x1b: subl $0x5, %esi
|
0x83, 0xee, 0x05, // 0x1b: subl $0x5, %esi
|
||||||
0x89, 0x74, 0x24, 0x04, // 0x1e: movl %esi, 0x4(%esp)
|
0x89, 0x74, 0x24, 0x04, // 0x1e: movl %esi, 0x4(%esp)
|
||||||
0xc7, 0x04, 0x24, 0x00, 0x00, 0x00, 0x00, // 0x22: movl <cbmgr>, (%esp)
|
0xc7, 0x04, 0x24, 0x00, 0x00, 0x00,
|
||||||
0xb8, 0x00, 0x00, 0x00, 0x00, // 0x29: movl <reentry>, %eax
|
0x00, // 0x22: movl <cbmgr>, (%esp)
|
||||||
0xff, 0xd0, // 0x2e: calll *%eax
|
0xb8, 0x00, 0x00, 0x00, 0x00, // 0x29: movl <reentry>, %eax
|
||||||
0x89, 0x45, 0x04, // 0x30: movl %eax, 0x4(%ebp)
|
0xff, 0xd0, // 0x2e: calll *%eax
|
||||||
0x0f, 0xae, 0x4c, 0x24, 0x10, // 0x33: fxrstor 0x10(%esp)
|
0x89, 0x45, 0x04, // 0x30: movl %eax, 0x4(%ebp)
|
||||||
0x81, 0xc4, 0x18, 0x02, 0x00, 0x00, // 0x38: addl $0x218, %esp
|
0x0f, 0xae, 0x4c, 0x24, 0x10, // 0x33: fxrstor 0x10(%esp)
|
||||||
0x5f, // 0x3e: popl %edi
|
0x81, 0xc4, 0x18, 0x02, 0x00, 0x00, // 0x38: addl $0x218, %esp
|
||||||
0x5e, // 0x3f: popl %esi
|
0x5f, // 0x3e: popl %edi
|
||||||
0x5a, // 0x40: popl %edx
|
0x5e, // 0x3f: popl %esi
|
||||||
0x59, // 0x41: popl %ecx
|
0x5a, // 0x40: popl %edx
|
||||||
0x5b, // 0x42: popl %ebx
|
0x59, // 0x41: popl %ecx
|
||||||
0x58, // 0x43: popl %eax
|
0x5b, // 0x42: popl %ebx
|
||||||
0x8b, 0x65, 0xfc, // 0x44: movl -0x4(%ebp), %esp
|
0x58, // 0x43: popl %eax
|
||||||
0x5d, // 0x48: popl %ebp
|
0x8b, 0x65, 0xfc, // 0x44: movl -0x4(%ebp), %esp
|
||||||
0xc3 // 0x49: retl
|
0x5d, // 0x48: popl %ebp
|
||||||
|
0xc3 // 0x49: retl
|
||||||
};
|
};
|
||||||
|
|
||||||
const unsigned ReentryFnAddrOffset = 0x2a;
|
const unsigned ReentryFnAddrOffset = 0x2a;
|
||||||
@ -216,16 +213,15 @@ void OrcI386::writeTrampolines(uint8_t *TrampolineMem, void *ResolverAddr,
|
|||||||
uint64_t CallRelImm = 0xF1C4C400000000e8;
|
uint64_t CallRelImm = 0xF1C4C400000000e8;
|
||||||
uint64_t Resolver = reinterpret_cast<uint64_t>(ResolverAddr);
|
uint64_t Resolver = reinterpret_cast<uint64_t>(ResolverAddr);
|
||||||
uint64_t ResolverRel =
|
uint64_t ResolverRel =
|
||||||
Resolver - reinterpret_cast<uint64_t>(TrampolineMem) - 5;
|
Resolver - reinterpret_cast<uint64_t>(TrampolineMem) - 5;
|
||||||
|
|
||||||
uint64_t *Trampolines = reinterpret_cast<uint64_t*>(TrampolineMem);
|
uint64_t *Trampolines = reinterpret_cast<uint64_t *>(TrampolineMem);
|
||||||
for (unsigned I = 0; I < NumTrampolines; ++I, ResolverRel -= TrampolineSize)
|
for (unsigned I = 0; I < NumTrampolines; ++I, ResolverRel -= TrampolineSize)
|
||||||
Trampolines[I] = CallRelImm | (ResolverRel << 8);
|
Trampolines[I] = CallRelImm | (ResolverRel << 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
Error OrcI386::emitIndirectStubsBlock(IndirectStubsInfo &StubsInfo,
|
Error OrcI386::emitIndirectStubsBlock(IndirectStubsInfo &StubsInfo,
|
||||||
unsigned MinStubs,
|
unsigned MinStubs, void *InitialPtrVal) {
|
||||||
void *InitialPtrVal) {
|
|
||||||
// Stub format is:
|
// Stub format is:
|
||||||
//
|
//
|
||||||
// .section __orc_stubs
|
// .section __orc_stubs
|
||||||
@ -255,35 +251,31 @@ Error OrcI386::emitIndirectStubsBlock(IndirectStubsInfo &StubsInfo,
|
|||||||
|
|
||||||
// Allocate memory for stubs and pointers in one call.
|
// Allocate memory for stubs and pointers in one call.
|
||||||
std::error_code EC;
|
std::error_code EC;
|
||||||
auto StubsMem =
|
auto StubsMem = sys::OwningMemoryBlock(sys::Memory::allocateMappedMemory(
|
||||||
sys::OwningMemoryBlock(
|
2 * NumPages * PageSize, nullptr,
|
||||||
sys::Memory::allocateMappedMemory(2 * NumPages * PageSize, nullptr,
|
sys::Memory::MF_READ | sys::Memory::MF_WRITE, EC));
|
||||||
sys::Memory::MF_READ |
|
|
||||||
sys::Memory::MF_WRITE,
|
|
||||||
EC));
|
|
||||||
|
|
||||||
if (EC)
|
if (EC)
|
||||||
return errorCodeToError(EC);
|
return errorCodeToError(EC);
|
||||||
|
|
||||||
// Create separate MemoryBlocks representing the stubs and pointers.
|
// Create separate MemoryBlocks representing the stubs and pointers.
|
||||||
sys::MemoryBlock StubsBlock(StubsMem.base(), NumPages * PageSize);
|
sys::MemoryBlock StubsBlock(StubsMem.base(), NumPages * PageSize);
|
||||||
sys::MemoryBlock PtrsBlock(static_cast<char*>(StubsMem.base()) +
|
sys::MemoryBlock PtrsBlock(static_cast<char *>(StubsMem.base()) +
|
||||||
NumPages * PageSize,
|
NumPages * PageSize,
|
||||||
NumPages * PageSize);
|
NumPages * PageSize);
|
||||||
|
|
||||||
// Populate the stubs page stubs and mark it executable.
|
// Populate the stubs page stubs and mark it executable.
|
||||||
uint64_t *Stub = reinterpret_cast<uint64_t*>(StubsBlock.base());
|
uint64_t *Stub = reinterpret_cast<uint64_t *>(StubsBlock.base());
|
||||||
uint64_t PtrAddr = reinterpret_cast<uint64_t>(PtrsBlock.base());
|
uint64_t PtrAddr = reinterpret_cast<uint64_t>(PtrsBlock.base());
|
||||||
for (unsigned I = 0; I < NumStubs; ++I, PtrAddr += 4)
|
for (unsigned I = 0; I < NumStubs; ++I, PtrAddr += 4)
|
||||||
Stub[I] = 0xF1C40000000025ff | (PtrAddr << 16);
|
Stub[I] = 0xF1C40000000025ff | (PtrAddr << 16);
|
||||||
|
|
||||||
if (auto EC = sys::Memory::protectMappedMemory(StubsBlock,
|
if (auto EC = sys::Memory::protectMappedMemory(
|
||||||
sys::Memory::MF_READ |
|
StubsBlock, sys::Memory::MF_READ | sys::Memory::MF_EXEC))
|
||||||
sys::Memory::MF_EXEC))
|
|
||||||
return errorCodeToError(EC);
|
return errorCodeToError(EC);
|
||||||
|
|
||||||
// Initialize all pointers to point at FailureAddress.
|
// Initialize all pointers to point at FailureAddress.
|
||||||
void **Ptr = reinterpret_cast<void**>(PtrsBlock.base());
|
void **Ptr = reinterpret_cast<void **>(PtrsBlock.base());
|
||||||
for (unsigned I = 0; I < NumStubs; ++I)
|
for (unsigned I = 0; I < NumStubs; ++I)
|
||||||
Ptr[I] = InitialPtrVal;
|
Ptr[I] = InitialPtrVal;
|
||||||
|
|
||||||
|
@ -19,11 +19,10 @@ LLVMOrcJITStackRef LLVMOrcCreateInstance(LLVMTargetMachineRef TM) {
|
|||||||
|
|
||||||
auto CompileCallbackMgr = OrcCBindingsStack::createCompileCallbackMgr(T);
|
auto CompileCallbackMgr = OrcCBindingsStack::createCompileCallbackMgr(T);
|
||||||
auto IndirectStubsMgrBuilder =
|
auto IndirectStubsMgrBuilder =
|
||||||
OrcCBindingsStack::createIndirectStubsMgrBuilder(T);
|
OrcCBindingsStack::createIndirectStubsMgrBuilder(T);
|
||||||
|
|
||||||
OrcCBindingsStack *JITStack =
|
OrcCBindingsStack *JITStack = new OrcCBindingsStack(
|
||||||
new OrcCBindingsStack(*TM2, std::move(CompileCallbackMgr),
|
*TM2, std::move(CompileCallbackMgr), IndirectStubsMgrBuilder);
|
||||||
IndirectStubsMgrBuilder);
|
|
||||||
|
|
||||||
return wrap(JITStack);
|
return wrap(JITStack);
|
||||||
}
|
}
|
||||||
@ -41,9 +40,7 @@ void LLVMOrcGetMangledSymbol(LLVMOrcJITStackRef JITStack, char **MangledName,
|
|||||||
strcpy(*MangledName, Mangled.c_str());
|
strcpy(*MangledName, Mangled.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void LLVMOrcDisposeMangledSymbol(char *MangledName) {
|
void LLVMOrcDisposeMangledSymbol(char *MangledName) { delete[] MangledName; }
|
||||||
delete[] MangledName;
|
|
||||||
}
|
|
||||||
|
|
||||||
LLVMOrcTargetAddress
|
LLVMOrcTargetAddress
|
||||||
LLVMOrcCreateLazyCompileCallback(LLVMOrcJITStackRef JITStack,
|
LLVMOrcCreateLazyCompileCallback(LLVMOrcJITStackRef JITStack,
|
||||||
|
@ -20,35 +20,36 @@ using namespace llvm;
|
|||||||
std::unique_ptr<OrcCBindingsStack::CompileCallbackMgr>
|
std::unique_ptr<OrcCBindingsStack::CompileCallbackMgr>
|
||||||
OrcCBindingsStack::createCompileCallbackMgr(Triple T) {
|
OrcCBindingsStack::createCompileCallbackMgr(Triple T) {
|
||||||
switch (T.getArch()) {
|
switch (T.getArch()) {
|
||||||
default: return nullptr;
|
default:
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
case Triple::x86: {
|
case Triple::x86: {
|
||||||
typedef orc::LocalJITCompileCallbackManager<orc::OrcI386> CCMgrT;
|
typedef orc::LocalJITCompileCallbackManager<orc::OrcI386> CCMgrT;
|
||||||
return llvm::make_unique<CCMgrT>(0);
|
return llvm::make_unique<CCMgrT>(0);
|
||||||
};
|
};
|
||||||
|
|
||||||
case Triple::x86_64: {
|
case Triple::x86_64: {
|
||||||
typedef orc::LocalJITCompileCallbackManager<orc::OrcX86_64> CCMgrT;
|
typedef orc::LocalJITCompileCallbackManager<orc::OrcX86_64> CCMgrT;
|
||||||
return llvm::make_unique<CCMgrT>(0);
|
return llvm::make_unique<CCMgrT>(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
OrcCBindingsStack::IndirectStubsManagerBuilder
|
OrcCBindingsStack::IndirectStubsManagerBuilder
|
||||||
OrcCBindingsStack::createIndirectStubsMgrBuilder(Triple T) {
|
OrcCBindingsStack::createIndirectStubsMgrBuilder(Triple T) {
|
||||||
switch (T.getArch()) {
|
switch (T.getArch()) {
|
||||||
default: return nullptr;
|
default:
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
case Triple::x86:
|
case Triple::x86:
|
||||||
return [](){
|
return []() {
|
||||||
return llvm::make_unique<
|
return llvm::make_unique<orc::LocalIndirectStubsManager<orc::OrcI386>>();
|
||||||
orc::LocalIndirectStubsManager<orc::OrcI386>>();
|
};
|
||||||
};
|
|
||||||
|
|
||||||
case Triple::x86_64:
|
case Triple::x86_64:
|
||||||
return [](){
|
return []() {
|
||||||
return llvm::make_unique<
|
return llvm::make_unique<
|
||||||
orc::LocalIndirectStubsManager<orc::OrcX86_64>>();
|
orc::LocalIndirectStubsManager<orc::OrcX86_64>>();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#ifndef LLVM_LIB_EXECUTIONENGINE_ORC_ORCCBINDINGSSTACK_H
|
#ifndef LLVM_LIB_EXECUTIONENGINE_ORC_ORCCBINDINGSSTACK_H
|
||||||
#define LLVM_LIB_EXECUTIONENGINE_ORC_ORCCBINDINGSSTACK_H
|
#define LLVM_LIB_EXECUTIONENGINE_ORC_ORCCBINDINGSSTACK_H
|
||||||
|
|
||||||
|
#include "llvm-c/OrcBindings.h"
|
||||||
#include "llvm/ADT/Triple.h"
|
#include "llvm/ADT/Triple.h"
|
||||||
#include "llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h"
|
#include "llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h"
|
||||||
#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
|
#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
|
||||||
@ -18,7 +19,6 @@
|
|||||||
#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
|
#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
|
||||||
#include "llvm/IR/LLVMContext.h"
|
#include "llvm/IR/LLVMContext.h"
|
||||||
#include "llvm/Support/Error.h"
|
#include "llvm/Support/Error.h"
|
||||||
#include "llvm-c/OrcBindings.h"
|
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
@ -29,19 +29,18 @@ DEFINE_SIMPLE_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef)
|
|||||||
|
|
||||||
class OrcCBindingsStack {
|
class OrcCBindingsStack {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
typedef orc::JITCompileCallbackManager CompileCallbackMgr;
|
typedef orc::JITCompileCallbackManager CompileCallbackMgr;
|
||||||
typedef orc::ObjectLinkingLayer<> ObjLayerT;
|
typedef orc::ObjectLinkingLayer<> ObjLayerT;
|
||||||
typedef orc::IRCompileLayer<ObjLayerT> CompileLayerT;
|
typedef orc::IRCompileLayer<ObjLayerT> CompileLayerT;
|
||||||
typedef orc::CompileOnDemandLayer<CompileLayerT, CompileCallbackMgr> CODLayerT;
|
typedef orc::CompileOnDemandLayer<CompileLayerT, CompileCallbackMgr>
|
||||||
|
CODLayerT;
|
||||||
|
|
||||||
typedef std::function<std::unique_ptr<CompileCallbackMgr>()>
|
typedef std::function<std::unique_ptr<CompileCallbackMgr>()>
|
||||||
CallbackManagerBuilder;
|
CallbackManagerBuilder;
|
||||||
|
|
||||||
typedef CODLayerT::IndirectStubsManagerBuilderT IndirectStubsManagerBuilder;
|
typedef CODLayerT::IndirectStubsManagerBuilderT IndirectStubsManagerBuilder;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
class GenericHandle {
|
class GenericHandle {
|
||||||
public:
|
public:
|
||||||
virtual ~GenericHandle() {}
|
virtual ~GenericHandle() {}
|
||||||
@ -50,20 +49,17 @@ private:
|
|||||||
virtual void removeModule() = 0;
|
virtual void removeModule() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename LayerT>
|
template <typename LayerT> class GenericHandleImpl : public GenericHandle {
|
||||||
class GenericHandleImpl : public GenericHandle {
|
|
||||||
public:
|
public:
|
||||||
GenericHandleImpl(LayerT &Layer, typename LayerT::ModuleSetHandleT Handle)
|
GenericHandleImpl(LayerT &Layer, typename LayerT::ModuleSetHandleT Handle)
|
||||||
: Layer(Layer), Handle(std::move(Handle)) {}
|
: Layer(Layer), Handle(std::move(Handle)) {}
|
||||||
|
|
||||||
orc::JITSymbol findSymbolIn(const std::string &Name,
|
orc::JITSymbol findSymbolIn(const std::string &Name,
|
||||||
bool ExportedSymbolsOnly) override {
|
bool ExportedSymbolsOnly) override {
|
||||||
return Layer.findSymbolIn(Handle, Name, ExportedSymbolsOnly);
|
return Layer.findSymbolIn(Handle, Name, ExportedSymbolsOnly);
|
||||||
}
|
}
|
||||||
|
|
||||||
void removeModule() override {
|
void removeModule() override { return Layer.removeModuleSet(Handle); }
|
||||||
return Layer.removeModuleSet(Handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
LayerT &Layer;
|
LayerT &Layer;
|
||||||
@ -78,7 +74,6 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// We need a 'ModuleSetHandleT' to conform to the layer concept.
|
// We need a 'ModuleSetHandleT' to conform to the layer concept.
|
||||||
typedef unsigned ModuleSetHandleT;
|
typedef unsigned ModuleSetHandleT;
|
||||||
|
|
||||||
@ -125,22 +120,20 @@ public:
|
|||||||
createLazyCompileCallback(LLVMOrcLazyCompileCallbackFn Callback,
|
createLazyCompileCallback(LLVMOrcLazyCompileCallbackFn Callback,
|
||||||
void *CallbackCtx) {
|
void *CallbackCtx) {
|
||||||
auto CCInfo = CCMgr->getCompileCallback();
|
auto CCInfo = CCMgr->getCompileCallback();
|
||||||
CCInfo.setCompileAction(
|
CCInfo.setCompileAction([=]() -> orc::TargetAddress {
|
||||||
[=]() -> orc::TargetAddress {
|
return Callback(wrap(this), CallbackCtx);
|
||||||
return Callback(wrap(this), CallbackCtx);
|
});
|
||||||
});
|
|
||||||
return CCInfo.getAddress();
|
return CCInfo.getAddress();
|
||||||
}
|
}
|
||||||
|
|
||||||
LLVMOrcErrorCode
|
LLVMOrcErrorCode createIndirectStub(StringRef StubName,
|
||||||
createIndirectStub(StringRef StubName, orc::TargetAddress Addr) {
|
orc::TargetAddress Addr) {
|
||||||
return mapError(
|
return mapError(
|
||||||
IndirectStubsMgr->createStub(StubName, Addr,
|
IndirectStubsMgr->createStub(StubName, Addr, JITSymbolFlags::Exported));
|
||||||
JITSymbolFlags::Exported));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LLVMOrcErrorCode
|
LLVMOrcErrorCode setIndirectStubPointer(StringRef Name,
|
||||||
setIndirectStubPointer(StringRef Name, orc::TargetAddress Addr) {
|
orc::TargetAddress Addr) {
|
||||||
return mapError(IndirectStubsMgr->updatePointer(Name, Addr));
|
return mapError(IndirectStubsMgr->updatePointer(Name, Addr));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,36 +141,33 @@ public:
|
|||||||
createResolver(LLVMOrcSymbolResolverFn ExternalResolver,
|
createResolver(LLVMOrcSymbolResolverFn ExternalResolver,
|
||||||
void *ExternalResolverCtx) {
|
void *ExternalResolverCtx) {
|
||||||
auto Resolver = orc::createLambdaResolver(
|
auto Resolver = orc::createLambdaResolver(
|
||||||
[this, ExternalResolver, ExternalResolverCtx](const std::string &Name) {
|
[this, ExternalResolver, ExternalResolverCtx](const std::string &Name) {
|
||||||
// Search order:
|
// Search order:
|
||||||
// 1. JIT'd symbols.
|
// 1. JIT'd symbols.
|
||||||
// 2. Runtime overrides.
|
// 2. Runtime overrides.
|
||||||
// 3. External resolver (if present).
|
// 3. External resolver (if present).
|
||||||
|
|
||||||
if (auto Sym = CODLayer.findSymbol(Name, true))
|
if (auto Sym = CODLayer.findSymbol(Name, true))
|
||||||
return RuntimeDyld::SymbolInfo(Sym.getAddress(),
|
return RuntimeDyld::SymbolInfo(Sym.getAddress(), Sym.getFlags());
|
||||||
Sym.getFlags());
|
if (auto Sym = CXXRuntimeOverrides.searchOverrides(Name))
|
||||||
if (auto Sym = CXXRuntimeOverrides.searchOverrides(Name))
|
return Sym;
|
||||||
return Sym;
|
|
||||||
|
|
||||||
if (ExternalResolver)
|
if (ExternalResolver)
|
||||||
return RuntimeDyld::SymbolInfo(ExternalResolver(Name.c_str(),
|
return RuntimeDyld::SymbolInfo(
|
||||||
ExternalResolverCtx),
|
ExternalResolver(Name.c_str(), ExternalResolverCtx),
|
||||||
llvm::JITSymbolFlags::Exported);
|
llvm::JITSymbolFlags::Exported);
|
||||||
|
|
||||||
return RuntimeDyld::SymbolInfo(nullptr);
|
return RuntimeDyld::SymbolInfo(nullptr);
|
||||||
},
|
},
|
||||||
[](const std::string &Name) {
|
[](const std::string &Name) {
|
||||||
return RuntimeDyld::SymbolInfo(nullptr);
|
return RuntimeDyld::SymbolInfo(nullptr);
|
||||||
}
|
});
|
||||||
);
|
|
||||||
|
|
||||||
return std::shared_ptr<RuntimeDyld::SymbolResolver>(std::move(Resolver));
|
return std::shared_ptr<RuntimeDyld::SymbolResolver>(std::move(Resolver));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename LayerT>
|
template <typename LayerT>
|
||||||
ModuleHandleT addIRModule(LayerT &Layer,
|
ModuleHandleT addIRModule(LayerT &Layer, Module *M,
|
||||||
Module *M,
|
|
||||||
std::unique_ptr<RuntimeDyld::MemoryManager> MemMgr,
|
std::unique_ptr<RuntimeDyld::MemoryManager> MemMgr,
|
||||||
LLVMOrcSymbolResolverFn ExternalResolver,
|
LLVMOrcSymbolResolverFn ExternalResolver,
|
||||||
void *ExternalResolverCtx) {
|
void *ExternalResolverCtx) {
|
||||||
@ -198,7 +188,7 @@ public:
|
|||||||
auto Resolver = createResolver(ExternalResolver, ExternalResolverCtx);
|
auto Resolver = createResolver(ExternalResolver, ExternalResolverCtx);
|
||||||
|
|
||||||
// Add the module to the JIT.
|
// Add the module to the JIT.
|
||||||
std::vector<Module*> S;
|
std::vector<Module *> S;
|
||||||
S.push_back(std::move(M));
|
S.push_back(std::move(M));
|
||||||
|
|
||||||
auto LH = Layer.addModuleSet(std::move(S), std::move(MemMgr),
|
auto LH = Layer.addModuleSet(std::move(S), std::move(MemMgr),
|
||||||
@ -215,7 +205,7 @@ public:
|
|||||||
return H;
|
return H;
|
||||||
}
|
}
|
||||||
|
|
||||||
ModuleHandleT addIRModuleEager(Module* M,
|
ModuleHandleT addIRModuleEager(Module *M,
|
||||||
LLVMOrcSymbolResolverFn ExternalResolver,
|
LLVMOrcSymbolResolverFn ExternalResolver,
|
||||||
void *ExternalResolverCtx) {
|
void *ExternalResolverCtx) {
|
||||||
return addIRModule(CompileLayer, std::move(M),
|
return addIRModule(CompileLayer, std::move(M),
|
||||||
@ -223,11 +213,11 @@ public:
|
|||||||
std::move(ExternalResolver), ExternalResolverCtx);
|
std::move(ExternalResolver), ExternalResolverCtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
ModuleHandleT addIRModuleLazy(Module* M,
|
ModuleHandleT addIRModuleLazy(Module *M,
|
||||||
LLVMOrcSymbolResolverFn ExternalResolver,
|
LLVMOrcSymbolResolverFn ExternalResolver,
|
||||||
void *ExternalResolverCtx) {
|
void *ExternalResolverCtx) {
|
||||||
return addIRModule(CODLayer, std::move(M),
|
return addIRModule(CODLayer, std::move(M),
|
||||||
llvm::make_unique<SectionMemoryManager>(),
|
llvm::make_unique<SectionMemoryManager>(),
|
||||||
std::move(ExternalResolver), ExternalResolverCtx);
|
std::move(ExternalResolver), ExternalResolverCtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -248,12 +238,9 @@ public:
|
|||||||
return GenericHandles[H]->findSymbolIn(Name, ExportedSymbolsOnly);
|
return GenericHandles[H]->findSymbolIn(Name, ExportedSymbolsOnly);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& getErrorMessage() const {
|
const std::string &getErrorMessage() const { return ErrMsg; }
|
||||||
return ErrMsg;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
template <typename LayerT>
|
template <typename LayerT>
|
||||||
unsigned createHandle(LayerT &Layer,
|
unsigned createHandle(LayerT &Layer,
|
||||||
typename LayerT::ModuleSetHandleT Handle) {
|
typename LayerT::ModuleSetHandleT Handle) {
|
||||||
@ -272,14 +259,13 @@ private:
|
|||||||
|
|
||||||
LLVMOrcErrorCode mapError(Error Err) {
|
LLVMOrcErrorCode mapError(Error Err) {
|
||||||
LLVMOrcErrorCode Result = LLVMOrcErrSuccess;
|
LLVMOrcErrorCode Result = LLVMOrcErrSuccess;
|
||||||
handleAllErrors(std::move(Err),
|
handleAllErrors(std::move(Err), [&](ErrorInfoBase &EIB) {
|
||||||
[&](ErrorInfoBase &EIB) {
|
// Handler of last resort.
|
||||||
// Handler of last resort.
|
Result = LLVMOrcErrGeneric;
|
||||||
Result = LLVMOrcErrGeneric;
|
ErrMsg = "";
|
||||||
ErrMsg = "";
|
raw_string_ostream ErrStream(ErrMsg);
|
||||||
raw_string_ostream ErrStream(ErrMsg);
|
EIB.log(ErrStream);
|
||||||
EIB.log(ErrStream);
|
});
|
||||||
});
|
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,8 +53,8 @@ namespace orc {
|
|||||||
|
|
||||||
Error orcError(OrcErrorCode ErrCode) {
|
Error orcError(OrcErrorCode ErrCode) {
|
||||||
typedef std::underlying_type<OrcErrorCode>::type UT;
|
typedef std::underlying_type<OrcErrorCode>::type UT;
|
||||||
return errorCodeToError(std::error_code(static_cast<UT>(ErrCode),
|
return errorCodeToError(
|
||||||
*OrcErrCat));
|
std::error_code(static_cast<UT>(ErrCode), *OrcErrCat));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,8 @@ namespace {
|
|||||||
|
|
||||||
class DummyCallbackManager : public orc::JITCompileCallbackManager {
|
class DummyCallbackManager : public orc::JITCompileCallbackManager {
|
||||||
public:
|
public:
|
||||||
DummyCallbackManager() : JITCompileCallbackManager(0) { }
|
DummyCallbackManager() : JITCompileCallbackManager(0) {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void grow() override { llvm_unreachable("not implemented"); }
|
void grow() override { llvm_unreachable("not implemented"); }
|
||||||
};
|
};
|
||||||
@ -26,7 +27,7 @@ public:
|
|||||||
class DummyStubsManager : public orc::IndirectStubsManager {
|
class DummyStubsManager : public orc::IndirectStubsManager {
|
||||||
public:
|
public:
|
||||||
Error createStub(StringRef StubName, TargetAddress InitAddr,
|
Error createStub(StringRef StubName, TargetAddress InitAddr,
|
||||||
JITSymbolFlags Flags) override {
|
JITSymbolFlags Flags) override {
|
||||||
llvm_unreachable("Not implemented");
|
llvm_unreachable("Not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,22 +43,20 @@ public:
|
|||||||
llvm_unreachable("Not implemented");
|
llvm_unreachable("Not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
Error updatePointer(StringRef Name,
|
Error updatePointer(StringRef Name, TargetAddress NewAddr) override {
|
||||||
TargetAddress NewAddr) override {
|
|
||||||
llvm_unreachable("Not implemented");
|
llvm_unreachable("Not implemented");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST(CompileOnDemandLayerTest, FindSymbol) {
|
TEST(CompileOnDemandLayerTest, FindSymbol) {
|
||||||
auto MockBaseLayer =
|
auto MockBaseLayer = createMockBaseLayer<int>(
|
||||||
createMockBaseLayer<int>(DoNothingAndReturn<int>(0),
|
DoNothingAndReturn<int>(0), DoNothingAndReturn<void>(),
|
||||||
DoNothingAndReturn<void>(),
|
[](const std::string &Name, bool) {
|
||||||
[](const std::string &Name, bool) {
|
if (Name == "foo")
|
||||||
if (Name == "foo")
|
return JITSymbol(1, JITSymbolFlags::Exported);
|
||||||
return JITSymbol(1, JITSymbolFlags::Exported);
|
return JITSymbol(nullptr);
|
||||||
return JITSymbol(nullptr);
|
},
|
||||||
},
|
DoNothingAndReturn<JITSymbol>(nullptr));
|
||||||
DoNothingAndReturn<JITSymbol>(nullptr));
|
|
||||||
|
|
||||||
typedef decltype(MockBaseLayer) MockBaseLayerT;
|
typedef decltype(MockBaseLayer) MockBaseLayerT;
|
||||||
DummyCallbackManager CallbackMgr;
|
DummyCallbackManager CallbackMgr;
|
||||||
@ -68,8 +67,7 @@ TEST(CompileOnDemandLayerTest, FindSymbol) {
|
|||||||
|
|
||||||
auto Sym = COD.findSymbol("foo", true);
|
auto Sym = COD.findSymbol("foo", true);
|
||||||
|
|
||||||
EXPECT_TRUE(!!Sym)
|
EXPECT_TRUE(!!Sym) << "CompileOnDemand::findSymbol should call findSymbol in "
|
||||||
<< "CompileOnDemand::findSymbol should call findSymbol in the base layer.";
|
"the base layer.";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,8 @@ using namespace llvm::orc::remote;
|
|||||||
|
|
||||||
class Queue : public std::queue<char> {
|
class Queue : public std::queue<char> {
|
||||||
public:
|
public:
|
||||||
std::mutex& getLock() { return Lock; }
|
std::mutex &getLock() { return Lock; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::mutex Lock;
|
std::mutex Lock;
|
||||||
};
|
};
|
||||||
@ -27,7 +28,7 @@ private:
|
|||||||
class QueueChannel : public RPCChannel {
|
class QueueChannel : public RPCChannel {
|
||||||
public:
|
public:
|
||||||
QueueChannel(Queue &InQueue, Queue &OutQueue)
|
QueueChannel(Queue &InQueue, Queue &OutQueue)
|
||||||
: InQueue(InQueue), OutQueue(OutQueue) {}
|
: InQueue(InQueue), OutQueue(OutQueue) {}
|
||||||
|
|
||||||
Error readBytes(char *Dst, unsigned Size) override {
|
Error readBytes(char *Dst, unsigned Size) override {
|
||||||
while (Size != 0) {
|
while (Size != 0) {
|
||||||
@ -60,10 +61,8 @@ private:
|
|||||||
Queue &OutQueue;
|
Queue &OutQueue;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DummyRPC : public testing::Test,
|
class DummyRPC : public testing::Test, public RPC<QueueChannel> {
|
||||||
public RPC<QueueChannel> {
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
enum FuncId : uint32_t {
|
enum FuncId : uint32_t {
|
||||||
VoidBoolId = RPCFunctionIdTraits<FuncId>::FirstValidId,
|
VoidBoolId = RPCFunctionIdTraits<FuncId>::FirstValidId,
|
||||||
IntIntId,
|
IntIntId,
|
||||||
@ -72,14 +71,12 @@ public:
|
|||||||
|
|
||||||
typedef Function<VoidBoolId, void(bool)> VoidBool;
|
typedef Function<VoidBoolId, void(bool)> VoidBool;
|
||||||
typedef Function<IntIntId, int32_t(int32_t)> IntInt;
|
typedef Function<IntIntId, int32_t(int32_t)> IntInt;
|
||||||
typedef Function<AllTheTypesId, void(int8_t, uint8_t, int16_t, uint16_t,
|
typedef Function<AllTheTypesId,
|
||||||
int32_t, uint32_t, int64_t, uint64_t,
|
void(int8_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t,
|
||||||
bool, std::string, std::vector<int>)>
|
int64_t, uint64_t, bool, std::string, std::vector<int>)>
|
||||||
AllTheTypes;
|
AllTheTypes;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
TEST_F(DummyRPC, TestAsyncVoidBool) {
|
TEST_F(DummyRPC, TestAsyncVoidBool) {
|
||||||
Queue Q1, Q2;
|
Queue Q1, Q2;
|
||||||
QueueChannel C1(Q1, Q2);
|
QueueChannel C1(Q1, Q2);
|
||||||
@ -91,12 +88,10 @@ TEST_F(DummyRPC, TestAsyncVoidBool) {
|
|||||||
|
|
||||||
{
|
{
|
||||||
// Expect a call to Proc1.
|
// Expect a call to Proc1.
|
||||||
auto EC = expect<VoidBool>(C2,
|
auto EC = expect<VoidBool>(C2, [&](bool &B) {
|
||||||
[&](bool &B) {
|
EXPECT_EQ(B, true) << "Bool serialization broken";
|
||||||
EXPECT_EQ(B, true)
|
return Error::success();
|
||||||
<< "Bool serialization broken";
|
});
|
||||||
return Error::success();
|
|
||||||
});
|
|
||||||
EXPECT_FALSE(EC) << "Simple expect over queue failed";
|
EXPECT_FALSE(EC) << "Simple expect over queue failed";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -122,12 +117,10 @@ TEST_F(DummyRPC, TestAsyncIntInt) {
|
|||||||
|
|
||||||
{
|
{
|
||||||
// Expect a call to Proc1.
|
// Expect a call to Proc1.
|
||||||
auto EC = expect<IntInt>(C2,
|
auto EC = expect<IntInt>(C2, [&](int32_t I) -> Expected<int32_t> {
|
||||||
[&](int32_t I) -> Expected<int32_t> {
|
EXPECT_EQ(I, 21) << "Bool serialization broken";
|
||||||
EXPECT_EQ(I, 21)
|
return 2 * I;
|
||||||
<< "Bool serialization broken";
|
});
|
||||||
return 2 * I;
|
|
||||||
});
|
|
||||||
EXPECT_FALSE(EC) << "Simple expect over queue failed";
|
EXPECT_FALSE(EC) << "Simple expect over queue failed";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,60 +143,32 @@ TEST_F(DummyRPC, TestSerialization) {
|
|||||||
|
|
||||||
// Make a call to Proc1.
|
// Make a call to Proc1.
|
||||||
std::vector<int> v({42, 7});
|
std::vector<int> v({42, 7});
|
||||||
auto ResOrErr = callAsyncWithSeq<AllTheTypes>(C1,
|
auto ResOrErr = callAsyncWithSeq<AllTheTypes>(
|
||||||
-101,
|
C1, -101, 250, -10000, 10000, -1000000000, 1000000000, -10000000000,
|
||||||
250,
|
10000000000, true, "foo", v);
|
||||||
-10000,
|
EXPECT_TRUE(!!ResOrErr) << "Big (serialization test) call over queue failed";
|
||||||
10000,
|
|
||||||
-1000000000,
|
|
||||||
1000000000,
|
|
||||||
-10000000000,
|
|
||||||
10000000000,
|
|
||||||
true,
|
|
||||||
"foo",
|
|
||||||
v);
|
|
||||||
EXPECT_TRUE(!!ResOrErr)
|
|
||||||
<< "Big (serialization test) call over queue failed";
|
|
||||||
|
|
||||||
{
|
{
|
||||||
// Expect a call to Proc1.
|
// Expect a call to Proc1.
|
||||||
auto EC = expect<AllTheTypes>(C2,
|
auto EC = expect<AllTheTypes>(
|
||||||
[&](int8_t &s8,
|
C2, [&](int8_t &s8, uint8_t &u8, int16_t &s16, uint16_t &u16,
|
||||||
uint8_t &u8,
|
int32_t &s32, uint32_t &u32, int64_t &s64, uint64_t &u64,
|
||||||
int16_t &s16,
|
bool &b, std::string &s, std::vector<int> &v) {
|
||||||
uint16_t &u16,
|
|
||||||
int32_t &s32,
|
|
||||||
uint32_t &u32,
|
|
||||||
int64_t &s64,
|
|
||||||
uint64_t &u64,
|
|
||||||
bool &b,
|
|
||||||
std::string &s,
|
|
||||||
std::vector<int> &v) {
|
|
||||||
|
|
||||||
EXPECT_EQ(s8, -101)
|
EXPECT_EQ(s8, -101) << "int8_t serialization broken";
|
||||||
<< "int8_t serialization broken";
|
EXPECT_EQ(u8, 250) << "uint8_t serialization broken";
|
||||||
EXPECT_EQ(u8, 250)
|
EXPECT_EQ(s16, -10000) << "int16_t serialization broken";
|
||||||
<< "uint8_t serialization broken";
|
EXPECT_EQ(u16, 10000) << "uint16_t serialization broken";
|
||||||
EXPECT_EQ(s16, -10000)
|
EXPECT_EQ(s32, -1000000000) << "int32_t serialization broken";
|
||||||
<< "int16_t serialization broken";
|
EXPECT_EQ(u32, 1000000000ULL) << "uint32_t serialization broken";
|
||||||
EXPECT_EQ(u16, 10000)
|
EXPECT_EQ(s64, -10000000000) << "int64_t serialization broken";
|
||||||
<< "uint16_t serialization broken";
|
EXPECT_EQ(u64, 10000000000ULL) << "uint64_t serialization broken";
|
||||||
EXPECT_EQ(s32, -1000000000)
|
EXPECT_EQ(b, true) << "bool serialization broken";
|
||||||
<< "int32_t serialization broken";
|
EXPECT_EQ(s, "foo") << "std::string serialization broken";
|
||||||
EXPECT_EQ(u32, 1000000000ULL)
|
EXPECT_EQ(v, std::vector<int>({42, 7}))
|
||||||
<< "uint32_t serialization broken";
|
<< "std::vector serialization broken";
|
||||||
EXPECT_EQ(s64, -10000000000)
|
return Error::success();
|
||||||
<< "int64_t serialization broken";
|
});
|
||||||
EXPECT_EQ(u64, 10000000000ULL)
|
|
||||||
<< "uint64_t serialization broken";
|
|
||||||
EXPECT_EQ(b, true)
|
|
||||||
<< "bool serialization broken";
|
|
||||||
EXPECT_EQ(s, "foo")
|
|
||||||
<< "std::string serialization broken";
|
|
||||||
EXPECT_EQ(v, std::vector<int>({42, 7}))
|
|
||||||
<< "std::vector serialization broken";
|
|
||||||
return Error::success();
|
|
||||||
});
|
|
||||||
EXPECT_FALSE(EC) << "Big (serialization test) call over queue failed";
|
EXPECT_FALSE(EC) << "Big (serialization test) call over queue failed";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user