[ORC] Errorize the ORC APIs.

This patch updates the ORC layers and utilities to return and propagate
llvm::Errors where appropriate. This is necessary to allow ORC to safely handle
error cases in cross-process and remote JITing.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@307350 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Lang Hames 2017-07-07 02:59:13 +00:00
parent d0585d352f
commit a81793582b
42 changed files with 566 additions and 277 deletions

View File

@ -75,8 +75,8 @@ public:
// Add the set to the JIT with the resolver we created above and a newly
// created SectionMemoryManager.
return CompileLayer.addModule(std::move(M),
std::move(Resolver));
return cantFail(CompileLayer.addModule(std::move(M),
std::move(Resolver)));
}
JITSymbol findSymbol(const std::string Name) {
@ -87,7 +87,7 @@ public:
}
void removeModule(ModuleHandle H) {
CompileLayer.removeModule(H);
cantFail(CompileLayer.removeModule(H));
}
};

View File

@ -1150,7 +1150,7 @@ static void HandleTopLevelExpression() {
// Get the symbol's address and cast it to the right type (takes no
// arguments, returns a double) so we can call it as a native function.
double (*FP)() = (double (*)())(intptr_t)ExprSymbol.getAddress();
double (*FP)() = (double (*)())(intptr_t)cantFail(ExprSymbol.getAddress());
fprintf(stderr, "Evaluated to %f\n", FP());
// Delete the anonymous expression module from the JIT.

View File

@ -88,8 +88,8 @@ public:
// Add the set to the JIT with the resolver we created above and a newly
// created SectionMemoryManager.
return OptimizeLayer.addModule(std::move(M),
std::move(Resolver));
return cantFail(OptimizeLayer.addModule(std::move(M),
std::move(Resolver)));
}
JITSymbol findSymbol(const std::string Name) {
@ -100,7 +100,7 @@ public:
}
void removeModule(ModuleHandle H) {
OptimizeLayer.removeModule(H);
cantFail(OptimizeLayer.removeModule(H));
}
private:

View File

@ -1150,7 +1150,7 @@ static void HandleTopLevelExpression() {
// Get the symbol's address and cast it to the right type (takes no
// arguments, returns a double) so we can call it as a native function.
double (*FP)() = (double (*)())(intptr_t)ExprSymbol.getAddress();
double (*FP)() = (double (*)())(intptr_t)cantFail(ExprSymbol.getAddress());
fprintf(stderr, "Evaluated to %f\n", FP());
// Delete the anonymous expression module from the JIT.

View File

@ -101,8 +101,7 @@ public:
// Add the set to the JIT with the resolver we created above and a newly
// created SectionMemoryManager.
return CODLayer.addModule(std::move(M),
std::move(Resolver));
return cantFail(CODLayer.addModule(std::move(M), std::move(Resolver)));
}
JITSymbol findSymbol(const std::string Name) {
@ -113,7 +112,7 @@ public:
}
void removeModule(ModuleHandle H) {
CODLayer.removeModule(H);
cantFail(CODLayer.removeModule(H));
}
private:

View File

