1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 02:52:53 +02:00

[ORC] Switch the object layer API from addObjectSet to addObject (singular), and

move the ObjectCache from the IRCompileLayer to SimpleCompiler.

This is the first in a series of patches aimed at cleaning up and improving the
robustness and performance of the ORC APIs.

llvm-svn: 306058
This commit is contained in:
Lang Hames 2017-06-22 21:06:54 +00:00
parent 1ad2576dfe
commit efe8bd1023
16 changed files with 318 additions and 364 deletions

View File

@ -40,8 +40,8 @@ class KaleidoscopeJIT {
private:
std::unique_ptr<TargetMachine> TM;
const DataLayout DL;
RTDyldObjectLinkingLayer<> ObjectLayer;
IRCompileLayer<decltype(ObjectLayer)> CompileLayer;
RTDyldObjectLinkingLayer ObjectLayer;
IRCompileLayer<decltype(ObjectLayer), SimpleCompiler> CompileLayer;
public:
using ModuleHandle = decltype(CompileLayer)::ModuleSetHandleT;

View File

@ -44,8 +44,8 @@ class KaleidoscopeJIT {
private:
std::unique_ptr<TargetMachine> TM;
const DataLayout DL;
RTDyldObjectLinkingLayer<> ObjectLayer;
IRCompileLayer<decltype(ObjectLayer)> CompileLayer;
RTDyldObjectLinkingLayer ObjectLayer;
IRCompileLayer<decltype(ObjectLayer), SimpleCompiler> CompileLayer;
using OptimizeFunction =
std::function<std::unique_ptr<Module>(std::unique_ptr<Module>)>;

View File

@ -47,8 +47,8 @@ class KaleidoscopeJIT {
private:
std::unique_ptr<TargetMachine> TM;
const DataLayout DL;
RTDyldObjectLinkingLayer<> ObjectLayer;
IRCompileLayer<decltype(ObjectLayer)> CompileLayer;
RTDyldObjectLinkingLayer ObjectLayer;
IRCompileLayer<decltype(ObjectLayer), SimpleCompiler> CompileLayer;
using OptimizeFunction =
std::function<std::unique_ptr<Module>(std::unique_ptr<Module>)>;

View File

@ -73,8 +73,8 @@ class KaleidoscopeJIT {
private:
std::unique_ptr<TargetMachine> TM;
const DataLayout DL;
RTDyldObjectLinkingLayer<> ObjectLayer;
IRCompileLayer<decltype(ObjectLayer)> CompileLayer;
RTDyldObjectLinkingLayer ObjectLayer;
IRCompileLayer<decltype(ObjectLayer), SimpleCompiler> CompileLayer;
using OptimizeFunction =
std::function<std::unique_ptr<Module>(std::unique_ptr<Module>)>;

View File

@ -78,8 +78,8 @@ class KaleidoscopeJIT {
private:
std::unique_ptr<TargetMachine> TM;
const DataLayout DL;
RTDyldObjectLinkingLayer<> ObjectLayer;
IRCompileLayer<decltype(ObjectLayer)> CompileLayer;
RTDyldObjectLinkingLayer ObjectLayer;
IRCompileLayer<decltype(ObjectLayer), SimpleCompiler> CompileLayer;
using OptimizeFunction =
std::function<std::unique_ptr<Module>(std::unique_ptr<Module>)>;

View File

@ -39,8 +39,8 @@ namespace orc {
class KaleidoscopeJIT {
public:
using ObjLayerT = RTDyldObjectLinkingLayer<>;
using CompileLayerT = IRCompileLayer<ObjLayerT>;
using ObjLayerT = RTDyldObjectLinkingLayer;
using CompileLayerT = IRCompileLayer<ObjLayerT, SimpleCompiler>;
using ModuleHandleT = CompileLayerT::ModuleSetHandleT;
KaleidoscopeJIT()

View File

@ -15,6 +15,7 @@
#define LLVM_EXECUTIONENGINE_ORC_COMPILEUTILS_H
#include "llvm/ADT/SmallVector.h"
#include "llvm/ExecutionEngine/ObjectCache.h"
#include "llvm/ExecutionEngine/ObjectMemoryBuffer.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/Object/Binary.h"
@ -38,11 +39,22 @@ namespace orc {
/// ObjectFile.
class SimpleCompiler {
public:
using CompileResult = object::OwningBinary<object::ObjectFile>;
/// @brief Construct a simple compile functor with the given target.
SimpleCompiler(TargetMachine &TM) : TM(TM) {}
SimpleCompiler(TargetMachine &TM, ObjectCache *ObjCache = nullptr)
: TM(TM), ObjCache(ObjCache) {}
/// @brief Set an ObjectCache to query before compiling.
void setObjectCache(ObjectCache *NewCache) { ObjCache = NewCache; }
/// @brief Compile a Module to an ObjectFile.
object::OwningBinary<object::ObjectFile> operator()(Module &M) const {
CompileResult operator()(Module &M) {
CompileResult CachedObject = tryToLoadFromObjectCache(M);
if (CachedObject.getBinary())
return CachedObject;
SmallVector<char, 0> ObjBufferSV;
raw_svector_ostream ObjStream(ObjBufferSV);
@ -55,16 +67,43 @@ public:
new ObjectMemoryBuffer(std::move(ObjBufferSV)));
Expected<std::unique_ptr<object::ObjectFile>> Obj =
object::ObjectFile::createObjectFile(ObjBuffer->getMemBufferRef());
using OwningObj = object::OwningBinary<object::ObjectFile>;
if (Obj)
return OwningObj(std::move(*Obj), std::move(ObjBuffer));
if (Obj) {
notifyObjectCompiled(M, *ObjBuffer);
return CompileResult(std::move(*Obj), std::move(ObjBuffer));
}
// TODO: Actually report errors helpfully.
consumeError(Obj.takeError());
return OwningObj(nullptr, nullptr);
return CompileResult(nullptr, nullptr);
}
private:
CompileResult tryToLoadFromObjectCache(const Module &M) {
if (!ObjCache)
return CompileResult();
std::unique_ptr<MemoryBuffer> ObjBuffer = ObjCache->getObject(&M);
if (!ObjBuffer)
return CompileResult();
Expected<std::unique_ptr<object::ObjectFile>> Obj =
object::ObjectFile::createObjectFile(ObjBuffer->getMemBufferRef());
if (!Obj) {
// TODO: Actually report errors helpfully.
consumeError(Obj.takeError());
return CompileResult();
}
return CompileResult(std::move(*Obj), std::move(ObjBuffer));
}
void notifyObjectCompiled(const Module &M, const MemoryBuffer &ObjBuffer) {
if (ObjCache)
ObjCache->notifyObjectCompiled(&M, ObjBuffer.getMemBufferRef());
}
TargetMachine &TM;
ObjectCache *ObjCache = nullptr;
};
} // end namespace orc

View File

@ -16,16 +16,9 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ExecutionEngine/JITSymbol.h"
#include "llvm/ExecutionEngine/ObjectCache.h"
#include "llvm/Object/Binary.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/MemoryBuffer.h"
#include <algorithm>
#include <functional>
#include <memory>
#include <string>
#include <vector>
namespace llvm {
@ -39,25 +32,19 @@ namespace orc {
/// immediately compiles each IR module to an object file (each IR Module is
/// compiled separately). The resulting set of object files is then added to
/// the layer below, which must implement the object layer concept.
template <typename BaseLayerT> class IRCompileLayer {
public:
using CompileFtor =
std::function<object::OwningBinary<object::ObjectFile>(Module &)>;
private:
using ObjSetHandleT = typename BaseLayerT::ObjSetHandleT;
template <typename BaseLayerT, typename CompileFtor>
class IRCompileLayer {
public:
/// @brief Handle to a set of compiled modules.
using ModuleSetHandleT = ObjSetHandleT;
using ModuleSetHandleT = typename BaseLayerT::ObjHandleT;
/// @brief Construct an IRCompileLayer with the given BaseLayer, which must
/// implement the ObjectLayer concept.
IRCompileLayer(BaseLayerT &BaseLayer, CompileFtor Compile)
: BaseLayer(BaseLayer), Compile(std::move(Compile)) {}
/// @brief Set an ObjectCache to query before compiling.
void setObjectCache(ObjectCache *NewCache) { ObjCache = NewCache; }
/// @brief Get a reference to the compiler functor.
CompileFtor& getCompiler() { return Compile; }
/// @brief Compile each module in the given module set, then add the resulting
/// set of objects to the base layer along with the memory manager and
@ -69,35 +56,15 @@ public:
ModuleSetHandleT addModuleSet(ModuleSetT Ms,
MemoryManagerPtrT MemMgr,
SymbolResolverPtrT Resolver) {
std::vector<std::unique_ptr<object::OwningBinary<object::ObjectFile>>>
Objects;
for (const auto &M : Ms) {
auto Object =
llvm::make_unique<object::OwningBinary<object::ObjectFile>>();
if (ObjCache)
*Object = tryToLoadFromObjectCache(*M);
if (!Object->getBinary()) {
*Object = Compile(*M);
if (ObjCache)
ObjCache->notifyObjectCompiled(&*M,
Object->getBinary()->getMemoryBufferRef());
}
Objects.push_back(std::move(Object));
}
ModuleSetHandleT H =
BaseLayer.addObjectSet(std::move(Objects), std::move(MemMgr),
std::move(Resolver));
return H;
assert(Ms.size() == 1);
using CompileResult = decltype(Compile(*Ms.front()));
auto Obj = std::make_shared<CompileResult>(Compile(*Ms.front()));
return BaseLayer.addObject(std::move(Obj), std::move(MemMgr),
std::move(Resolver));
}
/// @brief Remove the module set associated with the handle H.
void removeModuleSet(ModuleSetHandleT H) { BaseLayer.removeObjectSet(H); }
void removeModuleSet(ModuleSetHandleT H) { BaseLayer.removeObject(H); }
/// @brief Search for the given named symbol.
/// @param Name The name of the symbol to search for.
@ -128,27 +95,8 @@ public:
}
private:
object::OwningBinary<object::ObjectFile>
tryToLoadFromObjectCache(const Module &M) {
std::unique_ptr<MemoryBuffer> ObjBuffer = ObjCache->getObject(&M);
if (!ObjBuffer)
return object::OwningBinary<object::ObjectFile>();
Expected<std::unique_ptr<object::ObjectFile>> Obj =
object::ObjectFile::createObjectFile(ObjBuffer->getMemBufferRef());
if (!Obj) {
// TODO: Actually report errors helpfully.
consumeError(Obj.takeError());
return object::OwningBinary<object::ObjectFile>();
}
return object::OwningBinary<object::ObjectFile>(std::move(*Obj),
std::move(ObjBuffer));
}
BaseLayerT &BaseLayer;
CompileFtor Compile;
ObjectCache *ObjCache = nullptr;
};
} // end namespace orc

View File

@ -23,14 +23,14 @@ namespace orc {
/// @brief Object mutating layer.
///
/// This layer accepts sets of ObjectFiles (via addObjectSet). It
/// This layer accepts sets of ObjectFiles (via addObject). It
/// immediately applies the user supplied functor to each object, then adds
/// the set of transformed objects to the layer below.
template <typename BaseLayerT, typename TransformFtor>
class ObjectTransformLayer {
public:
/// @brief Handle to a set of added objects.
using ObjSetHandleT = typename BaseLayerT::ObjSetHandleT;
using ObjHandleT = typename BaseLayerT::ObjHandleT;
/// @brief Construct an ObjectTransformLayer with the given BaseLayer
ObjectTransformLayer(BaseLayerT &BaseLayer,
@ -42,19 +42,16 @@ public:
/// memory manager and symbol resolver.
///
/// @return A handle for the added objects.
template <typename ObjSetT, typename MemoryManagerPtrT,
template <typename ObjPtrT, typename MemoryManagerPtrT,
typename SymbolResolverPtrT>
ObjSetHandleT addObjectSet(ObjSetT Objects, MemoryManagerPtrT MemMgr,
SymbolResolverPtrT Resolver) {
for (auto I = Objects.begin(), E = Objects.end(); I != E; ++I)
*I = Transform(std::move(*I));
return BaseLayer.addObjectSet(std::move(Objects), std::move(MemMgr),
std::move(Resolver));
ObjHandleT addObject(ObjPtrT Obj, MemoryManagerPtrT MemMgr,
SymbolResolverPtrT Resolver) {
return BaseLayer.addObject(Transform(std::move(Obj)), std::move(MemMgr),
std::move(Resolver));
}
/// @brief Remove the object set associated with the handle H.
void removeObjectSet(ObjSetHandleT H) { BaseLayer.removeObjectSet(H); }
void removeObject(ObjHandleT H) { BaseLayer.removeObject(H); }
/// @brief Search for the given named symbol.
/// @param Name The name of the symbol to search for.
@ -72,7 +69,7 @@ public:
/// @param ExportedSymbolsOnly If true, search only for exported symbols.
/// @return A handle for the given named symbol, if it is found in the
/// given object set.
JITSymbol findSymbolIn(ObjSetHandleT H, const std::string &Name,
JITSymbol findSymbolIn(ObjHandleT H, const std::string &Name,
bool ExportedSymbolsOnly) {
return BaseLayer.findSymbolIn(H, Name, ExportedSymbolsOnly);
}
@ -80,10 +77,10 @@ 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(ObjSetHandleT H) { BaseLayer.emitAndFinalize(H); }
void emitAndFinalize(ObjHandleT H) { BaseLayer.emitAndFinalize(H); }
/// @brief Map section addresses for the objects associated with the handle H.
void mapSectionAddress(ObjSetHandleT H, const void *LocalAddress,
void mapSectionAddress(ObjHandleT H, const void *LocalAddress,
JITTargetAddress TargetAddr) {
BaseLayer.mapSectionAddress(H, LocalAddress, TargetAddr);
}

View File

@ -174,6 +174,12 @@ private:
ArgV[0] = "<jit process>";
for (auto &Arg : Args)
ArgV[Idx++] = Arg.c_str();
ArgV[ArgC] = 0;
DEBUG(
for (int Idx = 0; Idx < ArgC; ++Idx) {
llvm::dbgs() << "Arg " << Idx << ": " << ArgV[Idx] << "\n";
}
);
DEBUG(dbgs() << " Calling " << format("0x%016x", Addr) << "\n");
int Result = Fn(ArgC, ArgV.get());

View File

@ -35,19 +35,23 @@ namespace orc {
class RTDyldObjectLinkingLayerBase {
protected:
using ObjectPtr =
std::shared_ptr<object::OwningBinary<object::ObjectFile>>;
/// @brief Holds a set of objects to be allocated/linked as a unit in the JIT.
///
/// An instance of this class will be created for each set of objects added
/// via JITObjectLayer::addObjectSet. Deleting the instance (via
/// removeObjectSet) frees its memory, removing all symbol definitions that
/// via JITObjectLayer::addObject. Deleting the instance (via
/// removeObject) frees its memory, removing all symbol definitions that
/// had been provided by this instance. Higher level layers are responsible
/// for taking any action required to handle the missing symbols.
class LinkedObjectSet {
class LinkedObject {
public:
LinkedObjectSet() = default;
LinkedObjectSet(const LinkedObjectSet&) = delete;
void operator=(const LinkedObjectSet&) = delete;
virtual ~LinkedObjectSet() = default;
LinkedObject() = default;
LinkedObject(const LinkedObject&) = delete;
void operator=(const LinkedObject&) = delete;
virtual ~LinkedObject() = default;
virtual void finalize() = 0;
@ -74,19 +78,11 @@ protected:
bool Finalized = false;
};
using LinkedObjectSetListT = std::list<std::unique_ptr<LinkedObjectSet>>;
using LinkedObjectListT = std::list<std::unique_ptr<LinkedObject>>;
public:
/// @brief Handle to a set of loaded objects.
using ObjSetHandleT = LinkedObjectSetListT::iterator;
};
/// @brief Default (no-op) action to perform when loading objects.
class DoNothingOnNotifyLoaded {
public:
template <typename ObjSetT, typename LoadResult>
void operator()(RTDyldObjectLinkingLayerBase::ObjSetHandleT, const ObjSetT &,
const LoadResult &) {}
using ObjHandleT = LinkedObjectListT::iterator;
};
/// @brief Bare bones object linking layer.
@ -95,46 +91,54 @@ public:
/// object files to be loaded into memory, linked, and the addresses of their
/// symbols queried. All objects added to this layer can see each other's
/// symbols.
template <typename NotifyLoadedFtor = DoNothingOnNotifyLoaded>
class RTDyldObjectLinkingLayer : public RTDyldObjectLinkingLayerBase {
public:
using RTDyldObjectLinkingLayerBase::ObjectPtr;
/// @brief Functor for receiving object-loaded notifications.
using NotifyLoadedFtor = std::function<void(ObjHandleT, const ObjectPtr &Obj,
const LoadedObjectInfo &)>;
/// @brief Functor for receiving finalization notifications.
using NotifyFinalizedFtor = std::function<void(ObjSetHandleT)>;
using NotifyFinalizedFtor = std::function<void(ObjHandleT)>;
private:
template <typename ObjSetT, typename MemoryManagerPtrT,
typename SymbolResolverPtrT, typename FinalizerFtor>
class ConcreteLinkedObjectSet : public LinkedObjectSet {
template <typename MemoryManagerPtrT, typename SymbolResolverPtrT,
typename FinalizerFtor>
class ConcreteLinkedObject : public LinkedObject {
public:
ConcreteLinkedObjectSet(ObjSetT Objects, MemoryManagerPtrT MemMgr,
SymbolResolverPtrT Resolver,
FinalizerFtor Finalizer,
bool ProcessAllSections)
ConcreteLinkedObject(ObjectPtr Obj, MemoryManagerPtrT MemMgr,
SymbolResolverPtrT Resolver,
FinalizerFtor Finalizer,
bool ProcessAllSections)
: MemMgr(std::move(MemMgr)),
PFC(llvm::make_unique<PreFinalizeContents>(std::move(Objects),
PFC(llvm::make_unique<PreFinalizeContents>(std::move(Obj),
std::move(Resolver),
std::move(Finalizer),
ProcessAllSections)) {
buildInitialSymbolTable(PFC->Objects);
buildInitialSymbolTable(PFC->Obj);
}
~ConcreteLinkedObjectSet() override {
~ConcreteLinkedObject() override {
MemMgr->deregisterEHFrames();
}
void setHandle(ObjSetHandleT H) {
void setHandle(ObjHandleT H) {
PFC->Handle = H;
}
void finalize() override {
assert(PFC && "mapSectionAddress called on finalized LinkedObjectSet");
assert(PFC && "mapSectionAddress called on finalized LinkedObject");
RuntimeDyld RTDyld(*MemMgr, *PFC->Resolver);
RTDyld.setProcessAllSections(PFC->ProcessAllSections);
PFC->RTDyld = &RTDyld;
this->Finalized = true;
PFC->Finalizer(PFC->Handle, RTDyld, std::move(PFC->Objects),
PFC->Finalizer(PFC->Handle, RTDyld, std::move(PFC->Obj),
[&]() {
this->updateSymbolTable(RTDyld);
});
@ -156,27 +160,27 @@ private:
void mapSectionAddress(const void *LocalAddress,
JITTargetAddress TargetAddr) const override {
assert(PFC && "mapSectionAddress called on finalized LinkedObjectSet");
assert(PFC->RTDyld && "mapSectionAddress called on raw LinkedObjectSet");
assert(PFC && "mapSectionAddress called on finalized LinkedObject");
assert(PFC->RTDyld && "mapSectionAddress called on raw LinkedObject");
PFC->RTDyld->mapSectionAddress(LocalAddress, TargetAddr);
}
private:
void buildInitialSymbolTable(const ObjSetT &Objects) {
for (const auto &Obj : Objects)
for (auto &Symbol : getObject(*Obj).symbols()) {
if (Symbol.getFlags() & object::SymbolRef::SF_Undefined)
continue;
Expected<StringRef> SymbolName = Symbol.getName();
// FIXME: Raise an error for bad symbols.
if (!SymbolName) {
consumeError(SymbolName.takeError());
continue;
}
auto Flags = JITSymbolFlags::fromObjectSymbol(Symbol);
SymbolTable.insert(
std::make_pair(*SymbolName, JITEvaluatedSymbol(0, Flags)));
void buildInitialSymbolTable(const ObjectPtr &Obj) {
for (auto &Symbol : Obj->getBinary()->symbols()) {
if (Symbol.getFlags() & object::SymbolRef::SF_Undefined)
continue;
Expected<StringRef> SymbolName = Symbol.getName();
// FIXME: Raise an error for bad symbols.
if (!SymbolName) {
consumeError(SymbolName.takeError());
continue;
}
auto Flags = JITSymbolFlags::fromObjectSymbol(Symbol);
SymbolTable.insert(
std::make_pair(*SymbolName, JITEvaluatedSymbol(0, Flags)));
}
}
void updateSymbolTable(const RuntimeDyld &RTDyld) {
@ -187,17 +191,17 @@ private:
// Contains the information needed prior to finalization: the object files,
// memory manager, resolver, and flags needed for RuntimeDyld.
struct PreFinalizeContents {
PreFinalizeContents(ObjSetT Objects, SymbolResolverPtrT Resolver,
PreFinalizeContents(ObjectPtr Obj, SymbolResolverPtrT Resolver,
FinalizerFtor Finalizer, bool ProcessAllSections)
: Objects(std::move(Objects)), Resolver(std::move(Resolver)),
: Obj(std::move(Obj)), Resolver(std::move(Resolver)),
Finalizer(std::move(Finalizer)),
ProcessAllSections(ProcessAllSections) {}
ObjSetT Objects;
ObjectPtr Obj;
SymbolResolverPtrT Resolver;
FinalizerFtor Finalizer;
bool ProcessAllSections;
ObjSetHandleT Handle;
ObjHandleT Handle;
RuntimeDyld *RTDyld;
};
@ -205,27 +209,22 @@ private:
std::unique_ptr<PreFinalizeContents> PFC;
};
template <typename ObjSetT, typename MemoryManagerPtrT,
typename SymbolResolverPtrT, typename FinalizerFtor>
template <typename MemoryManagerPtrT, typename SymbolResolverPtrT,
typename FinalizerFtor>
std::unique_ptr<
ConcreteLinkedObjectSet<ObjSetT, MemoryManagerPtrT,
SymbolResolverPtrT, FinalizerFtor>>
createLinkedObjectSet(ObjSetT Objects, MemoryManagerPtrT MemMgr,
SymbolResolverPtrT Resolver,
FinalizerFtor Finalizer,
bool ProcessAllSections) {
using LOS = ConcreteLinkedObjectSet<ObjSetT, MemoryManagerPtrT,
SymbolResolverPtrT, FinalizerFtor>;
return llvm::make_unique<LOS>(std::move(Objects), std::move(MemMgr),
ConcreteLinkedObject<MemoryManagerPtrT, SymbolResolverPtrT, FinalizerFtor>>
createLinkedObject(ObjectPtr Obj, MemoryManagerPtrT MemMgr,
SymbolResolverPtrT Resolver,
FinalizerFtor Finalizer,
bool ProcessAllSections) {
using LOS = ConcreteLinkedObject<MemoryManagerPtrT, SymbolResolverPtrT,
FinalizerFtor>;
return llvm::make_unique<LOS>(std::move(Obj), std::move(MemMgr),
std::move(Resolver), std::move(Finalizer),
ProcessAllSections);
}
public:
/// @brief LoadedObjectInfo list. Contains a list of owning pointers to
/// RuntimeDyld::LoadedObjectInfo instances.
using LoadedObjInfoList =
std::vector<std::unique_ptr<RuntimeDyld::LoadedObjectInfo>>;
/// @brief Construct an ObjectLinkingLayer with the given NotifyLoaded,
/// and NotifyFinalized functors.
@ -250,23 +249,22 @@ public:
///
/// @return A handle that can be used to refer to the loaded objects (for
/// symbol searching, finalization, freeing memory, etc.).
template <typename ObjSetT,
typename MemoryManagerPtrT,
template <typename MemoryManagerPtrT,
typename SymbolResolverPtrT>
ObjSetHandleT addObjectSet(ObjSetT Objects,
MemoryManagerPtrT MemMgr,
SymbolResolverPtrT Resolver) {
auto Finalizer = [&](ObjSetHandleT H, RuntimeDyld &RTDyld,
const ObjSetT &Objs,
std::function<void()> LOSHandleLoad) {
LoadedObjInfoList LoadedObjInfos;
ObjHandleT addObject(ObjectPtr Obj,
MemoryManagerPtrT MemMgr,
SymbolResolverPtrT Resolver) {
for (auto &Obj : Objs)
LoadedObjInfos.push_back(RTDyld.loadObject(this->getObject(*Obj)));
auto Finalizer = [&](ObjHandleT H, RuntimeDyld &RTDyld,
const ObjectPtr &ObjToLoad,
std::function<void()> LOSHandleLoad) {
std::unique_ptr<RuntimeDyld::LoadedObjectInfo> Info =
RTDyld.loadObject(*ObjToLoad->getBinary());
LOSHandleLoad();
this->NotifyLoaded(H, Objs, LoadedObjInfos);
if (this->NotifyLoaded)
this->NotifyLoaded(H, ObjToLoad, *Info);
RTDyld.finalizeWithMemoryManagerLocking();
@ -274,17 +272,15 @@ public:
this->NotifyFinalized(H);
};
auto LOS =
createLinkedObjectSet(std::move(Objects), std::move(MemMgr),
std::move(Resolver), std::move(Finalizer),
ProcessAllSections);
auto LO =
createLinkedObject(std::move(Obj), std::move(MemMgr), std::move(Resolver),
std::move(Finalizer), ProcessAllSections);
// LOS is an owning-ptr. Keep a non-owning one so that we can set the handle
// below.
auto *LOSPtr = LOS.get();
auto *LOPtr = LO.get();
ObjSetHandleT Handle = LinkedObjSetList.insert(LinkedObjSetList.end(),
std::move(LOS));
LOSPtr->setHandle(Handle);
ObjHandleT Handle = LinkedObjList.insert(LinkedObjList.end(), std::move(LO));
LOPtr->setHandle(Handle);
return Handle;
}
@ -297,9 +293,9 @@ 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 removeObjectSet(ObjSetHandleT H) {
void removeObject(ObjHandleT H) {
// How do we invalidate the symbols in H?
LinkedObjSetList.erase(H);
LinkedObjList.erase(H);
}
/// @brief Search for the given named symbol.
@ -307,7 +303,7 @@ public:
/// @param ExportedSymbolsOnly If true, search only for exported symbols.
/// @return A handle for the given named symbol, if it exists.
JITSymbol findSymbol(StringRef Name, bool ExportedSymbolsOnly) {
for (auto I = LinkedObjSetList.begin(), E = LinkedObjSetList.end(); I != E;
for (auto I = LinkedObjList.begin(), E = LinkedObjList.end(); I != E;
++I)
if (auto Symbol = findSymbolIn(I, Name, ExportedSymbolsOnly))
return Symbol;
@ -322,13 +318,13 @@ public:
/// @param ExportedSymbolsOnly If true, search only for exported symbols.
/// @return A handle for the given named symbol, if it is found in the
/// given object set.
JITSymbol findSymbolIn(ObjSetHandleT H, StringRef Name,
JITSymbol findSymbolIn(ObjHandleT H, StringRef Name,
bool ExportedSymbolsOnly) {
return (*H)->getSymbol(Name, ExportedSymbolsOnly);
}
/// @brief Map section addresses for the objects associated with the handle H.
void mapSectionAddress(ObjSetHandleT H, const void *LocalAddress,
void mapSectionAddress(ObjHandleT H, const void *LocalAddress,
JITTargetAddress TargetAddr) {
(*H)->mapSectionAddress(LocalAddress, TargetAddr);
}
@ -336,22 +332,13 @@ 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(ObjSetHandleT H) {
void emitAndFinalize(ObjHandleT H) {
(*H)->finalize();
}
private:
static const object::ObjectFile& getObject(const object::ObjectFile &Obj) {
return Obj;
}
template <typename ObjT>
static const object::ObjectFile&
getObject(const object::OwningBinary<ObjT> &Obj) {
return *Obj.getBinary();
}
LinkedObjectSetListT LinkedObjSetList;
LinkedObjectListT LinkedObjList;
NotifyLoadedFtor NotifyLoaded;
NotifyFinalizedFtor NotifyFinalized;
bool ProcessAllSections = false;

View File

@ -47,11 +47,12 @@ DEFINE_SIMPLE_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef)
class OrcCBindingsStack {
public:
using CompileCallbackMgr = orc::JITCompileCallbackManager;
using ObjLayerT = orc::RTDyldObjectLinkingLayer<>;
using CompileLayerT = orc::IRCompileLayer<ObjLayerT>;
using ObjLayerT = orc::RTDyldObjectLinkingLayer;
using CompileLayerT = orc::IRCompileLayer<ObjLayerT, orc::SimpleCompiler>;
using CODLayerT =
orc::CompileOnDemandLayer<CompileLayerT, CompileCallbackMgr>;
orc::CompileOnDemandLayer<CompileLayerT, CompileCallbackMgr>;
using CallbackManagerBuilder =
std::function<std::unique_ptr<CompileCallbackMgr>()>;

View File

@ -198,17 +198,16 @@ public:
}
void addObjectFile(std::unique_ptr<object::ObjectFile> O) override {
std::vector<std::unique_ptr<object::ObjectFile>> Objs;
Objs.push_back(std::move(O));
ObjectLayer.addObjectSet(std::move(Objs), &MemMgr, &Resolver);
auto Obj =
std::make_shared<object::OwningBinary<object::ObjectFile>>(std::move(O),
nullptr);
ObjectLayer.addObject(std::move(Obj), &MemMgr, &Resolver);
}
void addObjectFile(object::OwningBinary<object::ObjectFile> O) override {
std::vector<std::unique_ptr<object::OwningBinary<object::ObjectFile>>> Objs;
Objs.push_back(
llvm::make_unique<object::OwningBinary<object::ObjectFile>>(
std::move(O)));
ObjectLayer.addObjectSet(std::move(Objs), &MemMgr, &Resolver);
auto Obj =
std::make_shared<object::OwningBinary<object::ObjectFile>>(std::move(O));
ObjectLayer.addObject(std::move(Obj), &MemMgr, &Resolver);
}
void addArchive(object::OwningBinary<object::Archive> A) override {
@ -260,7 +259,7 @@ public:
ArrayRef<GenericValue> ArgValues) override;
void setObjectCache(ObjectCache *NewCache) override {
CompileLayer.setObjectCache(NewCache);
CompileLayer.getCompiler().setObjectCache(NewCache);
}
void setProcessAllSections(bool ProcessAllSections) override {
@ -298,10 +297,12 @@ private:
}
std::unique_ptr<object::Binary> &ChildBin = ChildBinOrErr.get();
if (ChildBin->isObject()) {
std::vector<std::unique_ptr<object::ObjectFile>> ObjSet;
ObjSet.push_back(std::unique_ptr<object::ObjectFile>(
static_cast<object::ObjectFile *>(ChildBin.release())));
ObjectLayer.addObjectSet(std::move(ObjSet), &MemMgr, &Resolver);
std::unique_ptr<object::ObjectFile> ChildObj(
static_cast<object::ObjectFile*>(ChildBinOrErr->release()));
auto Obj =
std::make_shared<object::OwningBinary<object::ObjectFile>>(
std::move(ChildObj), nullptr);
ObjectLayer.addObject(std::move(Obj), &MemMgr, &Resolver);
if (auto Sym = ObjectLayer.findSymbol(Name, true))
return Sym;
}
@ -317,29 +318,14 @@ private:
NotifyObjectLoadedT(OrcMCJITReplacement &M) : M(M) {}
template <typename ObjListT>
void operator()(RTDyldObjectLinkingLayerBase::ObjSetHandleT H,
const ObjListT &Objects,
const LoadedObjInfoListT &Infos) const {
void operator()(RTDyldObjectLinkingLayerBase::ObjHandleT H,
const RTDyldObjectLinkingLayer::ObjectPtr &Obj,
const LoadedObjectInfo &Info) const {
M.UnfinalizedSections[H] = std::move(M.SectionsAllocatedSinceLastLoad);
M.SectionsAllocatedSinceLastLoad = SectionAddrSet();
assert(Objects.size() == Infos.size() &&
"Incorrect number of Infos for Objects.");
for (unsigned I = 0; I < Objects.size(); ++I)
M.MemMgr.notifyObjectLoaded(&M, getObject(*Objects[I]));
M.MemMgr.notifyObjectLoaded(&M, *Obj->getBinary());
}
private:
static const object::ObjectFile& getObject(const object::ObjectFile &Obj) {
return Obj;
}
template <typename ObjT>
static const object::ObjectFile&
getObject(const object::OwningBinary<ObjT> &Obj) {
return *Obj.getBinary();
}
OrcMCJITReplacement &M;
};
@ -347,7 +333,7 @@ private:
public:
NotifyFinalizedT(OrcMCJITReplacement &M) : M(M) {}
void operator()(RTDyldObjectLinkingLayerBase::ObjSetHandleT H) {
void operator()(RTDyldObjectLinkingLayerBase::ObjHandleT H) {
M.UnfinalizedSections.erase(H);
}
@ -364,8 +350,8 @@ private:
return MangledName;
}
using ObjectLayerT = RTDyldObjectLinkingLayer<NotifyObjectLoadedT>;
using CompileLayerT = IRCompileLayer<ObjectLayerT>;
using ObjectLayerT = RTDyldObjectLinkingLayer;
using CompileLayerT = IRCompileLayer<ObjectLayerT, orc::SimpleCompiler>;
using LazyEmitLayerT = LazyEmittingLayer<CompileLayerT>;
std::unique_ptr<TargetMachine> TM;
@ -385,14 +371,14 @@ private:
// that have been emitted but not yet finalized so that we can forward the
// mapSectionAddress calls appropriately.
using SectionAddrSet = std::set<const void *>;
struct ObjSetHandleCompare {
bool operator()(ObjectLayerT::ObjSetHandleT H1,
ObjectLayerT::ObjSetHandleT H2) const {
struct ObjHandleCompare {
bool operator()(ObjectLayerT::ObjHandleT H1,
ObjectLayerT::ObjHandleT H2) const {
return &*H1 < &*H2;
}
};
SectionAddrSet SectionsAllocatedSinceLastLoad;
std::map<ObjectLayerT::ObjSetHandleT, SectionAddrSet, ObjSetHandleCompare>
std::map<ObjectLayerT::ObjHandleT, SectionAddrSet, ObjHandleCompare>
UnfinalizedSections;
std::vector<object::OwningBinary<object::Archive>> Archives;

View File

@ -45,11 +45,12 @@ namespace llvm {
class OrcLazyJIT {
public:
using CompileCallbackMgr = orc::JITCompileCallbackManager;
using ObjLayerT = orc::RTDyldObjectLinkingLayer<>;
using CompileLayerT = orc::IRCompileLayer<ObjLayerT>;
using ObjLayerT = orc::RTDyldObjectLinkingLayer;
using CompileLayerT = orc::IRCompileLayer<ObjLayerT, orc::SimpleCompiler>;
using TransformFtor =
std::function<std::unique_ptr<Module>(std::unique_ptr<Module>)>;
std::function<std::unique_ptr<Module>(std::unique_ptr<Module>)>;
using IRDumpLayerT = orc::IRTransformLayer<CompileLayerT, TransformFtor>;
using CODLayerT = orc::CompileOnDemandLayer<IRDumpLayerT, CompileCallbackMgr>;
using IndirectStubsManagerBuilder = CODLayerT::IndirectStubsManagerBuilderT;

View File

@ -31,14 +31,14 @@ typedef int MockSymbolResolver;
typedef int MockObjectFile;
// stand-in for llvm::MemoryBuffer set
typedef int MockMemoryBufferSet;
typedef int MockMemoryBuffer;
// Mock transform that operates on unique pointers to object files, and
// allocates new object files rather than mutating the given ones.
struct AllocatingTransform {
std::unique_ptr<MockObjectFile>
operator()(std::unique_ptr<MockObjectFile> Obj) const {
return llvm::make_unique<MockObjectFile>(*Obj + 1);
std::shared_ptr<MockObjectFile>
operator()(std::shared_ptr<MockObjectFile> Obj) const {
return std::make_shared<MockObjectFile>(*Obj + 1);
}
};
@ -50,48 +50,41 @@ struct AllocatingTransform {
// transform layer called the base layer and forwarded any return value.
class MockBaseLayer {
public:
typedef int ObjSetHandleT;
typedef int ObjHandleT;
MockBaseLayer() : MockSymbol(nullptr) { resetExpectations(); }
template <typename ObjSetT, typename MemoryManagerPtrT,
template <typename ObjPtrT, typename MemoryManagerPtrT,
typename SymbolResolverPtrT>
ObjSetHandleT addObjectSet(ObjSetT Objects, MemoryManagerPtrT MemMgr,
SymbolResolverPtrT Resolver) {
ObjHandleT addObject(ObjPtrT Obj, MemoryManagerPtrT MemMgr,
SymbolResolverPtrT Resolver) {
EXPECT_EQ(MockManager, *MemMgr) << "MM should pass through";
EXPECT_EQ(MockResolver, *Resolver) << "Resolver should pass through";
size_t I = 0;
for (auto &ObjPtr : Objects) {
EXPECT_EQ(MockObjects[I] + 1, *ObjPtr) << "Transform should be applied";
I++;
}
EXPECT_EQ(MockObjects.size(), I) << "Number of objects should match";
LastCalled = "addObjectSet";
MockObjSetHandle = 111;
return MockObjSetHandle;
EXPECT_EQ(MockObject + 1, *Obj) << "Transform should be applied";
LastCalled = "addObject";
MockObjHandle = 111;
return MockObjHandle;
}
template <typename ObjSetT>
void expectAddObjectSet(ObjSetT &Objects, MockMemoryManager *MemMgr,
MockSymbolResolver *Resolver) {
template <typename ObjPtrT>
void expectAddObject(ObjPtrT Obj, MockMemoryManager *MemMgr,
MockSymbolResolver *Resolver) {
MockManager = *MemMgr;
MockResolver = *Resolver;
for (auto &ObjPtr : Objects) {
MockObjects.push_back(*ObjPtr);
}
MockObject = *Obj;
}
void verifyAddObjectSet(ObjSetHandleT Returned) {
EXPECT_EQ("addObjectSet", LastCalled);
EXPECT_EQ(MockObjSetHandle, Returned) << "Return should pass through";
void verifyAddObject(ObjHandleT Returned) {
EXPECT_EQ("addObject", LastCalled);
EXPECT_EQ(MockObjHandle, Returned) << "Return should pass through";
resetExpectations();
}
void removeObjectSet(ObjSetHandleT H) {
EXPECT_EQ(MockObjSetHandle, H);
LastCalled = "removeObjectSet";
void removeObject(ObjHandleT H) {
EXPECT_EQ(MockObjHandle, H);
LastCalled = "removeObject";
}
void expectRemoveObjectSet(ObjSetHandleT H) { MockObjSetHandle = H; }
void verifyRemoveObjectSet() {
EXPECT_EQ("removeObjectSet", LastCalled);
void expectRemoveObject(ObjHandleT H) { MockObjHandle = H; }
void verifyRemoveObject() {
EXPECT_EQ("removeObject", LastCalled);
resetExpectations();
}
@ -114,18 +107,18 @@ public:
resetExpectations();
}
llvm::JITSymbol findSymbolIn(ObjSetHandleT H, const std::string &Name,
llvm::JITSymbol findSymbolIn(ObjHandleT H, const std::string &Name,
bool ExportedSymbolsOnly) {
EXPECT_EQ(MockObjSetHandle, H) << "Handle should pass through";
EXPECT_EQ(MockObjHandle, H) << "Handle should pass through";
EXPECT_EQ(MockName, Name) << "Name should pass through";
EXPECT_EQ(MockBool, ExportedSymbolsOnly) << "Flag should pass through";
LastCalled = "findSymbolIn";
MockSymbol = llvm::JITSymbol(122, llvm::JITSymbolFlags::None);
return MockSymbol;
}
void expectFindSymbolIn(ObjSetHandleT H, const std::string &Name,
void expectFindSymbolIn(ObjHandleT H, const std::string &Name,
bool ExportedSymbolsOnly) {
MockObjSetHandle = H;
MockObjHandle = H;
MockName = Name;
MockBool = ExportedSymbolsOnly;
}
@ -136,26 +129,26 @@ public:
resetExpectations();
}
void emitAndFinalize(ObjSetHandleT H) {
EXPECT_EQ(MockObjSetHandle, H) << "Handle should pass through";
void emitAndFinalize(ObjHandleT H) {
EXPECT_EQ(MockObjHandle, H) << "Handle should pass through";
LastCalled = "emitAndFinalize";
}
void expectEmitAndFinalize(ObjSetHandleT H) { MockObjSetHandle = H; }
void expectEmitAndFinalize(ObjHandleT H) { MockObjHandle = H; }
void verifyEmitAndFinalize() {
EXPECT_EQ("emitAndFinalize", LastCalled);
resetExpectations();
}
void mapSectionAddress(ObjSetHandleT H, const void *LocalAddress,
void mapSectionAddress(ObjHandleT H, const void *LocalAddress,
llvm::JITTargetAddress TargetAddr) {
EXPECT_EQ(MockObjSetHandle, H);
EXPECT_EQ(MockObjHandle, H);
EXPECT_EQ(MockLocalAddress, LocalAddress);
EXPECT_EQ(MockTargetAddress, TargetAddr);
LastCalled = "mapSectionAddress";
}
void expectMapSectionAddress(ObjSetHandleT H, const void *LocalAddress,
void expectMapSectionAddress(ObjHandleT H, const void *LocalAddress,
llvm::JITTargetAddress TargetAddr) {
MockObjSetHandle = H;
MockObjHandle = H;
MockLocalAddress = LocalAddress;
MockTargetAddress = TargetAddr;
}
@ -169,27 +162,27 @@ private:
std::string LastCalled;
MockMemoryManager MockManager;
MockSymbolResolver MockResolver;
std::vector<MockObjectFile> MockObjects;
ObjSetHandleT MockObjSetHandle;
MockObjectFile MockObject;
ObjHandleT MockObjHandle;
std::string MockName;
bool MockBool;
llvm::JITSymbol MockSymbol;
const void *MockLocalAddress;
llvm::JITTargetAddress MockTargetAddress;
MockMemoryBufferSet MockBufferSet;
MockMemoryBuffer MockBuffer;
// Clear remembered parameters between calls
void resetExpectations() {
LastCalled = "nothing";
MockManager = 0;
MockResolver = 0;
MockObjects.clear();
MockObjSetHandle = 0;
MockObject = 0;
MockObjHandle = 0;
MockName = "bogus";
MockSymbol = llvm::JITSymbol(nullptr);
MockLocalAddress = nullptr;
MockTargetAddress = 0;
MockBufferSet = 0;
MockBuffer = 0;
}
};
@ -204,43 +197,36 @@ TEST(ObjectTransformLayerTest, Main) {
// Create a second object transform layer using a transform (as a lambda)
// that mutates objects in place, and deals in naked pointers
ObjectTransformLayer<MockBaseLayer,
std::function<MockObjectFile *(MockObjectFile *)>>
T2(M, [](MockObjectFile *Obj) {
std::function<std::shared_ptr<MockObjectFile>(
std::shared_ptr<MockObjectFile>)>>
T2(M, [](std::shared_ptr<MockObjectFile> Obj) {
++(*Obj);
return Obj;
});
// Instantiate some mock objects to use below
MockObjectFile MockObject1 = 211;
MockObjectFile MockObject2 = 222;
MockMemoryManager MockManager = 233;
MockSymbolResolver MockResolver = 244;
// Test addObjectSet with T1 (allocating, unique pointers)
std::vector<std::unique_ptr<MockObjectFile>> Objs1;
Objs1.push_back(llvm::make_unique<MockObjectFile>(MockObject1));
Objs1.push_back(llvm::make_unique<MockObjectFile>(MockObject2));
// Test addObject with T1 (allocating)
auto Obj1 = std::make_shared<MockObjectFile>(211);
auto MM = llvm::make_unique<MockMemoryManager>(MockManager);
auto SR = llvm::make_unique<MockSymbolResolver>(MockResolver);
M.expectAddObjectSet(Objs1, MM.get(), SR.get());
auto H = T1.addObjectSet(std::move(Objs1), std::move(MM), std::move(SR));
M.verifyAddObjectSet(H);
M.expectAddObject(Obj1, MM.get(), SR.get());
auto H = T1.addObject(std::move(Obj1), std::move(MM), std::move(SR));
M.verifyAddObject(H);
// Test addObjectSet with T2 (mutating, naked pointers)
llvm::SmallVector<MockObjectFile *, 2> Objs2Vec;
Objs2Vec.push_back(&MockObject1);
Objs2Vec.push_back(&MockObject2);
llvm::MutableArrayRef<MockObjectFile *> Objs2(Objs2Vec);
M.expectAddObjectSet(Objs2, &MockManager, &MockResolver);
H = T2.addObjectSet(Objs2, &MockManager, &MockResolver);
M.verifyAddObjectSet(H);
EXPECT_EQ(212, MockObject1) << "Expected mutation";
EXPECT_EQ(223, MockObject2) << "Expected mutation";
// Test addObjectSet with T2 (mutating)
auto Obj2 = std::make_shared<MockObjectFile>(222);
M.expectAddObject(Obj2, &MockManager, &MockResolver);
H = T2.addObject(Obj2, &MockManager, &MockResolver);
M.verifyAddObject(H);
EXPECT_EQ(223, *Obj2) << "Expected mutation";
// Test removeObjectSet
M.expectRemoveObjectSet(H);
T1.removeObjectSet(H);
M.verifyRemoveObjectSet();
M.expectRemoveObject(H);
T1.removeObject(H);
M.verifyRemoveObject();
// Test findSymbol
std::string Name = "foo";
@ -269,13 +255,13 @@ TEST(ObjectTransformLayerTest, Main) {
M.verifyMapSectionAddress();
// Verify transform getter (non-const)
MockObjectFile Mutatee = 277;
MockObjectFile *Out = T2.getTransform()(&Mutatee);
EXPECT_EQ(&Mutatee, Out) << "Expected in-place transform";
EXPECT_EQ(278, Mutatee) << "Expected incrementing transform";
auto Mutatee = std::make_shared<MockObjectFile>(277);
auto Out = T2.getTransform()(Mutatee);
EXPECT_EQ(*Mutatee, *Out) << "Expected in-place transform";
EXPECT_EQ(278, *Mutatee) << "Expected incrementing transform";
// Verify transform getter (const)
auto OwnedObj = llvm::make_unique<MockObjectFile>(288);
auto OwnedObj = std::make_shared<MockObjectFile>(288);
const auto &T1C = T1;
OwnedObj = T1C.getTransform()(std::move(OwnedObj));
EXPECT_EQ(289, *OwnedObj) << "Expected incrementing transform";
@ -287,8 +273,8 @@ TEST(ObjectTransformLayerTest, Main) {
// Make sure that ObjectTransformLayer implements the object layer concept
// correctly by sandwitching one between an ObjectLinkingLayer and an
// IRCompileLayer, verifying that it compiles if we have a call to the
// IRComileLayer's addModuleSet that should call the transform layer's
// addObjectSet, and also calling the other public transform layer methods
// IRComileLayer's addModule that should call the transform layer's
// addObject, and also calling the other public transform layer methods
// directly to make sure the methods they intend to forward to exist on
// the ObjectLinkingLayer.
@ -309,17 +295,20 @@ TEST(ObjectTransformLayerTest, Main) {
};
// Construct the jit layers.
RTDyldObjectLinkingLayer<> BaseLayer;
auto IdentityTransform = [](
std::unique_ptr<llvm::object::OwningBinary<llvm::object::ObjectFile>>
Obj) { return Obj; };
RTDyldObjectLinkingLayer BaseLayer;
auto IdentityTransform =
[](std::shared_ptr<llvm::object::OwningBinary<llvm::object::ObjectFile>>
Obj) {
return Obj;
};
ObjectTransformLayer<decltype(BaseLayer), decltype(IdentityTransform)>
TransformLayer(BaseLayer, IdentityTransform);
auto NullCompiler = [](llvm::Module &) {
return llvm::object::OwningBinary<llvm::object::ObjectFile>();
return llvm::object::OwningBinary<llvm::object::ObjectFile>(nullptr,
nullptr);
};
IRCompileLayer<decltype(TransformLayer)> CompileLayer(TransformLayer,
NullCompiler);
IRCompileLayer<decltype(TransformLayer), decltype(NullCompiler)>
CompileLayer(TransformLayer, NullCompiler);
// Make sure that the calls from IRCompileLayer to ObjectTransformLayer
// compile.
@ -329,11 +318,11 @@ TEST(ObjectTransformLayerTest, Main) {
// Make sure that the calls from ObjectTransformLayer to ObjectLinkingLayer
// compile.
decltype(TransformLayer)::ObjSetHandleT ObjSet;
TransformLayer.emitAndFinalize(ObjSet);
TransformLayer.findSymbolIn(ObjSet, Name, false);
decltype(TransformLayer)::ObjHandleT H2;
TransformLayer.emitAndFinalize(H2);
TransformLayer.findSymbolIn(H2, Name, false);
TransformLayer.findSymbol(Name, true);
TransformLayer.mapSectionAddress(ObjSet, nullptr, 0);
TransformLayer.removeObjectSet(ObjSet);
TransformLayer.mapSectionAddress(H2, nullptr, 0);
TransformLayer.removeObject(H2);
}
}

View File

@ -63,7 +63,7 @@ TEST(RTDyldObjectLinkingLayerTest, TestSetProcessAllSections) {
bool &DebugSeen;
};
RTDyldObjectLinkingLayer<> ObjLayer;
RTDyldObjectLinkingLayer ObjLayer;
LLVMContext Context;
auto M = llvm::make_unique<Module>("", Context);
@ -85,9 +85,9 @@ TEST(RTDyldObjectLinkingLayerTest, TestSetProcessAllSections) {
if (!TM)
return;
auto OwningObj = SimpleCompiler(*TM)(*M);
std::vector<object::ObjectFile*> Objs;
Objs.push_back(OwningObj.getBinary());
auto Obj =
std::make_shared<object::OwningBinary<object::ObjectFile>>(
SimpleCompiler(*TM)(*M));
bool DebugSectionSeen = false;
auto SMMW =
@ -103,21 +103,21 @@ TEST(RTDyldObjectLinkingLayerTest, TestSetProcessAllSections) {
{
// Test with ProcessAllSections = false (the default).
auto H = ObjLayer.addObjectSet(Objs, SMMW, &*Resolver);
auto H = ObjLayer.addObject(Obj, SMMW, &*Resolver);
ObjLayer.emitAndFinalize(H);
EXPECT_EQ(DebugSectionSeen, false)
<< "Unexpected debug info section";
ObjLayer.removeObjectSet(H);
ObjLayer.removeObject(H);
}
{
// Test with ProcessAllSections = true.
ObjLayer.setProcessAllSections(true);
auto H = ObjLayer.addObjectSet(Objs, SMMW, &*Resolver);
auto H = ObjLayer.addObject(Obj, SMMW, &*Resolver);
ObjLayer.emitAndFinalize(H);
EXPECT_EQ(DebugSectionSeen, true)
<< "Expected debug info section not seen";
ObjLayer.removeObjectSet(H);
ObjLayer.removeObject(H);
}
}
@ -125,7 +125,7 @@ TEST_F(RTDyldObjectLinkingLayerExecutionTest, NoDuplicateFinalization) {
if (!TM)
return;
RTDyldObjectLinkingLayer<> ObjLayer;
RTDyldObjectLinkingLayer ObjLayer;
SimpleCompiler Compile(*TM);
// Create a pair of modules that will trigger recursive finalization:
@ -151,9 +151,9 @@ TEST_F(RTDyldObjectLinkingLayerExecutionTest, NoDuplicateFinalization) {
Builder.CreateRet(FourtyTwo);
}
auto Obj1 = Compile(*MB1.getModule());
std::vector<object::ObjectFile*> Obj1Set;
Obj1Set.push_back(Obj1.getBinary());
auto Obj1 =
std::make_shared<object::OwningBinary<object::ObjectFile>>(
Compile(*MB1.getModule()));
ModuleBuilder MB2(Context, "", "dummy");
{
@ -164,9 +164,9 @@ TEST_F(RTDyldObjectLinkingLayerExecutionTest, NoDuplicateFinalization) {
IRBuilder<> Builder(FooEntry);
Builder.CreateRet(Builder.CreateCall(BarDecl));
}
auto Obj2 = Compile(*MB2.getModule());
std::vector<object::ObjectFile*> Obj2Set;
Obj2Set.push_back(Obj2.getBinary());
auto Obj2 =
std::make_shared<object::OwningBinary<object::ObjectFile>>(
Compile(*MB2.getModule()));
auto Resolver =
createLambdaResolver(
@ -180,10 +180,10 @@ TEST_F(RTDyldObjectLinkingLayerExecutionTest, NoDuplicateFinalization) {
});
auto SMMW = std::make_shared<SectionMemoryManagerWrapper>();
ObjLayer.addObjectSet(std::move(Obj1Set), SMMW, &*Resolver);
auto H = ObjLayer.addObjectSet(std::move(Obj2Set), SMMW, &*Resolver);
ObjLayer.addObject(std::move(Obj1), SMMW, &*Resolver);
auto H = ObjLayer.addObject(std::move(Obj2), SMMW, &*Resolver);
ObjLayer.emitAndFinalize(H);
ObjLayer.removeObjectSet(H);
ObjLayer.removeObject(H);
// Finalization of module 2 should trigger finalization of module 1.
// Verify that finalize on SMMW is only called once.
@ -195,7 +195,7 @@ TEST_F(RTDyldObjectLinkingLayerExecutionTest, NoPrematureAllocation) {
if (!TM)
return;
RTDyldObjectLinkingLayer<> ObjLayer;
RTDyldObjectLinkingLayer ObjLayer;
SimpleCompiler Compile(*TM);
// Create a pair of unrelated modules:
@ -222,9 +222,9 @@ TEST_F(RTDyldObjectLinkingLayerExecutionTest, NoPrematureAllocation) {
Builder.CreateRet(FourtyTwo);
}
auto Obj1 = Compile(*MB1.getModule());
std::vector<object::ObjectFile*> Obj1Set;
Obj1Set.push_back(Obj1.getBinary());
auto Obj1 =
std::make_shared<object::OwningBinary<object::ObjectFile>>(
Compile(*MB1.getModule()));
ModuleBuilder MB2(Context, "", "dummy");
{
@ -236,16 +236,16 @@ TEST_F(RTDyldObjectLinkingLayerExecutionTest, NoPrematureAllocation) {
Value *Seven = ConstantInt::getSigned(Int32Ty, 7);
Builder.CreateRet(Seven);
}
auto Obj2 = Compile(*MB2.getModule());
std::vector<object::ObjectFile*> Obj2Set;
Obj2Set.push_back(Obj2.getBinary());
auto Obj2 =
std::make_shared<object::OwningBinary<object::ObjectFile>>(
Compile(*MB2.getModule()));
auto SMMW = std::make_shared<SectionMemoryManagerWrapper>();
NullResolver NR;
auto H = ObjLayer.addObjectSet(std::move(Obj1Set), SMMW, &NR);
ObjLayer.addObjectSet(std::move(Obj2Set), SMMW, &NR);
auto H = ObjLayer.addObject(std::move(Obj1), SMMW, &NR);
ObjLayer.addObject(std::move(Obj2), SMMW, &NR);
ObjLayer.emitAndFinalize(H);
ObjLayer.removeObjectSet(H);
ObjLayer.removeObject(H);
// Only one call to needsToReserveAllocationSpace should have been made.
EXPECT_EQ(SMMW->NeedsToReserveAllocationSpaceCount, 1)