@ -1150,7 +1150,7 @@ static void HandleTopLevelExpression() {
// Get the symbol's address and cast it to the right type (takes no
// arguments, returns a double) so we can call it as a native function.
double (*FP)() = (double (*)())(intptr_t)ExprSymbol.getAddress();
double (*FP)() = (double (*)())(intptr_t)cantFail(ExprSymbol.getAddress());
fprintf(stderr, "Evaluated to %f\n", FP());
// Delete the anonymous expression module from the JIT.

View File

@ -128,8 +128,8 @@ public:
// Add the set to the JIT with the resolver we created above and a newly
// created SectionMemoryManager.
return OptimizeLayer.addModule(std::move(M),
std::move(Resolver));
return cantFail(OptimizeLayer.addModule(std::move(M),
std::move(Resolver)));
}
Error addFunctionAST(std::unique_ptr<FunctionAST> FnAST) {
@ -175,7 +175,7 @@ public:
addModule(std::move(M));
auto Sym = findSymbol(SharedFnAST->getName() + "$impl");
assert(Sym && "Couldn't find compiled function?");
JITTargetAddress SymAddr = Sym.getAddress();
JITTargetAddress SymAddr = cantFail(Sym.getAddress());
if (auto Err =
IndirectStubsMgr->updatePointer(mangle(SharedFnAST->getName()),
SymAddr)) {
@ -195,7 +195,7 @@ public:
}
void removeModule(ModuleHandle H) {
OptimizeLayer.removeModule(H);
cantFail(OptimizeLayer.removeModule(H));
}
private:

View File

@ -1153,7 +1153,7 @@ static void HandleTopLevelExpression() {
// Get the symbol's address and cast it to the right type (takes no
// arguments, returns a double) so we can call it as a native function.
double (*FP)() = (double (*)())(intptr_t)ExprSymbol.getAddress();
double (*FP)() = (double (*)())(intptr_t)cantFail(ExprSymbol.getAddress());
fprintf(stderr, "Evaluated to %f\n", FP());
// Delete the anonymous expression module from the JIT.

View File

@ -157,8 +157,8 @@ public:
// Add the set to the JIT with the resolver we created above and a newly
// created SectionMemoryManager.
return OptimizeLayer.addModule(std::move(M),
std::move(Resolver));
return cantFail(OptimizeLayer.addModule(std::move(M),
std::move(Resolver)));
}
Error addFunctionAST(std::unique_ptr<FunctionAST> FnAST) {
@ -204,7 +204,7 @@ public:
addModule(std::move(M));
auto Sym = findSymbol(SharedFnAST->getName() + "$impl");
assert(Sym && "Couldn't find compiled function?");
JITTargetAddress SymAddr = Sym.getAddress();
JITTargetAddress SymAddr = cantFail(Sym.getAddress());
if (auto Err =
IndirectStubsMgr->updatePointer(mangle(SharedFnAST->getName()),
SymAddr)) {
@ -228,7 +228,7 @@ public:
}
void removeModule(ModuleHandle H) {
OptimizeLayer.removeModule(H);
cantFail(OptimizeLayer.removeModule(H));
}
private:

View File

@ -1177,7 +1177,7 @@ static void HandleTopLevelExpression() {
// Get the symbol's address and cast it to the right type (takes no
// arguments, returns a double) so we can call it as a native function.
ExitOnErr(TheJIT->executeRemoteExpr(ExprSymbol.getAddress()));
ExitOnErr(TheJIT->executeRemoteExpr(cantFail(ExprSymbol.getAddress())));
// Delete the anonymous expression module from the JIT.
TheJIT->removeModule(H);

View File

@ -611,7 +611,7 @@ static void HandleTopLevelExpression() {
// Get the symbol's address and cast it to the right type (takes no
// arguments, returns a double) so we can call it as a native function.
double (*FP)() = (double (*)())(intptr_t)ExprSymbol.getAddress();
double (*FP)() = (double (*)())(intptr_t)cantFail(ExprSymbol.getAddress());
fprintf(stderr, "Evaluated to %f\n", FP());
// Delete the anonymous expression module from the JIT.

View File

@ -885,7 +885,7 @@ static void HandleTopLevelExpression() {
// Get the symbol's address and cast it to the right type (takes no
// arguments, returns a double) so we can call it as a native function.
double (*FP)() = (double (*)())(intptr_t)ExprSymbol.getAddress();
double (*FP)() = (double (*)())(intptr_t)cantFail(ExprSymbol.getAddress());
fprintf(stderr, "Evaluated to %f\n", FP());
// Delete the anonymous expression module from the JIT.

View File

@ -1004,7 +1004,7 @@ static void HandleTopLevelExpression() {
// Get the symbol's address and cast it to the right type (takes no
// arguments, returns a double) so we can call it as a native function.
double (*FP)() = (double (*)())(intptr_t)ExprSymbol.getAddress();
double (*FP)() = (double (*)())(intptr_t)cantFail(ExprSymbol.getAddress());
fprintf(stderr, "Evaluated to %f\n", FP());
// Delete the anonymous expression module from the JIT.

View File

@ -1173,7 +1173,7 @@ static void HandleTopLevelExpression() {
// Get the symbol's address and cast it to the right type (takes no
// arguments, returns a double) so we can call it as a native function.
double (*FP)() = (double (*)())(intptr_t)ExprSymbol.getAddress();
double (*FP)() = (double (*)())(intptr_t)cantFail(ExprSymbol.getAddress());
fprintf(stderr, "Evaluated to %f\n", FP());
// Delete the anonymous expression module from the JIT.

View File

@ -63,8 +63,8 @@ public:
return JITSymbol(nullptr);
},
[](const std::string &S) { return nullptr; });
auto H = CompileLayer.addModule(std::move(M),
std::move(Resolver));
auto H = cantFail(CompileLayer.addModule(std::move(M),
std::move(Resolver)));
ModuleHandles.push_back(H);
return H;
@ -72,7 +72,7 @@ public:
void removeModule(ModuleHandleT H) {
ModuleHandles.erase(find(ModuleHandles, H));
CompileLayer.removeModule(H);
cantFail(CompileLayer.removeModule(H));
}
JITSymbol findSymbol(const std::string Name) {

View File

@ -113,8 +113,9 @@ void LLVMOrcDisposeMangledSymbol(char *MangledSymbol);
/**
* Create a lazy compile callback.
*/
LLVMOrcTargetAddress
LLVMOrcErrorCode
LLVMOrcCreateLazyCompileCallback(LLVMOrcJITStackRef JITStack,
LLVMOrcTargetAddress *RetAddr,
LLVMOrcLazyCompileCallbackFn Callback,
void *CallbackCtx);
@ -135,8 +136,9 @@ LLVMOrcErrorCode LLVMOrcSetIndirectStubPointer(LLVMOrcJITStackRef JITStack,
/**
* Add module to be eagerly compiled.
*/
LLVMOrcModuleHandle
LLVMOrcErrorCode
LLVMOrcAddEagerlyCompiledIR(LLVMOrcJITStackRef JITStack,
LLVMOrcModuleHandle *RetHandle,
LLVMSharedModuleRef Mod,
LLVMOrcSymbolResolverFn SymbolResolver,
void *SymbolResolverCtx);
@ -144,8 +146,9 @@ LLVMOrcAddEagerlyCompiledIR(LLVMOrcJITStackRef JITStack,
/**
* Add module to be lazily compiled one function at a time.
*/
LLVMOrcModuleHandle
LLVMOrcErrorCode
LLVMOrcAddLazilyCompiledIR(LLVMOrcJITStackRef JITStack,
LLVMOrcModuleHandle *RetHandle,
LLVMSharedModuleRef Mod,
LLVMOrcSymbolResolverFn SymbolResolver,
void *SymbolResolverCtx);
@ -153,10 +156,11 @@ LLVMOrcAddLazilyCompiledIR(LLVMOrcJITStackRef JITStack,
/**
* Add an object file.
*/
LLVMOrcModuleHandle LLVMOrcAddObjectFile(LLVMOrcJITStackRef JITStack,
LLVMSharedObjectBufferRef Obj,
LLVMOrcSymbolResolverFn SymbolResolver,
void *SymbolResolverCtx);
LLVMOrcErrorCode LLVMOrcAddObjectFile(LLVMOrcJITStackRef JITStack,
LLVMOrcModuleHandle *RetHandle,
LLVMSharedObjectBufferRef Obj,
LLVMOrcSymbolResolverFn SymbolResolver,
void *SymbolResolverCtx);
/**
* Remove a module set from the JIT.
@ -164,18 +168,20 @@ LLVMOrcModuleHandle LLVMOrcAddObjectFile(LLVMOrcJITStackRef JITStack,
* This works for all modules that can be added via OrcAdd*, including object
* files.
*/
void LLVMOrcRemoveModule(LLVMOrcJITStackRef JITStack, LLVMOrcModuleHandle H);
LLVMOrcErrorCode LLVMOrcRemoveModule(LLVMOrcJITStackRef JITStack,
LLVMOrcModuleHandle H);
/**
* Get symbol address from JIT instance.
*/
LLVMOrcTargetAddress LLVMOrcGetSymbolAddress(LLVMOrcJITStackRef JITStack,
const char *SymbolName);
LLVMOrcErrorCode LLVMOrcGetSymbolAddress(LLVMOrcJITStackRef JITStack,
LLVMOrcTargetAddress *RetAddr,
const char *SymbolName);
/**
* Dispose of an ORC JIT stack.
*/
void LLVMOrcDisposeInstance(LLVMOrcJITStackRef JITStack);
LLVMOrcErrorCode LLVMOrcDisposeInstance(LLVMOrcJITStackRef JITStack);
#ifdef __cplusplus
}

View File

@ -21,6 +21,8 @@
#include <functional>
#include <string>
#include "llvm/Support/Error.h"
namespace llvm {
class GlobalValue;
@ -41,10 +43,11 @@ public:
enum FlagNames : UnderlyingType {
None = 0,
Weak = 1U << 0,
Common = 1U << 1,
Absolute = 1U << 2,
Exported = 1U << 3
HasError = 1U << 0,
Weak = 1U << 1,
Common = 1U << 2,
Absolute = 1U << 3,
Exported = 1U << 4
};
/// @brief Default-construct a JITSymbolFlags instance.
@ -53,6 +56,11 @@ public:
/// @brief Construct a JITSymbolFlags instance from the given flags.
JITSymbolFlags(FlagNames Flags) : Flags(Flags) {}
/// @brief Return true if there was an error retrieving this symbol.
bool hasError() const {
return (Flags & HasError) == HasError;
}
/// @brief Returns true is the Weak flag is set.
bool isWeak() const {
return (Flags & Weak) == Weak;
@ -113,11 +121,17 @@ private:
/// @brief Represents a symbol in the JIT.
class JITSymbol {
public:
using GetAddressFtor = std::function<JITTargetAddress()>;
using GetAddressFtor = std::function<Expected<JITTargetAddress>()>;
/// @brief Create a 'null' symbol that represents failure to find a symbol
/// definition.
JITSymbol(std::nullptr_t) {}
/// @brief Create a 'null' symbol, used to represent a "symbol not found"
/// result from a successful (non-erroneous) lookup.
JITSymbol(std::nullptr_t)
: CachedAddr(0) {}
/// @brief Create a JITSymbol representing an error in the symbol lookup
/// process (e.g. a network failure during a remote lookup).
JITSymbol(Error Err)
: Err(std::move(Err)), Flags(JITSymbolFlags::HasError) {}
/// @brief Create a symbol for a definition with a known address.
JITSymbol(JITTargetAddress Addr, JITSymbolFlags Flags)
@ -139,16 +153,57 @@ public:
JITSymbol(GetAddressFtor GetAddress, JITSymbolFlags Flags)
: GetAddress(std::move(GetAddress)), Flags(Flags) {}
JITSymbol(const JITSymbol&) = delete;
JITSymbol& operator=(const JITSymbol&) = delete;
JITSymbol(JITSymbol &&Other)
: GetAddress(std::move(Other.GetAddress)), Flags(std::move(Other.Flags)) {
if (Flags.hasError())
Err = std::move(Other.Err);
else
CachedAddr = std::move(Other.CachedAddr);
}
JITSymbol& operator=(JITSymbol &&Other) {
GetAddress = std::move(Other.GetAddress);
Flags = std::move(Other.Flags);
if (Flags.hasError())
Err = std::move(Other.Err);
else
CachedAddr = std::move(Other.CachedAddr);
return *this;
}
~JITSymbol() {
if (Flags.hasError())
Err.~Error();
else
CachedAddr.~JITTargetAddress();
}
/// @brief Returns true if the symbol exists, false otherwise.
explicit operator bool() const { return CachedAddr || GetAddress; }
explicit operator bool() const {
return !Flags.hasError() && (CachedAddr || GetAddress);
}
/// @brief Move the error field value out of this JITSymbol.
Error takeError() {
if (Flags.hasError())
return std::move(Err);
return Error::success();
}
/// @brief Get the address of the symbol in the target address space. Returns
/// '0' if the symbol does not exist.
JITTargetAddress getAddress() {
Expected<JITTargetAddress> getAddress() {
assert(!Flags.hasError() && "getAddress called on error value");
if (GetAddress) {
CachedAddr = GetAddress();
assert(CachedAddr && "Symbol could not be materialized.");
GetAddress = nullptr;
if (auto CachedAddrOrErr = GetAddress()) {
GetAddress = nullptr;
CachedAddr = *CachedAddrOrErr;
assert(CachedAddr && "Symbol could not be materialized.");
} else
return CachedAddrOrErr.takeError();
}
return CachedAddr;
}
@ -157,7 +212,10 @@ public:
private:
GetAddressFtor GetAddress;
JITTargetAddress CachedAddr = 0;
union {
JITTargetAddress CachedAddr;
Error Err;
};
JITSymbolFlags Flags;
};

View File

@ -176,12 +176,16 @@ private:
for (auto BLH : BaseLayerHandles)
if (auto Sym = BaseLayer.findSymbolIn(BLH, Name, ExportedSymbolsOnly))
return Sym;
else if (auto Err = Sym.takeError())
return std::move(Err);
return nullptr;
}
void removeModulesFromBaseLayer(BaseLayerT &BaseLayer) {
Error removeModulesFromBaseLayer(BaseLayerT &BaseLayer) {
for (auto &BLH : BaseLayerHandles)
BaseLayer.removeModule(BLH);
if (auto Err = BaseLayer.removeModule(BLH))
return Err;
return Error::success();
}
std::shared_ptr<JITSymbolResolver> ExternalSymbolResolver;
@ -216,13 +220,15 @@ public:
CloneStubsIntoPartitions(CloneStubsIntoPartitions) {}
~CompileOnDemandLayer() {
// FIXME: Report error on log.
while (!LogicalDylibs.empty())
removeModule(LogicalDylibs.begin());
consumeError(removeModule(LogicalDylibs.begin()));
}
/// @brief Add a module to the compile-on-demand layer.
ModuleHandleT addModule(std::shared_ptr<Module> M,
std::shared_ptr<JITSymbolResolver> Resolver) {
Expected<ModuleHandleT>
addModule(std::shared_ptr<Module> M,
std::shared_ptr<JITSymbolResolver> Resolver) {
LogicalDylibs.push_back(LogicalDylib());
auto &LD = LogicalDylibs.back();
@ -230,23 +236,25 @@ public:
LD.StubsMgr = CreateIndirectStubsManager();
// Process each of the modules in this module set.
addLogicalModule(LD, std::move(M));
if (auto Err = addLogicalModule(LD, std::move(M)))
return std::move(Err);
return std::prev(LogicalDylibs.end());
}
/// @brief Add extra modules to an existing logical module.
void addExtraModule(ModuleHandleT H, std::shared_ptr<Module> M) {
addLogicalModule(*H, std::move(M));
Error addExtraModule(ModuleHandleT H, std::shared_ptr<Module> M) {
return addLogicalModule(*H, std::move(M));
}
/// @brief Remove the module represented by the given handle.
///
/// This will remove all modules in the layers below that were derived from
/// the module represented by H.
void removeModule(ModuleHandleT H) {
H->removeModulesFromBaseLayer(BaseLayer);
Error removeModule(ModuleHandleT H) {
auto Err = H->removeModulesFromBaseLayer(BaseLayer);
LogicalDylibs.erase(H);
return Err;
}
/// @brief Search for the given named symbol.
@ -260,6 +268,8 @@ public:
return Sym;
if (auto Sym = findSymbolIn(LDI, Name, ExportedSymbolsOnly))
return Sym;
else if (auto Err = Sym.takeError())
return std::move(Err);
}
return BaseLayer.findSymbol(Name, ExportedSymbolsOnly);
}
@ -298,7 +308,7 @@ public:
private:
void addLogicalModule(LogicalDylib &LD, std::shared_ptr<Module> SrcMPtr) {
Error addLogicalModule(LogicalDylib &LD, std::shared_ptr<Module> SrcMPtr) {
// Rename all static functions / globals to $static.X :
// This will unique the names across all modules in the logical dylib,
@ -324,9 +334,12 @@ private:
// Skip weak functions for which we already have definitions.
auto MangledName = mangle(F.getName(), DL);
if (F.hasWeakLinkage() || F.hasLinkOnceLinkage())
if (F.hasWeakLinkage() || F.hasLinkOnceLinkage()) {
if (auto Sym = LD.findSymbol(BaseLayer, MangledName, false))
continue;
else if (auto Err = Sym.takeError())
return std::move(Err);
}
// Record all functions defined by this module.
if (CloneStubsIntoPartitions)
@ -339,9 +352,15 @@ private:
StubInits[MangledName] =
std::make_pair(CCInfo.getAddress(),
JITSymbolFlags::fromGlobalValue(F));
CCInfo.setCompileAction([this, &LD, LMId, &F]() {
return this->extractAndCompile(LD, LMId, F);
});
CCInfo.setCompileAction([this, &LD, LMId, &F]() -> JITTargetAddress {
if (auto FnImplAddrOrErr = this->extractAndCompile(LD, LMId, F))
return *FnImplAddrOrErr;
else {
// FIXME: Report error, return to 'abort' or something similar.
consumeError(FnImplAddrOrErr.takeError());
return 0;
}
});
}
auto EC = LD.StubsMgr->createStubs(StubInits);
@ -356,7 +375,7 @@ private:
// empty globals module.
if (SrcM.global_empty() && SrcM.alias_empty() &&
!SrcM.getModuleFlagsMetadata())
return;
return Error::success();
// Create the GlobalValues module.
auto GVsM = llvm::make_unique<Module>((SrcM.getName() + ".globals").str(),
@ -382,8 +401,9 @@ private:
// Initializers may refer to functions declared (but not defined) in this
// module. Build a materializer to clone decls on demand.
Error MaterializerErrors = Error::success();
auto Materializer = createLambdaMaterializer(
[&LD, &GVsM](Value *V) -> Value* {
[&LD, &GVsM, &MaterializerErrors](Value *V) -> Value* {
if (auto *F = dyn_cast<Function>(V)) {
// Decls in the original module just get cloned.
if (F->isDeclaration())
@ -394,13 +414,24 @@ private:
// instead.
const DataLayout &DL = GVsM->getDataLayout();
std::string FName = mangle(F->getName(), DL);
auto StubSym = LD.StubsMgr->findStub(FName, false);
unsigned PtrBitWidth = DL.getPointerTypeSizeInBits(F->getType());
ConstantInt *StubAddr =
ConstantInt::get(GVsM->getContext(),
APInt(PtrBitWidth, StubSym.getAddress()));
JITTargetAddress StubAddr = 0;
// Get the address for the stub. If we encounter an error while
// doing so, stash it in the MaterializerErrors variable and use a
// null address as a placeholder.
if (auto StubSym = LD.StubsMgr->findStub(FName, false)) {
if (auto StubAddrOrErr = StubSym.getAddress())
StubAddr = *StubAddrOrErr;
else
MaterializerErrors = joinErrors(std::move(MaterializerErrors),
StubAddrOrErr.takeError());
}
ConstantInt *StubAddrCI =
ConstantInt::get(GVsM->getContext(), APInt(PtrBitWidth, StubAddr));
Constant *Init = ConstantExpr::getCast(Instruction::IntToPtr,
StubAddr, F->getType());
StubAddrCI, F->getType());
return GlobalAlias::create(F->getFunctionType(),
F->getType()->getAddressSpace(),
F->getLinkage(), F->getName(),
@ -424,21 +455,31 @@ private:
NewA->setAliasee(cast<Constant>(Init));
}
if (MaterializerErrors)
return MaterializerErrors;
// Build a resolver for the globals module and add it to the base layer.
auto GVsResolver = createLambdaResolver(
[this, &LD](const std::string &Name) {
[this, &LD](const std::string &Name) -> JITSymbol {
if (auto Sym = LD.StubsMgr->findStub(Name, false))
return Sym;
if (auto Sym = LD.findSymbol(BaseLayer, Name, false))
return Sym;
else if (auto Err = Sym.takeError())
return std::move(Err);
return LD.ExternalSymbolResolver->findSymbolInLogicalDylib(Name);
},
[&LD](const std::string &Name) {
return LD.ExternalSymbolResolver->findSymbol(Name);
});
auto GVsH = BaseLayer.addModule(std::move(GVsM), std::move(GVsResolver));
LD.BaseLayerHandles.push_back(GVsH);
if (auto GVsHOrErr =
BaseLayer.addModule(std::move(GVsM), std::move(GVsResolver)))
LD.BaseLayerHandles.push_back(*GVsHOrErr);
else
return GVsHOrErr.takeError();
return Error::success();
}
static std::string mangle(StringRef Name, const DataLayout &DL) {
@ -450,7 +491,7 @@ private:
return MangledName;
}
JITTargetAddress
Expected<JITTargetAddress>
extractAndCompile(LogicalDylib &LD,
typename LogicalDylib::SourceModuleHandle LMId,
Function &F) {
@ -463,34 +504,42 @@ private:
// Grab the name of the function being called here.
std::string CalledFnName = mangle(F.getName(), SrcM.getDataLayout());
auto Part = Partition(F);
auto PartH = emitPartition(LD, LMId, Part);
JITTargetAddress CalledAddr = 0;
for (auto *SubF : Part) {
std::string FnName = mangle(SubF->getName(), SrcM.getDataLayout());
auto FnBodySym = BaseLayer.findSymbolIn(PartH, FnName, false);
assert(FnBodySym && "Couldn't find function body.");
auto Part = Partition(F);
if (auto PartHOrErr = emitPartition(LD, LMId, Part)) {
auto &PartH = *PartHOrErr;
for (auto *SubF : Part) {
std::string FnName = mangle(SubF->getName(), SrcM.getDataLayout());
if (auto FnBodySym = BaseLayer.findSymbolIn(PartH, FnName, false)) {
if (auto FnBodyAddrOrErr = FnBodySym.getAddress()) {
JITTargetAddress FnBodyAddr = *FnBodyAddrOrErr;
JITTargetAddress FnBodyAddr = FnBodySym.getAddress();
// If this is the function we're calling record the address so we can
// return it from this function.
if (SubF == &F)
CalledAddr = FnBodyAddr;
// If this is the function we're calling record the address so we can
// return it from this function.
if (SubF == &F)
CalledAddr = FnBodyAddr;
// Update the function body pointer for the stub.
if (auto EC = LD.StubsMgr->updatePointer(FnName, FnBodyAddr))
return 0;
// Update the function body pointer for the stub.
if (auto EC = LD.StubsMgr->updatePointer(FnName, FnBodyAddr))
return 0;
}
} else
return FnBodyAddrOrErr.takeError();
} else if (auto Err = FnBodySym.takeError())
return std::move(Err);
else
llvm_unreachable("Function not emitted for partition");
}
LD.BaseLayerHandles.push_back(PartH);
LD.BaseLayerHandles.push_back(PartH);
} else
return PartHOrErr.takeError();
return CalledAddr;
}
template <typename PartitionT>
BaseLayerModuleHandleT
Expected<BaseLayerModuleHandleT>
emitPartition(LogicalDylib &LD,
typename LogicalDylib::SourceModuleHandle LMId,
const PartitionT &Part) {
@ -554,9 +603,11 @@ private:
// Create memory manager and symbol resolver.
auto Resolver = createLambdaResolver(
[this, &LD](const std::string &Name) {
[this, &LD](const std::string &Name) -> JITSymbol {
if (auto Sym = LD.findSymbol(BaseLayer, Name, false))
return Sym;
else if (auto Err = Sym.takeError())
return std::move(Err);
return LD.ExternalSymbolResolver->findSymbolInLogicalDylib(Name);
},
[&LD](const std::string &Name) {

View File

@ -17,6 +17,8 @@
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/ExecutionEngine/JITSymbol.h"
#include "llvm/ExecutionEngine/RuntimeDyld.h"
#include "llvm/ExecutionEngine/Orc/OrcError.h"
#include <algorithm>
#include <cstdint>
#include <string>
@ -99,19 +101,24 @@ public:
/// @brief Run the recorded constructors/destructors through the given JIT
/// layer.
bool runViaLayer(JITLayerT &JITLayer) const {
Error runViaLayer(JITLayerT &JITLayer) const {
using CtorDtorTy = void (*)();
bool Error = false;
for (const auto &CtorDtorName : CtorDtorNames)
if (auto CtorDtorSym = JITLayer.findSymbolIn(H, CtorDtorName, false)) {
CtorDtorTy CtorDtor =
reinterpret_cast<CtorDtorTy>(
static_cast<uintptr_t>(CtorDtorSym.getAddress()));
CtorDtor();
} else
Error = true;
return !Error;
if (auto AddrOrErr = CtorDtorSym.getAddress()) {
CtorDtorTy CtorDtor =
reinterpret_cast<CtorDtorTy>(static_cast<uintptr_t>(*AddrOrErr));
CtorDtor();
} else
return AddrOrErr.takeError();
} else {
if (auto Err = CtorDtorSym.takeError())
return Err;
else
return make_error<JITSymbolNotFound>(CtorDtorName);
}
return Error::success();
}
private:

View File

@ -50,15 +50,18 @@ public:
/// along with the given memory manager and symbol resolver.
///
/// @return A handle for the added module.
ModuleHandleT addModule(std::shared_ptr<Module> M,
std::shared_ptr<JITSymbolResolver> Resolver) {
Expected<ModuleHandleT>
addModule(std::shared_ptr<Module> M,
std::shared_ptr<JITSymbolResolver> Resolver) {
using CompileResult = decltype(Compile(*M));
auto Obj = std::make_shared<CompileResult>(Compile(*M));
return BaseLayer.addObject(std::move(Obj), std::move(Resolver));
}
/// @brief Remove the module associated with the handle H.
void removeModule(ModuleHandleT H) { BaseLayer.removeObject(H); }
Error removeModule(ModuleHandleT H) {
return BaseLayer.removeObject(H);
}
/// @brief Search for the given named symbol.
/// @param Name The name of the symbol to search for.
@ -84,8 +87,8 @@ public:
/// @brief Immediately emit and finalize the module represented by the given
/// handle.
/// @param H Handle for module to emit/finalize.
void emitAndFinalize(ModuleHandleT H) {
BaseLayer.emitAndFinalize(H);
Error emitAndFinalize(ModuleHandleT H) {
return BaseLayer.emitAndFinalize(H);
}
private:

View File

@ -42,13 +42,14 @@ public:
/// the layer below, along with the memory manager and symbol resolver.
///
/// @return A handle for the added modules.
ModuleHandleT addModule(std::shared_ptr<Module> M,
std::shared_ptr<JITSymbolResolver> Resolver) {
Expected<ModuleHandleT>
addModule(std::shared_ptr<Module> M,
std::shared_ptr<JITSymbolResolver> Resolver) {
return BaseLayer.addModule(Transform(std::move(M)), std::move(Resolver));
}
/// @brief Remove the module associated with the handle H.
void removeModule(ModuleHandleT H) { BaseLayer.removeModule(H); }
Error removeModule(ModuleHandleT H) { return BaseLayer.removeModule(H); }
/// @brief Search for the given named symbol.
/// @param Name The name of the symbol to search for.
@ -74,8 +75,8 @@ public:
/// @brief Immediately emit and finalize the module represented by the given
/// handle.
/// @param H Handle for module to emit/finalize.
void emitAndFinalize(ModuleHandleT H) {
BaseLayer.emitAndFinalize(H);
Error emitAndFinalize(ModuleHandleT H) {
return BaseLayer.emitAndFinalize(H);
}
/// @brief Access the transform functor directly.

View File

@ -60,16 +60,24 @@ private:
std::string PName = Name;
JITSymbolFlags Flags = JITSymbolFlags::fromGlobalValue(*GV);
auto GetAddress =
[this, ExportedSymbolsOnly, PName, &B]() -> JITTargetAddress {
[this, ExportedSymbolsOnly, PName, &B]() -> Expected<JITTargetAddress> {
if (this->EmitState == Emitting)
return 0;
else if (this->EmitState == NotEmitted) {
this->EmitState = Emitting;
Handle = this->emitToBaseLayer(B);
if (auto HandleOrErr = this->emitToBaseLayer(B))
Handle = std::move(*HandleOrErr);
else
return HandleOrErr.takeError();
this->EmitState = Emitted;
}
auto Sym = B.findSymbolIn(Handle, PName, ExportedSymbolsOnly);
return Sym.getAddress();
if (auto Sym = B.findSymbolIn(Handle, PName, ExportedSymbolsOnly))
return Sym.getAddress();
else if (auto Err = Sym.takeError())
return std::move(Err);
else
llvm_unreachable("Successful symbol lookup should return "
"definition address here");
};
return JITSymbol(std::move(GetAddress), Flags);
} else
@ -127,7 +135,7 @@ private:
return buildMangledSymbols(Name, ExportedSymbolsOnly);
}
BaseLayerHandleT emitToBaseLayer(BaseLayerT &BaseLayer) {
Expected<BaseLayerHandleT> emitToBaseLayer(BaseLayerT &BaseLayer) {
// We don't need the mangled names set any more: Once we've emitted this
// to the base layer we'll just look for symbols there.
MangledSymbols.reset();
@ -204,8 +212,9 @@ public:
LazyEmittingLayer(BaseLayerT &BaseLayer) : BaseLayer(BaseLayer) {}
/// @brief Add the given module to the lazy emitting layer.
ModuleHandleT addModule(std::shared_ptr<Module> M,
std::shared_ptr<JITSymbolResolver> Resolver) {
Expected<ModuleHandleT>
addModule(std::shared_ptr<Module> M,
std::shared_ptr<JITSymbolResolver> Resolver) {
return ModuleList.insert(
ModuleList.end(),
llvm::make_unique<EmissionDeferredModule>(std::move(M),
@ -216,7 +225,7 @@ public:
///
/// This method will free the memory associated with the given module, both
/// in this layer, and the base layer.
void removeModule(ModuleHandleT H) {
Error removeModule(ModuleHandleT H) {
(*H)->removeModuleFromBaseLayer(BaseLayer);
ModuleList.erase(H);
}
@ -251,8 +260,8 @@ public:
/// @brief Immediately emit and finalize the module represented by the given
/// handle.
/// @param H Handle for module to emit/finalize.
void emitAndFinalize(ModuleHandleT H) {
(*H)->emitAndFinalize(BaseLayer);
Error emitAndFinalize(ModuleHandleT H) {
return (*H)->emitAndFinalize(BaseLayer);
}
};

View File

@ -44,13 +44,13 @@ public:
///
/// @return A handle for the added objects.
template <typename ObjectPtr>
ObjHandleT addObject(ObjectPtr Obj,
std::shared_ptr<JITSymbolResolver> Resolver) {
Expected<ObjHandleT> addObject(ObjectPtr Obj,
std::shared_ptr<JITSymbolResolver> Resolver) {
return BaseLayer.addObject(Transform(std::move(Obj)), std::move(Resolver));
}
/// @brief Remove the object set associated with the handle H.
void removeObject(ObjHandleT H) { BaseLayer.removeObject(H); }
Error removeObject(ObjHandleT H) { return BaseLayer.removeObject(H); }
/// @brief Search for the given named symbol.
/// @param Name The name of the symbol to search for.
@ -76,7 +76,9 @@ public:
/// @brief Immediately emit and finalize the object set represented by the
/// given handle.
/// @param H Handle for object set to emit/finalize.
void emitAndFinalize(ObjHandleT H) { BaseLayer.emitAndFinalize(H); }
Error emitAndFinalize(ObjHandleT H) {
return BaseLayer.emitAndFinalize(H);
}
/// @brief Map section addresses for the objects associated with the handle H.
void mapSectionAddress(ObjHandleT H, const void *LocalAddress,

View File

@ -22,7 +22,8 @@ namespace orc {
enum class OrcErrorCode : int {
// RPC Errors
RemoteAllocatorDoesNotExist = 1,
JITSymbolNotFound = 1,
RemoteAllocatorDoesNotExist,
RemoteAllocatorIdAlreadyInUse,
RemoteMProtectAddrUnrecognized,
RemoteIndirectStubsOwnerDoesNotExist,
@ -37,6 +38,18 @@ enum class OrcErrorCode : int {
std::error_code orcError(OrcErrorCode ErrCode);
class JITSymbolNotFound : public ErrorInfo<JITSymbolNotFound> {
public:
static char ID;
JITSymbolNotFound(std::string SymbolName);
std::error_code convertToErrorCode() const override;
void log(raw_ostream &OS) const override;
const std::string &getSymbolName() const;
private:
std::string SymbolName;
};
} // End namespace orc.
} // End namespace llvm.

View File

@ -258,8 +258,8 @@ public:
///
/// @return A handle that can be used to refer to the loaded objects (for
/// symbol searching, finalization, freeing memory, etc.).
ObjHandleT addObject(ObjectPtr Obj,
std::shared_ptr<JITSymbolResolver> Resolver) {
Expected<ObjHandleT> addObject(ObjectPtr Obj,
std::shared_ptr<JITSymbolResolver> Resolver) {
auto Finalizer = [&](ObjHandleT H, RuntimeDyld &RTDyld,
const ObjectPtr &ObjToLoad,
std::function<void()> LOSHandleLoad) {
@ -299,9 +299,10 @@ public:
/// indirectly) will result in undefined behavior. If dependence tracking is
/// required to detect or resolve such issues it should be added at a higher
/// layer.
void removeObject(ObjHandleT H) {
Error removeObject(ObjHandleT H) {
// How do we invalidate the symbols in H?
LinkedObjList.erase(H);
return Error::success();
}
/// @brief Search for the given named symbol.
@ -338,8 +339,9 @@ public:
/// @brief Immediately emit and finalize the object set represented by the
/// given handle.
/// @param H Handle for object set to emit/finalize.
void emitAndFinalize(ObjHandleT H) {
Error emitAndFinalize(ObjHandleT H) {
(*H)->finalize();
return Error::success();
}
private:

View File

@ -317,7 +317,13 @@ uint64_t MCJIT::getSymbolAddress(const std::string &Name,
raw_string_ostream MangledNameStream(MangledName);
Mangler::getNameWithPrefix(MangledNameStream, Name, getDataLayout());
}
return findSymbol(MangledName, CheckFunctionsOnly).getAddress();
if (auto Sym = findSymbol(MangledName, CheckFunctionsOnly)) {
if (auto AddrOrErr = Sym.getAddress())
return *AddrOrErr;
else
report_fatal_error(AddrOrErr.takeError());
} else
report_fatal_error(Sym.takeError());
}
JITSymbol MCJIT::findSymbol(const std::string &Name,
@ -599,11 +605,12 @@ GenericValue MCJIT::runFunction(Function *F, ArrayRef<GenericValue> ArgValues) {
void *MCJIT::getPointerToNamedFunction(StringRef Name, bool AbortOnFailure) {
if (!isSymbolSearchingDisabled()) {
void *ptr =
reinterpret_cast<void*>(
static_cast<uintptr_t>(Resolver.findSymbol(Name).getAddress()));
if (ptr)
return ptr;
if (auto Sym = Resolver.findSymbol(Name)) {
if (auto AddrOrErr = Sym.getAddress())
return reinterpret_cast<void*>(
static_cast<uintptr_t>(*AddrOrErr));
} else if (auto Err = Sym.takeError())
report_fatal_error(std::move(Err));
}
/// If a LazyFunctionCreator is installed, use it to get/create the function.

View File

@ -60,12 +60,13 @@ void LLVMOrcGetMangledSymbol(LLVMOrcJITStackRef JITStack, char **MangledName,
void LLVMOrcDisposeMangledSymbol(char *MangledName) { delete[] MangledName; }
LLVMOrcTargetAddress
LLVMOrcErrorCode
LLVMOrcCreateLazyCompileCallback(LLVMOrcJITStackRef JITStack,
LLVMOrcTargetAddress *RetAddr,
LLVMOrcLazyCompileCallbackFn Callback,
void *CallbackCtx) {
OrcCBindingsStack &J = *unwrap(JITStack);
return J.createLazyCompileCallback(Callback, CallbackCtx);
return J.createLazyCompileCallback(*RetAddr, Callback, CallbackCtx);
}
LLVMOrcErrorCode LLVMOrcCreateIndirectStub(LLVMOrcJITStackRef JITStack,
@ -82,38 +83,44 @@ LLVMOrcErrorCode LLVMOrcSetIndirectStubPointer(LLVMOrcJITStackRef JITStack,
return J.setIndirectStubPointer(StubName, NewAddr);
}
LLVMOrcModuleHandle
LLVMOrcErrorCode
LLVMOrcAddEagerlyCompiledIR(LLVMOrcJITStackRef JITStack,
LLVMOrcModuleHandle *RetHandle,
LLVMSharedModuleRef Mod,
LLVMOrcSymbolResolverFn SymbolResolver,
void *SymbolResolverCtx) {
OrcCBindingsStack &J = *unwrap(JITStack);
std::shared_ptr<Module> *M(unwrap(Mod));
return J.addIRModuleEager(*M, SymbolResolver, SymbolResolverCtx);
return J.addIRModuleEager(*RetHandle, *M, SymbolResolver, SymbolResolverCtx);
}
LLVMOrcModuleHandle
LLVMOrcErrorCode
LLVMOrcAddLazilyCompiledIR(LLVMOrcJITStackRef JITStack,
LLVMOrcModuleHandle *RetHandle,
LLVMSharedModuleRef Mod,
LLVMOrcSymbolResolverFn SymbolResolver,
void *SymbolResolverCtx) {
OrcCBindingsStack &J = *unwrap(JITStack);
std::shared_ptr<Module> *M(unwrap(Mod));
return J.addIRModuleLazy(*M, SymbolResolver, SymbolResolverCtx);
return J.addIRModuleLazy(*RetHandle, *M, SymbolResolver, SymbolResolverCtx);
}
void LLVMOrcRemoveModule(LLVMOrcJITStackRef JITStack, LLVMOrcModuleHandle H) {
LLVMOrcErrorCode LLVMOrcRemoveModule(LLVMOrcJITStackRef JITStack,
LLVMOrcModuleHandle H) {
OrcCBindingsStack &J = *unwrap(JITStack);
J.removeModule(H);
return J.removeModule(H);
}
LLVMOrcTargetAddress LLVMOrcGetSymbolAddress(LLVMOrcJITStackRef JITStack,
const char *SymbolName) {
LLVMOrcErrorCode LLVMOrcGetSymbolAddress(LLVMOrcJITStackRef JITStack,
LLVMOrcTargetAddress *RetAddr,
const char *SymbolName) {
OrcCBindingsStack &J = *unwrap(JITStack);
auto Sym = J.findSymbol(SymbolName, true);
return Sym.getAddress();
return J.findSymbolAddress(*RetAddr, SymbolName, true);
}
void LLVMOrcDisposeInstance(LLVMOrcJITStackRef JITStack) {
delete unwrap(JITStack);
LLVMOrcErrorCode LLVMOrcDisposeInstance(LLVMOrcJITStackRef JITStack) {
auto *J = unwrap(JITStack);
auto Err = J->shutdown();
delete J;
return Err;
}

View File

@ -70,7 +70,7 @@ private:
virtual JITSymbol findSymbolIn(const std::string &Name,
bool ExportedSymbolsOnly) = 0;
virtual void removeModule() = 0;
virtual Error removeModule() = 0;
};
template <typename LayerT> class GenericHandleImpl : public GenericHandle {
@ -83,7 +83,7 @@ private:
return Layer.findSymbolIn(Handle, Name, ExportedSymbolsOnly);
}
void removeModule() override { return Layer.removeModule(Handle); }
Error removeModule() override { return Layer.removeModule(Handle); }
private:
LayerT &Layer;
@ -116,12 +116,14 @@ public:
CXXRuntimeOverrides(
[this](const std::string &S) { return mangle(S); }) {}
~OrcCBindingsStack() {
LLVMOrcErrorCode shutdown() {
// Run any destructors registered with __cxa_atexit.
CXXRuntimeOverrides.runDestructors();
// Run any IR destructors.
for (auto &DtorRunner : IRStaticDestructorRunners)
DtorRunner.runViaLayer(*this);
if (auto Err = DtorRunner.runViaLayer(*this))
return mapError(std::move(Err));
return LLVMOrcErrSuccess;
}
std::string mangle(StringRef Name) {
@ -138,14 +140,17 @@ public:
return reinterpret_cast<PtrTy>(static_cast<uintptr_t>(Addr));
}
JITTargetAddress
createLazyCompileCallback(LLVMOrcLazyCompileCallbackFn Callback,
LLVMOrcErrorCode
createLazyCompileCallback(JITTargetAddress &RetAddr,
LLVMOrcLazyCompileCallbackFn Callback,
void *CallbackCtx) {
auto CCInfo = CCMgr->getCompileCallback();
CCInfo.setCompileAction([=]() -> JITTargetAddress {
return Callback(wrap(this), CallbackCtx);
});
return CCInfo.getAddress();
RetAddr = CCInfo.getAddress();
return LLVMOrcErrSuccess;
}
LLVMOrcErrorCode createIndirectStub(StringRef StubName,
@ -164,7 +169,7 @@ public:
void *ExternalResolverCtx) {
return orc::createLambdaResolver(
[this, ExternalResolver, ExternalResolverCtx](const std::string &Name)
-> JITSymbol {
-> JITSymbol {
// Search order:
// 1. JIT'd symbols.
// 2. Runtime overrides.
@ -172,6 +177,9 @@ public:
if (auto Sym = CODLayer.findSymbol(Name, true))
return Sym;
else if (auto Err = Sym.takeError())
return Sym.takeError();
if (auto Sym = CXXRuntimeOverrides.searchOverrides(Name))
return Sym;
@ -182,16 +190,19 @@ public:
return JITSymbol(nullptr);
},
[](const std::string &Name) {
[](const std::string &Name) -> JITSymbol {
return JITSymbol(nullptr);
});
}
template <typename LayerT>
ModuleHandleT addIRModule(LayerT &Layer, std::shared_ptr<Module> M,
std::unique_ptr<RuntimeDyld::MemoryManager> MemMgr,
LLVMOrcSymbolResolverFn ExternalResolver,
void *ExternalResolverCtx) {
LLVMOrcErrorCode
addIRModule(ModuleHandleT &RetHandle, LayerT &Layer,
std::shared_ptr<Module> M,
std::unique_ptr<RuntimeDyld::MemoryManager> MemMgr,
LLVMOrcSymbolResolverFn ExternalResolver,
void *ExternalResolverCtx) {
// Attach a data-layout if one isn't already present.
if (M->getDataLayout().isDefault())
M->setDataLayout(DL);
@ -208,42 +219,52 @@ public:
auto Resolver = createResolver(ExternalResolver, ExternalResolverCtx);
// Add the module to the JIT.
auto LH = Layer.addModule(std::move(M), std::move(Resolver));
ModuleHandleT H = createHandle(Layer, LH);
ModuleHandleT H;
if (auto LHOrErr = Layer.addModule(std::move(M), std::move(Resolver)))
H = createHandle(Layer, *LHOrErr);
else
return mapError(LHOrErr.takeError());
// Run the static constructors, and save the static destructor runner for
// execution when the JIT is torn down.
orc::CtorDtorRunner<OrcCBindingsStack> CtorRunner(std::move(CtorNames), H);
CtorRunner.runViaLayer(*this);
if (auto Err = CtorRunner.runViaLayer(*this))
return mapError(std::move(Err));
IRStaticDestructorRunners.emplace_back(std::move(DtorNames), H);
return H;
RetHandle = H;
return LLVMOrcErrSuccess;
}
ModuleHandleT addIRModuleEager(std::shared_ptr<Module> M,
LLVMOrcSymbolResolverFn ExternalResolver,
void *ExternalResolverCtx) {
return addIRModule(CompileLayer, std::move(M),
LLVMOrcErrorCode addIRModuleEager(ModuleHandleT &RetHandle,
std::shared_ptr<Module> M,
LLVMOrcSymbolResolverFn ExternalResolver,
void *ExternalResolverCtx) {
return addIRModule(RetHandle, CompileLayer, std::move(M),
llvm::make_unique<SectionMemoryManager>(),
std::move(ExternalResolver), ExternalResolverCtx);
}
ModuleHandleT addIRModuleLazy(std::shared_ptr<Module> M,
LLVMOrcSymbolResolverFn ExternalResolver,
void *ExternalResolverCtx) {
return addIRModule(CODLayer, std::move(M),
LLVMOrcErrorCode addIRModuleLazy(ModuleHandleT &RetHandle,
std::shared_ptr<Module> M,
LLVMOrcSymbolResolverFn ExternalResolver,
void *ExternalResolverCtx) {
return addIRModule(RetHandle, CODLayer, std::move(M),
llvm::make_unique<SectionMemoryManager>(),
std::move(ExternalResolver), ExternalResolverCtx);
}
void removeModule(ModuleHandleT H) {
GenericHandles[H]->removeModule();
LLVMOrcErrorCode removeModule(ModuleHandleT H) {
if (auto Err = GenericHandles[H]->removeModule())
return mapError(std::move(Err));
GenericHandles[H] = nullptr;
FreeHandleIndexes.push_back(H);
return LLVMOrcErrSuccess;
}
JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly) {
JITSymbol findSymbol(const std::string &Name,
bool ExportedSymbolsOnly) {
if (auto Sym = IndirectStubsMgr->findStub(Name, ExportedSymbolsOnly))
return Sym;
return CODLayer.findSymbol(mangle(Name), ExportedSymbolsOnly);
@ -254,6 +275,26 @@ public:
return GenericHandles[H]->findSymbolIn(Name, ExportedSymbolsOnly);
}
LLVMOrcErrorCode findSymbolAddress(JITTargetAddress &RetAddr,
const std::string &Name,
bool ExportedSymbolsOnly) {
RetAddr = 0;
if (auto Sym = findSymbol(Name, ExportedSymbolsOnly)) {
// Successful lookup, non-null symbol:
if (auto AddrOrErr = Sym.getAddress()) {
RetAddr = *AddrOrErr;
return LLVMOrcErrSuccess;
} else
return mapError(AddrOrErr.takeError());
} else if (auto Err = Sym.takeError()) {
// Lookup failure - report error.
return mapError(std::move(Err));
}
// Otherwise we had a successful lookup but got a null result. We already
// set RetAddr to '0' above, so just return success.
return LLVMOrcErrSuccess;
}
const std::string &getErrorMessage() const { return ErrMsg; }
private:

View File

@ -45,6 +45,8 @@ public:
return "Could not negotiate RPC function";
case OrcErrorCode::RPCResponseAbandoned:
return "RPC response abandoned";
case OrcErrorCode::JITSymbolNotFound:
return "JIT symbol not found";
case OrcErrorCode::UnexpectedRPCCall:
return "Unexpected RPC call";
case OrcErrorCode::UnexpectedRPCResponse:
@ -63,10 +65,29 @@ static ManagedStatic<OrcErrorCategory> OrcErrCat;
namespace llvm {
namespace orc {
char JITSymbolNotFound::ID = 0;
std::error_code orcError(OrcErrorCode ErrCode) {
typedef std::underlying_type<OrcErrorCode>::type UT;
return std::error_code(static_cast<UT>(ErrCode), *OrcErrCat);
}
JITSymbolNotFound::JITSymbolNotFound(std::string SymbolName)
: SymbolName(std::move(SymbolName)) {}
std::error_code JITSymbolNotFound::convertToErrorCode() const {
typedef std::underlying_type<OrcErrorCode>::type UT;
return std::error_code(static_cast<UT>(OrcErrorCode::JITSymbolNotFound),
*OrcErrCat);
}
void JITSymbolNotFound::log(raw_ostream &OS) const {
OS << "Could not find symbol '" << SymbolName << "'";
}
const std::string &JITSymbolNotFound::getSymbolName() const {
return SymbolName;
}
}
}

View File

@ -202,20 +202,20 @@ public:
delete Mod;
};
LocalModules.push_back(std::shared_ptr<Module>(MPtr, std::move(Deleter)));
LazyEmitLayer.addModule(LocalModules.back(), Resolver);
cantFail(LazyEmitLayer.addModule(LocalModules.back(), Resolver));
}
void addObjectFile(std::unique_ptr<object::ObjectFile> O) override {
auto Obj =
std::make_shared<object::OwningBinary<object::ObjectFile>>(std::move(O),
nullptr);
ObjectLayer.addObject(std::move(Obj), Resolver);
cantFail(ObjectLayer.addObject(std::move(Obj), Resolver));
}
void addObjectFile(object::OwningBinary<object::ObjectFile> O) override {
auto Obj =
std::make_shared<object::OwningBinary<object::ObjectFile>>(std::move(O));
ObjectLayer.addObject(std::move(Obj), Resolver);
cantFail(ObjectLayer.addObject(std::move(Obj), Resolver));
}
void addArchive(object::OwningBinary<object::Archive> A) override {
@ -234,7 +234,7 @@ public:
}
uint64_t getSymbolAddress(StringRef Name) {
return findSymbol(Name).getAddress();
return cantFail(findSymbol(Name).getAddress());
}
JITSymbol findSymbol(StringRef Name) {
@ -323,7 +323,7 @@ private:
auto Obj =
std::make_shared<object::OwningBinary<object::ObjectFile>>(
std::move(ChildObj), nullptr);
ObjectLayer.addObject(std::move(Obj), Resolver);
cantFail(ObjectLayer.addObject(std::move(Obj), Resolver));
if (auto Sym = ObjectLayer.findSymbol(Name, true))
return Sym;
}

View File

@ -128,7 +128,10 @@ void RuntimeDyldImpl::resolveRelocations() {
);
// First, resolve relocations associated with external symbols.
resolveExternalSymbols();
if (auto Err = resolveExternalSymbols()) {
HasError = true;
ErrorStr = toString(std::move(Err));
}
// Iterate over all outstanding relocations
for (auto it = Relocations.begin(), e = Relocations.end(); it != e; ++it) {
@ -243,9 +246,11 @@ RuntimeDyldImpl::loadObjectImpl(const object::ObjectFile &Obj) {
continue;
// Then check the symbol resolver to see if there's a definition
// elsewhere in this logical dylib.
if (auto Sym = Resolver.findSymbolInLogicalDylib(Name))
if (auto Sym = Resolver.findSymbolInLogicalDylib(Name)) {
if (Sym.getFlags().isStrongDefinition())
continue;
} else if (auto Err = Sym.takeError())
return std::move(Err);
// else
JITSymFlags &= ~JITSymbolFlags::Weak;
}
@ -953,7 +958,7 @@ void RuntimeDyldImpl::resolveRelocationList(const RelocationList &Relocs,
}
}
void RuntimeDyldImpl::resolveExternalSymbols() {
Error RuntimeDyldImpl::resolveExternalSymbols() {
while (!ExternalSymbolRelocations.empty()) {
StringMap<RelocationList>::iterator i = ExternalSymbolRelocations.begin();
@ -971,10 +976,24 @@ void RuntimeDyldImpl::resolveExternalSymbols() {
// This is an external symbol, try to get its address from the symbol
// resolver.
// First search for the symbol in this logical dylib.
Addr = Resolver.findSymbolInLogicalDylib(Name.data()).getAddress();
if (auto Sym = Resolver.findSymbolInLogicalDylib(Name.data())) {
if (auto AddrOrErr = Sym.getAddress())
Addr = *AddrOrErr;
else
return AddrOrErr.takeError();
} else if (auto Err = Sym.takeError())
return Err;
// If that fails, try searching for an external symbol.
if (!Addr)
Addr = Resolver.findSymbol(Name.data()).getAddress();
if (!Addr) {
if (auto Sym = Resolver.findSymbol(Name.data())) {
if (auto AddrOrErr = Sym.getAddress())
Addr = *AddrOrErr;
else
return AddrOrErr.takeError();
} else if (auto Err = Sym.takeError())
return Err;
}
// The call to getSymbolAddress may have caused additional modules to
// be loaded, which may have added new entries to the
// ExternalSymbolRelocations map. Consquently, we need to update our
@ -1009,6 +1028,8 @@ void RuntimeDyldImpl::resolveExternalSymbols() {
ExternalSymbolRelocations.erase(i);
}
return Error::success();
}
//===----------------------------------------------------------------------===//

View File

@ -742,7 +742,7 @@ uint64_t RuntimeDyldCheckerImpl::getSymbolLocalAddr(StringRef Symbol) const {
uint64_t RuntimeDyldCheckerImpl::getSymbolRemoteAddr(StringRef Symbol) const {
if (auto InternalSymbol = getRTDyld().getSymbol(Symbol))
return InternalSymbol.getAddress();
return getRTDyld().Resolver.findSymbol(Symbol).getAddress();
return cantFail(getRTDyld().Resolver.findSymbol(Symbol).getAddress());
}
uint64_t RuntimeDyldCheckerImpl::readMemoryAtAddr(uint64_t SrcAddr,

View File

@ -417,7 +417,7 @@ protected:
StubMap &Stubs) = 0;
/// \brief Resolve relocations to external symbols.
void resolveExternalSymbols();
Error resolveExternalSymbols();
// \brief Compute an upper bound of the memory that is required to load all
// sections

View File

@ -148,18 +148,19 @@ int llvm::runOrcLazyJIT(std::vector<std::unique_ptr<Module>> Ms,
// Add the module, look up main and run it.
for (auto &M : Ms)
J.addModule(std::shared_ptr<Module>(std::move(M)));
auto MainSym = J.findSymbol("main");
cantFail(J.addModule(std::shared_ptr<Module>(std::move(M))));
if (!MainSym) {
if (auto MainSym = J.findSymbol("main")) {
typedef int (*MainFnPtr)(int, const char*[]);
std::vector<const char *> ArgV;
for (auto &Arg : Args)
ArgV.push_back(Arg.c_str());
auto Main = fromTargetAddress<MainFnPtr>(cantFail(MainSym.getAddress()));
return Main(ArgV.size(), (const char**)ArgV.data());
} else if (auto Err = MainSym.takeError())
logAllUnhandledErrors(std::move(Err), llvm::errs(), "");
else
errs() << "Could not find main function.\n";
return 1;
}
using MainFnPtr = int (*)(int, const char*[]);
std::vector<const char *> ArgV;
for (auto &Arg : Args)
ArgV.push_back(Arg.c_str());
auto Main = fromTargetAddress<MainFnPtr>(MainSym.getAddress());
return Main(ArgV.size(), (const char**)ArgV.data());
return 1;
}

View File

@ -75,10 +75,14 @@ public:
CXXRuntimeOverrides.runDestructors();
// Run any IR destructors.
for (auto &DtorRunner : IRStaticDestructorRunners)
DtorRunner.runViaLayer(CODLayer);
if (auto Err = DtorRunner.runViaLayer(CODLayer)) {
// FIXME: OrcLazyJIT should probably take a "shutdownError" callback to
// report these errors on.
report_fatal_error(std::move(Err));
}
}
void addModule(std::shared_ptr<Module> M) {
Error addModule(std::shared_ptr<Module> M) {
if (M->getDataLayout().isDefault())
M->setDataLayout(DL);
@ -125,19 +129,27 @@ public:
);
// Add the module to the JIT.
ModulesHandle =
CODLayer.addModule(std::move(M), std::move(Resolver));
if (auto ModulesHandleOrErr =
CODLayer.addModule(std::move(M), std::move(Resolver)))
ModulesHandle = std::move(*ModulesHandleOrErr);
else
return ModulesHandleOrErr.takeError();
} else
CODLayer.addExtraModule(ModulesHandle, std::move(M));
if (auto Err = CODLayer.addExtraModule(ModulesHandle, std::move(M)))
return Err;
// Run the static constructors, and save the static destructor runner for
// execution when the JIT is torn down.
orc::CtorDtorRunner<CODLayerT> CtorRunner(std::move(CtorNames),
ModulesHandle);
CtorRunner.runViaLayer(CODLayer);
if (auto Err = CtorRunner.runViaLayer(CODLayer))
return Err;
IRStaticDestructorRunners.emplace_back(std::move(DtorNames),
ModulesHandle);
return Error::success();
}
JITSymbol findSymbol(const std::string &Name) {

View File

@ -50,13 +50,14 @@ public:
TEST(CompileOnDemandLayerTest, FindSymbol) {
auto MockBaseLayer = createMockBaseLayer<int>(
DoNothingAndReturn<int>(0), DoNothingAndReturn<void>(),
DoNothingAndReturn<int>(0),
[](int Handle) { return Error::success(); },
[](const std::string &Name, bool) {
if (Name == "foo")
return JITSymbol(1, JITSymbolFlags::Exported);
return JITSymbol(nullptr);
},
DoNothingAndReturn<JITSymbol>(nullptr));
ReturnNullJITSymbol());
typedef decltype(MockBaseLayer) MockBaseLayerT;
DummyCallbackManager CallbackMgr;

View File

@ -37,13 +37,15 @@ TEST(GlobalMappingLayerTest, Empty) {
// Test fall-through for symbol in base layer.
auto BarSym = L.findSymbol("bar", true);
EXPECT_EQ(BarSym.getAddress(), static_cast<JITTargetAddress>(0x4567))
EXPECT_EQ(cantFail(BarSym.getAddress()),
static_cast<JITTargetAddress>(0x4567))
<< "Symbol lookup fall-through failed.";
// Test setup of a global mapping.
L.setGlobalMapping("foo", 0x0123);
auto FooSym2 = L.findSymbol("foo", true);
EXPECT_EQ(FooSym2.getAddress(), static_cast<JITTargetAddress>(0x0123))
EXPECT_EQ(cantFail(FooSym2.getAddress()),
static_cast<JITTargetAddress>(0x0123))
<< "Symbol mapping setup failed.";
// Test removal of a global mapping.

View File

@ -27,7 +27,7 @@ struct MockBaseLayer {
TEST(LazyEmittingLayerTest, Empty) {
MockBaseLayer M;
llvm::orc::LazyEmittingLayer<MockBaseLayer> L(M);
L.addModule(std::unique_ptr<llvm::Module>(), nullptr);
cantFail(L.addModule(std::unique_ptr<llvm::Module>(), nullptr));
}
}

View File

@ -50,8 +50,9 @@ public:
MockBaseLayer() : MockSymbol(nullptr) { resetExpectations(); }
template <typename ObjPtrT>
ObjHandleT addObject(ObjPtrT Obj,
std::shared_ptr<llvm::JITSymbolResolver> Resolver) {
llvm::Expected<ObjHandleT>
addObject(ObjPtrT Obj,
std::shared_ptr<llvm::JITSymbolResolver> Resolver) {
EXPECT_EQ(MockResolver, Resolver) << "Resolver should pass through";
EXPECT_EQ(MockObject + 1, *Obj) << "Transform should be applied";
LastCalled = "addObject";
@ -73,10 +74,12 @@ public:
resetExpectations();
}
void removeObject(ObjHandleT H) {
llvm::Error removeObject(ObjHandleT H) {
EXPECT_EQ(MockObjHandle, H);
LastCalled = "removeObject";
return llvm::Error::success();
}
void expectRemoveObject(ObjHandleT H) { MockObjHandle = H; }
void verifyRemoveObject() {
EXPECT_EQ("removeObject", LastCalled);
@ -89,7 +92,7 @@ public:
EXPECT_EQ(MockBool, ExportedSymbolsOnly) << "Flag should pass through";
LastCalled = "findSymbol";
MockSymbol = llvm::JITSymbol(122, llvm::JITSymbolFlags::None);
return MockSymbol;
return llvm::JITSymbol(122, llvm::JITSymbolFlags::None);
}
void expectFindSymbol(const std::string &Name, bool ExportedSymbolsOnly) {
MockName = Name;
@ -97,7 +100,8 @@ public:
}
void verifyFindSymbol(llvm::JITSymbol Returned) {
EXPECT_EQ("findSymbol", LastCalled);
EXPECT_EQ(MockSymbol.getAddress(), Returned.getAddress())
EXPECT_EQ(cantFail(MockSymbol.getAddress()),
cantFail(Returned.getAddress()))
<< "Return should pass through";
resetExpectations();
}
@ -109,7 +113,7 @@ public:
EXPECT_EQ(MockBool, ExportedSymbolsOnly) << "Flag should pass through";
LastCalled = "findSymbolIn";
MockSymbol = llvm::JITSymbol(122, llvm::JITSymbolFlags::None);
return MockSymbol;
return llvm::JITSymbol(122, llvm::JITSymbolFlags::None);
}
void expectFindSymbolIn(ObjHandleT H, const std::string &Name,
bool ExportedSymbolsOnly) {
@ -119,16 +123,20 @@ public:
}
void verifyFindSymbolIn(llvm::JITSymbol Returned) {
EXPECT_EQ("findSymbolIn", LastCalled);
EXPECT_EQ(MockSymbol.getAddress(), Returned.getAddress())
EXPECT_EQ(cantFail(MockSymbol.getAddress()),
cantFail(Returned.getAddress()))
<< "Return should pass through";
resetExpectations();
}
void emitAndFinalize(ObjHandleT H) {
llvm::Error emitAndFinalize(ObjHandleT H) {
EXPECT_EQ(MockObjHandle, H) << "Handle should pass through";
LastCalled = "emitAndFinalize";
return llvm::Error::success();
}
void expectEmitAndFinalize(ObjHandleT H) { MockObjHandle = H; }
void verifyEmitAndFinalize() {
EXPECT_EQ("emitAndFinalize", LastCalled);
resetExpectations();
@ -201,38 +209,38 @@ TEST(ObjectTransformLayerTest, Main) {
auto Obj1 = std::make_shared<MockObjectFile>(211);
auto SR = std::make_shared<NullResolver>();
M.expectAddObject(Obj1, SR);
auto H = T1.addObject(std::move(Obj1), SR);
auto H = cantFail(T1.addObject(std::move(Obj1), SR));
M.verifyAddObject(H);
// Test addObjectSet with T2 (mutating)
auto Obj2 = std::make_shared<MockObjectFile>(222);
M.expectAddObject(Obj2, SR);
H = T2.addObject(Obj2, SR);
H = cantFail(T2.addObject(Obj2, SR));
M.verifyAddObject(H);
EXPECT_EQ(223, *Obj2) << "Expected mutation";
// Test removeObjectSet
M.expectRemoveObject(H);
T1.removeObject(H);
cantFail(T1.removeObject(H));
M.verifyRemoveObject();
// Test findSymbol
std::string Name = "foo";
bool ExportedOnly = true;
M.expectFindSymbol(Name, ExportedOnly);
llvm::JITSymbol Symbol = T2.findSymbol(Name, ExportedOnly);
M.verifyFindSymbol(Symbol);
llvm::JITSymbol Sym1 = T2.findSymbol(Name, ExportedOnly);
M.verifyFindSymbol(std::move(Sym1));
// Test findSymbolIn
Name = "bar";
ExportedOnly = false;
M.expectFindSymbolIn(H, Name, ExportedOnly);
Symbol = T1.findSymbolIn(H, Name, ExportedOnly);
M.verifyFindSymbolIn(Symbol);
llvm::JITSymbol Sym2 = T1.findSymbolIn(H, Name, ExportedOnly);
M.verifyFindSymbolIn(std::move(Sym2));
// Test emitAndFinalize
M.expectEmitAndFinalize(H);
T2.emitAndFinalize(H);
cantFail(T2.emitAndFinalize(H));
M.verifyEmitAndFinalize();
// Test mapSectionAddress
@ -305,15 +313,15 @@ TEST(ObjectTransformLayerTest, Main) {
// Make sure that the calls from IRCompileLayer to ObjectTransformLayer
// compile.
auto Resolver = std::make_shared<NullResolver>();
CompileLayer.addModule(std::shared_ptr<llvm::Module>(), Resolver);
cantFail(CompileLayer.addModule(std::shared_ptr<llvm::Module>(), Resolver));
// Make sure that the calls from ObjectTransformLayer to ObjectLinkingLayer
// compile.
decltype(TransformLayer)::ObjHandleT H2;
TransformLayer.emitAndFinalize(H2);
cantFail(TransformLayer.emitAndFinalize(H2));
TransformLayer.findSymbolIn(H2, Name, false);
TransformLayer.findSymbol(Name, true);
TransformLayer.mapSectionAddress(H2, nullptr, 0);
TransformLayer.removeObject(H2);
cantFail(TransformLayer.removeObject(H2));
}
}

View File

@ -66,10 +66,11 @@ protected:
auto *ET = CCtx->APIExecTest;
CCtx->M = ET->createTestModule(ET->TM->getTargetTriple());
LLVMSharedModuleRef SM = LLVMOrcMakeSharedModule(wrap(CCtx->M.release()));
CCtx->H = LLVMOrcAddEagerlyCompiledIR(JITStack, SM, myResolver, nullptr);
LLVMOrcAddEagerlyCompiledIR(JITStack, &CCtx->H, SM, myResolver, nullptr);
LLVMOrcDisposeSharedModuleRef(SM);
CCtx->Compiled = true;
LLVMOrcTargetAddress MainAddr = LLVMOrcGetSymbolAddress(JITStack, "main");
LLVMOrcTargetAddress MainAddr;
LLVMOrcGetSymbolAddress(JITStack, &MainAddr, "main");
LLVMOrcSetIndirectStubPointer(JITStack, "foo", MainAddr);
return MainAddr;
}
@ -89,10 +90,12 @@ TEST_F(OrcCAPIExecutionTest, TestEagerIRCompilation) {
LLVMOrcGetMangledSymbol(JIT, &testFuncName, "testFunc");
LLVMSharedModuleRef SM = LLVMOrcMakeSharedModule(wrap(M.release()));
LLVMOrcModuleHandle H =
LLVMOrcAddEagerlyCompiledIR(JIT, SM, myResolver, nullptr);
LLVMOrcModuleHandle H;
LLVMOrcAddEagerlyCompiledIR(JIT, &H, SM, myResolver, nullptr);
LLVMOrcDisposeSharedModuleRef(SM);
MainFnTy MainFn = (MainFnTy)LLVMOrcGetSymbolAddress(JIT, "main");
LLVMOrcTargetAddress MainAddr;
LLVMOrcGetSymbolAddress(JIT, &MainAddr, "main");
MainFnTy MainFn = (MainFnTy)MainAddr;
int Result = MainFn();
EXPECT_EQ(Result, 42)
<< "Eagerly JIT'd code did not return expected result";
@ -115,10 +118,12 @@ TEST_F(OrcCAPIExecutionTest, TestLazyIRCompilation) {
LLVMOrcGetMangledSymbol(JIT, &testFuncName, "testFunc");
LLVMSharedModuleRef SM = LLVMOrcMakeSharedModule(wrap(M.release()));
LLVMOrcModuleHandle H =
LLVMOrcAddLazilyCompiledIR(JIT, SM, myResolver, nullptr);
LLVMOrcModuleHandle H;
LLVMOrcAddLazilyCompiledIR(JIT, &H, SM, myResolver, nullptr);
LLVMOrcDisposeSharedModuleRef(SM);
MainFnTy MainFn = (MainFnTy)LLVMOrcGetSymbolAddress(JIT, "main");
LLVMOrcTargetAddress MainAddr;
LLVMOrcGetSymbolAddress(JIT, &MainAddr, "main");
MainFnTy MainFn = (MainFnTy)MainAddr;
int Result = MainFn();
EXPECT_EQ(Result, 42)
<< "Lazily JIT'd code did not return expected result";
@ -140,11 +145,12 @@ TEST_F(OrcCAPIExecutionTest, TestDirectCallbacksAPI) {
CompileContext C;
C.APIExecTest = this;
LLVMOrcCreateIndirectStub(JIT, "foo",
LLVMOrcCreateLazyCompileCallback(JIT,
myCompileCallback,
&C));
MainFnTy FooFn = (MainFnTy)LLVMOrcGetSymbolAddress(JIT, "foo");
LLVMOrcTargetAddress CCAddr;
LLVMOrcCreateLazyCompileCallback(JIT, &CCAddr, myCompileCallback, &C);
LLVMOrcCreateIndirectStub(JIT, "foo", CCAddr);
LLVMOrcTargetAddress MainAddr;
LLVMOrcGetSymbolAddress(JIT, &MainAddr, "foo");
MainFnTy FooFn = (MainFnTy)MainAddr;
int Result = FooFn();
EXPECT_TRUE(C.Compiled)
<< "Function wasn't lazily compiled";

View File

@ -119,19 +119,21 @@ public:
RemoveModuleFtor &&RemoveModule,
FindSymbolFtor &&FindSymbol,
FindSymbolInFtor &&FindSymbolIn)
: AddModule(AddModule), RemoveModule(RemoveModule),
FindSymbol(FindSymbol), FindSymbolIn(FindSymbolIn)
: AddModule(std::move(AddModule)),
RemoveModule(std::move(RemoveModule)),
FindSymbol(std::move(FindSymbol)),
FindSymbolIn(std::move(FindSymbolIn))
{}
template <typename ModuleT, typename MemoryManagerPtrT,
typename SymbolResolverPtrT>
ModuleHandleT addModule(ModuleT Ms, MemoryManagerPtrT MemMgr,
SymbolResolverPtrT Resolver) {
Expected<ModuleHandleT> addModule(ModuleT Ms, MemoryManagerPtrT MemMgr,
SymbolResolverPtrT Resolver) {
return AddModule(std::move(Ms), std::move(MemMgr), std::move(Resolver));
}
void removeModule(ModuleHandleT H) {
RemoveModule(H);
Error removeModule(ModuleHandleT H) {
return RemoveModule(H);
}
JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly) {
@ -169,15 +171,24 @@ createMockBaseLayer(AddModuleFtor &&AddModule,
std::forward<FindSymbolInFtor>(FindSymbolIn));
}
class ReturnNullJITSymbol {
public:
template <typename... Args>
JITSymbol operator()(Args...) const {
return nullptr;
}
};
template <typename ReturnT>
class DoNothingAndReturn {
public:
DoNothingAndReturn(ReturnT Val) : Val(Val) {}
DoNothingAndReturn(ReturnT Ret) : Ret(std::move(Ret)) {}
template <typename... Args>
ReturnT operator()(Args...) const { return Val; }
void operator()(Args...) const { return Ret; }
private:
ReturnT Val;
ReturnT Ret;
};
template <>

View File

@ -103,21 +103,21 @@ TEST(RTDyldObjectLinkingLayerTest, TestSetProcessAllSections) {
{
// Test with ProcessAllSections = false (the default).
auto H = ObjLayer.addObject(Obj, Resolver);
ObjLayer.emitAndFinalize(H);
auto H = cantFail(ObjLayer.addObject(Obj, Resolver));
cantFail(ObjLayer.emitAndFinalize(H));
EXPECT_EQ(DebugSectionSeen, false)
<< "Unexpected debug info section";
ObjLayer.removeObject(H);
cantFail(ObjLayer.removeObject(H));
}
{
// Test with ProcessAllSections = true.
ObjLayer.setProcessAllSections(true);
auto H = ObjLayer.addObject(Obj, Resolver);
ObjLayer.emitAndFinalize(H);
auto H = cantFail(ObjLayer.addObject(Obj, Resolver));
cantFail(ObjLayer.emitAndFinalize(H));
EXPECT_EQ(DebugSectionSeen, true)
<< "Expected debug info section not seen";
ObjLayer.removeObject(H);
cantFail(ObjLayer.removeObject(H));
}
}
@ -181,10 +181,10 @@ TEST_F(RTDyldObjectLinkingLayerExecutionTest, NoDuplicateFinalization) {
return JITSymbol(nullptr);
});
ObjLayer.addObject(std::move(Obj1), Resolver);
auto H = ObjLayer.addObject(std::move(Obj2), Resolver);
ObjLayer.emitAndFinalize(H);
ObjLayer.removeObject(H);
cantFail(ObjLayer.addObject(std::move(Obj1), Resolver));
auto H = cantFail(ObjLayer.addObject(std::move(Obj2), Resolver));
cantFail(ObjLayer.emitAndFinalize(H));
cantFail(ObjLayer.removeObject(H));
// Finalization of module 2 should trigger finalization of module 1.
// Verify that finalize on SMMW is only called once.
@ -244,10 +244,10 @@ TEST_F(RTDyldObjectLinkingLayerExecutionTest, NoPrematureAllocation) {
Compile(*MB2.getModule()));
auto NR = std::make_shared<NullResolver>();
auto H = ObjLayer.addObject(std::move(Obj1), NR);
ObjLayer.addObject(std::move(Obj2), NR);
ObjLayer.emitAndFinalize(H);
ObjLayer.removeObject(H);
auto H = cantFail(ObjLayer.addObject(std::move(Obj1), NR));
cantFail(ObjLayer.addObject(std::move(Obj2), NR));
cantFail(ObjLayer.emitAndFinalize(H));
cantFail(ObjLayer.removeObject(H));
// Only one call to needsToReserveAllocationSpace should have been made.
EXPECT_EQ(MM->NeedsToReserveAllocationSpaceCount, 1)